diff -u --recursive --new-file v2.4.9/linux/CREDITS linux/CREDITS
--- v2.4.9/linux/CREDITS	Mon Aug 27 12:41:37 2001
+++ linux/CREDITS	Sun Sep  9 10:43:02 2001
@@ -400,13 +400,12 @@
 S: USA
 
 N: Peter Braam
-E: braam@cs.cmu.edu
-W: http://coda.cs.cmu.edu/~braam
-D: Coda Filesystem
-S: Dept of Computer Science
-S: 5000 Forbes Avenue
-S: Pittsburgh, Pennsylvania 15213
-S: USA
+E: braam@clusterfs.com
+W: http://www.clusterfs.com/
+D: Coda & InterMezzo filesystems
+S: 181 McNeil
+S: Canmore, AB
+S: Canada, T1W 2R9
 
 N: Ryan Bradetich
 E: rbradetich@uswest.net
@@ -535,6 +534,12 @@
 S: Stanford, California 94305
 S: USA
 
+N: Randolph Chung
+E: tausq@debian.org
+D: Linux/PA-RISC hacker
+S: Fremont, CA 94538
+S: USA
+
 N: Juan Jose Ciarlante
 W: http://juanjox.kernelnotes.org/
 E: jjciarla@raiz.uncu.edu.ar
@@ -633,10 +638,11 @@
 S: USA
 
 N: Frank Davis
+E: fdavis@si.rr.com
 E: fdavis112@juno.com
 D: Various kernel patches
 S: 8 Lakeview Terr.
-S: Kerhonskon, NY 12446
+S: Kerhonkson, NY 12446
 S: USA
 
 N: Wayne Davison
@@ -714,7 +720,7 @@
 N: Oleg Drokin
 E: green@ccssu.crimea.ua
 W: http://www.ccssu.crimea.ua/~green
-D: Cleaning up sound drivers.
+D: Cleaning up sound drivers, SA1100 Watchdog.
 S: Skvoznoy per., 14a
 S: Evpatoria
 S: Crimea
diff -u --recursive --new-file v2.4.9/linux/Documentation/00-INDEX linux/Documentation/00-INDEX
--- v2.4.9/linux/Documentation/00-INDEX	Thu Feb  8 16:32:44 2001
+++ linux/Documentation/00-INDEX	Mon Aug 27 07:44:15 2001
@@ -5,6 +5,11 @@
 Please try and keep the descriptions small enough to fit on one line.
 							 Thanks -- Paul G.
 
+Following translations are available on the WWW:
+
+   - Japanese, maintained by the JF Project (JF@linux.or.jp), at
+     http://www.linux.or.jp/JF/
+
 00-INDEX
 	- this file.
 BUG-HUNTING
diff -u --recursive --new-file v2.4.9/linux/Documentation/CodingStyle linux/Documentation/CodingStyle
--- v2.4.9/linux/Documentation/CodingStyle	Wed Sep 29 13:59:12 1999
+++ linux/Documentation/CodingStyle	Sun Sep  9 16:40:43 2001
@@ -233,3 +233,34 @@
 stable. All options that are known to trash data (experimental write-
 support for file-systems, for instance) should be denoted (DANGEROUS), other
 Experimental options should be denoted (EXPERIMENTAL).
+
+
+		Chapter 8: Data structures
+
+Data structures that have visibility outside the single-threaded
+environment they are created and destroyed in should always have
+reference counts.  In the kernel, garbage collection doesn't exist (and
+outside the kernel garbage collection is slow and inefficient), which
+means that you absolutely _have_ to reference count all your uses. 
+
+Reference counting means that you can avoid locking, and allows multiple
+users to have access to the data structure in parallel - and not having
+to worry about the structure suddenly going away from under them just
+because they slept or did something else for a while. 
+
+Note that locking is _not_ a replacement for reference counting. 
+Locking is used to keep data structures coherent, while reference
+counting is a memory management technique.  Usually both are needed, and
+they are not to be confused with each other.
+
+Many data structures can indeed have two levels of reference counting,
+when there are users of different "classes".  The subclass count counts
+the number of subclass users, and decrements the global count just once
+when the subclass count goes to zero.
+
+Examples of this kind of "multi-reference-counting" can be found in
+memory management ("struct mm_struct": mm_users and mm_count), and in
+filesystem code ("struct super_block": s_count and s_active).
+
+Remember: if another thread can find your data structure, and you don't
+have a reference count on it, you almost certainly have a bug.
diff -u --recursive --new-file v2.4.9/linux/Documentation/Configure.help linux/Documentation/Configure.help
--- v2.4.9/linux/Documentation/Configure.help	Mon Aug 27 12:41:37 2001
+++ linux/Documentation/Configure.help	Sat Sep  8 12:39:33 2001
@@ -1746,6 +1746,36 @@
   similar) CPU, R4xx0 might be a safe bet.
   If the resulting Kernel does not work try to recompile with R3000.
 
+CPU type
+CONFIG_CPU_VR41XX
+  The options selects support for the NEC VR41xx series of processors.
+  Only choose this option if you have one of these processors as a
+  kernel built with this option will not run on any other type of
+  processor or vice versa.
+
+CPU feature configuration
+CONFIG_CPU_ADVANCED
+  Saying yes here allows you to select support for various features your
+  CPU may or may not have.  Most people should say N here.
+
+ll and sc instructions
+CONFIG_CPU_HAS_LLSC
+  Say Y here if your CPU has the ll and sc instructions.  Say Y here for
+  better performance, N if you don't know.  You must say Y here for
+  multiprocessor machines.
+
+lld and scd instructions
+CONFIG_CPU_HAS_LLDSCD
+  Say Y here if your CPU has the lld and scd instructions, the 64-bit
+  equivalents of ll and sc.  Say Y here for better performance, N if
+  you don't know.  You must say Y here for multiprocessor machines.
+
+Support for writebuffer flushing
+CONFIG_CPU_HAS_WB
+  Say N here for slightly better performance.  You must say Y here for
+  machines which require flushing of write buffers in software.  Saying
+  Y is the safe option; N may result in kernel malfunction and crashes.
+
 Support for large 64-bit configurations
 CONFIG_MIPS_INSANE_LARGE
   MIPS R10000 does support a 44 bit / 16TB address space as opposed to
@@ -11478,6 +11508,45 @@
   The module will be called pegasus.o. If you want to compile it as a
   module, say M here and read Documentation/modules.txt.
 
+CONFIG_USB_KAWETH
+  Say Y here if you want to use one of the following 10Mbps only
+  USB Ethernet adapters based on the KLSI KL5KUSB101B chipset:
+       3Com 3C19250
+       ADS USB-10BT
+       ATEN USB Ethernet
+       ASANTE USB To Ethernet Adapter
+       AOX Endpoints USB Ethernet
+       Correga K.K.
+       D-Link DSB-650C and DU-E10
+       Entrega / Portgear E45
+       I-O DATA USB-ET/T
+       Jaton USB Ethernet Device Adapter
+       Kingston Technology USB Ethernet Adapter
+       Linksys USB10T
+       Mobility USB-Ethernet Adapter
+        NetGear EA-101
+       Peracom Enet and Enet2
+       Portsmith Express Ethernet Adapter
+       Shark Pocket Adapter
+       SMC 2202USB
+       Sony Vaio port extender
+
+  This driver is likely to work with most 10Mbps only USB Ethernet
+  adapters, including some "no brand" devices. It does NOT work on
+  SmartBridges smartNIC or on Belkin F5U111 devices - you should use
+  the CATC NetMate driver for those. If you are not sure which one
+  you need, select both, and the correct one should be selected for
+  you.
+
+  This driver makes the adapter appear as a normal Ethernet interface,
+  typically on eth0, if it is the only ethernet device, or perhaps on
+  eth1, if you have a PCI or ISA ethernet card installed.
+
+  This code is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called kaweth.o. If you want to compile it as a
+  module, say M here and read <file:Documentation/modules.txt>.
+
 USB CATC NetMate-based Ethernet device support
 CONFIG_USB_CATC
   Say Y if you want to use one of the following 10Mbps USB Ethernet
@@ -11532,6 +11601,20 @@
   Say Y here in order to have the USB Mass Storage code generate
   verbose debugging messages.
 
+ISD-200 USB/ATA driver
+CONFIG_USB_STORAGE_ISD200
+  Say Y here if you want to use USB Mass Store devices based
+  on the In-Systems Design ISD-200 USB/ATA bridge.
+
+  Some of the products that use this chip are:
+
+    - Archos Jukebox 6000
+    - ISD SmartCable for Storage
+    - Taiwan Skymaster CD530U/DEL-0241 IDE bridge
+    - Sony CRX10U CD-R/RW drive
+    - CyQ've CQ8060A CDRW drive
+    - Planex eXtreme Drive RX-25HU USB-IDE cable (not model RX-25U)
+
 USS720 parport driver
 CONFIG_USB_USS720
   This driver is for USB parallel port adapters that use the Lucent
@@ -11604,18 +11687,22 @@
   The module will be called dabusb.o. If you want to compile it as a
   module, say M here and read Documentation/modules.txt.
 
-PLUSB driver
-CONFIG_USB_PLUSB
-  A driver for the Prolific PL-2302 USB-to-USB network device. This
-  'USB cable' connects two hosts via a point-to-point network with
-  bandwidth of 5 Mbit/s. Configure this driver after connecting the
-  USB cable via ifconfig plusb0 10.0.0.1 pointopoint 10.0.0.2 (and
-  vice versa on the other host).
+Host-to-Host USB networking
+CONFIG_USB_USBNET
+  This driver supports network links over USB with USB "Network"
+  or "data transfer" cables, often used to network laptops to PCs.
+  Such cables have chips from suppliers such as NetChip and Prolific.
+  Intelligent USB devices could also use this approach to provide
+  Internet access, using standard USB cabling.
+
+  These links will have names like "usb0", "usb1", etc.  They act
+  like two-node Ethernets, so you can use 802.1d Ethernet Bridging
+  (CONFIG_BRIDGE) to simplify your network routing.
 
-  This code is also available as a module ( = code which can be
+  This code is also available as a kernel module (code which can be
   inserted in and removed from the running kernel whenever you want).
-  The module will be called plusb.o. If you want to compile it as a
-  module, say M here and read Documentation/modules.txt.
+  The module will be called usbnet.o. If you want to compile it as a
+  module, say M here and read <file:Documentation/modules.txt>.
 
 USB Diamond Rio500 support
 CONFIG_USB_RIO500
@@ -15754,6 +15841,14 @@
   better 32 MB RAM to avoid excessive linking time. This is only
   useful for kernel hackers. If unsure, say N.
 
+Run uncached
+CONFIG_MIPS_UNCACHED
+  If you say Y here there kernel will disable all CPU caches.  This will
+  reduce the system's performance dramatically but can help finding
+  otherwise hard to track bugs.  It can also useful if you're doing
+  hardware debugging with a logic analyzer and need to see all traffic
+  on the bus.
+
 Magic System Request Key support
 CONFIG_MAGIC_SYSRQ
   If you say Y here, you will have some control over the system even
@@ -16960,12 +17055,12 @@
 
 Motorola MPC8260 CPM support
 CONFIG_8260
-   The MPC8260 CPM (Communications Processor Module) is a typically
-   embedded CPU made by Motorola.  Selecting this option means that
-   you wish to build a kernel for a machine with specifically an 8260
-   for a CPU.
+  The MPC8260 CPM (Communications Processor Module) is a typical
+  embedded CPU made by Motorola. Selecting this option means that you
+  wish to build a kernel for a machine with specifically an 8260 for
+  a CPU.
 
-   If in doubt, say N.
+  If in doubt, say N.
 
 Workarounds for PPC601 bugs
 CONFIG_PPC601_SYNC_FIX
@@ -16983,11 +17078,190 @@
 CONFIG_ALL_PPC
   Linux currently supports several different kinds of PowerPC-based
   machines: Apple Power Macintoshes and clones (such as the Motorola
-  Starmax series), PReP (PowerPC Reference Platform) machines such as
-  the Motorola PowerStack, CHRP (Common Hardware Reference Platform), 
-  the embedded MBX boards from Motorola and many others. Currently, 
-  the default option is to build a kernel which works on the first 
-  three.  Support for other machines is currently incomplete.
+  Starmax series), PReP (PowerPC Reference Platform) machines (such
+  as the Motorola PowerStacks, Motorola cPCI/VME embedded systems,
+  and some IBM RS/6000 systems), CHRP (Common Hardware Reference
+  Platform), and several embedded PowerPC systems containing 4xx, 6xx,
+  7xx, 8xx, 74xx, and 82xx processors.  Currently, the default option
+  is to build a kernel which works on the first three. 
+
+Embedded 8xx Board Type
+CONFIG_RPXLITE
+  RPX-Lite:
+    Embedded Planet RPX Lite
+
+  RPX-Classic:
+    Embedded Planet RPX Classic Low-fat.
+
+  BSE-IP: 
+    Bright Star Engineering ip-Engine.
+
+  TQM823L:
+  TQM850L:
+  TQM855L:
+  TQM860L:
+    MPC8xx based family of mini modules, half credit card size,
+    up to 64 MB of RAM, 8 MB Flash, (Fast) Ethernet, 2 x serial ports,
+    2 x CAN bus interface, ...
+      Manufacturer: TQ Components, www.tq-group.de
+      Date of Release: October (?) 1999
+      End of Life: not yet :-)
+      URL:
+      - module: http://www.denx.de/PDF/TQM8xxLHWM201.pdf
+      - starter kit: http://www.denx.de/PDF/STK8xxLHWM201.pdf
+      - images: http://www.denx.de/embedded-ppc-en.html
+
+  FPS850L:
+    FingerPrint Sensor System (based on TQM850L)
+      Manufacturer: IKENDI AG, http://www.ikendi.com/
+      Date of Release: November 1999
+      End of life: end 2000 ?
+      URL: see TQM850L
+
+  SPD823TS:
+    MPC823 based board used in the "Tele Server" product
+    Manufacturer: Speech Design, http://www.speech-design.de/
+    Date of Release: Mid 2000 (?)
+    End of life: -
+    URL: http://www.speech-design.de/
+         select "English", then "Teleteam Solutions", then "TeleServer"
+
+  IVMS8:
+    MPC860 based board used in the "Integrated Voice Mail System",
+    Small Version (8 voice channels)
+    Manufacturer: Speech Design, http://www.speech-design.de/
+    Date of Release: December 2000 (?)
+    End of life: -
+    URL: http://www.speech-design.de/
+
+  IVML24:
+    MPC860 based board used in the "Integrated Voice Mail System", 
+    Large Version (24 voice channels)
+    Manufacturer: Speech Design, http://www.speech-design.de/
+    Date of Release: March 2001  (?)
+    End of life: -
+    URL: http://www.speech-design.de/
+
+  SM850:
+    Service Module (based on TQM850L)
+    Manufacturer: Dependable Computer Systems, http://www.decomsys.com/
+    Date of Release: end 2000 (?)
+    End of life: mid 2001 (?)
+    URL: http://www.tz-mikroelektronik.de/ServiceModule/index.html
+
+  HERMES:
+    Hermes-Pro ISDN/LAN router with integrated 8 x hub
+    Manufacturer: Multidata Gesellschaft für Datentechnik und Informatik
+      http://www.multidata.de/
+    Date of Release: 2000 (?)
+    End of life: -
+    URL: http://www.multidata.de/english/products/hpro.htm
+
+  IP860:	
+    VMEBus IP (Industry Pack) carrier board with MPC860
+    Manufacturer: MicroSys GmbH, http://www.microsys.de/
+    Date of Release: ?
+    End of life: -
+    URL: http://www.microsys.de/html/ip860.html
+
+  PCU_E:
+    PCU = Peripheral Controller Unit, Extended
+    Manufacturer: Siemens AG, ICN (Information and Communication Networks)
+    	http://www.siemens.de/page/1,3771,224315-1-999_2_226207-0,00.html
+    Date of Release: April 2001
+    End of life: August 2001
+    URL: n. a.
+
+Embedded 82xx Board Type
+CONFIG_EST8260
+  EST8260: Wind River System, Inc. EST SBC8260
+
+  TQM8260:
+    MPC8260 based module, little larger than credit card,
+    up to 128 MB global + 64 MB local RAM, 32 MB Flash,
+    32 kB EEPROM, 256 kB L@ Cache, 10baseT + 100baseT Ethernet,
+    2 x serial ports, ...
+      Manufacturer: TQ Components, www.tq-group.de
+      Date of Release: June 2001
+      End of Life: not yet :-)
+      URL: http://www.denx.de/PDF/TQM82xx_SPEC_Rev005.pdf
+
+  PM826:
+    Modular system with MPC8260 CPU
+    Manufacturer: MicroSys GmbH, http://www.microsys.de/
+    Date of Release: mid 2001
+    End of life: -
+    URL: http://www.microsys.de/html/pm826.html
+
+  CU824:
+    VMEBus Board with PCI extension with MPC8240 CPU
+    Manufacturer: MicroSys GmbH, http://www.microsys.de/
+    Date of Release: early 2001 (?)
+    End of life: -
+    URL: http://www.microsys.de/html/cu824.html
+
+AltiVec Kernel Support
+CONFIG_ALTIVEC
+  This option enables kernel support for the Altivec extensions to the
+  PowerPC processor. The kernel currently supports saving and restoring
+  altivec registers, and turning on the 'altivec enable' bit so user
+  processes can execute altivec instructions.
+
+  This option is only usefully if you have a processor that supports 
+  altivec (G4, otherwise known as 74xx series), but does not have
+  any affect on a non-altivec cpu (it does, however add code to the
+  kernel).
+
+  If in doubt, say Y here.
+
+Thermal Management Support
+CONFIG_TAU
+  G3 and G4 processors have an on-chip temperature sensor called the
+  'Thermal Assist Unit (TAU)', which, in theory, can measure the on-die
+  temperature within 2-4 degrees celcius. This option shows the current
+  on-die temperature in /proc/cpuinfo if the cpu supports it.
+
+  Unfortunately, on some chip revisions, this sensor is very inaccurate
+  and in some cases, does not work at all, so don't assume the cpu
+  temp is actually what /proc/cpuinfo says it is.
+
+Interrupt driven TAU driver
+CONFIG_TAU_INT
+  The TAU supports an interrupt driven mode which causes an interrupt
+  whenever the temperature goes out of range. This is the fastest way
+  to get notified the temp has exceeded a range. With this option off,
+  a timer is used to re-check the temperature periodically.
+
+  However, on some cpus it appears that the TAU interrupt hardware
+  is buggy and can cause a situation which would lead unexplained hard
+  lockups.
+
+  Unless you are extending the TAU driver, or enjoy kernel/hardware
+  debugging, leave this option off.
+
+Average high and low temp
+CONFIG_TAU_AVERAGE
+  The TAU hardware can compare the temperature to an upper and lower bound.
+  The default behavior is to show both the upper and lower bound in 
+  /proc/cpuinfo. If the range is large, the temperature is either changing
+  a lot, or the TAU hardware is broken (likely on some G4's). If the range
+  is small (around 4 degrees), the temperature is relatively stable.
+
+Support for CUDA based PowerMacs
+CONFIG_ADB_CUDA
+  This provides support for CUDA based Power Macintosh systems.  This
+  includes most OldWorld PowerMacs, the first generation iMacs, the
+  Blue&White G3 and the Yikes G4 (PCI Graphics).  All later models
+  should use CONFIG_ADB_PMU instead.
+
+  If unsure say Y.
+
+Support for PMU based PowerMacs
+CONFIG_ADB_PMU
+  This provides support for PMU based Power Macintosh systems.  This
+  includes all PowerBooks and all AGP-based machines.
+  
+  If unsure say Y.
 
 Power management support for PowerBooks
 CONFIG_PMAC_PBOOK
@@ -17004,13 +17278,6 @@
   You may also want to compile the dma sound driver as a module and
   have it autoloaded. The act of removing the module shuts down the
   sound hardware for more power savings.
-
-Mac-on-Linux support
-CONFIG_MOL
-  This option enables low-level support for Mac-on-Linux.
-  MOL lets you run MacOS and Linux simultaneously. Please
-  visit <http://www.maconlinux.org> for more information.
-  If unsure, say Y.
 
 ADB raw keycode support
 CONFIG_MAC_ADBKEYCODES
diff -u --recursive --new-file v2.4.9/linux/Documentation/DocBook/Makefile linux/Documentation/DocBook/Makefile
--- v2.4.9/linux/Documentation/DocBook/Makefile	Wed Jul 25 17:10:16 2001
+++ linux/Documentation/DocBook/Makefile	Fri Sep  7 18:15:17 2001
@@ -24,10 +24,10 @@
 html:	$(HTML)
 
 %.eps: %.fig
-	-fig2dev -Leps $< $@
+	fig2dev -Leps $< $@
 
 %.jpeg: %.fig
-	-fig2dev -Ljpeg $< $@
+	fig2dev -Ljpeg $< $@
 
 %.sgml: %.c
 	echo "<programlisting>" > $@
@@ -129,7 +129,7 @@
 		$(PERL) $(TOPDIR)/scripts/split-man $(TOPDIR)/Documentation/man
 
 parportbook: $(JPG-parportbook)
-parportbook.ps: $(EPS-parportbook)
+parportbook.ps parportbook.pdf: $(EPS-parportbook)
 parportbook.sgml: parportbook.tmpl $(TOPDIR)/drivers/parport/init.c
 	$(TOPDIR)/scripts/docgen $(TOPDIR)/drivers/parport/init.c <$< >$@
 
diff -u --recursive --new-file v2.4.9/linux/Documentation/DocBook/kernel-api.tmpl linux/Documentation/DocBook/kernel-api.tmpl
--- v2.4.9/linux/Documentation/DocBook/kernel-api.tmpl	Thu May 24 15:14:08 2001
+++ linux/Documentation/DocBook/kernel-api.tmpl	Sun Sep  9 12:00:55 2001
@@ -187,6 +187,11 @@
 !Edrivers/block/ll_rw_blk.c
   </chapter>
 
+  <chapter id="part">
+     <title>Partition Handling</title>
+!Edrivers/block/genhd.c
+  </chapter>
+
   <chapter id="miscdev">
      <title>Miscellaneous Devices</title>
 !Edrivers/char/misc.c
diff -u --recursive --new-file v2.4.9/linux/Documentation/DocBook/parportbook.tmpl linux/Documentation/DocBook/parportbook.tmpl
--- v2.4.9/linux/Documentation/DocBook/parportbook.tmpl	Sun Aug 12 13:27:58 2001
+++ linux/Documentation/DocBook/parportbook.tmpl	Fri Sep  7 18:15:17 2001
@@ -1654,6 +1654,16 @@
 
       </listitem></varlistentry>
 
+     <varlistentry><term><constant>PPGETMODE</constant></term>
+      <listitem>
+
+       <para>
+	Retrieves the current IEEE 1284 mode to use for
+	<function>read</function> and <function>write</function>.
+       </para>
+
+      </listitem></varlistentry>
+
      <varlistentry><term><constant>PPGETTIME</constant></term>
       <listitem>
 
@@ -1681,6 +1691,36 @@
 	should be a pointer to a <structname>struct
 	timeval</structname>.
        </para>
+
+      </listitem></varlistentry>
+
+     <varlistentry><term><constant>PPGETMODES</constant></term>
+      <listitem>
+
+       <para>
+	Retrieves the capabilities of the hardware (i.e. the
+	<structfield>modes</structfield> field of the
+	<structname>parport</structname> structure).
+       </para>
+
+      </listitem></varlistentry>
+
+     <varlistentry><term><constant>PPSETFLAGS</constant></term>
+      <listitem>
+
+       <para>
+	Sets flags on the <literal>ppdev</literal> device which can
+	affect future I/O operations.  Available flags are:
+       </para>
+
+       <itemizedlist spacing=compact>
+	<listitem><para>
+	  <constant>PP_FASTWRITE</constant></para></listitem>
+	<listitem><para>
+	  <constant>PP_FASTREAD</constant></para></listitem>
+	<listitem><para>
+	  <constant>PP_W91284PIC</constant></para></listitem>
+       </itemizedlist>
 
       </listitem></varlistentry>
 
diff -u --recursive --new-file v2.4.9/linux/Documentation/DocBook/procfs-guide.tmpl linux/Documentation/DocBook/procfs-guide.tmpl
--- v2.4.9/linux/Documentation/DocBook/procfs-guide.tmpl	Tue Jul  3 17:08:18 2001
+++ linux/Documentation/DocBook/procfs-guide.tmpl	Sat Sep  8 12:20:25 2001
@@ -207,7 +207,7 @@
         will return <constant>NULL</constant>. <xref
         linkend="userland"> describes how to do something useful with
         regular files.
-      <para>
+      </para>
 
       <para>
         Note that it is specifically supported that you can pass a
@@ -577,7 +577,7 @@
         the <structfield>owner</structfield> field in the
         <structname>struct proc_dir_entry</structname> to
         <constant>THIS_MODULE</constant>.
-      <para>
+      </para>
 
       <programlisting>
 struct proc_dir_entry* entry;
diff -u --recursive --new-file v2.4.9/linux/Documentation/arm/SA1100/Assabet linux/Documentation/arm/SA1100/Assabet
--- v2.4.9/linux/Documentation/arm/SA1100/Assabet	Fri May 12 11:21:20 2000
+++ linux/Documentation/arm/SA1100/Assabet	Fri Sep  7 09:28:38 2001
@@ -9,38 +9,268 @@
 http://www.cs.cmu.edu/~wearable/software/assabet.html
 
 
-To build the kernel:
+Building the kernel
+-------------------
+
+To build the kernel with current defaults:
 
 	make assabet_config
-	make config
-	[accept all defaults]
+	make oldconfig
 	make dep
 	make zImage
 
-Typically, you'll need angelboot to load the kernel.
-The following angelboot.opt file should be used:
+The resulting kernel image should be available in linux/arch/arm/boot/zImage.
+
+
+Installing a bootloader
+-----------------------
+
+A couple of bootloaders able to boot Linux on Assabet are available:
+
+BLOB (http://www.lart.tudelft.nl/lartware/blob/)
+
+   BLOB is a bootloader used within the LART project.  Some contributed
+   patches were merged into BLOB to add support for Assabet.
+
+Compaq's Bootldr + John Dorsey's patch for Assabet support
+(http://www.handhelds.org/Compaq/bootldr.html)
+(http://www.wearablegroup.org/software/bootldr/)
+
+   Bootldr is the bootloader developed by Compaq for the iPAQ Pocket PC.
+   John Dorsey has produced add-on patches to add support for Assabet and
+   the JFFS filesystem.
+
+RedBoot (http://sources.redhat.com/redboot/)
+
+   RedBoot is a bootloader developed by Red Hat based on the eCos RTOS
+   hardware abstraction layer.  It supports Assabet amongst many other
+   hardware platforms.
+
+RedBoot is currently the recommended choice since it's the only one to have
+networking support, and is the most actively maintained.
+
+Brief examples on how to boot Linux with RedBoot are shown below.  But first
+you need to have RedBoot installed in your flash memory.  A known to work
+precompiled RedBoot binary is available from the following location:
+
+ftp://ftp.netwinder.org/users/n/nico/
+ftp://ftp.arm.linux.org.uk/pub/linux/arm/people/nico/
+ftp://ftp.handhelds.org/pub/linux/arm/sa-1100-patches/
+
+Look for redboot-assabet*.tgz.  Some installation infos are provided in
+redboot-assabet*.txt.
+
+
+Initial RedBoot configuration
+-----------------------------
+
+The commands used here are explained in The RedBoot User's Guide available
+on-line at http://sources.redhat.com/ecos/docs-latest/redboot/redboot.html.
+Please refer to it for explanations.
+
+If you have a CF network card (my Assabet kit contained a CF+ LP-E from
+Socket Communications Inc.), you should strongly consider using it for TFTP
+file transfers.  You must insert it before RedBoot runs since it can't detect
+it dynamically.
+
+To initialize the flash directory:
+
+	fis init -f
+
+To initialize the non-volatile settings, like whether you want to use BOOTP or
+a static IP address, etc, use this command:
+
+	fconfig -i
+
+
+Writing a kernel image into flash
+---------------------------------
+
+First, the kernel image must be loaded into RAM.  If you have the zImage file
+available on a TFTP server:
+
+	load zImage -r -b 0x100000
+
+If you rather want to use Y-Modem upload over the serial port:
+
+	load -m ymodem -r -b 0x100000
+
+To write it to flash:
+
+	fis create "Linux kernel" -b 0x100000 -l 0xc0000
+
+
+Booting the kernel
+------------------
+
+The kernel still requires a filesystem to boot.  A ramdisk image can be loaded
+as follows:
+
+	load ramdisk_image.gz -r -b 0x800000
+
+Again, Y-Modem upload can be used instead of TFTP by replacing the file name
+by '-y ymodem'.
+
+Now the kernel can be retrieved from flash like this:
+
+	fis load "Linux kernel"
+
+or loaded as described previously.  To boot the kernel:
+
+	exec -b 0x100000 -l 0xc0000
+
+The ramdisk image could be stored into flash as well, but there are better
+solutions for on-flash filesystems as mentioned below.
+
+
+Using JFFS2
+-----------
+
+Using JFFS2 (the Second Journaling Flash File System) is probably the most
+convenient way to store a writable filesystem into flash.  JFFS2 is used in
+conjunction with the MTD layer which is responsible for low-level flash
+management.  More information on the Linux MTD can be found on-line at:
+http://www.linux-mtd.infradead.org/.  A JFFS howto with some infos about
+creating JFFS/JFFS2 images is available from the same site.
+
+For instance, a sample JFFS2 image can be retrieved from the same FTP sites
+mentioned below for the precompiled RedBoot image.
+
+To load this file:
+
+	load sample_img.jffs2 -r -b 0x100000
+
+The result should look like:
+
+RedBoot> load sample_img.jffs2 -r -b 0x100000
+Raw file loaded 0x00100000-0x00377424
+
+Now we must know the size of the unallocated flash:
+
+	fis free
+
+Result:
+
+RedBoot> fis free
+  0x500E0000 .. 0x503C0000
+
+The values above may be different depending on the size of the filesystem and
+the type of flash.  See their usage below as an example and take care of
+substituting yours appropriately.
+
+We must determine some values:
+
+size of unallocated flash:	0x503c0000 - 0x500e0000 = 0x2e0000
+size of the filesystem image:	0x00377424 - 0x00100000 = 0x277424
+
+We want to fit the filesystem image of course, but we also want to give it all
+the remaining flash space as well.  To write it:
+
+	fis unlock -f 0x500E0000 -l 0x2e0000
+	fis erase -f 0x500E0000 -l 0x2e0000
+	fis write -b 0x100000 -l 0x277424 -f 0x500E0000
+	fis create "JFFS2" -n -f 0x500E0000 -l 0x2e0000
+
+Now the filesystem is associated to a MTD "partition" once Linux has discovered
+what they are in the boot process.  From Redboot, the 'fis list' command
+displays them:
+
+RedBoot> fis list
+Name              FLASH addr  Mem addr    Length      Entry point
+RedBoot           0x50000000  0x50000000  0x00020000  0x00000000
+RedBoot config    0x503C0000  0x503C0000  0x00020000  0x00000000
+FIS directory     0x503E0000  0x503E0000  0x00020000  0x00000000
+Linux kernel      0x50020000  0x00100000  0x000C0000  0x00000000
+JFFS2             0x500E0000  0x500E0000  0x002E0000  0x00000000
+
+However Linux should display something like:
+
+SA1100 flash: probing 32-bit flash bus
+SA1100 flash: Found 2 x16 devices at 0x0 in 32-bit mode
+Using RedBoot partition definition
+Creating 5 MTD partitions on "SA1100 flash":
+0x00000000-0x00020000 : "RedBoot"
+0x00020000-0x000e0000 : "Linux kernel"
+0x000e0000-0x003c0000 : "JFFS2"
+0x003c0000-0x003e0000 : "RedBoot config"
+0x003e0000-0x00400000 : "FIS directory"
+
+What's important here is the position of the partition we are interested in,
+which is the third one.  Within Linux, this correspond to /dev/mtdblock2.
+Therefore to boot Linux with the kernel and its root filesystem in flash, we
+need this RedBoot command:
+
+	fis load "Linux kernel"
+	exec -b 0x100000 -l 0xc0000 -c "root=/dev/mtdblock2"
+
+Of course other filesystems than JFFS might be used, like cramfs for example.
+You might want to boot with a root filesystem over NFS, etc.  It is also
+possible, and sometimes more convenient, to flash a filesystem directly from
+within Linux while booted from a ramdisk or NFS.  The Linux MTD repository has
+many tools to deal with flash memory as well, to erase it for example.  JFFS2
+can then be mounted directly on a freshly erased partition and files can be
+copied over directly.  Etc...
+
+
+RedBoot scripting
+-----------------
+
+All the commands above aren't so useful if they have to be typed in every
+time the Assabet is rebooted.  Therefore it's possible to automatize the boot
+process using RedBoot's scripting capability.
+
+For example, I use this to boot Linux with both the kernel and the ramdisk
+images retrieved from a TFTP server on the network:
+
+RedBoot> fconfig
+Run script at boot: false true
+Boot script:
+Enter script, terminate with empty line
+>> load zImage -r -b 0x100000
+>> load ramdisk_ks.gz -r -b 0x800000
+>> exec -b 0x100000 -l 0xc0000
+>>
+Boot script timeout (1000ms resolution): 3
+Use BOOTP for network configuration: true
+GDB connection port: 9000
+Network debug at boot time: false
+Update RedBoot non-volatile configuration - are you sure (y/n)? y
+
+Then, rebooting the Assabet is just a matter of waiting for the login prompt.
+
+
+
+Nicolas Pitre
+nico@cam.org
+June 12, 2001
+
+
+Status of peripherals in -rmk tree
+----------------------------------
+
+Assabet:
+ Serial ports:
+  Radio:	TX, RX, CTS, DSR, DCD, RI
+  COM:		TX, RX, CTS, DSR, DCD, RTS, DTR, PM
+  I2C:		TX, RX
+  L3:		No
+
+ Video:
+  LCD:		PM
+  Video out:	Not fully
+  Touchscreen:	No
+
+ Audio:
+  Codec:	No
+  POTS:		No
+
+ Other:
+  PCMCIA:	Yes
+  USB:		No
 
------ begin angelboot.opt -----
-base 0xc0008000
-entry 0xc0008000
-r0 0x00000000
-r1 0x00000019
-device /dev/ttyS1
-options "9600 8N1"
-baud 115200
-otherfile ramdisk_img.gz
-otherbase 0xc0800000
-exec minicom
------ end angelboot.opt -----
-
-Then load the kernel and ramdisk with:
-
-	angelboot -f angelboot.opt zImage
-
-Here it is assumed that your Assabet is connected to ttyS1 and that
-minicom is preconfigured with /dev/ttyS1, 9600 baud, 8N1, no flow control
-by default.
+Neponset:
+ Serial ports:
+  COM1,2:	TX, RX, CTS, DSR, DCD, RTS, DTR
 
-This is work in progress...
+More stuff can be found in the -np (Nicolas Pitre's) tree.
 
-Please send any patches to nico@cam.org.
diff -u --recursive --new-file v2.4.9/linux/Documentation/arm/SA1100/DMA linux/Documentation/arm/SA1100/DMA
--- v2.4.9/linux/Documentation/arm/SA1100/DMA	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/arm/SA1100/DMA	Fri Sep  7 09:28:38 2001
@@ -0,0 +1,248 @@
+Support functions for the SA11x0 internal DMA channels
+======================================================
+
+Nicolas Pitre <nico@cam.org>
+Last updated: 2001/07/15
+
+
+The DMA controller consists of six independent DMA channels. Each channel
+can be configured to service any of the serial controllers. Two channels
+are required to service a full-duplex serial controller. The DMA
+controller is intended to relieve the processor of the interrupt overhead
+in servicing these ports with programmed I/ O.
+
+If desired, any or all peripherals (except the UDC) may be serviced with
+programmed I/ O instead of DMA. Each peripheral is capable of requesting
+processor service through its own interrupt lines or through a DMA
+request.
+
+A set of functions is provided to support drivers working with DMA buffers
+through a generic interface for (wishfully) all DMA usages.  Those
+functions will take care of buffer queueing and splitting, DMA register
+management, interrupt handling, etc.
+
+
+SA11x0 DMA API
+--------------
+
+Here is the description for the DMA API.
+
+
+int sa1100_request_dma( dmach_t *channel, const char *device_id,
+			dma_device_t device );
+
+This function will search for a free DMA channel and returns the channel
+number in '*channel'.  'device_id' should point to a string identifying
+the DMA usage or device (mainly for /proc).  'device' is the SA11x0
+peripheral's ports.  Note that reading from a port and writing to the
+same port are actually considered as two different streams requiring
+two DMA channels with their own device type.  All possible dma_device_t
+are defined in include/asm-arm/arch-sa1100/dma.h.  If no channel is
+available, or if the desired device is already in use by another DMA
+channel, then an error code is returned.  This function must be called
+before any other DMA calls.
+
+
+int sa1100_dma_queue_buffer( dmach_t channel, void *buf_id,
+                             dma_addr_t data, int size );
+
+This function enqueue the specified buffer for DMA processing.  The buffer
+will be transmitted or filled with incoming data depending on the channel
+configuration made through sa1100_dma_set_device().  If the queue is
+empty, DMA starts immediately on the given buffer.
+
+Arguments are:
+
+dmach_t channel:	the channel number.
+void *buf_id:		a buffer identification known by the caller.
+dma_addr_t data:	the buffer's physical address.
+int size:		the buffer size in bytes.
+
+Note here the dma_addr_t which is not the same as the virtual address as
+returned by kmalloc() and friends.  The DMA controller must be given a
+physical address to a buffer which is not cached bye the CPU data cache.
+To get such address, the DMA mapping functions (see
+Documentation/DMA-mapping.txt) are recommended.  The only relevant
+functions are pci_alloc_consistent(), pci_map_single() and their unmap
+counterparts.  The PCI dev argument is NULL of course.
+
+There is no restriction on the buffer size.  The DMA code will split it up
+internally to acommodate the DMA controller as needed.  If the buffer
+can't be enqueued the appropriate error code is returned.
+
+
+int sa1100_dma_set_callback( dmach_t channel, dma_callback_t cb );
+
+As soon as the DMa completes with a buffer, a callback function is used to
+notify the driver which would have registered one.  The callback function
+is prototyped as:
+
+void dma_callback( void *buf_id, int size );
+
+The 'buf_id' argument is the buffer identifier as passed to
+sa1100_dma_queue_buffer().  The 'size' argument is the number of bytes the
+DMA processed (should be the same as the buffer size).
+
+Note that this callback function is called while in interrupt context.
+So it has to be small and efficient while posponing more complex
+processing to a bottom-half function or similar.  All
+restrictions for interrupt handlers still apply.
+
+
+int sa1100_dma_get_current( dmach_t channel, void **buf_id,
+                            dma_addr_t *addr );
+
+This returns the buffer ID and the DMA address pointer within the buffer
+currently being processed.  If no such buffer is currently processed, an
+error code is returned.  This is useful for mmap()'ed buffers like in
+audio drivers.
+
+
+int sa1100_dma_stop( dmach_t channel );
+
+This call stops any DMA transfer on the given channel.
+
+
+int sa1100_dma_resume( dmach_t channel );
+
+This call resumes a DMA transfer which would have been stopped through
+sa1100_dma_stop().
+
+
+int sa1100_dma_flush_all( dmach_t channel );
+
+This completely flushes all queued buffers and on-going DMA transfers on a
+given channel.  The next enqueued buffer following this call will be
+processed right away.
+
+
+int sa1100_dma_set_spin( dmach_t channel, dma_addr_t addr, int size );
+
+Because there is at least one device out there that uses its receive
+signal for its transmit clock reference, we need a mecanism to make the
+DMA "spin" on a certain buffer for when there is no more actual buffer to
+process.  The 'addr' argument is the physical memory address to use, and
+the 'size' argument determines the spin DMA chunk.  This size can't be
+larger than 8191 (if so, it is clamped to 4096).  When the size is 0,
+the spin function is turned off.
+
+When activated, DMA will "spin" until there is any buffer in the queue.
+The current DMA chunk will terminate before a newly queued buffer is
+processed.  The spin buffer will only be reused when there is no more
+acctual buffer to process.
+
+It is important not to choose a too small 'size' value since it will
+greatly increase the interrupt load required to restart the spin.  Since
+this feature will typically be used on transmit DMAs, and because a buffer
+full of zeros is probably the best thing to spin out, the 'addr' argument
+may well be used with FLUSH_BASE_PHYS for which no allocation nor memory
+bus request are needed.
+
+The spinning DMA is affected by sa1100_dma_stop() and sa1100_dma_resume()
+but not bu sa1100_dma_flush_all().
+
+
+void sa1100_free_dma( dmach_t channel );
+
+This clears all activities on a given DMA channel and releases it for
+future requests.
+
+
+Buffer allocation
+-----------------
+
+Like mentionned above, it is the driver's responsibility to allocate, free
+and keep track of buffer space with dma_addr_t type addresses. However the
+driver must not change the state of any buffer after it has been sent to
+sa1100-dma_queue_buffer().  When that function has been called, the buffer
+becomes the DMA's ownership until one of these events occur:
+
+- The callback function is called by the DMA code with a buffer ID to
+  indicate that DMA processing terminated on that buffer.  Then the
+  driver owns the buffer again.
+- The sa1100-dma_flush_all() function is called by the driver at which
+  point *all* queued buffers are owned by the driver again.
+- The sa1100-free_dma() does the same as sa1100-dma_flush_all().
+
+This doesn't mean that you can't change the content of a queued buffer in
+conjonction with the usage of pci_map_consistent() and
+sa1100_dma_get_current()... but then you must be sure you know what you're
+doing (this doesn't work with pci_map_single()).
+
+
+Examples
+--------
+
+A real example of audio ring buffers is implemented in the
+drivers/sound/sa1100-audio.c driver.  The SA1110 USB client and the
+SA11x0 FIR drivers are also using this interface to implement packetized
+DMA.
+
+A transmit DMA for network packets could look like this (largely simplified):
+
+struct sk_buff *tx_ring_skb[RING_SIZE];
+dma_addr_t      tx_ring_dma[RING_SIZE];
+int cur_tx;
+...
+
+transmit function:
+
+	tx_ring_skb[cur_tx] = skb;
+	tx_ring_dma[cur_tx] = pci_map_single(NULL, skb->data, skb->len,
+	                                     PCI_DMA_TODEVICE);
+	sa1100_dma_queue_buffer(channel, (void*)cur_tx,
+	                        tx_ring_dma[cur_tx], skb->len);
+	cur_tx++; cur_tx %= RING_SIZE;
+	...
+
+and the callback function:
+
+void tx_done_callback( void *buf_id, int size ) {
+	int done_tx = (int) buf_id;
+	struct sk_buff *skb = tx_ring_skb[done_tx];
+	pci_unmap_single(NULL, tx_ring_dma[done_tx], skb->len,
+	                 PCI_DMA_TODEVICE);
+	stats.tx_packets++;
+	stats.tx_bytes += size;
+	dev_kfree_skb_irq(skb);
+	tx_ring_skb[done_tx] = NULL;
+}
+
+
+For drivers expecting variable length packets i.e. USB client, it is
+necessary to register the appropriate IRQ to be notified when the receiver
+is idle, the packet is complete, etc.  We could use one buffer at a time
+with its ID being the virtual address of the buffer.
+
+Then the sequence:
+
+	/* be sure DMA won't continue under our feet */
+	sa1100_dma_stop(channel);
+	/* get the actual DMA length */
+	sa1100_get_current(channel, &data, &dma_ptr);
+	/* acquire ownership for the buffer */
+	sa1100_dma_flush_all(channel);
+	/* unmap the DMA buffer (actually doing cache coherency on ARM) */
+	pci_unmap_single (NULL, dma_addr, MAX_PKT_SIZE, PCI_DMA_FROMDEVICE);
+	/* get remaining bytes from the fifo */
+	ptr = data + dma_ptr - dma_addr;
+	while (fifo_not_empty)
+		*ptr++ = get_byte_from_fifo;
+	/* feed another free buffer for the next packet */
+	dma_addr2 = pci_map_single(NULL, data2, MAX_PKT_SIZE,
+					PCI_DMA_FROMDEVICE);
+	sa1100_dma_queue_buffer(channel, data2, dma_addr2, MAX_PKT_SIZE);
+	/* process the current packet */
+	...
+
+might do the trick.  This looks a bit ugly but that's a starting point for
+improvements.
+
+
+TODO
+----
+
+- Create kernel-doc comments in the source to document the API and
+  let the documentation be generated automatically.
+
+
diff -u --recursive --new-file v2.4.9/linux/Documentation/arm/SA1100/FreeBird linux/Documentation/arm/SA1100/FreeBird
--- v2.4.9/linux/Documentation/arm/SA1100/FreeBird	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/arm/SA1100/FreeBird	Fri Sep  7 09:28:38 2001
@@ -0,0 +1,21 @@
+Freebird-1.1 is produced by Legned(C) ,Inc.
+(http://www.legend.com.cn)
+and software/linux mainatined by Coventive(C),Inc.
+(http://www.coventive.com)
+
+Based on the Nicolas's strongarm kernel tree.
+
+===============================================================
+Maintainer:
+
+Chester Kuo <chester@coventive.com>
+	    <chester@linux.org.tw>
+
+Author :
+Tim wu <timwu@coventive.com>
+CIH <cih@coventive.com>
+Eric Peng <ericpeng@coventive.com>
+Jeff Lee <jeff_lee@coventive.com>
+Allen Cheng
+Tony Liu <tonyliu@coventive.com>
+
diff -u --recursive --new-file v2.4.9/linux/Documentation/arm/SA1100/GraphicsClient linux/Documentation/arm/SA1100/GraphicsClient
--- v2.4.9/linux/Documentation/arm/SA1100/GraphicsClient	Mon Nov 27 17:07:59 2000
+++ linux/Documentation/arm/SA1100/GraphicsClient	Fri Sep  7 09:28:38 2001
@@ -1,15 +1,18 @@
-ADS GraphicsClient/ThinClient Single Board Computer
+ADS GraphicsClient Plus Single Board Computer
 
 For more details, contact Applied Data Systems or see
-http://www.flatpanels.com/products.html
+http://www.applieddata.net/products.html
 
 The original Linux support for this product has been provided by 
-Nicolas Pitre <nico@cam.org>.
+Nicolas Pitre <nico@cam.org>. Continued development work by
+Woojung Huh <whuh@applieddata.net>
 
 It's currently possible to mount a root filesystem via NFS providing a
-complete Linux environment.  Otherwise a ramdisk image may be used.  Use
-'make graphicsclient_config' before any 'make config'.  This will set up
-defaults for GraphicsClient/ThinClient support.
+complete Linux environment.  Otherwise a ramdisk image may be used.  The
+board supports MTD/JFFS, so you could also mount something on there.
+
+Use 'make graphicsclient_config' before any 'make config'.  This will set up
+defaults for GraphicsClient Plus support.
 
 The kernel zImage is linked to be loaded and executed at 0xc0200000.  
 Also the following registers should have the specified values upon entry:
@@ -17,8 +20,18 @@
 	r0 = 0
 	r1 = 29	(this is the GraphicsClient architecture number)
 
-Here is a tipical angel.opt option file if the kernel is loaded through
-the Angel Debug Monitor:
+Linux can  be used with the ADS BootLoader that ships with the
+newer rev boards. See their documentation on how to load Linux.
+Angel is not available for the GraphicsClient Plus AFAIK.
+
+There is a  board known as just the GraphicsClient that ADS used to
+produce but has end of lifed. This code will not work on the older
+board with the ADS bootloader, but should still work with Angel,
+as outlined below.  In any case, if you're planning on deploying
+something en masse, you should probably get the newer board.
+
+If using Angel on the older boards, here is a typical angel.opt option file
+if the kernel is loaded through the Angel Debug Monitor:
 
 ----- begin angelboot.opt -----
 base 0xc0200000
@@ -26,7 +39,7 @@
 r0 0x00000000
 r1 0x0000001d
 device /dev/ttyS1
-options "9600 8N1"
+options "38400 8N1"
 baud 115200
 #otherfile ramdisk.gz
 #otherbase 0xc0800000
@@ -39,7 +52,7 @@
 	angelboot -f angelboot.opt zImage
 
 Here it is assumed that the board is connected to ttyS1 on your PC
-and that minicom is preconfigured with /dev/ttyS1, 9600 baud, 8N1, no flow
+and that minicom is preconfigured with /dev/ttyS1, 38400 baud, 8N1, no flow
 control by default.
 
 If any other bootloader is used, ensure it accomplish the same, especially
@@ -47,19 +60,39 @@
 
 
 Supported peripherals:
-- SA1100 LCD frame buffer (only 8bpp yet)
-- on-board SMC 92C94 ethernet NIC
+- SA1100 LCD frame buffer (8/16bpp...sort of)
+- on-board SMC 92C96 ethernet NIC
 - SA1100 serial port
-- flash memory access
+- flash memory access (MTD/JFFS)
 - pcmcia
-- possibly UCB1200 audio (not tested yet)
+- touchscreen(ucb1200)
+- ps/2 keyboard
+- console on LCD screen
+- serial ports (ttyS[0-2])
+  - ttyS0 is default for serial console
+- Smart I/O (ADC, keypad, digital inputs, etc)
+  See http://www.applieddata.com/developers/linux for IOCTL documentation
+  and example user space code. ps/2 keybd is multiplexed through this driver
 
 To do:
-- touchscreen driver
-- 16bpp frame buffer support
-- extra (external) serial port driver
-- some console keyboard support (maybe IR?)
+- UCB1200 audio with new ucb_generic layer
 - everything else!  :-)
+
+Notes:
+
+- The flash on board is divided into 3 partitions.  mtd0 is where
+  the ADS boot ROM and zImage is stored.  It's been marked as
+  read-only to keep you from blasting over the bootloader. :)  mtd1 is
+  for the ramdisk.gz image.  mtd2 is user flash space and can be
+  utilized for either JFFS or if you're feeling crazy, running ext2
+  on top of it. If you're not using the ADS bootloader, you're
+  welcome to blast over the mtd1 partition also.
+
+- 16bpp mode requires a different cable than what ships with the board.
+  Contact ADS or look through the manual to wire your own. Currently,
+  if you compile with 16bit mode support and switch into a lower bpp
+  mode, the timing is off so the image is corrupted.  This will be
+  fixed soon.
 
 Any contribution can be sent to nico@cam.org and will be greatly welcome!
 
diff -u --recursive --new-file v2.4.9/linux/Documentation/arm/SA1100/HUW_WEBPANEL linux/Documentation/arm/SA1100/HUW_WEBPANEL
--- v2.4.9/linux/Documentation/arm/SA1100/HUW_WEBPANEL	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/arm/SA1100/HUW_WEBPANEL	Fri Sep  7 09:28:38 2001
@@ -0,0 +1,18 @@
+The HUW_WEBPANEL is a product of the german company Hoeft & Wessel AG
+
+If you want more information, please visit
+http://www.hoeft-wessel.de
+
+To build the kernel:
+	make huw_webpanel_config
+	make oldconfig
+	[accept all defaults]
+	make dep
+	make zImage
+
+Mostly of the work is done by:
+Roman Jordan         jor@hoeft-wessel.de
+Christoph Schulz    schu@hoeft-wessel.de
+
+2000/12/18/
+
diff -u --recursive --new-file v2.4.9/linux/Documentation/arm/SA1100/Itsy linux/Documentation/arm/SA1100/Itsy
--- v2.4.9/linux/Documentation/arm/SA1100/Itsy	Wed Oct 20 16:29:07 1999
+++ linux/Documentation/arm/SA1100/Itsy	Fri Sep  7 09:28:38 2001
@@ -2,11 +2,38 @@
 Research Center in Palo Alto, CA. The Itsy project is one of several
 research projects at Compaq that are related to pocket computing.
 
-Itsy support has yet to be fully integrated in this kernel.  Linux 2.0.x
-support is available though.
-
 For more information, see:
 
 	http://www.research.digital.com/wrl/itsy/index.html
 
+Notes on initial 2.4 Itsy support (8/27/2000) :
+The port was done on an Itsy version 1.5 machine with a daughtercard with
+64 Meg of DRAM and 32 Meg of Flash. The initial work includes support for
+serial console (to see what you're doing).  No other devices have been
+enabled.
+
+To build, do a "make menuconfig" (or xmenuconfig) and select Itsy support.
+Disable Flash and LCD support. and then do a make dep and a make zImage.
+Finally, you will need to cd to arch/arm/boot/tools and execute a make there
+to build the params-itsy program used to boot the kernel.
+
+In order to install the port of 2.4 to the itsy, You will need to set the
+configuration parameters in the monitor as follows:
+Arg 1:0x08340000, Arg2: 0xC0000000, Arg3:18 (0x12), Arg4:0
+Make sure the start-routine address is set to 0x00060000.
+
+Next, flash the params-itsy program to 0x00060000 ("p 1 0x00060000" in the
+flash menu)  Flash the kernel in arch/arm/boot/zImage into 0x08340000
+("p 1 0x00340000").  Finally flash an initial ramdisk into 0xC8000000
+("p 2 0x0")  We used ramdisk-2-30.gz from the 0.11 version directory on
+handhelds.org.
+
+The serial connection we established was at:
+ 8-bit data, no parity, 1 stop bit(s), 115200.00 b/s. in the monitor, in the
+params-itsy program, and in the kernel itself.  This can be changed, but
+not easily. The monitor parameters are easily changed, the params program
+setup is assembly outl's, and the kernel is a configuration item specific to
+the itsy. (i.e. grep for CONFIG_SA1100_ITSY and you'll find where it is.)
+
 
+This should get you a properly booting 2.4 kernel on the itsy.
diff -u --recursive --new-file v2.4.9/linux/Documentation/arm/SA1100/PCMCIA linux/Documentation/arm/SA1100/PCMCIA
--- v2.4.9/linux/Documentation/arm/SA1100/PCMCIA	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/arm/SA1100/PCMCIA	Fri Sep  7 09:28:38 2001
@@ -0,0 +1,374 @@
+Kernel Low-Level PCMCIA Interface Documentation
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+John G Dorsey <john+@cs.cmu.edu>
+Updated: 30 June, 2000
+
+
+Note: this interface has not been finalized!
+See also: http://www.cs.cmu.edu/~wearable/software/pcmcia-arm.html
+
+
+Introduction
+
+Early versions of PCMCIA Card Services for StrongARM were designed to
+permit a single socket driver to run on a variety of SA-1100 boards by
+using a userland configuration process. During the conversion to the 2.3
+kernel series, all of the configuration has moved into sub-drivers in the
+kernel proper (see linux/drivers/pcmcia/sa1100*). This document describes
+the low-level interface between those sub-drivers and the sa1100 socket
+driver module.
+
+Presently, there are six operations which must be provided by the
+board-specific code. Only functions whose implementation is likely to
+differ across board designs are required at this level. Some examples
+include:
+
+  - configuring card detect lines to generate interrupts
+  - sensing the legal voltage levels for inserted cards
+  - asserting the reset signal for a card
+
+Functions which are assumed to be the same across all designs are
+performed within the generic socket driver itself. Some examples of these
+kinds of operations include:
+
+  - configuring memory access times based on the core clock frequency
+  - reads/writes on memory, byte swizzling, ...
+
+The current implementation allows the specific per-board set of low-level
+operations to be determined at run time. For each specific board, the
+following structure should be filled in:
+
+  struct pcmcia_low_level {
+    int (*init)(struct pcmcia_init *);
+    int (*shutdown)(void);
+    int (*socket_state)(struct pcmcia_state_array *);
+    int (*get_irq_info)(struct pcmcia_irq_info *);
+    int (*configure_socket)(const struct pcmcia_configure *);
+  };
+
+The component functions are described in detail below. Using the
+machine_is_*() tests, the pointer `pcmcia_low_level' should be assigned to
+the location of the table for your board.
+
+
+0. init(struct pcmcia_init *init)
+
+This operation has three responsibilities:
+
+  - perform any board-specific initialization tasks
+  - associate the given handler with any interrupt-generating signals
+    such as card detection, or battery voltage detection
+  - set up any necessary edge detection for card ready signals
+
+Argument passing for this operation is implemented by the following
+structure:
+
+  struct pcmcia_init {
+    void (*handler)(int irq, void *dev, struct pt_regs *regs);
+    struct pcmcia_maps *maps;
+  };
+
+Here, `handler' is provided by the socket driver, and `maps' must be
+modified if the default mapping isn't appropriate. This operation should
+return one of two values:
+
+  - the highest-numbered socket available, plus one
+  - a negative number, indicating an error in configuration
+
+Note that the former case is _not_ the same as "the number of sockets
+available." In particular, if your design uses SA-1100 slot "one" but
+not slot "zero," you MUST report "2" to the socket driver.
+
+
+1. shutdown(void)
+
+This operation takes no arguments, and will be called during cleanup for
+the socket driver module. Any state associated with the socket controller,
+including allocated data structures, reserved IRQs, etc. should be
+released in this routine.
+
+The return value for this operation is not examined.
+
+
+2. socket_state(struct pcmcia_state_array *state_array)
+
+This operation will be invoked from the interrupt handler which was set up
+in the earlier call to init(). Note, however, that it should not include
+any side effects which would be inappropriate if the operation were to
+occur when no interrupt is pending. (An extra invocation of this operation
+currently takes place to initialize state in the socket driver.)
+
+Argument passing for this operation is handled by a structure which
+contains an array of the following type:
+
+  struct pcmcia_state {
+    unsigned detect: 1,
+              ready: 1,
+               bvd1: 1,
+               bvd2: 1,
+             wrprot: 1,
+              vs_3v: 1,
+              vs_Xv: 1;
+  };
+
+Upon return from the operation, a struct pcmcia_state should be filled in
+for each socket available in the hardware. For every array element (up to
+`size' in the struct pcmcia_state_saarray) which does not correspond to an
+available socket, zero the element bits. (This includes element [0] if
+socket zero is not used.)
+
+Regardless of how the various signals are routed to the SA-1100, the bits
+in struct pcmcia_state always have the following semantics:
+
+  detect - 1 if a card is fully inserted, 0 otherwise
+  ready  - 1 if the card ready signal is asserted, 0 otherwise
+  bvd1   - the value of the Battery Voltage Detect 1 signal
+  bvd2   - the value of the Battery Voltage Detect 2 signal
+  wrprot - 1 if the card is write-protected, 0 otherwise
+  vs_3v  - 1 if the card must be operated at 3.3V, 0 otherwise
+  vs_Xv  - 1 if the card must be operated at X.XV, 0 otherwise
+
+A note about the BVD signals: if your board does not make both lines
+directly observable to the processor, just return reasonable values. The
+standard interpretation of the BVD signals is:
+
+  BVD1  BVD2
+
+   0     x    battery is dead
+   1     0    battery warning
+   1     1    battery ok
+
+Regarding the voltage sense flags (vs_3v, vs_Xv), these bits should be set
+based on a sampling of the Voltage Sense pins, if available. The standard
+interpretation of the VS signals (for a "low-voltage" socket) is:
+
+  VS1   VS2
+
+   0     0    X.XV, else 3.3V, else none
+   0     1    3.3V, else none
+   1     0    X.XV, else none
+   1     1    5V, else none
+
+More information about the BVD and VS conventions is available in chapter
+5 of "PCMCIA System Architecture," 2nd ed., by Don Anderson.
+
+This operation should return 1 if an IRQ is actually pending for the
+socket controller, 0 if no IRQ is pending (but no error condition exists,
+such as an undersized state array), or -1 on any error.
+
+
+3. get_irq_info(struct pcmcia_irq_info *info)
+
+This operation obtains the IRQ assignment which is legal for the given
+socket. An argument of the following type is passed:
+
+  struct pcmcia_irq_info {
+    unsigned int sock;
+    unsigned int irq ;
+  };
+
+The `sock' field contains the socket index being queried. The `irq' field
+should contain the IRQ number corresponding to the card ready signal from
+the device.
+
+This operation should return 0 on success, or -1 on any error.
+
+
+4. configure_socket(const struct pcmcia_configure *configure)
+
+This operation allows the caller to apply power to the socket, issue a
+reset, or enable various outputs. The argument is of the following type:
+
+  struct pcmcia_configure {
+    unsigned sock: 8,
+              vcc: 8,
+              vpp: 8,
+           output: 1,
+          speaker: 1,
+            reset: 1;
+  };
+
+The `sock' field contains the index of the socket to be configured. The
+`vcc' and `vpp' fields contain the voltages to be applied for Vcc and Vpp,
+respectively, in units of 0.1V. (Note that vpp==120 indicates that
+programming voltage should be applied.)
+
+The two output enables, `output' and `speaker', refer to the card data
+signal enable and the card speaker enable, respectively. The `reset' bit,
+when set, indicates that the card reset should be asserted.
+
+This operation should return 0 on success, or -1 on any error.
+
+
+Board-Specific Notes
+
+The following information is known about various SA-11x0 board designs
+which may be used as reference while adding support to the kernel.
+
+
+Carnegie Mellon Itsy/Cue (http://www.cs.cmu.edu/~wearable/itsy/)
+
+  Itsy Chip Select 3 (CS3) Interface
+  ("ITSY MEMORY/PCMCIA ADD-ON BOARD with BATTERY and CHARGER CIRCUITRY,"
+   memo dated 5-20-99, from Tim Manns to Richard Martin, et. al)
+
+  Read:
+    ABVD2    (SS)D0          A slot, Battery Voltage Detect
+    ABVD1    (SS)D1
+    AVSS2    (SS)D2          A slot, Voltage Sense
+    AVSS1    (SS)D3
+    GND      (SS)D4
+    GND      (SS)D5
+    GND      (SS)D6
+    GND      (SS)D7
+  
+    BBVD2    (SS)D8          B slot, Battery Voltage Detect
+    BBVD1    (SS)D9
+    BVSS2    (SS)D10         B slot, Voltage Sense
+    BVSS1    (SS)D11
+    GND      (SS)D12
+    GND      (SS)D13
+    GND      (SS)D14
+    GND      (SS)D15
+  
+  Write:
+    (SS)D0   A_VPP_VCC       LTC1472 VPPEN1
+    (SS)D1   A_VPP_PGM       LTC1472 VPPEN0
+    (SS)D2   A_VCC_3         LTC1472 VCCEN0
+    (SS)D3   A_VCC_5         LTC1472 VCCEN1
+    (SS)D4   RESET (A SLOT)
+    (SS)D5   GND
+    (SS)D6   GND
+    (SS)D7   GND
+ 
+    (SS)D8   B_VPP_VCC       LTC1472 VPPEN1
+    (SS)D9   B_VPP_PGM       LTC1472 VPPEN0
+    (SS)D10  B_VCC_3         LTC1472 VCCEN0
+    (SS)D11  B_VCC_5         LTC1472 VCCEN1
+    (SS)D12  RESET (B SLOT)
+    (SS)D13  GND
+    (SS)D14  GND
+    (SS)D15  GND
+ 
+  GPIO pin assignments are as follows: (from schematics)
+ 
+    GPIO 10                  Slot 0 Card Detect
+    GPIO 11                  Slot 1 Card Detect
+    GPIO 12                  Slot 0 Ready/Interrupt
+    GPIO 13                  Slot 1 Ready/Interrupt
+
+
+
+Intel SA-1100 Multimedia Board (http://developer.intel.com/design/strong/)
+
+  CPLD Registers
+  SA-1100 Multimedia Development Board with Companion SA-1101 Development
+    Board User's Guide, p.4-42
+
+  This SA-1100/1101 development package uses only one GPIO pin (24) to
+  signal changes in card status, and requires software to inspect a
+  PCMCIA status register to determine the source.
+
+  Read: (PCMCIA Power Sense Register - 0x19400000)
+    S0VS1           0        Slot 0 voltage sense
+    S0VS2           1
+    S0BVD1          2        Slot 0 battery voltage sense
+    S0BVD2          3
+    S1VS1           4        Slot 1 voltage sense
+    S1VS2           5
+    S1BVD1          6        Slot 1 battery voltage sense
+    S1BVD2          7
+
+  Read/Write: (PCMCIA Power Control Register - 0x19400002)
+    S0VPP0          0        Slot 0 Vpp
+    S0VPP1          1
+    S0VCC0          2        Slot 0 Vcc
+    S0VCC1          3
+    S1VPP0          4        Slot 1 Vpp
+    S1VPP1          5
+    S1VCC0          6        Slot 1 Vcc
+    S1VCC1          7
+
+  Read: (PCMCIA Status Register - 0x19400004)
+    S0CD1           0        Slot 0 Card Detect 1
+    S0RDY           1        Slot 0 Ready/Interrupt
+    S0STSCHG        2        Slot 0 Status Change
+    S0Reset         3        Slot 0 Reset (RW)
+    S1CD1           4        Slot 1 Card Detect 1
+    S1RDY           5        Slot 1 Ready/Interrupt
+    S1STSCHG        6        Slot 1 Status Change
+    S1Reset         7        Slot 1 Reset (RW)
+
+
+
+Intel SA-1100 Evaluation Platform (http://developer.intel.com/design/strong/)
+
+  Brutus I/O Pins and Chipselect Register
+  pcmcia-brutus.c, by Ivo Clarysse
+  (What's the official reference for this info?)
+
+  This SA-1100 development board uses more GPIO pins than say, the Itsy
+  or the SA-1100/1101 multimedia package. The pin assignments are as
+  follows:
+
+    GPIO 2                   Slot 0 Battery Voltage Detect 1
+    GPIO 3                   Slot 0 Ready/Interrupt
+    GPIO 4                   Slot 0 Card Detect
+    GPIO 5                   Slot 1 Battery Voltage Detect 1
+    GPIO 6                   Slot 1 Ready/Interrupt
+    GPIO 7                   Slot 1 Card Detect
+
+  Like the Itsy, Brutus uses a chipselect register in static memory
+  bank 3 for the other signals, such as voltage sense or reset:
+
+  Read:
+    P0_VS1          8        Slot 0 Voltage Sense
+    P0_VS2          9
+    P0_STSCHG      10        Slot 0 Status Change
+    P1_VS1         12        Slot 1 Voltage Sense
+    P1_VS2         13
+    P1_STSCHG      14        Slot 1 Status Change
+
+  Read/Write:
+    P0_            16        Slot 0 MAX1600EAI control line
+    P0_            17        Slot 0 MAX1600EAI control line
+    P0_            18        Slot 0 MAX1600EAI control line
+    P0_            19        Slot 0 MAX1600EAI control line
+    P0_            20        Slot 0 12V
+    P0_            21        Slot 0 Vpp to Vcc (CONFIRM?)
+    P0_            22        Slot 0 enable fan-out drivers & xcvrs
+    P0_SW_RST      23        Slot 0 Reset
+    P1_            24        Slot 1 MAX1600EAI control line
+    P1_            25        Slot 1 MAX1600EAI control line
+    P1_            26        Slot 1 MAX1600EAI control line
+    P1_            27        Slot 1 MAX1600EAI control line
+    P1_            28        Slot 1 12V
+    P1_            29        Slot 1 Vpp to Vcc (CONFIRM?)
+    P1_            30        Slot 1 enable fan-out drivers & xcvrs
+    P1_SW_RST      31        Slot 1 Reset
+
+  For each slot, the bits labelled "MAX1600EAI" should (apparently)
+  be written with the value 0101 for Vcc 3.3V, and 1001 for Vcc 5V.
+
+
+
+Intel SA-1110 Development Platform (http://developer.intel.com/design/strong/)
+
+  GPIO Pin Descriptions and Board Control Register
+  SA-1110 Microprocessor Development Board User's Guide, p.4-7, 4-10
+
+  The Assabet board contains only a single Compact Flash slot,
+  attached to slot 1 on the SA-1110. Card detect, ready, and BVD
+  signals are routed through GPIO, with power and reset placed in a
+  control register. Note that the CF bus must be enabled before use.
+
+    GPIO 21                  Slot 1 Compact Flash interrupt
+    GPIO 22                  Slot 1 card detect (CD1 NOR CD2)
+    GPIO 24                  Slot 1 Battery Voltage Detect 2
+    GPIO 25                  Slot 1 Battery Voltage Detect 1
+
+  Write-only: (Board Control Register - 0x12000000)
+    CF_PWR          0        CF bus power (3.3V)
+    CF_RST          1        CF reset
+    CF_Bus_On       7        CF bus enable
+
diff -u --recursive --new-file v2.4.9/linux/Documentation/arm/SA1100/Pangolin linux/Documentation/arm/SA1100/Pangolin
--- v2.4.9/linux/Documentation/arm/SA1100/Pangolin	Mon Nov 27 17:07:59 2000
+++ linux/Documentation/arm/SA1100/Pangolin	Fri Sep  7 09:28:38 2001
@@ -1,25 +1,20 @@
-Pangolin is a StrongARM 1110-based evaluation  platform produced
-by Dialogue Technoloy (http://www.dialogue.com.tw/).
+Pangolin is a StrongARM 1110-based evaluation platform produced
+by Dialogue Technology (http://www.dialogue.com.tw/).
 It has EISA slots for ease of configuration with SDRAM/Flash
 memory card, USB/Serial/Audio card, Compact Flash card,
 and TFT-LCD card.
-This platform is currently under development.
 
 To compile for Pangolin, you must issue the following commands:
 
 	make pangolin_config
-	make config
-	[accept all defaults]
+	make oldconfig
 	make dep
 	make zImage
 
 Supported peripherals:
-- SA1110 serial port
+- SA1110 serial port (UART1/UART2/UART3)
 - flash memory access
-
-Testing:
-- pcmcia driver
-- sound driver
-
-To do:
-- MQ-200 driver
+- compact flash driver
+- UDA1341 sound driver
+- SA1100 LCD controller for 800x600 16bpp TFT-LCD
+- MQ-200 driver for 800x600 16bpp TFT-LCD
diff -u --recursive --new-file v2.4.9/linux/Documentation/arm/SA1100/Yopy linux/Documentation/arm/SA1100/Yopy
--- v2.4.9/linux/Documentation/arm/SA1100/Yopy	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/arm/SA1100/Yopy	Fri Sep  7 09:28:38 2001
@@ -0,0 +1,2 @@
+See http://www.yopydeveloper.org for more.
+
diff -u --recursive --new-file v2.4.9/linux/Documentation/arm/SA1100/nanoEngine linux/Documentation/arm/SA1100/nanoEngine
--- v2.4.9/linux/Documentation/arm/SA1100/nanoEngine	Sun Aug 13 09:58:24 2000
+++ linux/Documentation/arm/SA1100/nanoEngine	Fri Sep  7 09:28:38 2001
@@ -4,6 +4,8 @@
 "nanoEngine" is a SA1110 based single board computer from 
 Bright Star Engineering Inc.  See www.brightstareng.com/arm
 for more info.
+(Ref: Stuart Adams <sja@brightstareng.com>)
 
-Ref: Stuart Adams <sja@brightstareng.com>
+Also visit Larry Doolittle's "Linux for the nanoEngine" site:
+http://recycle.lbl.gov/~ldoolitt/bse/
 
diff -u --recursive --new-file v2.4.9/linux/Documentation/arm/SA1100/serial_UART linux/Documentation/arm/SA1100/serial_UART
--- v2.4.9/linux/Documentation/arm/SA1100/serial_UART	Mon Nov 27 17:07:59 2000
+++ linux/Documentation/arm/SA1100/serial_UART	Fri Sep  7 09:28:38 2001
@@ -1,5 +1,4 @@
-The SA1100 serial port finally had its major/minor numbers officially 
-assigned:
+The SA1100 serial port had its major/minor numbers officially assigned:
 
 > Date: Sun, 24 Sep 2000 21:40:27 -0700
 > From: H. Peter Anvin <hpa@transmeta.com>
@@ -25,7 +24,7 @@
 >                   7 = /dev/cusa2                Callout device for ttySA2
 >
 
-So, if you're not using devfs, you must create those inodes in /dev
+If you're not using devfs, you must create those inodes in /dev
 on the root filesystem used by your SA1100-based device:
 
 	mknod ttySA0 c 204 5
@@ -35,31 +34,14 @@
 	mknod cusa1 c 205 6
 	mknod cusa2 c 205 7
 
-Note that the old incorrect use of /dev/ttyS0 in order to use the serial port 
-won't work anymore.  This device node is reserved to the conventionnal 16x50
-UART which may appear on devices like PCMCIA modem, etc.
-
-In addition to the creation of the appropriate device nodes above, you must
-ensure your user space applications make use of the correct device name.
-The classic example is the content of the /etc/inittab where you might have 
-a getty process started on ttyS0.  In this case you have two choices:
-
-1- replace occurences of ttyS0 with ttySA0, ttyS1 with ttySA1, etc.
-
-2- in the occurence of 'ttyS0', you may consider replacing it with 'console'.
-   as in "T0:12345:respawn:/sbin/getty -L console 9600 vt100"
-
-(don't forget to add 'ttySA0', 'console', or the appropriate tty name 
- in /etc/securetty for root to be allowed to login as well.)
-
-The use of /dev/console has the advantage of being independent of the real
-serial device used.  The kernel automatically forward all operations on
-/dev/console to the apropriate serial device.  The nature of the console may
-also be modified with a kernel command line parameter (see
-Documentation/serial-console.txt for the details).  Of course, 
-/dev/console must have been created as a char device with major 5 minor 1.
-
-Using /dev/console is also compatible with older kernels that used /dev/ttyS0.
-Therefore it is handy for ramdisk images which are targetted for different
-StrongARM platforms and older kernels.
+In addition to the creation of the appropriate device nodes above, you
+must ensure your user space applications make use of the correct device
+name. The classic example is the content of the /etc/inittab file where
+you might have a getty process started on ttyS0.  In this case:
+
+- replace occurences of ttyS0 with ttySA0, ttyS1 with ttySA1, etc.
+
+- don't forget to add 'ttySA0', 'console', or the appropriate tty name
+  in /etc/securetty for root to be allowed to login as well.
+
 
diff -u --recursive --new-file v2.4.9/linux/Documentation/fb/README-sstfb.txt linux/Documentation/fb/README-sstfb.txt
--- v2.4.9/linux/Documentation/fb/README-sstfb.txt	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/fb/README-sstfb.txt	Fri Sep  7 09:28:38 2001
@@ -0,0 +1,167 @@
+
+Introduction
+
+	  This is a frame buffer device driver for 3dfx' Voodoo Graphics 
+	(aka voodoo 1, aka sst1) and Voodoo² (aka Voodoo 2, aka CVG) based 
+	video boards. It's highly experimental code, but is guaranteed to work
+	on my computer, with my "Maxi Gamer 3D" and "Maxi Gamer 3d²" boards,
+	and with me "between chair and keyboard". Some people tested other
+	combinations and it seems that it works.
+	  The main page is located at <http://sstfb.sourceforge.net>, and if
+	you want the latest version, check out the CVS, as the driver is a work
+	in progress, i feel incomfortable with releasing tarballs of something
+	not completely working...Don't worry, it's still more than useable
+	(I eat my own dog food)
+
+	  Please read the Bug section, and report any success or failure to me
+	(Ghozlane Toumi <gtoumi@messel.emse.fr>).
+	  BTW, If you have only one monitor , and you don't feel like playing
+	with the vga passthrou cable, I can only suggest borrowing a screen
+	somewhere... 
+
+
+Installation 
+
+	  This driver (should) work on ix86, with any 2.2.x kernel (tested
+	with x = 19) and "recent" 2.4.x kernel, as a module or compiled in.
+	  You can apply the patches found in sstfb/kernel/*-2.{2|4}.x.patch,
+	and copy sstfb.c to linux/drivers/video/, or apply a single patch, 
+	sstfb/patch-2.{2|4}.x-sstfb-yymmdd to your linux source tree.
+
+	  Then configure your kernel as usual: choose "m" or "y" to 3Dfx Voodoo
+	Graphics in section "console". Compile, install, have fun... and please
+	drop me a report :)
+
+
+Module Usage
+	
+	Warnings.
+	# You should read completely this section before issuing any command.
+	# If you have only one monitor to play with, once you insmod the
+	  module, the 3dfx takes control of the output, so you'll have to
+	  plug the monitor to the "normal" video board in order to issue
+	  the commands, or you can blindly use sst_dbg_vgapass
+          in the tools directory (See Tools). The latest option is pass the
+	  parameter vgapass=1 when insmodding the driver. (See Kernel/Modules
+	  Options)
+
+	Module insertion:
+	# insmod sstfb.o
+	  you should see some strange output frome the board: 
+	  a big blue square, a green and a red small squares and a vertical
+	  white rectangle. why ? the function's name is self explanatory :
+	  "sstfb_test()"...
+	  (if you don't have a second monitor, you'll have to plug your monitor
+	  directely to the 2D videocard to see what you're typing)
+	# con2fb /dev/fbx /dev/ttyx
+	  bind a tty to the new frame buffer. if you already have a frame
+	  buffer driver, the voodoo fb will likely be /dev/fb1. if not, 
+	  the device will be /dev/fb0. You can check this by doing a 
+	  cat /proc/fb. You can find a copy of con2fb in tools/ directory.
+	  if you don't have another fb device, this step is superfluous,
+	  as the console subsystem automagicaly binds ttys to the fb.
+	# switch to the virtual console you just mapped. "tadaaa" ...
+
+	Module removal:
+	# con2fb /dev/fbx /dev/ttyx
+	  bind the tty to the old frame buffer so the module can be removed.
+	  (how does it work with vgacon ? short answer : it doesn't work)
+	# rmmod sstfb
+
+
+Kernel/Modules Options
+
+	You can pass some otions to sstfb module, and via the kernel command
+	line when the driver is compiled in :
+	for module : insmod sstfb.o option1=value1 option2=value2 ...
+	in kernel :  video=sstfb:option1,option2:value2,option3 ...
+	
+	sstfb supports the folowing options :
+	module		kernel		description
+
+	vgapass=1	vgapass		enable or disable VGA passthrou cable
+	vgapass=0	vganopass	when enabled, the monitor will
+					get the signal from the VGA board
+					and not from the voodoo. default nopass
+
+	mem=x		mem:x		force frame buffer memory in MiB
+					allowed values: 1, 2, 4. default detect
+
+	inverse=1	inverse		suposed to enable inverse console.
+					doesn't work ...
+
+	clipping=1	clipping	enable or disable clipping . with
+	clipping=0	noclipping	clipping enabled, all offscreen reads
+					and writes are disgarded. default:
+					enable clipping.
+
+	gfxclk=x	gfxclk:x	force graphic clock frequency (in MHz)
+					becarefull with this option .
+					default is 50Mhz for voodoo1, 75MHz
+					for voodoo2. Be carefull, this one is
+					dangerous. default=auto
+
+	slowpci=0	slowpci		enable or disable fast PCI read/writes
+	slowpci=1	fastpci		default : fastpci
+
+	dev=x		dev:x		attach the driver to device number x
+					0 is the first compatible board (in 
+					lspci order)
+
+Tools
+
+	These tools are mostly for debugging purposes, but you can 
+	find some of these interesting :
+	 - con2fb , maps a tty to a fbramebuffer .
+		con2fb /dev/fb1 /dev/tty5
+	 - sst_dbg_vgapass , changes vga passthrou. You have to recompile the
+	driver with SST_DEBUG and SST_DEBUG_IOCTL set to 1
+		sst_dbg_vgapass /dev/fb1 1 (enables vga cable)
+		sst_dbg_vgapass /dev/fb1 0 (disables vga cable)
+	 - glide_reset , resets the voodoo using glide
+		use this after rmmoding sstfb, if the module refuses to
+		reinsert .
+
+Bugs
+
+	- DO NOT use glide while the sstfb module is in, you'll most likely
+	hang your computer.
+	- if you see some artefacts (pixels not cleaning and stuff like that), 
+	try turning off clipping (clipping=0)
+	- the driver don't detect the 4Mb frame buffer voodoos, it seems that
+	the 2 last Mbs wrap around. looking into that .
+	- The driver is 16 bpp only, 24/32 won't work.
+	- The driver is not your_favorite_toy-safe. this includes SMP...
+          [Actually from inspection it seems to be safe - Alan]
+	- when using XFree86 FBdev (X over fbdev) you may see strange color
+	patterns at the border of your windows (the pixels loose the lowest
+	byte -> basicaly the blue component nd some of the green) . I'm unable
+	to reproduce this with XFree86-3.3, but one of the testers has this
+	problem with XFree86-4. I don't know yet if this is the drivers fault
+	or X's (most likely the driver, of course).
+	- I didn't really test changing the palette, so you may find some weird
+	things when playing with that.
+	- Sometimes the driver will not recognise the DAC , and the
+        initialisation will fail. this is specificaly true for
+	voodoo 2 boards , but it should be solved in recent versions. please
+	contact me .
+	- the 24/32 is not likely to work anytime soon , knowing that the
+	hardware does ... unusual thigs in 24/32 bpp
+
+Todo
+
+	- Get rid of the previous paragraph.
+	- Buy more coffee.
+	- test/port to other arch.
+	- try to add panning using tweeks with front and back buffer .
+	- try to implement accel en voodoo2 , this board can actualy do a 
+	  lot in 2D even if it was sold as a 3D only board ...
+
+ghoz.
+
+-- 
+Ghozlane Toumi <gtoumi@messel.emse.fr>
+
+
+$Date: 2001/08/29 00:21:11 $
+http://sstfb.sourceforge.net/README
diff -u --recursive --new-file v2.4.9/linux/Documentation/filesystems/ntfs.txt linux/Documentation/filesystems/ntfs.txt
--- v2.4.9/linux/Documentation/filesystems/ntfs.txt	Mon Aug 27 12:41:37 2001
+++ linux/Documentation/filesystems/ntfs.txt	Sat Sep  8 12:24:40 2001
@@ -64,6 +64,25 @@
 			Be careful not to write anything to them or you could
 			crash the kernel and/or corrupt your file system!
 
+mft_zone_multiplier=	Set the MFT zone multiplier for the volume (this
+			setting is not persistent across mounts and can be
+			changed from mount to mount but cannot be changed on
+			remount). Values of 1 to 4 are allowed, 1 being the
+			default. The MFT zone multiplier determines how much
+			space is reserved for the MFT on the volume. If all
+			other space is used up, then the MFT zone will be
+			shrunk dynamically, so this has no impact on the
+			amount of free space. However, it can have an impact
+			on performance by affecting fragmentation of the MFT.
+			In general use the default. If you have a lot of small
+			files then use a higher value. The values have the
+			following meaning:
+			      Value	     MFT zone size (% of volume size)
+				1		12.5%
+				2		25%
+				3		37.5%
+				4		50%
+
 Known bugs and (mis-)features
 =============================
 
@@ -71,10 +90,6 @@
   use it, get the Linux-NTFS tools and use the ntfsfix utility after
   dismounting a partition you wrote to.
 
-- Use the show_sys_files mount option which should make things work generally
-  better. (It results in both the short and long file names being shown as well
-  as the sytem files.)
-
 - Writing of extension records is not supported properly.
 
 Please send bug reports/comments/feed back/abuse to the Linux-NTFS development
@@ -82,6 +97,86 @@
 
 ChangeLog
 =========
+
+NTFS 1.1.18:
+
+	- Enhanced & bug fixed cluster deallocation (race fixes, etc.)
+	- Complete rewrite of cluster allocation, now race free.
+	- Fixed several bugs in the attribute modification codepaths.
+	- Hopefully fixed bug where the first sectors of some people's
+	  partitions would be overwritten by the mft. And in general fixed up
+	  mft extension code a bit (still incomplete though).
+	- Introduce splice_runlist() to allow generic splicing of two run
+	  lists into one.
+	- MFT zone is now implemented. [Stage 2 of 3; only lack dynamic
+	  growing of mft zone but that is AFAIK not even done by Windows, and
+	  the overhead would be so large that it is probably not worth doing
+	  at all, so Stage 3 might never happen...]
+	- Complete rewrite of $MFT extension and ntfs inode allocation code.
+	- Made the NTFS driver initialization string show the compile options
+	  used (i.e. whether read-only or read-write, whether a module, and
+	  whether with debug support).
+	- Modify ntfs_fill_mft_header() to set all fields and to accept more
+	  arguments.
+	- Get rid of superfluous add_mft_header().
+	- Get rid of some unused code.
+	- Fixed several bugs in and generally cleaned up ntfs_readdir,
+	  ntfs_getdir_unsorted(), and ntfs_printcb. Now they spew out huge
+	  amounts of debug output if debugging is enabled. This will be
+	  removed once I know that this works for everyone.
+	- ntfs_readdir now shows hidden files. The only files that are now
+	  hidden are the first 16 inodes (i.e. the hard coded system files),
+	  which is consistent with Windows NT4. Using the show_sys_files mount
+	  option, these files are then shown, too.
+	- Fixed the displaying of the "." and ".." directories. We still cannot
+	  cope with more than 65536 files in a directory index block which is
+	  not a problem and we now cannot cope with more than 32766 directory
+	  index blocks which should not be a problem unless you have a
+	  directory with an insanely large number of files in it. The exact
+	  number depends on the length of the file names of the directory
+	  entries and on the size of the dircetory index blocks.
+	- Fixed all problems with the last file in a directory (e.g. the last
+	  file should no longer disappear and tab completion should work). If
+	  there are still disappearing files or any other problems with the
+	  last file in a directory, please report them! Thanks.
+	- Rewrote ntfs_extend_attr() to use the new cluster allocator and the
+	  freshly introduced splice_runlists() function. This simplified
+	  ntfs_extend_attr() a lot which in turn seems to have removed one or
+	  more bugs from it.
+	- Probably other things I have forgotten... (-;
+	- Removed dollar signs from the names in the system file enumeration.
+	  Apparently gcc doesn't support dollar signs on PPC architecture.
+	  (Andrzej Krzysztofowicz)
+
+NTFS 1.1.17:
+
+	- Fixed system file handling. No longer need to use show_sys_files
+	  option for driver to work fine. System files are now always treated
+	  the same, but without the option, they are made invisible to
+	  directory listings. As a result system files can once again be opened
+	  even without the show_sys_files option. This is important for the
+	  statfs system call to work properly, for example.
+	- Implemented MFT zone including mount parameter to tune it (just like
+	  in Windows via the registry, only we make it per mount rather than
+	  global for the whole driver, so we are better but we have no way of
+	  storing the value as we don't have a registry so either specify on
+	  each mount or put it in /etc/fstab). [Stage 1 of 3, mount parameter
+	  handling.]
+	- Fixed fixup functions to handle corruption cases and to return error
+	  codes to the caller.
+	- Made fixup functions apply hotfixes where sensible. [Stage 1 of 2+,
+	  in memory only.]
+	- Fixed ommission of "NTFS: " string in ntfs_error() output.
+	- Fixed stupid if statement bug in unistr.c. Thanks to Yann E. Morin
+	  for spotting it. 
+	- Get rid of all uses of max and min macros. This actually allowed for
+	  optimizing the code in several places so it was a Good Thing(TM).
+	- Make ntfs use generic_file_open to enforce the O_LARGEFILE flag.
+	- Detect encrypted files and refuse to access them (return EACCES
+	  error code to user space).
+	- Fix handling of encrypted & compressed files so that an encrypted
+	  file no longer is considered to be compressed (this was causing
+	  kernel segmentation faults).
 
 NTFS 1.1.16:
 
diff -u --recursive --new-file v2.4.9/linux/Documentation/ide.txt linux/Documentation/ide.txt
--- v2.4.9/linux/Documentation/ide.txt	Sat Feb 26 20:32:12 2000
+++ linux/Documentation/ide.txt	Fri Sep  7 09:28:38 2001
@@ -314,7 +314,7 @@
  "ide0=ht6560b"		: probe/support HT6560B interface
  "ide0=cmd640_vlb"	: *REQUIRED* for VLB cards with the CMD640 chip
 			  (not for PCI -- automatically detected)
- "ide0=qd6580"		: probe/support qd6580 interface
+ "ide0=qd65xx"		: probe/support qd65xx interface
  "ide0=ali14xx"		: probe/support ali14xx chipsets (ALI M1439/M1445)
  "ide0=umc8672"		: probe/support umc8672 chipsets
 
diff -u --recursive --new-file v2.4.9/linux/Documentation/isdn/README linux/Documentation/isdn/README
--- v2.4.9/linux/Documentation/isdn/README	Sun Aug 13 10:05:32 2000
+++ linux/Documentation/isdn/README	Sun Sep  9 10:52:35 2001
@@ -276,6 +276,8 @@
                                       1 = Add CPN to RING message on
                             Bit 1:    0 = Add CPN to FCON message off
                                       1 = Add CPN to FCON message on
+                            Bit 2:    0 = Add CDN to RING/FCON message off
+                                      1 = Add CDN to RING/FCON message on
 
   Last but not least a (at the moment fairly primitive) device to request
   the line-status (/dev/isdninfo) is made available.
diff -u --recursive --new-file v2.4.9/linux/Documentation/kernel-doc-nano-HOWTO.txt linux/Documentation/kernel-doc-nano-HOWTO.txt
--- v2.4.9/linux/Documentation/kernel-doc-nano-HOWTO.txt	Fri Mar  2 18:43:11 2001
+++ linux/Documentation/kernel-doc-nano-HOWTO.txt	Fri Sep  7 18:15:17 2001
@@ -35,9 +35,9 @@
 
 - Makefile
 
-  The targets 'sgmldocs', 'psdocs', and 'pdfdocs' are used to build
-  DocBook files, PostScript files, and PDF files in
-  Documentation/DocBook.
+  The targets 'sgmldocs', 'psdocs', 'pdfdocs', and 'htmldocs' are used
+  to build DocBook files, PostScript files, PDF files, and html files
+  in Documentation/DocBook.
 
 - Documentation/DocBook/Makefile
 
@@ -49,10 +49,11 @@
 
 If you just want to read the ready-made books on the various
 subsystems (see Documentation/DocBook/*.tmpl), just type 'make
-psdocs', or 'make pdfdocs', depending on your preference.  If you
-would rather read a different format, you can type 'make sgmldocs' and
-then use DocBook tools to convert Documentation/DocBook/*.sgml to a
-format of your choice (for example, 'db2html ...').
+psdocs', or 'make pdfdocs', or 'make htmldocs', depending on your 
+preference.  If you would rather read a different format, you can type 
+'make sgmldocs' and then use DocBook tools to convert 
+Documentation/DocBook/*.sgml to a format of your choice (for example, 
+'db2html ...' if 'make htmldocs' was not defined).
 
 If you want to see man pages instead, you can do this:
 
@@ -111,7 +112,9 @@
 (*)?*/
 
 The short function description cannot be multiline, but the other
-descriptions can be.
+descriptions can be (and they can contain blank lines). Avoid putting a
+spurious blank line after the function name, or else the description will
+be repeated!
 
 All descriptive text is further processed, scanning for the following special
 patterns, which are highlighted appropriately.
diff -u --recursive --new-file v2.4.9/linux/Documentation/mips/pci/pci.README linux/Documentation/mips/pci/pci.README
--- v2.4.9/linux/Documentation/mips/pci/pci.README	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/mips/pci/pci.README	Mon Aug 27 08:56:31 2001
@@ -0,0 +1,67 @@
+
+Pete Popov, ppopov@pacbell.net
+07/11/2001
+
+This README briefly explains how to use the pci and pci_auto
+code in arch/mips/kernel.  The code was ported from PowerPC and
+modified slightly. It has been tested pretty well on PPC on some
+rather complex systems with multiple bridges and devices behind
+each bridge. However, at the time this README was written, the
+mips port was tested only on boards with a single pci bus and
+no P2P bridges.  It's very possible that on boards with P2P
+bridges some modifications have to be made. The code will 
+evolve, no doubt, but currently every single mips board
+is doing its own pcibios thing and it has become a big
+mess.  This generic pci code is meant to clean up the mips
+pci mess and make it easier to add pci support to new boards.
+
+arch/mips/kernel/pci_auto.c has the pci bus enumeration code.
+This code scans the pci bus(es) and assigns all of the resources.
+Thus, you don't need the boot code to that, and many boot codes
+don't do it correctly anyway.  To enable the pci_auto code, add
+
+define_bool CONFIG_PCI_AUTO y 
+
+inside the define for your board in arch/mips/config.in. 
+For example, the Galileo EV96100 board  looks like this:
+
+if [ "$CONFIG_MIPS_EV96100" = "y" ]; then
+	define_bool CONFIG_PCI y
+	define_bool CONFIG_MIPS_GT96100 y
+	define_bool CONFIG_NEW_PCI y
+	define_bool CONFIG_PCI_AUTO y
+	define_bool CONFIG_SWAP_IO_SPACE y
+fi 
+
+
+Next, if you want to use the arch/mips/kernel/pci code, which has the
+pcibios_init() function, add
+
+define_bool CONFIG_NEW_PCI y
+ 
+inside the define for your board. Again, the EV96100 example above
+show NEW_PCI turned on.
+
+Note that you can enable CONFIG_NEW_PCI code without enabling 
+CONFIG_PCI_AUTO. But you can't do the opposite because the pci_auto
+routines are called from pcibios_init(), which is part of the 
+CONFIG_NEW_PCI code.
+
+
+Now you need to add your files to hook in your pci configuration
+cycles.  Usually you'll need only a couple of files named something
+like pci_fixups.c and pci_ops.c.  You can copy the templates
+provided and fill in the code.
+
+The file pci_ops.c should contain the pci configuration cycles routines.
+It also has the mips_pci_channels[] array which contains the descriptors
+of each pci controller.
+
+The file pci_fixups.c contains a few routines to do interrupt fixups,
+resources fixups, and, if needed, pci bios fixups.
+
+Usually you'll put your pci_fixups.c file in your board specific directory, 
+since the functions in that file are board specific.  The functions in
+pci_ops.c, on the other hand, are usually pci controller specific so that
+file could be shared among a few different boards using the same
+pci controller.
diff -u --recursive --new-file v2.4.9/linux/Documentation/s390/3270.txt linux/Documentation/s390/3270.txt
--- v2.4.9/linux/Documentation/s390/3270.txt	Thu May 24 15:14:08 2001
+++ linux/Documentation/s390/3270.txt	Fri Sep  7 09:28:38 2001
@@ -34,17 +34,6 @@
 dialed-in x3270.
 
 
-HELP !!!
-
-The device name of e.g. /dev/3270/tty620 noted below is at variance
-with "standard" Linux device names.  What should it be?  The portion
-"/dev/3270" was recommended by H. Peter Anvin, maintainer of the
-official Linux major-numbers list; the portion "tty620" was recommended
-by me.  Please send your thoughts on this issue at least to me at
-rbh00@utsglobal.com.  Even if you think it's okay as is, please let me
-know.  Thanks.
-
-
 INSTALLATION.
 
 You install the driver by installing a patch, doing a kernel build, and
@@ -60,9 +49,14 @@
 
 If you have chosen to make tub3270 a module, you add a line to
 /etc/modules.conf.  If you are working on a VM virtual machine, you
-can use DEF GRAF to define virtual 3270 devices.  If you generate 3270
-console support, the driver automatically converts your console at boot
-time to a 3270 if it is a 3215.
+can use DEF GRAF to define virtual 3270 devices.
+
+You may generate both 3270 and 3215 console support, or one or the
+other, or neither.  If you generate both, the console type under VM is
+not changed.  Use #CP Q TERM to see what the current console type is.
+Use #CP TERM CONMODE 3270 to change it to 3270.  If you generate only
+3270 console support, then the driver automatically converts your console
+at boot time to a 3270 if it is a 3215.
 
 In brief, these are the steps:
 	1. Install the tub3270 patch
@@ -78,21 +72,17 @@
 
 Here are the installation steps in detail:
 
-	0.  Retrieve the patch file via anonymous ftp from
-	ftp://ftp.utsglobal.com/pub/tub3270.  The patch is designed
-	to apply smoothly to an IBM 2.4.0 system with no other
-	UTS-Global patches applied.  We know of some easily resolvable
-	conflicts between this and other of our patches.
-
-	1. Apply the patch.  Then do
+	1.  The 3270 driver is a part of the official Linux kernel
+	source.  Build a tree with the kernel source and any necessary
+	patches.  Then do
 		make oldconfig
-			(Reply "y" or "m" for CONFIG_3270; if "y",
-			reply "y" or "n" for CONFIG_3270_CONSOLE)
+		(If you wish to disable 3215 console support, edit
+		.config; change CONFIG_TN3215's value to "n";
+		and rerun "make oldconfig".)
 		make dep
 		make image
 		make modules
 		make modules_install
-		<run silo in the usual way>
 
 	2. (Perform this step only if you have configured tub3270 as a
 	module.)  Add a line to /etc/modules.conf to automatically
@@ -122,12 +112,17 @@
 	config3270.sh.	Inspect the output script it produces,
 	/tmp/mkdev3270, and then run that script.  This will create the
 	necessary character special device files and make the necessary
-	changes to /etc/inittab.  Then notify /sbin/init that /etc/inittab
-	has changed, by issuing the telinit command with the q operand:
+	changes to /etc/inittab.  If you have selected DEVFS, the driver
+	itself creates the device files, and /tmp/mkdev3270 only changes
+	/etc/inittab.
+
+	Then notify /sbin/init that /etc/inittab has changed, by issuing
+	the telinit command with the q operand:
 		cd /usr/src/linux/Documentation/s390
 		sh config3270.sh
 		sh /tmp/mkdev3270
 		telinit q
+
 	This should be sufficient for your first time.	If your 3270
 	configuration has changed and you're reusing config3270, you
 	should follow these steps:
diff -u --recursive --new-file v2.4.9/linux/Documentation/s390/config3270.sh linux/Documentation/s390/config3270.sh
--- v2.4.9/linux/Documentation/s390/config3270.sh	Wed Apr 11 19:02:27 2001
+++ linux/Documentation/s390/config3270.sh	Fri Sep  7 09:28:38 2001
@@ -37,10 +37,14 @@
 echo "#!/bin/sh" > $SCR || exit 1
 echo " " >> $SCR
 echo "# Script built by /sbin/config3270" >> $SCR
-echo rm -rf "$D/$SUBD/*" >> $SCR
+if [ ! -d /dev/dasd ]; then
+	echo rm -rf "$D/$SUBD/*" >> $SCR
+fi
 echo "grep -v $TTY $INITTAB > $NINITTAB" > $SCRTMP || exit 1
 echo "echo $ADDNOTE >> $NINITTAB" >> $SCRTMP
-echo mkdir -p $D/$SUBD >> $SCR
+if [ ! -d /dev/dasd ]; then
+	echo mkdir -p $D/$SUBD >> $SCR
+fi
 
 # Now query the tub3270 driver for 3270 device information
 # and add appropriate mknod and mingetty lines to our files
@@ -48,13 +52,19 @@
 while read devno maj min;do
 	if [ $min = 0 ]; then
 		fsmaj=$maj
-		echo mknod $D/$TUB c $fsmaj 0 >> $SCR
-		echo chmod 666 $D/$TUB >> $SCR
+		if [ ! -d /dev/dasd ]; then
+			echo mknod $D/$TUB c $fsmaj 0 >> $SCR
+			echo chmod 666 $D/$TUB >> $SCR
+		fi
 	elif [ $maj = CONSOLE ]; then
-		echo mknod $D/$TUB$devno c $fsmaj $min >> $SCR
+		if [ ! -d /dev/dasd ]; then
+			echo mknod $D/$TUB$devno c $fsmaj $min >> $SCR
+		fi
 	else
-		echo mknod $D/$TTY$devno c $maj $min >>$SCR
-		echo mknod $D/$TUB$devno c $fsmaj $min >> $SCR
+		if [ ! -d /dev/dasd ]; then
+			echo mknod $D/$TTY$devno c $maj $min >>$SCR
+			echo mknod $D/$TUB$devno c $fsmaj $min >> $SCR
+		fi
 		echo "echo t$min$GETTYLINE $TTY$devno >> $NINITTAB" >> $SCRTMP
 	fi
 done < $P
diff -u --recursive --new-file v2.4.9/linux/Documentation/sound/CMI8338 linux/Documentation/sound/CMI8338
--- v2.4.9/linux/Documentation/sound/CMI8338	Wed Jul 25 17:10:17 2001
+++ linux/Documentation/sound/CMI8338	Fri Sep  7 09:28:38 2001
@@ -69,8 +69,8 @@
   Some functions for the cm8738 can be configured in Kernel Configuration
   or modules parameters. Set these parameters to 1 to enable.
 
-  mpu_io:	I/O ports base for MPU-401, 0 if disabled.
-  fm_io:	I/O ports base for OPL-3, 0 if disabled.
+  mpuio:	I/O ports base for MPU-401, 0 if disabled.
+  fmio:		I/O ports base for OPL-3, 0 if disabled.
   spdif_inverse:Inverse the S/PDIF-in signal, this depends on your
 		CD-ROM or DVD-ROM.
   spdif_loop:   Enable S/PDIF loop, this route S/PDIF-in to S/PDIF-out
@@ -80,8 +80,6 @@
                 rear-out.
   use_line_as_bass:Enable this if you want to use line-in as
                 bass-out.
-  modem:	You will need to set this parameter if you want to use
-		the HSP modem. You need install the pctel.o, the modem
-		driver itself.
   joystick:	Enable joystick. You will need to install Linux joystick
 		driver.
+
diff -u --recursive --new-file v2.4.9/linux/Documentation/sound/WaveArtist linux/Documentation/sound/WaveArtist
--- v2.4.9/linux/Documentation/sound/WaveArtist	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/sound/WaveArtist	Fri Sep  7 09:28:38 2001
@@ -0,0 +1,170 @@
+
+ (the following is from the armlinux CVS)
+
+ WaveArtist mixer and volume levels can be accessed via these commands:
+
+  nn30	read registers nn, where nn = 00 - 09 for mixer settings
+		                              0a - 13 for channel volumes
+  mm31	write the volume setting in pairs, where mm = (nn - 10) / 2
+  rr32	write the mixer settings in pairs, where rr = nn/2
+  xx33	reset all settings to default
+  0y34	select mono source, y=0 = left, y=1 = right
+
+                                           bits
+ nn  15  14 13 12 11   10    9     8     7    6     5     4     3     2     1     0
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 00 | 0 | 0  0  1  1 | left line mixer gain       | left aux1 mixer gain        |lmute|
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 01 | 0 | 0  1  0  1 | left aux2 mixer gain       | right 2 left mic gain       |mmute|
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 02 | 0 | 0  1  1  1 | left mic mixer gain        | left mic  | left mixer gain |dith |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 03 | 0 | 1  0  0  1 | left mixer input select                |lrfg | left ADC gain   |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 04 | 0 | 1  0  1  1 | right line mixer gain      | right aux1 mixer gain       |rmute|
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 05 | 0 | 1  1  0  1 | right aux2 mixer gain      | left 2 right mic gain       |test |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 06 | 0 | 1  1  1  1 | right mic mixer gain       | right mic |right mixer gain |rbyps|
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 07 | 1 | 0  0  0  1 | right mixer select                     |rrfg | right ADC gain  |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 08 | 1 | 0  0  1  1 | mono mixer gain            |right ADC mux sel|left ADC mux sel |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 09 | 1 | 0  1  0  1 |loopb|left linout|loop|ADCch|TxFch|OffCD|test |loopb|loopb|osamp|
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 0a | 0 | left PCM channel volume                                                     |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 0b | 0 | right PCM channel volume                                                    |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 0c | 0 | left FM channel volume                                                      |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 0d | 0 | right FM channel volume                                                     |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 0e | 0 | left wavetable channel volume                                               |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 0f | 0 | right wavetable channel volume                                              |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 10 | 0 | left PCM expansion channel volume                                           |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 11 | 0 | right PCM expansion channel volume                                          |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 12 | 0 | left FM expansion channel volume                                            |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 13 | 0 | right FM expansion channel volume                                           |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+
+ lmute: left mute
+ mmute: mono mute
+ dith: dithds
+ lrfg:
+ rmute: right mute
+ rbyps: right bypass
+ rrfg:
+ ADCch:
+ TxFch:
+ OffCD:
+ osamp:
+
+ And the following diagram is derived from the description in the CVS archive:
+
+ MIC L (mouthpiece)
+   +------+
+ -->PreAmp>-\
+   +--^---+ |
+      |     |
+    r2b4-5  |                                +--------+
+       /----*-------------------------------->5       |
+       |                                     |        |
+       | /----------------------------------->4       |
+       | |                                   |        |
+       | | /--------------------------------->3 1of5  |  +---+
+       | | |                                 |  mux   >-->AMP>--> ADC L
+       | | | /------------------------------->2       |  +-^-+
+       | | | |                               |        |    |
+ Line  | | | | +----+  +------+  +---+  /---->1       |  r3b3-0
+ ------------*->mute>--> Gain >-->   |  |    |        |
+  L    | | |   +----+  +------+  |   |  |  *->0       |
+       | | |                     |   |  |    +---^----+
+ Aux2  | | |   +----+  +------+  |   |  |        |
+ ----------*--->mute>--> Gain >--> M |  |     r8b0-2
+  L    | |     +----+  +------+  |   |  |
+       | |                       |   |  \------\
+ Aux1  | |     +----+  +------+  |   |         |
+ --------*----->mute>--> Gain >--> I |         |
+  L    |       +----+  +------+  |   |         |
+       |                         |   |         |
+       |       +----+  +------+  |   |  +---+  |
+       *------->mute>--> Gain >--> X >-->AMP>--*
+       |       +----+  +------+  |   |  +-^-+  |
+       |                         |   |    |    |
+       |       +----+  +------+  |   |  r2b1-3 |  
+       | /----->mute>--> Gain >--> E |         |
+       | |     +----+  +------+  |   |         |
+       | |                       |   |         |
+       | |     +----+  +------+  |   |         |
+       | | /--->mute>--> Gain >--> R |         |
+       | | |   +----+  +------+  |   |         |
+       | | |                     |   |         |   r9b8-9
+       | | |   +----+  +------+  |   |         |     |
+       | | | /->mute>--> Gain >-->   |         | +---v---+
+       | | | | +----+  +------+  +---+       /-*->0      |
+ DAC   | | | |                               |   |       |
+ ------------*----------------------------------->?      |  +----+
+  L    | | |                                 |   |  Mux  >-->mute>--> L output
+       | | |                                 | /->?      |  +--^-+
+       | | |                                 | | |       |     |
+       | | |                           /--------->?      |   r0b0
+       | | |                           |     | | +-------+
+       | | |                           |     | |
+ Mono  | | |                           |     | | +-------+
+ ----------*                           |     \--->       |  +----+
+       | | |                           |       | |  Mix  >-->mute>--> Mono output
+       | | |                           |       *->       |  +--^-+
+       | | |                           |       | +-------+     |
+       | | |                           |       |             r1b0
+ DAC   | | |                           |       | +-------+
+ ------------*-------------------------*--------->1      |  +----+
+  R    | | | |                                 | |  Mux  >-->mute>--> R output
+       | | | | +----+  +------+  +---+         *->0      |  +--^-+
+       | | | \->mute>--> Gain >-->   |         | +---^---+     |
+       | | |   +----+  +------+  |   |         |     |       r5b0
+       | | |                     |   |         |   r6b0
+       | | |   +----+  +------+  |   |         |
+       | | \--->mute>--> Gain >--> M |         |
+       | |     +----+  +------+  |   |         |
+       | |                       |   |         |
+       | |     +----+  +------+  |   |         |
+       | *----->mute>--> Gain >--> I |         |
+       | |     +----+  +------+  |   |         |
+       | |                       |   |         |
+       | |     +----+  +------+  |   |  +---+  |
+       \------->mute>--> Gain >--> X >-->AMP>--*
+         |     +----+  +------+  |   |  +-^-+  |
+      /--/                       |   |    |    |
+ Aux1 |        +----+  +------+  |   |  r6b1-3 |
+ -------*------>mute>--> Gain >--> E |         |
+  R   | |      +----+  +------+  |   |         |
+      | |                        |   |         |
+ Aux2 | |      +----+  +------+  |   |  /------/
+ ---------*---->mute>--> Gain >--> R |  |
+  R   | | |    +----+  +------+  |   |  |
+      | | |                      |   |  |    +--------+
+ Line | | |    +----+  +------+  |   |  |  *->0       |
+ -----------*-->mute>--> Gain >-->   |  |    |        |
+  R   | | | |  +----+  +------+  +---+  \---->1       |
+      | | | |                                |        |
+      | | | \-------------------------------->2       |  +---+
+      | | |                                  |  Mux   >-->AMP>--> ADC R
+      | | \---------------------------------->3       |  +-^-+
+      | |                                    |        |    |
+      | \------------------------------------>4       |  r7b3-0
+      |                                      |        |
+      \-----*-------------------------------->5       |
+            |                                +---^----+
+    r6b4-5  |                                    |
+      |     |                                  r8b3-5
+   +--v---+ |
+ -->PreAmp>-/
+   +------+
+ MIC R (electret mic)
diff -u --recursive --new-file v2.4.9/linux/Documentation/watchdog.txt linux/Documentation/watchdog.txt
--- v2.4.9/linux/Documentation/watchdog.txt	Fri Aug 11 15:57:57 2000
+++ linux/Documentation/watchdog.txt	Fri Sep  7 09:28:38 2001
@@ -11,6 +11,7 @@
 	ICS	WDT501-P (no fan tachometer)
 	ICS	WDT500-P
 	Software Only
+	SA1100 Internal Watchdog
 	Berkshire Products PC Watchdog Revision A & C (by Ken Hollis)
 
 
@@ -35,6 +36,9 @@
 The wdt card cannot be safely probed for. Instead you need to pass
 wdt=ioaddr,irq as a boot parameter - eg "wdt=0x240,11".
 
+The SA1100 watchdog module can be configured with the "sa1100_margin"
+commandline argument which specifies timeout value in seconds.
+
 The i810 TCO watchdog modules can be configured with the "i810_margin"
 commandline argument which specifies the counter initial value. The counter
 is decremented every 0.6 seconds and default to 50 (30 seconds). Values can
@@ -47,15 +51,15 @@
 
 Features
 --------
-		WDT501P		WDT500P		Software	Berkshire	i810 TCO
-Reboot Timer	   X               X                X		    X               X
-External Reboot	   X	           X                o		    o               o
-I/O Port Monitor   o		   o		    o		    X               o
-Temperature	   X		   o		    o               X               o
-Fan Speed          X		   o		    o               o               o
-Power Under	   X               o                o               o               o
-Power Over         X               o                o               o               o
-Overheat           X               o                o               o               o
+		WDT501P		WDT500P		Software	Berkshire	i810 TCO	SA1100WD
+Reboot Timer	   X               X                X		    X               X               X
+External Reboot	   X	           X                o		    o               o               X
+I/O Port Monitor   o		   o		    o		    X               o               o
+Temperature	   X		   o		    o               X               o               o
+Fan Speed          X		   o		    o               o               o               o
+Power Under	   X               o                o               o               o               o
+Power Over         X               o                o               o               o               o
+Overheat           X               o                o               o               o               o
 
 The external event interfaces on the WDT boards are not currently supported.
 Minor numbers are however allocated for it.
diff -u --recursive --new-file v2.4.9/linux/MAINTAINERS linux/MAINTAINERS
--- v2.4.9/linux/MAINTAINERS	Mon Aug 27 12:41:37 2001
+++ linux/MAINTAINERS	Sun Sep  9 10:52:35 2001
@@ -81,6 +81,12 @@
 L:	linux-net@vger.kernel.org
 S:	Maintained
 
+53C700 AND 53C700-66 SCSI DRIVER
+P:	James E.J. Bottomley
+M:	James.Bottomley@HansenPartnership.com
+L:	linux-scsi@vger.kernel.org
+S:	Maintained
+
 6PACK NETWORK DRIVER FOR AX.25
 P:	Andreas Koensgen
 M:	ajk@iehk.rwth-aachen.de
@@ -182,9 +188,9 @@
 M:	linux@treblig.org
 S:	Maintained
 
-ARM PORT
+ARM/STRONGARM110 PORT
 P:	Russell King
-M:	linux@arm.linux.org.uk
+M:	rmk@arm.linux.org.uk
 L:	linux-arm-kernel@lists.arm.linux.org.uk
 W:	http://www.arm.linux.org.uk/
 S:	Maintained
@@ -337,7 +343,7 @@
 
 CYBERPRO FB DRIVER
 P:	Russell King
-M:	linux@arm.linux.org.uk
+M:	rmk@arm.linux.org.uk
 W:	http://www.arm.linux.org.uk/
 S:	Maintained
 
@@ -689,8 +695,8 @@
 S:	Orphan
 
 IEEE 1394 OHCI DRIVER
-P:	Sebastien Rougeaux
-M:	sebastien.rougeaux@anu.edu.au
+P:	Ben Collins
+M:	bcollins@debian.org
 L:	linux1394-devel@lists.sourceforge.net
 S:	Maintained
 
@@ -823,6 +829,12 @@
 L:	linux-x25@vger.kernel.org
 S:	Maintained
 
+LASI 53c700 driver for PARISC
+P:	James E.J. Bottomley
+M:	James.Bottomley@HansenPartnership.com
+L:	linux-scsi@vger.kernel.org
+S:	Maintained
+
 LINUX FOR IBM pSERIES (RS/6000)
 P:	Paul Mackerras
 M:	paulus@au.ibm.com
@@ -902,9 +914,9 @@
 
 MIPS
 P:	Ralf Baechle
-M:	ralf@gnu.ai.mit.edu
-W:	http://lena.fnet.fr/
-L:	linux-mips@fnet.fr
+M:	ralf@gnu.org
+W:	http://oss.sgi.com/mips/mips-howto.html
+L:	linux-mips@oss.sgi.com
 S:	Maintained
 
 MISCELLANEOUS MCA-SUPPORT
@@ -948,6 +960,12 @@
 L:	linware@sh.cvut.cz
 S:	Maintained
 
+NCR DUAL 700 SCSI DRIVER (MICROCHANNEL)
+P:	James E.J. Bottomley
+M:	James.Bottomley@HansenPartnership.com
+L:	linux-scsi@vger.kernel.org
+S:	Maintained
+
 NETFILTER
 P:	Rusty Russell
 M:	rusty@rustcorp.com.au
@@ -1413,15 +1431,6 @@
 W:	http://www.kernel.dk
 S:	Maintained
 
-USB SUBSYSTEM
-P:	Johannes Erdfelt
-M:	jerdfelt@valinux.com
-M:	johannes@erdfelt.com
-L:	linux-usb-users@lists.sourceforge.net
-L:	linux-usb-devel@lists.sourceforge.net
-W:	http://www.linux-usb.org
-S:	Supported
-
 USB ACM DRIVER
 P:	Vojtech Pavlik
 M:	vojtech@suse.cz
@@ -1437,6 +1446,13 @@
 S:	Maintained
 W:	http://www.kroah.com/linux-usb/
 
+USB CDC ETHERNET DRIVER
+P:	Brad Hards
+M:	bhards@bigpond.net.au
+L:	linux-usb-users@lists.sourceforge.net
+L:	linux-usb-devel@lists.sourceforge.net
+S:	Maintained
+
 USB HID/HIDBP/INPUT DRIVERS
 P:	Vojtech Pavlik
 M:	vojtech@suse.cz
@@ -1453,6 +1469,21 @@
 L:	linux-usb-devel@lists.sourceforge.net
 S:	Maintained
 
+USB KAWASAKI LSI DRIVER
+P:	Brad Hards
+M:	bhards@bigpond.net.au
+L:	linux-usb-users@lists.sourceforge.net
+L:	linux-usb-devel@lists.sourceforge.net
+S:	Maintained
+
+USB MASS STORAGE DRIVER
+P:	Matthew Dharm
+M:	mdharm-usb@one-eyed-alien.net
+L:	linux-usb-users@lists.sourceforge.net
+L:	linux-usb-devel@lists.sourceforge.net
+S:	Maintained
+W:	http://www.one-eyed-alien.net/~mdharm/linux-usb/
+
 USB OHCI DRIVER
 P:	Roman Weissgaerber
 M:	weissg@vienna.at
@@ -1482,21 +1513,21 @@
 L:	linux-usb-devel@lists.sourceforge.net
 S:	Supported
 
-USB SERIAL DIGI ACCELEPORT DRIVER
-P:	Peter Berger and Al Borchers
-M:	pberger@brimson.com
-M:	alborchers@steinerpoint.com
+USB SE401 DRIVER
+P:	Jeroen Vreeken
+M:	pe1rxq@amsat.org
 L:	linux-usb-users@lists.sourceforge.net
 L:	linux-usb-devel@lists.sourceforge.net
+W:	http://www.chello.nl/~j.vreeken/se401/
 S:	Maintained
 
-USB SERIAL KEYSPAN DRIVER
-P:	Hugh Blemings
-M:	hugh@misc.nu
+USB SERIAL DIGI ACCELEPORT DRIVER
+P:	Peter Berger and Al Borchers
+M:	pberger@brimson.com
+M:	alborchers@steinerpoint.com
 L:	linux-usb-users@lists.sourceforge.net
 L:	linux-usb-devel@lists.sourceforge.net
 S:	Maintained
-W:	http://misc.nu/hugh/keyspan/
 
 USB SERIAL DRIVER
 P:	Greg Kroah-Hartman
@@ -1514,6 +1545,12 @@
 L:	linux-usb-devel@lists.sourceforge.net
 S:	Maintained
 
+USB SERIAL CYBERJACK PINPAD/E-COM DRIVER
+M:	linux-usb@sii.li
+L:	linux-usb-users@lists.sourceforge.net
+L:	linux-usb-devel@lists.sourceforge.net
+S:	Supported
+
 USB SERIAL EMPEG EMPEG-CAR MARK I/II DRIVER
 P:	Gary Brubaker
 M:	xavyer@ix.netcom.com
@@ -1521,19 +1558,22 @@
 L:	linux-usb-devel@lists.sourceforge.net
 S:	Maintained
 
-USB SERIAL CYBERJACK PINPAD/E-COM DRIVER
-M:  linux-usb@sii.li
-L:  linux-usb-users@lists.sourceforge.net
-L:  linux-usb-devel@lists.sourceforge.net
-S:  Supported
-
-USB MASS STORAGE DRIVER
-P:	Matthew Dharm
-M:	mdharm-usb@one-eyed-alien.net
+USB SERIAL KEYSPAN DRIVER
+P:	Hugh Blemings
+M:	hugh@misc.nu
 L:	linux-usb-users@lists.sourceforge.net
 L:	linux-usb-devel@lists.sourceforge.net
 S:	Maintained
-W:	http://www.one-eyed-alien.net/~mdharm/linux-usb/
+W:	http://misc.nu/hugh/keyspan/
+
+USB SUBSYSTEM
+P:	Johannes Erdfelt
+M:	jerdfelt@valinux.com
+M:	johannes@erdfelt.com
+L:	linux-usb-users@lists.sourceforge.net
+L:	linux-usb-devel@lists.sourceforge.net
+W:	http://www.linux-usb.org
+S:	Supported
 
 USB UHCI DRIVER
 P:	Georg Acher
diff -u --recursive --new-file v2.4.9/linux/Makefile linux/Makefile
--- v2.4.9/linux/Makefile	Mon Aug 27 12:41:37 2001
+++ linux/Makefile	Sun Sep  9 10:52:35 2001
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
-SUBLEVEL = 9
-EXTRAVERSION =
+SUBLEVEL = 10
+EXTRAVERSION =-pre7
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
@@ -197,6 +197,10 @@
 	drivers/zorro/devlist.h drivers/zorro/gen-devlist \
 	drivers/sound/bin2hex drivers/sound/hex2hex \
 	drivers/atm/fore200e_mkfirm drivers/atm/{pca,sba}*{.bin,.bin1,.bin2} \
+	drivers/scsi/aic7xxx/aicasm/aicasm_gram.c \
+	drivers/scsi/aic7xxx/aicasm/aicasm_scan.c \
+	drivers/scsi/aic7xxx/aicasm/y.tab.h \
+	drivers/scsi/aic7xxx/aicasm/aicasm \
 	net/khttpd/make_times_h \
 	net/khttpd/times.h \
 	submenu*
diff -u --recursive --new-file v2.4.9/linux/arch/alpha/kernel/alpha_ksyms.c linux/arch/alpha/kernel/alpha_ksyms.c
--- v2.4.9/linux/arch/alpha/kernel/alpha_ksyms.c	Mon Aug 27 12:41:37 2001
+++ linux/arch/alpha/kernel/alpha_ksyms.c	Mon Aug 27 07:56:48 2001
@@ -77,6 +77,14 @@
 EXPORT_SYMBOL(_writeb);
 EXPORT_SYMBOL(_writew);
 EXPORT_SYMBOL(_writel);
+EXPORT_SYMBOL(___raw_readb); 
+EXPORT_SYMBOL(___raw_readw); 
+EXPORT_SYMBOL(___raw_readl); 
+EXPORT_SYMBOL(___raw_readq); 
+EXPORT_SYMBOL(___raw_writeb); 
+EXPORT_SYMBOL(___raw_writew); 
+EXPORT_SYMBOL(___raw_writel); 
+EXPORT_SYMBOL(___raw_writeq); 
 EXPORT_SYMBOL(_memcpy_fromio);
 EXPORT_SYMBOL(_memcpy_toio);
 EXPORT_SYMBOL(_memset_c_io);
diff -u --recursive --new-file v2.4.9/linux/arch/arm/kernel/arthur.c linux/arch/arm/kernel/arthur.c
--- v2.4.9/linux/arch/arm/kernel/arthur.c	Thu Apr 12 12:20:31 2001
+++ linux/arch/arm/kernel/arthur.c	Fri Sep  7 09:28:38 2001
@@ -1,7 +1,7 @@
 /*
  *  linux/arch/arm/kernel/arthur.c
  *
- *  Copyright (C) 1998, 1999, 2000 Philip Blundell
+ *  Copyright (C) 1998, 1999, 2000, 2001 Philip Blundell
  *
  * Arthur personality
  */
@@ -58,7 +58,7 @@
 {
 	struct siginfo info;
 	info.si_signo = SIGSWI;
-	info.si_code = nr;
+	info.si_errno = nr;
 	/* Bounce it to the emulator */
 	send_sig_info(SIGSWI, &info, current);
 }
diff -u --recursive --new-file v2.4.9/linux/arch/arm/kernel/process.c linux/arch/arm/kernel/process.c
--- v2.4.9/linux/arch/arm/kernel/process.c	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/kernel/process.c	Fri Sep  7 09:28:38 2001
@@ -124,7 +124,7 @@
 		pm_power_off();
 }
 
-void machine_restart(void * __unused)
+void machine_restart(char * __unused)
 {
 	/*
 	 * Clean and disable cache, and turn off interrupts
diff -u --recursive --new-file v2.4.9/linux/arch/arm/lib/io-readsl-armv4.S linux/arch/arm/lib/io-readsl-armv4.S
--- v2.4.9/linux/arch/arm/lib/io-readsl-armv4.S	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/lib/io-readsl-armv4.S	Fri Sep  7 09:28:38 2001
@@ -63,8 +63,8 @@
 		strne	ip, [r1], #4
 		movne	ip, r3, lsr #8
 		bne	7b
-		strb	ip, [r1], #1
-		mov	ip, ip, lsr #8
 		strh	ip, [r1], #2
+		mov	ip, ip, lsr #16
+		strb	ip, [r1]
 		mov	pc, lr
 
diff -u --recursive --new-file v2.4.9/linux/arch/arm/lib/io-writesl.S linux/arch/arm/lib/io-writesl.S
--- v2.4.9/linux/arch/arm/lib/io-writesl.S	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/lib/io-writesl.S	Fri Sep  7 09:28:38 2001
@@ -25,31 +25,30 @@
 
 2:		bic	r1, r1, #3
 		cmp	ip, #2
-		ldr	ip, [r1], #4
-		mov	ip, ip, lsr #16
-		blt	4f
-		bgt	5f
+		ldr	r3, [r1], #4
+		bgt	4f
+		blt	5f
 
-3:		ldr	r3, [r1], #4
+3:		mov	ip, r3, lsr #16
+		ldr	r3, [r1], #4
 		orr	ip, ip, r3, lsl #16
 		str	ip, [r0]
-		mov	ip, r3, lsr #16
 		subs	r2, r2, #1
 		bne	3b
 		mov	pc, lr
 
-4:		ldr	r3, [r1], #4
+4:		mov	ip, r3, lsr #24
+		ldr	r3, [r1], #4
 		orr	ip, ip, r3, lsl #8
 		str	ip, [r0]
-		mov	ip, r3, lsr #24
 		subs	r2, r2, #1
 		bne	4b
 		mov	pc, lr
 
-5:		ldr	r3, [r1], #4
+5:		mov	ip, r3, lsr #8
+		ldr	r3, [r1], #4
 		orr	ip, ip, r3, lsl #24
 		str	ip, [r0]
-		mov	ip, r3, lsr #8
 		subs	r2, r2, #1
 		bne	5b
 		mov	pc, lr
diff -u --recursive --new-file v2.4.9/linux/arch/arm/mm/fault-armv.c linux/arch/arm/mm/fault-armv.c
--- v2.4.9/linux/arch/arm/mm/fault-armv.c	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mm/fault-armv.c	Fri Sep  7 09:28:38 2001
@@ -20,6 +20,7 @@
 #include <linux/mm.h>
 #include <linux/interrupt.h>
 #include <linux/proc_fs.h>
+#include <linux/bitops.h>
 #include <linux/init.h>
 
 #include <asm/system.h>
@@ -366,8 +367,7 @@
 	ai_multi += 1;
 
 	/* count the number of registers in the mask to be transferred */
-	for (regbits = REGMASK_BITS(instr), nr_regs = 0; regbits; regbits >>= 1)
-		nr_regs += 4;
+	nr_regs = hweight16(REGMASK_BITS(instr)) * 4;
 
 	rn = RN_BITS(instr);
 	newaddr = eaddr = regs->uregs[rn];
@@ -385,10 +385,12 @@
 	 * This is a "hint" - we already have eaddr worked out by the
 	 * processor for us.
 	 */
-	if (addr != eaddr)
+	if (addr != eaddr) {
 		printk(KERN_ERR "LDMSTM: PC = %08lx, instr = %08lx, "
 			"addr = %08lx, eaddr = %08lx\n",
 			 instruction_pointer(regs), instr, addr, eaddr);
+		show_regs(regs);
+	}
 
 	for (regbits = REGMASK_BITS(instr), rd = 0; regbits; regbits >>= 1, rd += 1)
 		if (regbits & 1) {
diff -u --recursive --new-file v2.4.9/linux/arch/arm/tools/Makefile linux/arch/arm/tools/Makefile
--- v2.4.9/linux/arch/arm/tools/Makefile	Tue Jul  3 17:08:18 2001
+++ linux/arch/arm/tools/Makefile	Fri Sep  7 09:28:38 2001
@@ -26,7 +26,8 @@
 # directories
 
 dep:
-	$(TOPDIR)/scripts/mkdep getconstants.c | sed s,getconstants.o,$(TOPDIR)/include/asm-arm/constants.h, > .depend
+	$(TOPDIR)/scripts/mkdep $(CFLAGS) $(EXTRA_CFLAGS) -- getconstants.c |\
+	 sed s,getconstants.o,$(TOPDIR)/include/asm-arm/constants.h, > .depend
 	$(MAKE) all
 
 .PHONY:	all dep
diff -u --recursive --new-file v2.4.9/linux/arch/arm/tools/mach-types linux/arch/arm/tools/mach-types
--- v2.4.9/linux/arch/arm/tools/mach-types	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/tools/mach-types	Fri Sep  7 09:28:38 2001
@@ -6,7 +6,7 @@
 # To add an entry into this database, please see Documentation/arm/README,
 # or contact rmk@arm.linux.org.uk
 #
-# Last update: Thu Aug 9 22:46:02 2001
+# Last update: Thu Aug 23 12:38:13 2001
 #
 # machine_is_xxx	CONFIG_xxxx		MACH_TYPE_xxx		number
 #
@@ -31,7 +31,7 @@
 l7200			ARCH_L7200		L7200			19
 pleb			SA1100_PLEB		PLEB			20
 integrator		ARCH_INTEGRATOR		INTEGRATOR		21
-bitsy			SA1100_BITSY		BITSY			22
+h3600			SA1100_H3600		H3600			22
 ixp1200			ARCH_IXP1200		IXP1200			23
 p720t			ARCH_P720T		P720T			24
 assabet			SA1100_ASSABET		ASSABET			25
@@ -89,7 +89,7 @@
 tardis			ARCH_TARDIS		TARDIS			77
 mercury			ARCH_MERCURY		MERCURY			78
 empeg			SA1100_EMPEG		EMPEG			79
-adi_eb			ARCH_I80200FCC		I80200FCC		80
+adi_evb			ARCH_I80200FCC		I80200FCC		80
 itt_cpb			SA1100_ITT_CPB		ITT_CPB			81
 svc			SA1100_SVC		SVC			82
 alpha2			SA1100_ALPHA2		ALPHA2			84
@@ -115,3 +115,10 @@
 granite			ARCH_GRANITE		GRANITE			104
 consus			SA1100_CONSUS		CONSUS			105
 aaec2000_aaed20		ARCH_AAEC2000_AAED2000	AAEC2000_AAED2000	106
+cdb89712		ARCH_CDB89712		CDB89712		107
+graphicsmaster		SA1100_GRAPHICSMASTER	GRAPHICSMASTER		108
+adsbitsy		SA1100_ADSBITSY		ADSBITSY		109
+cotulla_idp		ARCH_COTULLA_IDP	COTULLA_IDP		110
+plce			ARCH_PLCE		PLCE			111
+pt_system3		SA1100_PT_SYSTEM3	PT_SYSTEM3		112
+medalb			ARCH_MEDALB		MEDALB			113
diff -u --recursive --new-file v2.4.9/linux/arch/i386/defconfig linux/arch/i386/defconfig
--- v2.4.9/linux/arch/i386/defconfig	Mon Aug 27 12:41:39 2001
+++ linux/arch/i386/defconfig	Sun Sep  9 11:18:03 2001
@@ -175,6 +175,7 @@
 #
 # CONFIG_PHONE is not set
 # CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA is not set
 
 #
 # ATA/IDE/MFM/RLL support
@@ -288,6 +289,7 @@
 # CONFIG_SCSI_AHA1740 is not set
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
 # CONFIG_SCSI_AM53C974 is not set
@@ -306,6 +308,7 @@
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_NCR_D700 is not set
 # CONFIG_SCSI_NCR53C7xx is not set
 # CONFIG_SCSI_NCR53C8XX is not set
 CONFIG_SCSI_SYM53C8XX=y
@@ -705,6 +708,7 @@
 CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
 # CONFIG_USB_STORAGE_DPCM is not set
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
@@ -738,10 +742,10 @@
 #
 # USB Network adaptors
 #
-# CONFIG_USB_PLUSB is not set
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_CATC is not set
-# CONFIG_USB_NET1080 is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_USBNET is not set
 
 #
 # USB port drivers
diff -u --recursive --new-file v2.4.9/linux/arch/i386/kernel/bluesmoke.c linux/arch/i386/kernel/bluesmoke.c
--- v2.4.9/linux/arch/i386/kernel/bluesmoke.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/i386/kernel/bluesmoke.c	Sat Sep  8 12:23:14 2001
@@ -19,7 +19,7 @@
 	u32 mcgstl, mcgsth;
 	int i;
 	
-	rdmsr(0x17a, mcgstl, mcgsth);
+	rdmsr(MSR_IA32_MCG_STATUS, mcgstl, mcgsth);
 	if(mcgstl&(1<<0))	/* Recoverable ? */
 		recover=0;
 
@@ -27,7 +27,7 @@
 	
 	for(i=0;i<banks;i++)
 	{
-		rdmsr(0x401+i*4,low, high);
+		rdmsr(MSR_IA32_MC0_STATUS+i*4,low, high);
 		if(high&(1<<31))
 		{
 			if(high&(1<<29))
@@ -38,18 +38,18 @@
 			high&=~(1<<31);
 			if(high&(1<<27))
 			{
-				rdmsr(0x402+i*4, alow, ahigh);
+				rdmsr(MSR_IA32_MC0_MISC+i*4, alow, ahigh);
 				printk("[%08x%08x]", alow, ahigh);
 			}
 			if(high&(1<<26))
 			{
-				rdmsr(0x402+i*4, alow, ahigh);
+				rdmsr(MSR_IA32_MC0_ADDR+i*4, alow, ahigh);
 				printk(" at %08x%08x", 
 					high, low);
 			}
 			printk("\n");
 			/* Clear it */
-			wrmsr(0x401+i*4, 0UL, 0UL);
+			wrmsr(MSR_IA32_MC0_STATUS+i*4, 0UL, 0UL);
 			/* Serialize */
 			wmb();
 		}
@@ -61,7 +61,7 @@
 		panic("Unable to continue");
 	printk(KERN_EMERG "Attempting to continue.\n");
 	mcgstl&=~(1<<2);
-	wrmsr(0x17a,mcgstl, mcgsth);
+	wrmsr(MSR_IA32_MCG_STATUS,mcgstl, mcgsth);
 }
 
 /*
@@ -71,8 +71,8 @@
 static void pentium_machine_check(struct pt_regs * regs, long error_code)
 {
 	u32 loaddr, hi, lotype;
-	rdmsr(0x0, loaddr, hi);
-	rdmsr(0x1, lotype, hi);
+	rdmsr(MSR_IA32_P5_MC_ADDR, loaddr, hi);
+	rdmsr(MSR_IA32_P5_MC_TYPE, lotype, hi);
 	printk(KERN_EMERG "CPU#%d: Machine Check Exception:  0x%8X (type 0x%8X).\n", smp_processor_id(), loaddr, lotype);
 	if(lotype&(1<<5))
 		printk(KERN_EMERG "CPU#%d: Possible thermal failure (CPU on fire ?).\n", smp_processor_id());
@@ -133,8 +133,8 @@
 		machine_check_vector = pentium_machine_check;
 		wmb();
 		/* Read registers before enabling */
-		rdmsr(0x0, l, h);
-		rdmsr(0x1, l, h);
+		rdmsr(MSR_IA32_P5_MC_ADDR, l, h);
+		rdmsr(MSR_IA32_P5_MC_TYPE, l, h);
 		if(done==0)
 			printk(KERN_INFO "Intel old style machine check architecture supported.\n");
 		/* Enable MCE */		
@@ -161,17 +161,17 @@
 	
 	if(done==0)
 		printk(KERN_INFO "Intel machine check architecture supported.\n");
-	rdmsr(0x179, l, h);
+	rdmsr(MSR_IA32_MCG_CAP, l, h);
 	if(l&(1<<8))
-		wrmsr(0x17b, 0xffffffff, 0xffffffff);
+		wrmsr(MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff);
 	banks = l&0xff;
 	for(i=1;i<banks;i++)
 	{
-		wrmsr(0x400+4*i, 0xffffffff, 0xffffffff); 
+		wrmsr(MSR_IA32_MC0_CTL+4*i, 0xffffffff, 0xffffffff);
 	}
 	for(i=0;i<banks;i++)
 	{
-		wrmsr(0x401+4*i, 0x0, 0x0); 
+		wrmsr(MSR_IA32_MC0_STATUS+4*i, 0x0, 0x0);
 	}
 	set_in_cr4(X86_CR4_MCE);
 	printk(KERN_INFO "Intel machine check reporting enabled on CPU#%d.\n", smp_processor_id());
@@ -191,10 +191,10 @@
 	/* Winchip C6 */
 	machine_check_vector = winchip_machine_check;
 	wmb();
-	rdmsr(0x107, lo, hi);
+	rdmsr(MSR_IDT_FCR1, lo, hi);
 	lo|= (1<<2);	/* Enable EIERRINT (int 18 MCE) */
 	lo&= ~(1<<4);	/* Enable MCE */
-	wrmsr(0x107, lo, hi);
+	wrmsr(MSR_IDT_FCR1, lo, hi);
 	__asm__ __volatile__ (
 		"movl %%cr4, %%eax\n\t"
 		"orl $0x40, %%eax\n\t"
@@ -236,6 +236,6 @@
 static int __init mcheck_disable(char *str)
 {
 	mce_disabled = 1;
-	return 1;
+	return 0;
 }
 __setup("nomce", mcheck_disable);
diff -u --recursive --new-file v2.4.9/linux/arch/i386/kernel/entry.S linux/arch/i386/kernel/entry.S
--- v2.4.9/linux/arch/i386/kernel/entry.S	Tue Jul  3 17:08:18 2001
+++ linux/arch/i386/kernel/entry.S	Sat Sep  8 12:02:32 2001
@@ -621,12 +621,6 @@
 	.long SYMBOL_NAME(sys_fcntl64)
 	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for TUX */
 
-	/*
-	 * NOTE!! This doesn't have to be exact - we just have
-	 * to make sure we have _enough_ of the "sys_ni_syscall"
-	 * entries. Don't panic if you notice that this hasn't
-	 * been shrunk every time we add a new system call.
-	 */
-	.rept NR_syscalls-221
+	.rept NR_syscalls-(.-sys_call_table)/4
 		.long SYMBOL_NAME(sys_ni_syscall)
 	.endr
diff -u --recursive --new-file v2.4.9/linux/arch/i386/kernel/mtrr.c linux/arch/i386/kernel/mtrr.c
--- v2.4.9/linux/arch/i386/kernel/mtrr.c	Thu May 24 15:14:08 2001
+++ linux/arch/i386/kernel/mtrr.c	Sat Sep  1 11:05:16 2001
@@ -389,21 +389,19 @@
 	 return;
 
     /*  Save value of CR4 and clear Page Global Enable (bit 7)  */
-    if ( test_bit(X86_FEATURE_PGE, &boot_cpu_data.x86_capability) )
-	asm volatile ("movl  %%cr4, %0\n\t"
-		      "movl  %0, %1\n\t"
-		      "andb  $0x7f, %b1\n\t"
-		      "movl  %1, %%cr4\n\t"
-		      : "=r" (ctxt->cr4val), "=q" (tmp) : : "memory");
+    if ( test_bit(X86_FEATURE_PGE, &boot_cpu_data.x86_capability) ) {
+	ctxt->cr4val = read_cr4();
+	write_cr4(ctxt->cr4val & (unsigned char) ~(1<<7));
+    }
 
     /*  Disable and flush caches. Note that wbinvd flushes the TLBs as
 	a side-effect  */
-    asm volatile ("movl  %%cr0, %0\n\t"
-		  "orl   $0x40000000, %0\n\t"
-		  "wbinvd\n\t"
-		  "movl  %0, %%cr0\n\t"
-		  "wbinvd\n\t"
-		  : "=r" (tmp) : : "memory");
+    {
+	unsigned int cr0 = read_cr0() | 0x40000000;
+	wbinvd();
+	write_cr0( cr0 );
+	wbinvd();
+    }
 
     if ( mtrr_if == MTRR_IF_INTEL ) {
 	/*  Disable MTRRs, and set the default type to uncached  */
@@ -420,15 +418,13 @@
 /*  Restore the processor after a set_mtrr_prepare  */
 static void set_mtrr_done (struct set_mtrr_context *ctxt)
 {
-    unsigned long tmp;
-
     if ( mtrr_if != MTRR_IF_INTEL && mtrr_if != MTRR_IF_CYRIX_ARR ) {
 	 __restore_flags (ctxt->flags);
 	 return;
     }
 
     /*  Flush caches and TLBs  */
-    asm volatile ("wbinvd" : : : "memory" );
+    wbinvd();
 
     /*  Restore MTRRdefType  */
     if ( mtrr_if == MTRR_IF_INTEL ) {
@@ -440,15 +436,11 @@
     }
 
     /*  Enable caches  */
-    asm volatile ("movl  %%cr0, %0\n\t"
-		  "andl  $0xbfffffff, %0\n\t"
-		  "movl  %0, %%cr0\n\t"
-		  : "=r" (tmp) : : "memory");
+    write_cr0( read_cr0() & 0xbfffffff );
 
     /*  Restore value of CR4  */
     if ( test_bit(X86_FEATURE_PGE, &boot_cpu_data.x86_capability) )
-	asm volatile ("movl  %0, %%cr4"
-		      : : "r" (ctxt->cr4val) : "memory");
+	write_cr4(ctxt->cr4val);
 
     /*  Re-enable interrupts locally (if enabled previously)  */
     __restore_flags (ctxt->flags);
@@ -607,7 +599,7 @@
 {
     unsigned long low, high;
 
-    rdmsr (0xC0000085, low, high);
+    rdmsr (MSR_K6_UWCCR, low, high);
     /*  Upper dword is region 1, lower is region 0  */
     if (reg == 1) low = high;
     /*  The base masks off on the right alignment  */
@@ -771,7 +763,7 @@
     /*
      *	Low is MTRR0 , High MTRR 1
      */
-    rdmsr (0xC0000085, regs[0], regs[1]);
+    rdmsr (MSR_K6_UWCCR, regs[0], regs[1]);
     /*
      *	Blank to disable
      */
@@ -792,8 +784,8 @@
      *	The writeback rule is quite specific. See the manual. Its
      *	disable local interrupts, write back the cache, set the mtrr
      */
-    __asm__ __volatile__ ("wbinvd" : : : "memory");
-    wrmsr (0xC0000085, regs[0], regs[1]);
+	wbinvd();
+	wrmsr (MSR_K6_UWCCR, regs[0], regs[1]);
     if (do_safe) set_mtrr_done (&ctxt);
 }   /*  End Function amd_set_mtrr_up  */
 
@@ -826,7 +818,7 @@
     }
     centaur_mcr[reg].high = high;
     centaur_mcr[reg].low = low;
-    wrmsr (0x110 + reg, low, high);
+    wrmsr (MSR_IDT_MCR0 + reg, low, high);
     if (do_safe) set_mtrr_done( &ctxt );
 }   /*  End Function centaur_set_mtrr_up  */
 
@@ -2012,12 +2004,12 @@
      * find out what the bios might have done.
      */
      
-    rdmsr(0x120, lo, hi);
+    rdmsr(MSR_IDT_MCR_CTRL, lo, hi);
     if(((lo>>17)&7)==1)		/* Type 1 Winchip2 MCR */
     {
     	lo&= ~0x1C0;		/* clear key */
     	lo|= 0x040;		/* set key to 1 */
-	wrmsr(0x120, lo, hi);	/* unlock MCR */
+	wrmsr(MSR_IDT_MCR_CTRL, lo, hi);	/* unlock MCR */
     }    
     
     centaur_mcr_type = 1;
@@ -2031,7 +2023,7 @@
     	if(centaur_mcr[i]. high == 0 && centaur_mcr[i].low == 0)
     	{
     		if(!(lo & (1<<(9+i))))
-			wrmsr (0x110 + i , 0, 0);
+			wrmsr (MSR_IDT_MCR0 + i , 0, 0);
 		else
 			/*
 			 *	If the BIOS set up an MCR we cannot see it
@@ -2047,7 +2039,7 @@
      */
 
     lo |= 15;			/* Write combine enables */
-    wrmsr(0x120, lo, hi);
+    wrmsr(MSR_IDT_MCR_CTRL, lo, hi);
 }   /*  End Function centaur_mcr1_init  */
 
 /*
@@ -2071,10 +2063,10 @@
     for (i = 0; i < 8; ++i)
     {
     	if(centaur_mcr[i]. high == 0 && centaur_mcr[i].low == 0)
-		wrmsr (0x110 + i , 0, 0);
+		wrmsr (MSR_IDT_MCR0 + i , 0, 0);
     }
 
-    wrmsr(0x120, 0x01F0001F, 0);	/* Write only */
+    wrmsr(MSR_IDT_MCR_CTRL, 0x01F0001F, 0);	/* Write only */
 }   /*  End Function centaur_mcr0_init  */
 
 /*
@@ -2230,6 +2222,8 @@
 	 *  :-)
 	 */
 	cyrix_arr_init_secondary ();
+	break;
+    case MTRR_IF_NONE:
 	break;
     default:
 	/* I see no MTRRs I can support in SMP mode... */
diff -u --recursive --new-file v2.4.9/linux/arch/i386/kernel/pci-pc.c linux/arch/i386/kernel/pci-pc.c
--- v2.4.9/linux/arch/i386/kernel/pci-pc.c	Mon Aug 27 12:41:39 2001
+++ linux/arch/i386/kernel/pci-pc.c	Sat Sep  1 11:01:28 2001
@@ -20,65 +20,145 @@
 unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2;
 
 int pcibios_last_bus = -1;
-struct pci_bus *pci_root_bus;
-struct pci_ops *pci_root_ops;
+struct pci_bus *pci_root_bus = NULL;
+struct pci_ops *pci_root_ops = NULL;
+
+int (*pci_config_read)(int seg, int bus, int dev, int fn, int reg, int len, u32 *value) = NULL;
+int (*pci_config_write)(int seg, int bus, int dev, int fn, int reg, int len, u32 value) = NULL;
 
 /*
- * Direct access to PCI hardware...
+ * This interrupt-safe spinlock protects all accesses to PCI
+ * configuration space.
  */
+spinlock_t pci_config_lock = SPIN_LOCK_UNLOCKED;
 
-#ifdef CONFIG_PCI_DIRECT
 
 /*
  * Functions for accessing PCI configuration space with type 1 accesses
  */
 
-#define CONFIG_CMD(dev, where)   (0x80000000 | (dev->bus->number << 16) | (dev->devfn << 8) | (where & ~3))
+#ifdef CONFIG_PCI_DIRECT
+
+#define PCI_CONF1_ADDRESS(bus, dev, fn, reg) \
+	(0x80000000 | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3))
+
+static int pci_conf1_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
+{
+	unsigned long flags;
+
+	if (!value || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
+		return -EINVAL;
+
+	spin_lock_irqsave(&pci_config_lock, flags);
+
+	outl(PCI_CONF1_ADDRESS(bus, dev, fn, reg), 0xCF8);
+
+	switch (len) {
+	case 1:
+		*value = inb(0xCFC + (reg & 3));
+		break;
+	case 2:
+		*value = inw(0xCFC + (reg & 2));
+		break;
+	case 4:
+		*value = inl(0xCFC);
+		break;
+	}
+
+	spin_unlock_irqrestore(&pci_config_lock, flags);
+
+	return 0;
+}
+
+static int pci_conf1_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
+{
+	unsigned long flags;
+
+	if ((bus > 255) || (dev > 31) || (fn > 7) || (reg > 255)) 
+		return -EINVAL;
+
+	spin_lock_irqsave(&pci_config_lock, flags);
+
+	outl(PCI_CONF1_ADDRESS(bus, dev, fn, reg), 0xCF8);
+
+	switch (len) {
+	case 1:
+		outb((u8)value, 0xCFC + (reg & 3));
+		break;
+	case 2:
+		outw((u16)value, 0xCFC + (reg & 2));
+		break;
+	case 4:
+		outl((u32)value, 0xCFC);
+		break;
+	}
+
+	spin_unlock_irqrestore(&pci_config_lock, flags);
+
+	return 0;
+}
+
+#undef PCI_CONF1_ADDRESS
 
 static int pci_conf1_read_config_byte(struct pci_dev *dev, int where, u8 *value)
 {
-	outl(CONFIG_CMD(dev,where), 0xCF8);
-	*value = inb(0xCFC + (where&3));
-	return PCIBIOS_SUCCESSFUL;
+	int result; 
+	u32 data;
+
+	if (!value) 
+		return -EINVAL;
+
+	result = pci_conf1_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 1, &data);
+
+	*value = (u8)data;
+
+	return result;
 }
 
 static int pci_conf1_read_config_word(struct pci_dev *dev, int where, u16 *value)
 {
-	outl(CONFIG_CMD(dev,where), 0xCF8);    
-	*value = inw(0xCFC + (where&2));
-	return PCIBIOS_SUCCESSFUL;    
+	int result; 
+	u32 data;
+
+	if (!value) 
+		return -EINVAL;
+
+	result = pci_conf1_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 2, &data);
+
+	*value = (u16)data;
+
+	return result;
 }
 
 static int pci_conf1_read_config_dword(struct pci_dev *dev, int where, u32 *value)
 {
-	outl(CONFIG_CMD(dev,where), 0xCF8);
-	*value = inl(0xCFC);
-	return PCIBIOS_SUCCESSFUL;    
+	if (!value) 
+		return -EINVAL;
+
+	return pci_conf1_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 4, value);
 }
 
 static int pci_conf1_write_config_byte(struct pci_dev *dev, int where, u8 value)
 {
-	outl(CONFIG_CMD(dev,where), 0xCF8);    
-	outb(value, 0xCFC + (where&3));
-	return PCIBIOS_SUCCESSFUL;
+	return pci_conf1_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 1, value);
 }
 
 static int pci_conf1_write_config_word(struct pci_dev *dev, int where, u16 value)
 {
-	outl(CONFIG_CMD(dev,where), 0xCF8);
-	outw(value, 0xCFC + (where&2));
-	return PCIBIOS_SUCCESSFUL;
+	return pci_conf1_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 2, value);
 }
 
 static int pci_conf1_write_config_dword(struct pci_dev *dev, int where, u32 value)
 {
-	outl(CONFIG_CMD(dev,where), 0xCF8);
-	outl(value, 0xCFC);
-	return PCIBIOS_SUCCESSFUL;
+	return pci_conf1_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 4, value);
 }
 
-#undef CONFIG_CMD
-
 static struct pci_ops pci_direct_conf1 = {
 	pci_conf1_read_config_byte,
 	pci_conf1_read_config_word,
@@ -88,68 +168,131 @@
 	pci_conf1_write_config_dword
 };
 
+
 /*
  * Functions for accessing PCI configuration space with type 2 accesses
  */
 
-#define IOADDR(devfn, where)	((0xC000 | ((devfn & 0x78) << 5)) + where)
-#define FUNC(devfn)		(((devfn & 7) << 1) | 0xf0)
-#define SET(dev)		if (dev->devfn & 0x80) return PCIBIOS_DEVICE_NOT_FOUND;		\
-				outb(FUNC(dev->devfn), 0xCF8);					\
-				outb(dev->bus->number, 0xCFA);
+#define PCI_CONF2_ADDRESS(dev, reg)	(u16)(0xC000 | (dev << 8) | reg)
 
-static int pci_conf2_read_config_byte(struct pci_dev *dev, int where, u8 *value)
+static int pci_conf2_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
 {
-	SET(dev);
-	*value = inb(IOADDR(dev->devfn,where));
+	unsigned long flags;
+
+	if (!value || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
+		return -EINVAL;
+
+	if (dev & 0x10) 
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	spin_lock_irqsave(&pci_config_lock, flags);
+
+	outb((u8)(0xF0 | (fn << 1)), 0xCF8);
+	outb((u8)bus, 0xCFA);
+
+	switch (len) {
+	case 1:
+		*value = inb(PCI_CONF2_ADDRESS(dev, reg));
+		break;
+	case 2:
+		*value = inw(PCI_CONF2_ADDRESS(dev, reg));
+		break;
+	case 4:
+		*value = inl(PCI_CONF2_ADDRESS(dev, reg));
+		break;
+	}
+
 	outb (0, 0xCF8);
-	return PCIBIOS_SUCCESSFUL;
+
+	spin_unlock_irqrestore(&pci_config_lock, flags);
+
+	return 0;
+}
+
+static int pci_conf2_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
+{
+	unsigned long flags;
+
+	if ((bus > 255) || (dev > 31) || (fn > 7) || (reg > 255)) 
+		return -EINVAL;
+
+	if (dev & 0x10) 
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	spin_lock_irqsave(&pci_config_lock, flags);
+
+	outb((u8)(0xF0 | (fn << 1)), 0xCF8);
+	outb((u8)bus, 0xCFA);
+
+	switch (len) {
+	case 1:
+		outb ((u8)value, PCI_CONF2_ADDRESS(dev, reg));
+		break;
+	case 2:
+		outw ((u16)value, PCI_CONF2_ADDRESS(dev, reg));
+		break;
+	case 4:
+		outl ((u32)value, PCI_CONF2_ADDRESS(dev, reg));
+		break;
+	}
+
+	outb (0, 0xCF8);    
+
+	spin_unlock_irqrestore(&pci_config_lock, flags);
+
+	return 0;
+}
+
+#undef PCI_CONF2_ADDRESS
+
+static int pci_conf2_read_config_byte(struct pci_dev *dev, int where, u8 *value)
+{
+	int result; 
+	u32 data;
+	result = pci_conf2_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 1, &data);
+	*value = (u8)data;
+	return result;
 }
 
 static int pci_conf2_read_config_word(struct pci_dev *dev, int where, u16 *value)
 {
-	SET(dev);
-	*value = inw(IOADDR(dev->devfn,where));
-	outb (0, 0xCF8);
-	return PCIBIOS_SUCCESSFUL;
+	int result; 
+	u32 data;
+	result = pci_conf2_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 2, &data);
+	*value = (u8)data;
+	return result;
 }
 
 static int pci_conf2_read_config_dword(struct pci_dev *dev, int where, u32 *value)
 {
-	SET(dev);
-	*value = inl (IOADDR(dev->devfn,where));    
-	outb (0, 0xCF8);    
-	return PCIBIOS_SUCCESSFUL;
+	int result; 
+	u32 data;
+	result = pci_conf2_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 4, &data);
+	*value = (u8)data;
+	return result;
 }
 
 static int pci_conf2_write_config_byte(struct pci_dev *dev, int where, u8 value)
 {
-	SET(dev);
-	outb (value, IOADDR(dev->devfn,where));
-	outb (0, 0xCF8);    
-	return PCIBIOS_SUCCESSFUL;
+	return pci_conf2_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 1, value);
 }
 
 static int pci_conf2_write_config_word(struct pci_dev *dev, int where, u16 value)
 {
-	SET(dev);
-	outw (value, IOADDR(dev->devfn,where));
-	outb (0, 0xCF8);    
-	return PCIBIOS_SUCCESSFUL;
+	return pci_conf2_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 2, value);
 }
 
 static int pci_conf2_write_config_dword(struct pci_dev *dev, int where, u32 value)
 {
-	SET(dev);
-	outl (value, IOADDR(dev->devfn,where));    
-	outb (0, 0xCF8);    
-	return PCIBIOS_SUCCESSFUL;
+	return pci_conf2_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 4, value);
 }
 
-#undef SET
-#undef IOADDR
-#undef FUNC
-
 static struct pci_ops pci_direct_conf2 = {
 	pci_conf2_read_config_byte,
 	pci_conf2_read_config_word,
@@ -159,6 +302,7 @@
 	pci_conf2_write_config_dword
 };
 
+
 /*
  * Before we decide to use direct hardware access mechanisms, we try to do some
  * trivial checks to ensure it at least _seems_ to be working -- we just test
@@ -420,114 +564,176 @@
 	return (int) (ret & 0xff00) >> 8;
 }
 
+static int pci_bios_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
+{
+	unsigned long result = 0;
+	unsigned long flags;
+	unsigned long bx = ((bus << 8) | (dev << 3) | fn);
+
+	if (!value || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
+		return -EINVAL;
+
+	spin_lock_irqsave(&pci_config_lock, flags);
+
+	switch (len) {
+	case 1:
+		__asm__("lcall (%%esi); cld\n\t"
+			"jc 1f\n\t"
+			"xor %%ah, %%ah\n"
+			"1:"
+			: "=c" (*value),
+			  "=a" (result)
+			: "1" (PCIBIOS_READ_CONFIG_BYTE),
+			  "b" (bx),
+			  "D" ((long)reg),
+			  "S" (&pci_indirect));
+		break;
+	case 2:
+		__asm__("lcall (%%esi); cld\n\t"
+			"jc 1f\n\t"
+			"xor %%ah, %%ah\n"
+			"1:"
+			: "=c" (*value),
+			  "=a" (result)
+			: "1" (PCIBIOS_READ_CONFIG_WORD),
+			  "b" (bx),
+			  "D" ((long)reg),
+			  "S" (&pci_indirect));
+		break;
+	case 4:
+		__asm__("lcall (%%esi); cld\n\t"
+			"jc 1f\n\t"
+			"xor %%ah, %%ah\n"
+			"1:"
+			: "=c" (*value),
+			  "=a" (result)
+			: "1" (PCIBIOS_READ_CONFIG_DWORD),
+			  "b" (bx),
+			  "D" ((long)reg),
+			  "S" (&pci_indirect));
+		break;
+	}
+
+	spin_unlock_irqrestore(&pci_config_lock, flags);
+
+	return (int)((result & 0xff00) >> 8);
+}
+
+static int pci_bios_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
+{
+	unsigned long result = 0;
+	unsigned long flags;
+	unsigned long bx = ((bus << 8) | (dev << 3) | fn);
+
+	if ((bus > 255) || (dev > 31) || (fn > 7) || (reg > 255)) 
+		return -EINVAL;
+
+	spin_lock_irqsave(&pci_config_lock, flags);
+
+	switch (len) {
+	case 1:
+		__asm__("lcall (%%esi); cld\n\t"
+			"jc 1f\n\t"
+			"xor %%ah, %%ah\n"
+			"1:"
+			: "=a" (result)
+			: "0" (PCIBIOS_WRITE_CONFIG_BYTE),
+			  "c" (value),
+			  "b" (bx),
+			  "D" ((long)reg),
+			  "S" (&pci_indirect));
+		break;
+	case 2:
+		__asm__("lcall (%%esi); cld\n\t"
+			"jc 1f\n\t"
+			"xor %%ah, %%ah\n"
+			"1:"
+			: "=a" (result)
+			: "0" (PCIBIOS_WRITE_CONFIG_WORD),
+			  "c" (value),
+			  "b" (bx),
+			  "D" ((long)reg),
+			  "S" (&pci_indirect));
+		break;
+	case 4:
+		__asm__("lcall (%%esi); cld\n\t"
+			"jc 1f\n\t"
+			"xor %%ah, %%ah\n"
+			"1:"
+			: "=a" (result)
+			: "0" (PCIBIOS_WRITE_CONFIG_DWORD),
+			  "c" (value),
+			  "b" (bx),
+			  "D" ((long)reg),
+			  "S" (&pci_indirect));
+		break;
+	}
+
+	spin_unlock_irqrestore(&pci_config_lock, flags);
+
+	return (int)((result & 0xff00) >> 8);
+}
+
 static int pci_bios_read_config_byte(struct pci_dev *dev, int where, u8 *value)
 {
-	unsigned long ret;
-	unsigned long bx = (dev->bus->number << 8) | dev->devfn;
+	int result; 
+	u32 data;
 
-	__asm__("lcall (%%esi); cld\n\t"
-		"jc 1f\n\t"
-		"xor %%ah, %%ah\n"
-		"1:"
-		: "=c" (*value),
-		  "=a" (ret)
-		: "1" (PCIBIOS_READ_CONFIG_BYTE),
-		  "b" (bx),
-		  "D" ((long) where),
-		  "S" (&pci_indirect));
-	return (int) (ret & 0xff00) >> 8;
+	if (!value) 
+		return -EINVAL;
+
+	result = pci_bios_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 1, &data);
+
+	*value = (u8)data;
+
+	return result;
 }
 
 static int pci_bios_read_config_word(struct pci_dev *dev, int where, u16 *value)
 {
-	unsigned long ret;
-	unsigned long bx = (dev->bus->number << 8) | dev->devfn;
+	int result; 
+	u32 data;
 
-	__asm__("lcall (%%esi); cld\n\t"
-		"jc 1f\n\t"
-		"xor %%ah, %%ah\n"
-		"1:"
-		: "=c" (*value),
-		  "=a" (ret)
-		: "1" (PCIBIOS_READ_CONFIG_WORD),
-		  "b" (bx),
-		  "D" ((long) where),
-		  "S" (&pci_indirect));
-	return (int) (ret & 0xff00) >> 8;
+	if (!value) 
+		return -EINVAL;
+
+	result = pci_bios_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 2, &data);
+
+	*value = (u16)data;
+
+	return result;
 }
 
 static int pci_bios_read_config_dword(struct pci_dev *dev, int where, u32 *value)
 {
-	unsigned long ret;
-	unsigned long bx = (dev->bus->number << 8) | dev->devfn;
-
-	__asm__("lcall (%%esi); cld\n\t"
-		"jc 1f\n\t"
-		"xor %%ah, %%ah\n"
-		"1:"
-		: "=c" (*value),
-		  "=a" (ret)
-		: "1" (PCIBIOS_READ_CONFIG_DWORD),
-		  "b" (bx),
-		  "D" ((long) where),
-		  "S" (&pci_indirect));
-	return (int) (ret & 0xff00) >> 8;
+	if (!value) 
+		return -EINVAL;
+	
+	return pci_bios_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 4, value);
 }
 
 static int pci_bios_write_config_byte(struct pci_dev *dev, int where, u8 value)
 {
-	unsigned long ret;
-	unsigned long bx = (dev->bus->number << 8) | dev->devfn;
-
-	__asm__("lcall (%%esi); cld\n\t"
-		"jc 1f\n\t"
-		"xor %%ah, %%ah\n"
-		"1:"
-		: "=a" (ret)
-		: "0" (PCIBIOS_WRITE_CONFIG_BYTE),
-		  "c" (value),
-		  "b" (bx),
-		  "D" ((long) where),
-		  "S" (&pci_indirect));
-	return (int) (ret & 0xff00) >> 8;
+	return pci_bios_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 1, value);
 }
 
 static int pci_bios_write_config_word(struct pci_dev *dev, int where, u16 value)
 {
-	unsigned long ret;
-	unsigned long bx = (dev->bus->number << 8) | dev->devfn;
-
-	__asm__("lcall (%%esi); cld\n\t"
-		"jc 1f\n\t"
-		"xor %%ah, %%ah\n"
-		"1:"
-		: "=a" (ret)
-		: "0" (PCIBIOS_WRITE_CONFIG_WORD),
-		  "c" (value),
-		  "b" (bx),
-		  "D" ((long) where),
-		  "S" (&pci_indirect));
-	return (int) (ret & 0xff00) >> 8;
+	return pci_bios_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 2, value);
 }
 
 static int pci_bios_write_config_dword(struct pci_dev *dev, int where, u32 value)
 {
-	unsigned long ret;
-	unsigned long bx = (dev->bus->number << 8) | dev->devfn;
-
-	__asm__("lcall (%%esi); cld\n\t"
-		"jc 1f\n\t"
-		"xor %%ah, %%ah\n"
-		"1:"
-		: "=a" (ret)
-		: "0" (PCIBIOS_WRITE_CONFIG_DWORD),
-		  "c" (value),
-		  "b" (bx),
-		  "D" ((long) where),
-		  "S" (&pci_indirect));
-	return (int) (ret & 0xff00) >> 8;
+	return pci_bios_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 4, value);
 }
 
+
 /*
  * Function table for BIOS32 access
  */
@@ -981,34 +1187,47 @@
 	pci_read_bridge_bases(b);
 }
 
-/*
- * Initialization. Try all known PCI access methods. Note that we support
- * using both PCI BIOS and direct access: in such cases, we use I/O ports
- * to access config space, but we still keep BIOS order of cards to be
- * compatible with 2.0.X. This should go away some day.
- */
 
-void __init pcibios_init(void)
+void __init pcibios_config_init(void)
 {
-	struct pci_ops *bios = NULL;
-	struct pci_ops *dir = NULL;
+	/*
+	 * Try all known PCI access methods. Note that we support using 
+	 * both PCI BIOS and direct access, with a preference for direct.
+	 */
 
 #ifdef CONFIG_PCI_BIOS
-	if ((pci_probe & PCI_PROBE_BIOS) && ((bios = pci_find_bios()))) {
+	if ((pci_probe & PCI_PROBE_BIOS) 
+		&& ((pci_root_ops = pci_find_bios()))) {
 		pci_probe |= PCI_BIOS_SORT;
 		pci_bios_present = 1;
+		pci_config_read = pci_bios_read;
+		pci_config_write = pci_bios_write;
 	}
 #endif
+
 #ifdef CONFIG_PCI_DIRECT
-	if (pci_probe & (PCI_PROBE_CONF1 | PCI_PROBE_CONF2))
-		dir = pci_check_direct();
+	if ((pci_probe & (PCI_PROBE_CONF1 | PCI_PROBE_CONF2)) 
+		&& (pci_root_ops = pci_check_direct())) {
+		if (pci_root_ops == &pci_direct_conf1) {
+			pci_config_read = pci_conf1_read;
+			pci_config_write = pci_conf1_write;
+		}
+		else {
+			pci_config_read = pci_conf2_read;
+			pci_config_write = pci_conf2_write;
+		}
+	}
 #endif
-	if (dir)
-		pci_root_ops = dir;
-	else if (bios)
-		pci_root_ops = bios;
-	else {
-		printk("PCI: No PCI bus detected\n");
+
+	return;
+}
+
+void __init pcibios_init(void)
+{
+	if (!pci_root_ops)
+		pcibios_config_init();
+	if (!pci_root_ops) {
+		printk("PCI: System does not support PCI\n");
 		return;
 	}
 
diff -u --recursive --new-file v2.4.9/linux/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c
--- v2.4.9/linux/arch/i386/kernel/setup.c	Wed Jul 25 17:10:17 2001
+++ linux/arch/i386/kernel/setup.c	Sat Sep  8 21:56:53 2001
@@ -64,6 +64,9 @@
  *
  *  VIA C3 Support.
  *  Dave Jones <davej@suse.de>, March 2001
+ *
+ *  AMD Athlon/Duron/Thunderbird bluesmoke support.
+ *  Dave Jones <davej@suse.de>, April 2001.
  */
 
 /*
@@ -93,6 +96,7 @@
 #include <linux/bootmem.h>
 #include <asm/processor.h>
 #include <linux/console.h>
+#include <asm/mtrr.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
 #include <asm/io.h>
@@ -145,9 +149,9 @@
 
 unsigned char aux_device_present;
 
+extern void mcheck_init(struct cpuinfo_x86 *c);
 extern int root_mountflags;
 extern char _text, _etext, _edata, _end;
-extern unsigned long cpu_khz;
 
 static int disable_x86_serial_nr __initdata = 1;
 static int disable_x86_fxsr __initdata = 0;
@@ -937,7 +941,6 @@
 	 * trampoline before removing it. (see the GDT stuff)
 	 */
 	reserve_bootmem(PAGE_SIZE, PAGE_SIZE);
-	smp_alloc_memory(); /* AP processor realmode stacks in low memory*/
 #endif
 
 #ifdef CONFIG_X86_IO_APIC
@@ -946,18 +949,6 @@
 	 */
 	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
 	if (LOADER_TYPE && INITRD_START) {
 		if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
@@ -977,6 +968,26 @@
 #endif
 
 	/*
+	 * NOTE: before this point _nobody_ is allowed to allocate
+	 * any memory using the bootmem allocator.
+	 */
+
+#ifdef CONFIG_SMP
+	smp_alloc_memory(); /* AP processor realmode stacks in low memory*/
+#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
+
+	/*
 	 * Request address space for all standard RAM and ROM resources
 	 * and also for regions reported as reserved by the e820.
 	 */
@@ -1088,11 +1099,18 @@
 	l2size = ecx >> 16;
 
 	/* AMD errata T13 (order #21922) */
-	if (c->x86_vendor == X86_VENDOR_AMD &&
-	    c->x86 == 6 &&
-	    c->x86_model == 3 &&
-	    c->x86_mask == 0) {
-		l2size = 64;
+	if ((c->x86_vendor == X86_VENDOR_AMD) && (c->x86 == 6)) {
+		if (c->x86_model == 3 && c->x86_mask == 0)	/* Duron Rev A0 */
+			l2size = 64;
+		if (c->x86_model == 4 &&
+			(c->x86_mask==0 || c->x86_mask==1))	/* Tbird rev A1/A2 */
+			l2size = 256;
+	}
+
+	/* VIA C3 CPUs (670-68F) need further shifting. */
+	if (c->x86_vendor == X86_VENDOR_CENTAUR && (c->x86 == 6) &&
+		((c->x86_model == 7) || (c->x86_model == 8))) {
+		l2size = l2size >> 8;
 	}
 
 	if ( l2size == 0 )
@@ -1109,7 +1127,7 @@
  *	misexecution of code under Linux. Owners of such processors should
  *	contact AMD for precise details and a CPU swap.
  *
- *	See	http://www.mygale.com/~poulot/k6bug.html
+ *	See	http://www.multimania.com/poulot/k6bug.html
  *		http://www.amd.com/K6/k6docs/revgd.html
  *
  *	The following test is erm.. interesting. AMD neglected to up
@@ -1126,6 +1144,12 @@
 	int mbytes = max_mapnr >> (20-PAGE_SHIFT);
 	int r;
 
+	/*
+	 *	FIXME: We should handle the K5 here. Set up the write
+	 *	range and also turn on MSR 83 bits 4 and 31 (write alloc,
+	 *	no bus pipeline)
+	 */
+
 	/* Bit 31 in normal CPUID used for nonstandard 3DNow ID;
 	   3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway */
 	clear_bit(0*32+31, &c->x86_capability);
@@ -1185,13 +1209,13 @@
 				if(mbytes>508)
 					mbytes=508;
 					
-				rdmsr(0xC0000082, l, h);
+				rdmsr(MSR_K6_WHCR, l, h);
 				if ((l&0x0000FFFF)==0) {
 					unsigned long flags;
 					l=(1<<0)|((mbytes/4)<<1);
 					local_irq_save(flags);
-					__asm__ __volatile__ ("wbinvd": : :"memory");
-					wrmsr(0xC0000082, l, h);
+					wbinvd();
+					wrmsr(MSR_K6_WHCR, l, h);
 					local_irq_restore(flags);
 					printk(KERN_INFO "Enabling old style K6 write allocation for %d Mb\n",
 						mbytes);
@@ -1206,13 +1230,13 @@
 				if(mbytes>4092)
 					mbytes=4092;
 
-				rdmsr(0xC0000082, l, h);
+				rdmsr(MSR_K6_WHCR, l, h);
 				if ((l&0xFFFF0000)==0) {
 					unsigned long flags;
 					l=((mbytes>>2)<<22)|(1<<16);
 					local_irq_save(flags);
-					__asm__ __volatile__ ("wbinvd": : :"memory");
-					wrmsr(0xC0000082, l, h);
+					wbinvd();
+					wrmsr(MSR_K6_WHCR, l, h);
 					local_irq_restore(flags);
 					printk(KERN_INFO "Enabling new style K6 write allocation for %d Mb\n",
 						mbytes);
@@ -1226,10 +1250,10 @@
 					set_bit(X86_FEATURE_K6_MTRR, &c->x86_capability);
 				break;
 			}
-
 			break;
 
 		case 6:	/* An Athlon/Duron. We can trust the BIOS probably */
+			mcheck_init(c);
 			break;		
 	}
 
@@ -1312,9 +1336,10 @@
 
 static void __init check_cx686_slop(struct cpuinfo_x86 *c)
 {
+	unsigned long flags;
+
 	if (Cx86_dir0_msb == 3) {
 		unsigned char ccr3, ccr5;
-		unsigned long flags;
 
 		local_irq_save(flags);
 		ccr3 = getCx86(CX86_CCR3);
@@ -1551,14 +1576,12 @@
 				name="??";
 			}
 
-			/* get FCR  */
-			rdmsr(0x107, lo, hi);
-
+			rdmsr(MSR_IDT_FCR1, lo, hi);
 			newlo=(lo|fcr_set) & (~fcr_clr);
 
 			if (newlo!=lo) {
 				printk(KERN_INFO "Centaur FCR was 0x%X now 0x%X\n", lo, newlo );
-				wrmsr(0x107, newlo, hi );
+				wrmsr(MSR_IDT_FCR1, newlo, hi );
 			} else {
 				printk(KERN_INFO "Centaur FCR is 0x%X\n",lo);
 			}
@@ -1577,14 +1600,15 @@
 				c->x86_cache_size = (cc>>24)+(dd>>24);
 			}
 			sprintf( c->x86_model_id, "WinChip %s", name );
+			mcheck_init(c);
 			break;
 
 		case 6:
 			switch (c->x86_model) {
 				case 6 ... 7:		/* Cyrix III or C3 */
-					rdmsr (0x1107, lo, hi);
+					rdmsr (MSR_VIA_FCR, lo, hi);
 					lo |= (1<<1 | 1<<7);	/* Report CX8 & enable PGE */
-					wrmsr (0x1107, lo, hi);
+					wrmsr (MSR_VIA_FCR, lo, hi);
 
 					set_bit(X86_FEATURE_CX8, &c->x86_capability);
 					set_bit(X86_FEATURE_3DNOW, &c->x86_capability);
@@ -1595,7 +1619,6 @@
 			}
 			break;
 	}
-
 }
 
 
@@ -1668,7 +1691,6 @@
 	if (c->x86_model > 2)
 		printk(" II");
 	printk("\n");
-	printk("If you have one of these please email davej@suse.de\n");
 
 	/* Unhide possibly hidden capability flags
 	   The mp6 iDragon family don't have MSRs.
@@ -1694,7 +1716,6 @@
 #ifndef CONFIG_M686
 	static int f00f_workaround_enabled = 0;
 #endif
-	extern void mcheck_init(struct cpuinfo_x86 *c);
 	char *p = NULL;
 	unsigned int l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */
 
@@ -1989,9 +2010,9 @@
 	    disable_x86_serial_nr ) {
 		/* Disable processor serial number */
 		unsigned long lo,hi;
-		rdmsr(0x119,lo,hi);
+		rdmsr(MSR_IA32_BBL_CR_CTL,lo,hi);
 		lo |= 0x200000;
-		wrmsr(0x119,lo,hi);
+		wrmsr(MSR_IA32_BBL_CR_CTL,lo,hi);
 		printk(KERN_NOTICE "CPU serial number disabled.\n");
 		clear_bit(X86_FEATURE_PN, &c->x86_capability);
 
diff -u --recursive --new-file v2.4.9/linux/arch/i386/mm/fault.c linux/arch/i386/mm/fault.c
--- v2.4.9/linux/arch/i386/mm/fault.c	Tue May 15 00:16:51 2001
+++ linux/arch/i386/mm/fault.c	Fri Sep  7 19:11:12 2001
@@ -313,7 +313,7 @@
 	tsk->thread.cr2 = address;
 	tsk->thread.error_code = error_code;
 	tsk->thread.trap_no = 14;
-	info.si_code = SIGBUS;
+	info.si_signo = SIGBUS;
 	info.si_errno = 0;
 	info.si_code = BUS_ADRERR;
 	info.si_addr = (void *)address;
diff -u --recursive --new-file v2.4.9/linux/arch/mips/Makefile linux/arch/mips/Makefile
--- v2.4.9/linux/arch/mips/Makefile	Tue Jul  3 17:08:18 2001
+++ linux/arch/mips/Makefile	Sun Sep  9 10:43:02 2001
@@ -36,8 +36,9 @@
 # crossformat linking we rely on the elf2ecoff tool for format conversion.
 #
 GCCFLAGS	:= -G 0 -mno-abicalls -fno-pic
-LINKFLAGS	+= -static -G 0
+LINKFLAGS	+= -static
 MODFLAGS	+= -mlong-calls
+LD		:= $(LD) -G 0
 
 ifdef CONFIG_REMOTE_DEBUG
 CFLAGS		:= $(CFLAGS) -g
@@ -55,12 +56,18 @@
 ifdef CONFIG_CPU_R4300
 GCCFLAGS	+= -mcpu=r4300 -mips2 -Wa,--trap
 endif
+ifdef CONFIG_CPU_VR41XX
+GCCFLAGS	+= -mcpu=r4600 -mips2 -Wa,--trap
+endif
 ifdef CONFIG_CPU_R4X00
 GCCFLAGS	+= -mcpu=r4600 -mips2 -Wa,--trap
 endif
 ifdef CONFIG_CPU_MIPS32
 GCCFLAGS	+= -mcpu=r4600 -mips2 -Wa,--trap
 endif
+ifdef CONFIG_CPU_MIPS64
+GCCFLAGS	+= -mcpu=r4600 -mips2 -Wa,--trap
+endif
 ifdef CONFIG_CPU_R5000
 GCCFLAGS	+= -mcpu=r5000 -mips2 -Wa,--trap
 endif
@@ -68,7 +75,8 @@
 GCCFLAGS        += -mcpu=r5000 -mips2 -Wa,--trap
 endif
 ifdef CONFIG_CPU_NEVADA
-GCCFLAGS	+= -mcpu=r5000 -mips2 -Wa,--trap -mmad
+# Cannot use -mmad with currently recommended tools
+GCCFLAGS	+= -mcpu=r5000 -mips2 -Wa,--trap
 endif
 ifdef CONFIG_CPU_RM7000
 GCCFLAGS	+= -mcpu=r5000 -mips2 -Wa,--trap
@@ -77,11 +85,6 @@
 GCCFLAGS	+= -mcpu=sb1 -mips2 -Wa,--trap
 endif
 
-ifdef CONFIG_MIPS_FPU_EMULATOR
-CORE_FILES	+=arch/mips/math-emu/fpu_emulator.o
-SUBDIRS		+=arch/mips/math-emu
-endif
-
 GCCFLAGS	+= -pipe
 
 CFLAGS		:= -I $(TOPDIR)/include/asm/gcc $(CFLAGS) $(GCCFLAGS)
@@ -89,6 +92,12 @@
 ASFLAGS		+= $(GCCFLAGS)
 
 #
+# We unconditionally build the math emulator
+#
+CORE_FILES	+=arch/mips/math-emu/fpu_emulator.o
+SUBDIRS		+=arch/mips/math-emu
+
+#
 # Board-dependent options and extra files
 #
 ifdef CONFIG_ALGOR_P4032
@@ -229,11 +238,27 @@
 # ITE 8172 eval board with QED 5231 CPU
 #
 ifdef CONFIG_MIPS_ITE8172
-LIBS		+= arch/mips/ite-boards/qed-4n-s01b/ite.o		     \
-		   arch/mips/ite-boards/generic/it8172.o
-SUBDIRS		+= arch/mips/ite-boards/generic				     \
-		   arch/mips/ite-boards/qed-4n-s01b
-LOADADDR	+= 0x80100000
+LIBS          += arch/mips/ite-boards/qed-4n-s01b/ite.o arch/mips/ite-boards/generic/it8172.o
+SUBDIRS       += arch/mips/ite-boards/generic arch/mips/ite-boards/qed-4n-s01b
+LOADADDR      += 0x80100000
+endif
+
+#
+# Globespan IVR eval board with QED 5231 CPU
+#
+ifdef CONFIG_MIPS_IVR
+LIBS          += arch/mips/ite-boards/ivr/ivr.o arch/mips/ite-boards/generic/it8172.o
+SUBDIRS       += arch/mips/ite-boards/generic arch/mips/ite-boards/ivr
+LOADADDR      += 0x80100000
+endif
+
+#
+# Au1000 eval board
+#
+ifdef CONFIG_MIPS_PB1000
+LIBS          += arch/mips/au1000/pb1000/pb1000.o arch/mips/au1000/common/au1000.o
+SUBDIRS       += arch/mips/au1000/pb1000 arch/mips/au1000/common
+LOADADDR      += 0x80100000
 endif
 
 #
@@ -273,14 +298,6 @@
 
 vmlinux.ecoff: vmlinux
 	@$(MAKEBOOT) $@
-
-zImage: vmlinux
-	@$(MAKEBOOT) zImage
-
-compressed: zImage
-
-zdisk: vmlinux
-	@$(MAKEBOOT) zdisk
 
 archclean:
 	@$(MAKEBOOT) clean
diff -u --recursive --new-file v2.4.9/linux/arch/mips/au1000/common/Makefile linux/arch/mips/au1000/common/Makefile
--- v2.4.9/linux/arch/mips/au1000/common/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/au1000/common/Makefile	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,31 @@
+#
+#  Copyright 2000 MontaVista Software Inc.
+#  Author: MontaVista Software, Inc.
+#     	ppopov@mvista.com or source@mvista.com
+#
+# Makefile for the Alchemy Au1000 CPU, generic files.
+#
+# 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.s:
+	$(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+	$(CC) $(CFLAGS) -c $< -o $*.o
+
+all: au1000.o
+
+O_TARGET := au1000.o
+
+obj-y := prom.o dbg_io.o int-handler.o irq.o puts.o time.o reset.o
+
+obj-$(CONFIG_AU1000_UART) += serial.o             
+obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o             
+obj-$(CONFIG_BLK_DEV_INITRD) += ramdisk.o
+
+ramdisk.o: 
+	mkramobj ramdisk ramdisk.o
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.9/linux/arch/mips/au1000/common/dbg_io.c linux/arch/mips/au1000/common/dbg_io.c
--- v2.4.9/linux/arch/mips/au1000/common/dbg_io.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/au1000/common/dbg_io.c	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,118 @@
+
+#include <linux/config.h>
+#include <asm/io.h>
+#include <asm/au1000.h>
+
+#ifdef CONFIG_REMOTE_DEBUG
+
+/*
+ * FIXME the user should be able to select the
+ * uart to be used for debugging.
+ */
+#define	DEBUG_BASE  UART2_ADDR
+/**/
+
+/* we need uint32 uint8 */
+/* #include "types.h" */
+typedef         unsigned char uint8;
+typedef         unsigned int  uint32;
+
+#define         UART16550_BAUD_2400             2400
+#define         UART16550_BAUD_4800             4800
+#define         UART16550_BAUD_9600             9600
+#define         UART16550_BAUD_19200            19200
+#define         UART16550_BAUD_38400            38400
+#define         UART16550_BAUD_57600            57600
+#define         UART16550_BAUD_115200           115200
+
+#define         UART16550_PARITY_NONE           0
+#define         UART16550_PARITY_ODD            0x08
+#define         UART16550_PARITY_EVEN           0x18
+#define         UART16550_PARITY_MARK           0x28
+#define         UART16550_PARITY_SPACE          0x38
+
+#define         UART16550_DATA_5BIT             0x0
+#define         UART16550_DATA_6BIT             0x1
+#define         UART16550_DATA_7BIT             0x2
+#define         UART16550_DATA_8BIT             0x3
+
+#define         UART16550_STOP_1BIT             0x0
+#define         UART16550_STOP_2BIT             0x4
+
+
+#define UART_RX		0	/* Receive buffer */
+#define UART_TX		4	/* Transmit buffer */
+#define UART_IER	8	/* Interrupt Enable Register */
+#define UART_IIR	0xC	/* Interrupt ID Register */
+#define UART_FCR	0x10	/* FIFO Control Register */
+#define UART_LCR	0x14	/* Line Control Register */
+#define UART_MCR	0x18	/* Modem Control Register */
+#define UART_LSR	0x1C	/* Line Status Register */
+#define UART_MSR	0x20	/* Modem Status Register */
+#define UART_CLK	0x28	/* Baud Rat4e Clock Divider */
+#define UART_MOD_CNTRL	0x100	/* Module Control */
+
+/* memory-mapped read/write of the port */
+#define UART16550_READ(y)    (inl(DEBUG_BASE + y) & 0xff)
+#define UART16550_WRITE(y,z) (outl(z&0xff, DEBUG_BASE + y))
+
+void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
+{
+
+	if (UART16550_READ(UART_MOD_CNTRL) != 0x3) {
+		UART16550_WRITE(UART_MOD_CNTRL, 3);
+	}
+	cal_r4koff();
+
+	/* disable interrupts */
+	UART16550_WRITE(UART_IER, 0);
+
+	/* set up baud rate */
+	{ 
+		uint32 divisor;
+
+		/* set divisor */
+		divisor = get_au1000_uart_baud() / baud;
+		UART16550_WRITE(UART_CLK, divisor & 0xffff);
+	}
+
+	/* set data format */
+	UART16550_WRITE(UART_LCR, data | parity | stop);
+}
+
+static int remoteDebugInitialized = 0;
+
+uint8 getDebugChar(void)
+{
+	if (!remoteDebugInitialized) {
+		remoteDebugInitialized = 1;
+		debugInit(UART16550_BAUD_115200,
+			  UART16550_DATA_8BIT,
+			  UART16550_PARITY_NONE,
+			  UART16550_STOP_1BIT);
+	}
+
+	while((UART16550_READ(UART_LSR) & 0x1) == 0);
+	return UART16550_READ(UART_RX);
+}
+
+
+int putDebugChar(uint8 byte)
+{
+	int i;
+	if (!remoteDebugInitialized) {
+		remoteDebugInitialized = 1;
+		debugInit(UART16550_BAUD_115200,
+			  UART16550_DATA_8BIT,
+			  UART16550_PARITY_NONE,
+			  UART16550_STOP_1BIT);
+	}
+
+	while ((UART16550_READ(UART_LSR)&0x40) == 0);
+	UART16550_WRITE(UART_TX, byte);
+	//for (i=0;i<0xfff;i++);
+
+	return 1;
+}
+
+#endif
diff -u --recursive --new-file v2.4.9/linux/arch/mips/au1000/common/int-handler.S linux/arch/mips/au1000/common/int-handler.S
--- v2.4.9/linux/arch/mips/au1000/common/int-handler.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/au1000/common/int-handler.S	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: ppopov@mvista.com
+ *
+ * Interrupt dispatcher for Au1000 boards.
+ *
+ * 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/config.h>
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+	.text
+	.set	macro
+	.set	noat
+	.align	5
+
+NESTED(au1000_IRQ, PT_SIZE, sp)
+	SAVE_ALL
+	CLI				# Important: mark KERNEL mode !
+
+	mfc0	t0,CP0_CAUSE		# get pending interrupts
+	mfc0	t1,CP0_STATUS		# get enabled interrupts
+	and	t0,t1			# isolate allowed ones
+
+	andi	t0,0xff00		# isolate pending bits
+	beqz	t0, 3f			# spurious interrupt
+
+	andi	a0, t0, CAUSEF_IP7
+	beq	a0, zero, 1f
+	move	a0, sp
+	jal	mips_timer_interrupt
+	j	ret_from_irq
+
+1:
+	andi	a0, t0, CAUSEF_IP2	# Interrupt Controller 0, Request 0
+	beq	a0, zero, 2f	        
+	move	a0,sp  
+	jal	intc0_req0_irqdispatch
+	j	ret_from_irq
+2:
+	andi	a0, t0, CAUSEF_IP3	# Interrupt Controller 0, Request 1
+	beq	a0, zero, 3f	       
+	move	a0,sp  
+	jal	intc0_req1_irqdispatch
+	j	ret_from_irq
+3:
+	andi	a0, t0, CAUSEF_IP4	# Interrupt Controller 1, Request 0
+	beq	a0, zero, 4f	       
+	move	a0,sp  
+	jal	intc1_req0_irqdispatch
+	j	ret_from_irq
+4:
+	andi	a0, t0, CAUSEF_IP5	# Interrupt Controller 1, Request 1
+	beq	a0, zero, 5f	       
+	move	a0, sp  
+	jal	intc1_req1_irqdispatch
+	j	ret_from_irq
+
+5:	
+	move	a0, sp
+	jal	mips_spurious_interrupt
+done:
+	j	ret_from_irq
+END(au1000_IRQ)
diff -u --recursive --new-file v2.4.9/linux/arch/mips/au1000/common/irq.c linux/arch/mips/au1000/common/irq.c
--- v2.4.9/linux/arch/mips/au1000/common/irq.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/au1000/common/irq.c	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,471 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Au1000 interrupt routines.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *		ppopov@mvista.com or source@mvista.com
+ *
+ *  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  SOFTWARE  IS PROVIDED	  ``AS	IS'' AND   ANY	EXPRESS OR IMPLIED
+ *  WARRANTIES,	  INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO	EVENT  SHALL   THE AUTHOR  BE	 LIABLE FOR ANY	  DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED	  TO, PROCUREMENT OF  SUBSTITUTE GOODS	OR SERVICES; LOSS OF
+ *  USE, DATA,	OR PROFITS; OR	BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN	 CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.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/slab.h>
+#include <linux/random.h>
+#include <linux/delay.h>
+
+#include <asm/bitops.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/au1000.h>
+
+#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
+
+#undef DEBUG_IRQ
+#ifdef DEBUG_IRQ
+/* note: prints function name for you */
+#define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+#define EXT_INTC0_REQ0 2 /* IP 2 */
+#define EXT_INTC0_REQ1 3 /* IP 3 */
+#define EXT_INTC1_REQ0 4 /* IP 4 */
+#define EXT_INTC1_REQ1 5 /* IP 5 */
+#define MIPS_TIMER_IP  7 /* IP 7 */
+
+#ifdef CONFIG_REMOTE_DEBUG
+extern void breakpoint(void);
+#endif
+
+extern asmlinkage void au1000_IRQ(void);
+
+extern void set_debug_traps(void);
+extern irq_cpustat_t irq_stat [];
+extern irq_desc_t irq_desc[NR_IRQS];
+
+unsigned int local_bh_count[NR_CPUS];
+unsigned int local_irq_count[NR_CPUS];
+
+static void setup_local_irq(unsigned int irq, int type, int int_req);
+static unsigned int startup_irq(unsigned int irq);
+static void end_irq(unsigned int irq_nr);
+static inline void mask_and_ack_level_irq(unsigned int irq_nr);
+static inline void mask_and_ack_rise_edge_irq(unsigned int irq_nr);
+static inline void mask_and_ack_fall_edge_irq(unsigned int irq_nr);
+static inline void local_enable_irq(unsigned int irq_nr);
+static inline void local_disable_irq(unsigned int irq_nr);
+
+unsigned long spurious_interrupts;
+extern unsigned int do_IRQ(int irq, struct pt_regs *regs);
+extern void __init init_generic_irq(void);
+
+static inline void sync(void)
+{
+	__asm volatile ("sync");
+}
+
+
+/* Function for careful CP0 interrupt mask access */
+static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask)
+{
+	unsigned long status = read_32bit_cp0_register(CP0_STATUS);
+	status &= ~((clr_mask & 0xFF) << 8);
+	status |=   (set_mask & 0xFF) << 8;
+	write_32bit_cp0_register(CP0_STATUS, status);
+}
+
+
+static inline void mask_cpu_irq_input(unsigned int irq_nr)
+{
+	modify_cp0_intmask(irq_nr, 0);
+}
+
+
+static inline void unmask_cpu_irq_input(unsigned int irq_nr)
+{
+	modify_cp0_intmask(0, irq_nr);
+}
+
+
+static void disable_cpu_irq_input(unsigned int irq_nr)
+{
+	unsigned long flags;
+
+	save_and_cli(flags);
+	mask_cpu_irq_input(irq_nr);
+	restore_flags(flags);
+}
+
+
+static void enable_cpu_irq_input(unsigned int irq_nr)
+{
+	unsigned long flags;
+
+	save_and_cli(flags);
+	unmask_cpu_irq_input(irq_nr);
+	restore_flags(flags);
+}
+
+
+static void setup_local_irq(unsigned int irq_nr, int type, int int_req)
+{
+	/* Config2[n], Config1[n], Config0[n] */
+	if (irq_nr > AU1000_LAST_INTC0_INT) {
+		switch (type) {
+			case INTC_INT_RISE_EDGE: /* 0:0:1 */
+				outl(1<<irq_nr,INTC1_CONFIG2_CLEAR);
+				outl(1<<irq_nr, INTC1_CONFIG1_CLEAR);
+				outl(1<<irq_nr, INTC1_CONFIG0_SET);
+				break;
+			case INTC_INT_FALL_EDGE: /* 0:1:0 */
+				outl(1<<irq_nr, INTC1_CONFIG2_CLEAR);
+				outl(1<<irq_nr, INTC1_CONFIG1_SET);
+				outl(1<<irq_nr, INTC1_CONFIG0_CLEAR);
+				break;
+			case INTC_INT_HIGH_LEVEL: /* 1:0:1 */
+				outl(1<<irq_nr, INTC1_CONFIG2_SET);
+				outl(1<<irq_nr, INTC1_CONFIG1_CLEAR);
+				outl(1<<irq_nr, INTC1_CONFIG0_SET);
+				break;
+			case INTC_INT_LOW_LEVEL: /* 1:1:0 */
+				outl(1<<irq_nr, INTC1_CONFIG2_SET);
+				outl(1<<irq_nr, INTC1_CONFIG1_SET);
+				outl(1<<irq_nr, INTC1_CONFIG0_CLEAR);
+				break;
+			case INTC_INT_DISABLED: /* 0:0:0 */
+				outl(1<<irq_nr, INTC1_CONFIG0_CLEAR);
+				outl(1<<irq_nr, INTC1_CONFIG1_CLEAR);
+				outl(1<<irq_nr, INTC1_CONFIG2_CLEAR);
+				break;
+			default: /* disable the interrupt */
+				printk("unexpected int type %d (irq %d)\n", type, irq_nr);
+				outl(1<<irq_nr, INTC1_CONFIG0_CLEAR);
+				outl(1<<irq_nr, INTC1_CONFIG1_CLEAR);
+				outl(1<<irq_nr, INTC1_CONFIG2_CLEAR);
+				return;
+		}
+		if (int_req) /* assign to interrupt request 1 */
+			outl(1<<irq_nr, INTC1_ASSIGN_REQ_CLEAR);
+		else	     /* assign to interrupt request 0 */
+			outl(1<<irq_nr, INTC1_ASSIGN_REQ_SET);
+		outl(1<<irq_nr, INTC1_SOURCE_SET);
+		outl(1<<irq_nr, INTC1_MASK_CLEAR);
+	}
+	else {
+		switch (type) {
+			case INTC_INT_RISE_EDGE: /* 0:0:1 */
+				outl(1<<irq_nr,INTC0_CONFIG2_CLEAR);
+				outl(1<<irq_nr, INTC0_CONFIG1_CLEAR);
+				outl(1<<irq_nr, INTC0_CONFIG0_SET);
+				break;
+			case INTC_INT_FALL_EDGE: /* 0:1:0 */
+				outl(1<<irq_nr, INTC0_CONFIG2_CLEAR);
+				outl(1<<irq_nr, INTC0_CONFIG1_SET);
+				outl(1<<irq_nr, INTC0_CONFIG0_CLEAR);
+				break;
+			case INTC_INT_HIGH_LEVEL: /* 1:0:1 */
+				outl(1<<irq_nr, INTC0_CONFIG2_SET);
+				outl(1<<irq_nr, INTC0_CONFIG1_CLEAR);
+				outl(1<<irq_nr, INTC0_CONFIG0_SET);
+				break;
+			case INTC_INT_LOW_LEVEL: /* 1:1:0 */
+				outl(1<<irq_nr, INTC0_CONFIG2_SET);
+				outl(1<<irq_nr, INTC0_CONFIG1_SET);
+				outl(1<<irq_nr, INTC0_CONFIG0_CLEAR);
+				break;
+			case INTC_INT_DISABLED: /* 0:0:0 */
+				outl(1<<irq_nr, INTC0_CONFIG0_CLEAR);
+				outl(1<<irq_nr, INTC0_CONFIG1_CLEAR);
+				outl(1<<irq_nr, INTC0_CONFIG2_CLEAR);
+				break;
+			default: /* disable the interrupt */
+				printk("unexpected int type %d (irq %d)\n", type, irq_nr);
+				outl(1<<irq_nr, INTC0_CONFIG0_CLEAR);
+				outl(1<<irq_nr, INTC0_CONFIG1_CLEAR);
+				outl(1<<irq_nr, INTC0_CONFIG2_CLEAR);
+				return;
+		}
+		if (int_req) /* assign to interrupt request 1 */
+			outl(1<<irq_nr, INTC0_ASSIGN_REQ_CLEAR);
+		else	     /* assign to interrupt request 0 */
+			outl(1<<irq_nr, INTC0_ASSIGN_REQ_SET);
+		outl(1<<irq_nr, INTC0_SOURCE_SET);
+		outl(1<<irq_nr, INTC0_MASK_CLEAR);
+	}
+	sync();
+}
+
+
+static unsigned int startup_irq(unsigned int irq_nr)
+{
+	local_enable_irq(irq_nr);
+	return 0; 
+}
+
+
+static void shutdown_irq(unsigned int irq_nr)
+{
+	local_disable_irq(irq_nr);
+	return;
+}
+
+
+static inline void local_enable_irq(unsigned int irq_nr)
+{
+	if (irq_nr > AU1000_LAST_INTC0_INT) {
+		outl(1<<irq_nr, INTC1_MASK_SET);
+	}
+	else {
+		outl(1<<irq_nr, INTC0_MASK_SET);
+	}
+	sync();
+}
+
+
+static inline void local_disable_irq(unsigned int irq_nr)
+{
+	if (irq_nr > AU1000_LAST_INTC0_INT) {
+		outl(1<<irq_nr, INTC1_MASK_CLEAR);
+	}
+	else {
+		outl(1<<irq_nr, INTC0_MASK_CLEAR);
+	}
+	sync();
+}
+
+
+static inline void mask_and_ack_rise_edge_irq(unsigned int irq_nr)
+{
+	if (irq_nr > AU1000_LAST_INTC0_INT) {
+		outl(1<<irq_nr, INTC1_R_EDGE_DETECT_CLEAR);
+		outl(1<<irq_nr, INTC1_MASK_CLEAR);
+	}
+	else {
+		outl(1<<irq_nr, INTC0_R_EDGE_DETECT_CLEAR);
+		outl(1<<irq_nr, INTC0_MASK_CLEAR);
+	}
+	sync();
+}
+
+
+static inline void mask_and_ack_fall_edge_irq(unsigned int irq_nr)
+{
+	if (irq_nr > AU1000_LAST_INTC0_INT) {
+		outl(1<<irq_nr, INTC1_F_EDGE_DETECT_CLEAR);
+		outl(1<<irq_nr, INTC1_MASK_CLEAR);
+	}
+	else {
+		outl(1<<irq_nr, INTC0_F_EDGE_DETECT_CLEAR);
+		outl(1<<irq_nr, INTC0_MASK_CLEAR);
+	}
+}
+
+
+static inline void mask_and_ack_level_irq(unsigned int irq_nr)
+{
+	local_disable_irq(irq_nr);
+	sync();
+	return;
+}
+
+
+static void end_irq(unsigned int irq_nr)
+{
+	if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		local_enable_irq(irq_nr);
+	else
+		printk("warning: end_irq %d did not enable\n", irq_nr);
+}
+
+
+static struct hw_interrupt_type rise_edge_irq_type = {
+	"Au1000 Rise Edge",
+	startup_irq,
+	shutdown_irq,
+	local_enable_irq,
+	local_disable_irq,
+	mask_and_ack_rise_edge_irq,
+	end_irq,
+	NULL
+};
+
+
+static struct hw_interrupt_type fall_edge_irq_type = {
+	"Au1000 Fall Edge",
+	startup_irq,
+	shutdown_irq,
+	local_enable_irq,
+	local_disable_irq,
+	mask_and_ack_fall_edge_irq,
+	end_irq,
+	NULL
+};
+
+
+static struct hw_interrupt_type level_irq_type = {
+	"Au1000 Level",
+	startup_irq,
+	shutdown_irq,
+	local_enable_irq,
+	local_disable_irq,
+	mask_and_ack_level_irq,
+	end_irq,
+	NULL
+};
+
+
+void enable_cpu_timer(void)
+{
+	enable_cpu_irq_input(1<<MIPS_TIMER_IP); /* timer interrupt */
+}
+
+
+void __init init_IRQ(void)
+{
+	int i;
+	unsigned long cp0_status;
+
+	cp0_status = read_32bit_cp0_register(CP0_STATUS);
+	memset(irq_desc, 0, sizeof(irq_desc));
+	set_except_vector(0, au1000_IRQ);
+
+	init_generic_irq();
+	
+	/* 
+	 * Setup high priority interrupts on int_request0; low priority on
+	 * int_request1
+	 */
+	for (i = 0; i <= NR_IRQS; i++) {
+		switch (i) {
+			case AU1000_MAC0_DMA_INT:
+			case AU1000_MAC1_DMA_INT:
+				setup_local_irq(i, INTC_INT_HIGH_LEVEL, 0);
+				irq_desc[i].handler = &level_irq_type;
+				break;
+			default: /* active high, level interrupt */
+				setup_local_irq(i, INTC_INT_HIGH_LEVEL, 1);
+				irq_desc[i].handler = &level_irq_type;
+				break;
+		}
+	}
+
+	set_cp0_status(ALLINTS);
+#ifdef CONFIG_REMOTE_DEBUG
+	/* If local serial I/O used for debug port, enter kgdb at once */
+	puts("Waiting for kgdb to connect...");
+	set_debug_traps();
+	breakpoint(); 
+#endif
+}
+
+
+void mips_spurious_interrupt(struct pt_regs *regs)
+{
+	spurious_interrupts++;
+}
+
+
+void intc0_req0_irqdispatch(struct pt_regs *regs)
+{
+	int irq = 0, i;
+	unsigned long int_request;
+
+	int_request = inl(INTC0_REQ0_INT);
+
+	if (!int_request) return;
+
+	for (i=0; i<32; i++) {
+		if ((int_request & 0x1)) {
+			do_IRQ(irq, regs);
+		}
+		irq++;
+		int_request >>= 1;
+	}
+}
+
+
+void intc0_req1_irqdispatch(struct pt_regs *regs)
+{
+	int irq = 0, i;
+	unsigned long int_request;
+
+	int_request = inl(INTC0_REQ1_INT);
+
+	if (!int_request) return;
+
+	for (i=0; i<32; i++) {
+		if ((int_request & 0x1)) {
+			do_IRQ(irq, regs);
+		}
+		irq++;
+		int_request >>= 1;
+	}
+}
+
+
+void intc1_req0_irqdispatch(struct pt_regs *regs)
+{
+	int irq = 0, i;
+	unsigned long int_request;
+
+	int_request = inl(INTC1_REQ0_INT);
+
+	if (!int_request) return;
+
+	for (i=0; i<32; i++) {
+		if ((int_request & 0x1)) {
+			do_IRQ(irq, regs);
+		}
+		irq++;
+		int_request >>= 1;
+	}
+}
+
+
+void intc1_req1_irqdispatch(struct pt_regs *regs)
+{
+	int irq = 0, i;
+	unsigned long int_request;
+
+	int_request = inl(INTC1_REQ1_INT);
+
+	if (!int_request) return;
+
+	for (i=0; i<32; i++) {
+		if ((int_request & 0x1)) {
+			do_IRQ(irq, regs);
+		}
+		irq++;
+		int_request >>= 1;
+	}
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips/au1000/common/prom.c linux/arch/mips/au1000/common/prom.c
--- v2.4.9/linux/arch/mips/au1000/common/prom.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/au1000/common/prom.c	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,120 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *    PROM library initialisation code, assuming a version of
+ *    pmon is the boot code.
+ *
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ * This file was derived from Carsten Langgaard's 
+ * arch/mips/mips-boards/xx files.
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ *  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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+
+/* #define DEBUG_CMDLINE */
+
+char arcs_cmdline[COMMAND_LINE_SIZE];
+int prom_argc;
+char **prom_argv, **prom_envp;
+
+typedef struct {
+	char *name;
+/*	char *val; */
+} t_env_var;
+
+
+char * __init prom_getcmdline(void)
+{
+	return &(arcs_cmdline[0]);
+}
+
+void  __init prom_init_cmdline(void)
+{
+	char *cp;
+	int actr;
+
+	actr = 1; /* Always ignore argv[0] */
+
+	cp = &(arcs_cmdline[0]);
+	while(actr < prom_argc) {
+	        strcpy(cp, prom_argv[actr]);
+		cp += strlen(prom_argv[actr]);
+		*cp++ = ' ';
+		actr++;
+	}
+	if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */
+		--cp;
+	*cp = '\0';
+
+}
+
+
+char *prom_getenv(char *envname)
+{
+	/*
+	 * Return a pointer to the given environment variable.
+	 * Environment variables are stored in the form of "memsize=64".
+	 */
+
+	t_env_var *env = (t_env_var *)prom_envp;
+	int i;
+
+	i = strlen(envname);
+
+	while(env->name) {
+		if(strncmp(envname, env->name, i) == 0) {
+			return(env->name + strlen(envname) + 1);
+		}
+		env++;
+	}
+	return(NULL);
+}
+
+static inline unsigned char str2hexnum(unsigned char c)
+{
+	if(c >= '0' && c <= '9')
+	return c - '0';
+	if(c >= 'a' && c <= 'f')
+	return c - 'a' + 10;
+	return 0; /* foo */
+}
+
+int __init page_is_ram(unsigned long pagenr)
+{
+	return 1;
+}
+
+void prom_free_prom_memory (void)
+{
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips/au1000/common/puts.c linux/arch/mips/au1000/common/puts.c
--- v2.4.9/linux/arch/mips/au1000/common/puts.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/au1000/common/puts.c	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,144 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Low level uart routines to directly access a 16550 uart.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ *  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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/types.h>
+
+#define SERIAL_BASE   0xB1100000 /* au1000, uart 0 */
+#define SER_CMD       0x7
+#define SER_DATA      0x1
+#define TX_BUSY       0x20
+
+#define TIMEOUT       0xffffff
+#define SLOW_DOWN
+
+static const char digits[16] = "0123456789abcdef";
+static volatile unsigned long * const com1 = (unsigned char *)SERIAL_BASE;
+
+
+#ifdef SLOW_DOWN
+static inline void slow_down()
+{
+    int k;
+    for (k=0; k<10000; k++);
+}
+#else
+#define slow_down()
+#endif
+
+void
+putch(const unsigned char c)
+{
+    unsigned char ch;
+    int i = 0;
+
+    do {
+        ch = com1[SER_CMD];
+        slow_down();
+        i++;
+        if (i>TIMEOUT) {
+            break;
+        }
+    } while (0 == (ch & TX_BUSY));
+    com1[SER_DATA] = c;
+}
+
+void
+puts(unsigned char *cp)
+{
+    unsigned char ch;
+    int i = 0;
+
+    while (*cp) {
+        do {
+             ch = com1[SER_CMD];
+            slow_down();
+            i++;
+            if (i>TIMEOUT) {
+                break;
+            }
+        } while (0 == (ch & TX_BUSY));
+        com1[SER_DATA] = *cp++;
+    }
+    putch('\r');
+    putch('\n');
+}
+
+void
+fputs(unsigned char *cp)
+{
+    unsigned char ch;
+    int i = 0;
+
+    while (*cp) {
+
+        do {
+             ch = com1[SER_CMD];
+             slow_down();
+            i++;
+            if (i>TIMEOUT) {
+                break;
+            }
+        } while (0 == (ch & TX_BUSY));
+        com1[SER_DATA] = *cp++;
+    }
+}
+
+
+void
+put64(uint64_t ul)
+{
+    int cnt;
+    unsigned ch;
+
+    cnt = 16;            /* 16 nibbles in a 64 bit long */
+    putch('0');
+    putch('x');
+    do {
+        cnt--;
+        ch = (unsigned char)(ul >> cnt * 4) & 0x0F;
+                putch(digits[ch]);
+    } while (cnt > 0);
+}
+
+void
+put32(unsigned u)
+{
+    int cnt;
+    unsigned ch;
+
+    cnt = 8;            /* 8 nibbles in a 32 bit long */
+    putch('0');
+    putch('x');
+    do {
+        cnt--;
+        ch = (unsigned char)(u >> cnt * 4) & 0x0F;
+                putch(digits[ch]);
+    } while (cnt > 0);
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips/au1000/common/reset.c linux/arch/mips/au1000/common/reset.c
--- v2.4.9/linux/arch/mips/au1000/common/reset.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/au1000/common/reset.c	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,60 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Au1000 reset routines.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ *  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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+
+void au1000_restart(char *command)
+{
+	set_cp0_status(ST0_BEV | ST0_ERL);
+	set_cp0_config(CONF_CM_UNCACHED);
+	flush_cache_all();
+	write_32bit_cp0_register(CP0_WIRED, 0);
+	__asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
+}
+
+void au1000_halt(void)
+{
+	printk(KERN_NOTICE "\n** You can safely turn off the power\n");
+	while (1)
+		__asm__(".set\tmips3\n\t"
+	                "wait\n\t"
+			".set\tmips0");
+}
+
+void au1000_power_off(void)
+{
+	au1000_halt();
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips/au1000/common/serial.c linux/arch/mips/au1000/common/serial.c
--- v2.4.9/linux/arch/mips/au1000/common/serial.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/au1000/common/serial.c	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,3100 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Au1000 serial port driver.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ *  Derived almost entirely from drivers/char/serial.c:
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *  Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 
+ * 		1998, 1999  Theodore Ts'o
+ *
+ *  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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+static char *serial_version = "1.01";
+static char *serial_revdate = "2001-02-08";
+
+
+#include <linux/config.h>
+#include <linux/version.h>
+
+#undef SERIAL_PARANOIA_CHECK
+#define CONFIG_SERIAL_NOPAUSE_IO
+#define SERIAL_DO_RESTART
+
+
+/* Set of debugging defines */
+
+#undef SERIAL_DEBUG_INTR
+#undef SERIAL_DEBUG_OPEN
+#undef SERIAL_DEBUG_FLOW
+#undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
+#undef SERIAL_DEBUG_PCI
+#undef SERIAL_DEBUG_AUTOCONF
+
+#ifdef MODULE
+#undef CONFIG_AU1000_SERIAL_CONSOLE
+#endif
+
+#define CONFIG_SERIAL_RSA
+
+#define RS_STROBE_TIME (10*HZ)
+#define RS_ISR_PASS_LIMIT 256
+  
+/*
+ * End of serial driver configuration section.
+ */
+
+#ifdef MODVERSIONS
+#include <linux/modversions.h>
+#endif
+#include <linux/module.h>
+
+#include <linux/types.h>
+#ifdef LOCAL_HEADERS
+#include "serial_local.h"
+#else
+#include <linux/serial.h>
+#include <linux/serialP.h>
+#include <asm/au1000.h>
+#include <asm/serial.h>
+#define LOCAL_VERSTRING ""
+#endif
+
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <asm/uaccess.h>
+#include <linux/delay.h>
+#ifdef CONFIG_AU1000_SERIAL_CONSOLE
+#include <linux/console.h>
+#endif
+#ifdef CONFIG_MAGIC_SYSRQ
+#include <linux/sysrq.h>
+#endif
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/bitops.h>
+
+#ifdef CONFIG_MAC_SERIAL
+#define SERIAL_DEV_OFFSET	2
+#else
+#define SERIAL_DEV_OFFSET	0
+#endif
+
+#ifdef SERIAL_INLINE
+#define _INLINE_ inline
+#else
+#define _INLINE_
+#endif
+
+static char *serial_name = "Serial driver";
+
+static DECLARE_TASK_QUEUE(tq_serial);
+
+static struct tty_driver serial_driver, callout_driver;
+static int serial_refcount;
+
+static struct timer_list serial_timer;
+
+extern unsigned long get_au1000_uart_baud(void);
+
+/* serial subtype definitions */
+#ifndef SERIAL_TYPE_NORMAL
+#define SERIAL_TYPE_NORMAL	1
+#define SERIAL_TYPE_CALLOUT	2
+#endif
+
+/* number of characters left in xmit buffer before we ask for more */
+#define WAKEUP_CHARS 256
+
+/*
+ * IRQ_timeout		- How long the timeout should be for each IRQ
+ * 				should be after the IRQ has been active.
+ */
+
+static struct async_struct *IRQ_ports[NR_IRQS];
+static int IRQ_timeout[NR_IRQS];
+#ifdef CONFIG_AU1000_SERIAL_CONSOLE
+static struct console sercons;
+static int lsr_break_flag;
+#endif
+#if defined(CONFIG_AU1000_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+static unsigned long break_pressed; /* break, really ... */
+#endif
+
+static void autoconfig(struct serial_state * state);
+static void change_speed(struct async_struct *info, struct termios *old);
+static void rs_wait_until_sent(struct tty_struct *tty, int timeout);
+
+/*
+ * Here we define the default xmit fifo size used for each type of
+ * UART
+ */
+static struct serial_uart_config uart_config[] = {
+	{ "unknown", 1, 0 }, 
+	{ "8250", 1, 0 }, 
+	{ "16450", 1, 0 }, 
+	{ "16550", 1, 0 }, 
+	{ 0, 0}
+};
+
+
+static struct serial_state rs_table[RS_TABLE_SIZE] = {
+	SERIAL_PORT_DFNS	/* Defined in serial.h */
+};
+
+#define NR_PORTS	(sizeof(rs_table)/sizeof(struct serial_state))
+
+#ifndef PREPARE_FUNC
+#define PREPARE_FUNC(dev)  (dev->prepare)
+#define ACTIVATE_FUNC(dev)  (dev->activate)
+#define DEACTIVATE_FUNC(dev)  (dev->deactivate)
+#endif
+
+#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
+
+static struct tty_struct *serial_table[NR_PORTS];
+static struct termios *serial_termios[NR_PORTS];
+static struct termios *serial_termios_locked[NR_PORTS];
+
+
+#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT)
+#define DBG_CNT(s) printk("(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \
+ kdevname(tty->device), (info->flags), serial_refcount,info->count,tty->count,s)
+#else
+#define DBG_CNT(s)
+#endif
+
+/*
+ * tmp_buf is used as a temporary buffer by serial_write.  We need to
+ * lock it in case the copy_from_user blocks while swapping in a page,
+ * and some other program tries to do a serial write at the same time.
+ * Since the lock will only come under contention when the system is
+ * swapping and available memory is low, it makes sense to share one
+ * buffer across all the serial ports, since it significantly saves
+ * memory if large numbers of serial ports are open.
+ */
+static unsigned char *tmp_buf;
+#ifdef DECLARE_MUTEX
+static DECLARE_MUTEX(tmp_buf_sem);
+#else
+static struct semaphore tmp_buf_sem = MUTEX;
+#endif
+
+
+static inline int serial_paranoia_check(struct async_struct *info,
+					kdev_t device, const char *routine)
+{
+#ifdef SERIAL_PARANOIA_CHECK
+	static const char *badmagic =
+		"Warning: bad magic number for serial struct (%s) in %s\n";
+	static const char *badinfo =
+		"Warning: null async_struct for (%s) in %s\n";
+
+	if (!info) {
+		printk(badinfo, kdevname(device), routine);
+		return 1;
+	}
+	if (info->magic != SERIAL_MAGIC) {
+		printk(badmagic, kdevname(device), routine);
+		return 1;
+	}
+#endif
+	return 0;
+}
+
+
+static _INLINE_ unsigned int serial_in(struct async_struct *info, int offset)
+{
+	return (inl(info->port+offset) & 0xff);
+}
+
+static _INLINE_ void serial_out(struct async_struct *info, int offset, int value)
+{
+	outl(value & 0xff, info->port+offset);
+}
+
+
+/*
+ * We used to support using pause I/O for certain machines.  We
+ * haven't supported this for a while, but just in case it's badly
+ * needed for certain old 386 machines, I've left these #define's
+ * in....
+ */
+#define serial_inp(info, offset)		serial_in(info, offset)
+#define serial_outp(info, offset, value)	serial_out(info, offset, value)
+
+
+/*
+ * ------------------------------------------------------------
+ * rs_stop() and rs_start()
+ *
+ * This routines are called before setting or resetting tty->stopped.
+ * They enable or disable transmitter interrupts, as necessary.
+ * ------------------------------------------------------------
+ */
+static void rs_stop(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+
+	if (serial_paranoia_check(info, tty->device, "rs_stop"))
+		return;
+	
+	save_flags(flags); cli();
+	if (info->IER & UART_IER_THRI) {
+		info->IER &= ~UART_IER_THRI;
+		serial_out(info, UART_IER, info->IER);
+	}
+	restore_flags(flags);
+}
+
+static void rs_start(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+	
+	if (serial_paranoia_check(info, tty->device, "rs_start"))
+		return;
+	
+	save_flags(flags); cli();
+	if (info->xmit.head != info->xmit.tail
+	    && info->xmit.buf
+	    && !(info->IER & UART_IER_THRI)) {
+		info->IER |= UART_IER_THRI;
+		serial_out(info, UART_IER, info->IER);
+	}
+	restore_flags(flags);
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * Here starts the interrupt handling routines.  All of the following
+ * subroutines are declared as inline and are folded into
+ * rs_interrupt().  They were separated out for readability's sake.
+ *
+ * Note: rs_interrupt() is a "fast" interrupt, which means that it
+ * runs with interrupts turned off.  People who may want to modify
+ * rs_interrupt() should try to keep the interrupt handler as fast as
+ * possible.  After you are done making modifications, it is not a bad
+ * idea to do:
+ * 
+ * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
+ *
+ * and look at the resulting assemble code in serial.s.
+ *
+ * 				- Ted Ts'o (tytso@mit.edu), 7-Mar-93
+ * -----------------------------------------------------------------------
+ */
+
+/*
+ * This routine is used by the interrupt handler to schedule
+ * processing in the software interrupt portion of the driver.
+ */
+static _INLINE_ void rs_sched_event(struct async_struct *info,
+				  int event)
+{
+	info->event |= 1 << event;
+	queue_task(&info->tqueue, &tq_serial);
+	mark_bh(SERIAL_BH);
+}
+
+static _INLINE_ void receive_chars(struct async_struct *info,
+				 int *status, struct pt_regs * regs)
+{
+	struct tty_struct *tty = info->tty;
+	unsigned char ch;
+	int ignored = 0;
+	struct	async_icount *icount;
+
+	icount = &info->state->icount;
+	do {
+		ch = serial_inp(info, UART_RX);
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+			goto ignore_char;
+		*tty->flip.char_buf_ptr = ch;
+		icount->rx++;
+		
+#ifdef SERIAL_DEBUG_INTR
+		printk("DR%02x:%02x...", ch, *status);
+#endif
+		*tty->flip.flag_buf_ptr = 0;
+		if (*status & (UART_LSR_BI | UART_LSR_PE |
+			       UART_LSR_FE | UART_LSR_OE)) {
+			/*
+			 * For statistics only
+			 */
+			if (*status & UART_LSR_BI) {
+				*status &= ~(UART_LSR_FE | UART_LSR_PE);
+				icount->brk++;
+				/*
+				 * We do the SysRQ and SAK checking
+				 * here because otherwise the break
+				 * may get masked by ignore_status_mask
+				 * or read_status_mask.
+				 */
+#if defined(CONFIG_AU1000_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+				if (info->line == sercons.index) {
+					if (!break_pressed) {
+						break_pressed = jiffies;
+						goto ignore_char;
+					}
+					break_pressed = 0;
+				}
+#endif
+				if (info->flags & ASYNC_SAK)
+					do_SAK(tty);
+			} else if (*status & UART_LSR_PE)
+				icount->parity++;
+			else if (*status & UART_LSR_FE)
+				icount->frame++;
+			if (*status & UART_LSR_OE)
+				icount->overrun++;
+
+			/*
+			 * Now check to see if character should be
+			 * ignored, and mask off conditions which
+			 * should be ignored.
+			 */
+			if (*status & info->ignore_status_mask) {
+				if (++ignored > 100)
+					break;
+				goto ignore_char;
+			}
+			*status &= info->read_status_mask;
+
+#ifdef CONFIG_AU1000_SERIAL_CONSOLE
+			if (info->line == sercons.index) {
+				/* Recover the break flag from console xmit */
+				*status |= lsr_break_flag;
+				lsr_break_flag = 0;
+			}
+#endif
+			if (*status & (UART_LSR_BI)) {
+#ifdef SERIAL_DEBUG_INTR
+				printk("handling break....");
+#endif
+				*tty->flip.flag_buf_ptr = TTY_BREAK;
+			} else if (*status & UART_LSR_PE)
+				*tty->flip.flag_buf_ptr = TTY_PARITY;
+			else if (*status & UART_LSR_FE)
+				*tty->flip.flag_buf_ptr = TTY_FRAME;
+			if (*status & UART_LSR_OE) {
+				/*
+				 * Overrun is special, since it's
+				 * reported immediately, and doesn't
+				 * affect the current character
+				 */
+				tty->flip.count++;
+				tty->flip.flag_buf_ptr++;
+				tty->flip.char_buf_ptr++;
+				*tty->flip.flag_buf_ptr = TTY_OVERRUN;
+				if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+					goto ignore_char;
+			}
+		}
+#if defined(CONFIG_AU1000_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+		if (break_pressed && info->line == sercons.index) {
+			if (ch != 0 &&
+			    time_before(jiffies, break_pressed + HZ*5)) {
+				handle_sysrq(ch, regs, NULL, NULL);
+				break_pressed = 0;
+				goto ignore_char;
+			}
+			break_pressed = 0;
+		}
+#endif
+		tty->flip.flag_buf_ptr++;
+		tty->flip.char_buf_ptr++;
+		tty->flip.count++;
+	ignore_char:
+		*status = serial_inp(info, UART_LSR);
+	} while (*status & UART_LSR_DR);
+	tty_flip_buffer_push(tty);
+}
+
+static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done)
+{
+	int count;
+
+	if (info->x_char) {
+		serial_outp(info, UART_TX, info->x_char);
+		info->state->icount.tx++;
+		info->x_char = 0;
+		if (intr_done)
+			*intr_done = 0;
+		return;
+	}
+	if (info->xmit.head == info->xmit.tail
+	    || info->tty->stopped
+	    || info->tty->hw_stopped) {
+		info->IER &= ~UART_IER_THRI;
+		serial_out(info, UART_IER, info->IER);
+		return;
+	}
+	
+	count = info->xmit_fifo_size;
+	do {
+		serial_out(info, UART_TX, info->xmit.buf[info->xmit.tail]);
+		info->xmit.tail = (info->xmit.tail + 1) & (SERIAL_XMIT_SIZE-1);
+		info->state->icount.tx++;
+		if (info->xmit.head == info->xmit.tail)
+			break;
+	} while (--count > 0);
+	
+	if (CIRC_CNT(info->xmit.head,
+		     info->xmit.tail,
+		     SERIAL_XMIT_SIZE) < WAKEUP_CHARS)
+		rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
+
+#ifdef SERIAL_DEBUG_INTR
+	printk("THRE...");
+#endif
+	if (intr_done)
+		*intr_done = 0;
+
+	if (info->xmit.head == info->xmit.tail) {
+		info->IER &= ~UART_IER_THRI;
+		serial_out(info, UART_IER, info->IER);
+	}
+}
+
+static _INLINE_ void check_modem_status(struct async_struct *info)
+{
+	int	status;
+	struct	async_icount *icount;
+	
+	status = serial_in(info, UART_MSR);
+
+	if (status & UART_MSR_ANY_DELTA) {
+		icount = &info->state->icount;
+		/* update input line counters */
+		if (status & UART_MSR_TERI)
+			icount->rng++;
+		if (status & UART_MSR_DDSR)
+			icount->dsr++;
+		if (status & UART_MSR_DDCD) {
+			icount->dcd++;
+#ifdef CONFIG_HARD_PPS
+			if ((info->flags & ASYNC_HARDPPS_CD) &&
+			    (status & UART_MSR_DCD))
+				hardpps();
+#endif
+		}
+		if (status & UART_MSR_DCTS)
+			icount->cts++;
+		wake_up_interruptible(&info->delta_msr_wait);
+	}
+
+	if ((info->flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) {
+#if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR))
+		printk("ttys%d CD now %s...", info->line,
+		       (status & UART_MSR_DCD) ? "on" : "off");
+#endif		
+		if (status & UART_MSR_DCD)
+			wake_up_interruptible(&info->open_wait);
+		else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) &&
+			   (info->flags & ASYNC_CALLOUT_NOHUP))) {
+#ifdef SERIAL_DEBUG_OPEN
+			printk("doing serial hangup...");
+#endif
+			if (info->tty)
+				tty_hangup(info->tty);
+		}
+	}
+	if (info->flags & ASYNC_CTS_FLOW) {
+		if (info->tty->hw_stopped) {
+			if (status & UART_MSR_CTS) {
+#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
+				printk("CTS tx start...");
+#endif
+				info->tty->hw_stopped = 0;
+				info->IER |= UART_IER_THRI;
+				serial_out(info, UART_IER, info->IER);
+				rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
+				return;
+			}
+		} else {
+			if (!(status & UART_MSR_CTS)) {
+#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
+				printk("CTS tx stop...");
+#endif
+				info->tty->hw_stopped = 1;
+				info->IER &= ~UART_IER_THRI;
+				serial_out(info, UART_IER, info->IER);
+			}
+		}
+	}
+}
+
+
+
+/*
+ * This is the serial driver's interrupt routine for a single port
+ */
+static void rs_interrupt_single(int irq, void *dev_id, struct pt_regs * regs)
+{
+	int status;
+	int pass_counter = 0;
+	struct async_struct * info;
+	
+#ifdef SERIAL_DEBUG_INTR
+	printk("rs_interrupt_single(%d)...", irq);
+#endif
+
+	info = IRQ_ports[irq];
+	if (!info || !info->tty)
+		return;
+
+	do {
+		status = serial_inp(info, UART_LSR);
+#ifdef SERIAL_DEBUG_INTR
+		printk("status = %x...", status);
+#endif
+		if (status & UART_LSR_DR)
+			receive_chars(info, &status, regs);
+		check_modem_status(info);
+		if (status & UART_LSR_THRE)
+			transmit_chars(info, 0);
+		if (pass_counter++ > RS_ISR_PASS_LIMIT) {
+#if 0
+			printk("rs_single loop break.\n");
+#endif
+			break;
+		}
+	} while (!(serial_in(info, UART_IIR) & UART_IIR_NO_INT));
+	info->last_active = jiffies;
+#ifdef SERIAL_DEBUG_INTR
+	printk("end.\n");
+#endif
+}
+
+
+/*
+ * -------------------------------------------------------------------
+ * Here ends the serial interrupt routines.
+ * -------------------------------------------------------------------
+ */
+
+/*
+ * This routine is used to handle the "bottom half" processing for the
+ * serial driver, known also the "software interrupt" processing.
+ * This processing is done at the kernel interrupt level, after the
+ * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
+ * is where time-consuming activities which can not be done in the
+ * interrupt driver proper are done; the interrupt driver schedules
+ * them using rs_sched_event(), and they get done here.
+ */
+static void do_serial_bh(void)
+{
+	run_task_queue(&tq_serial);
+}
+
+static void do_softint(void *private_)
+{
+	struct async_struct	*info = (struct async_struct *) private_;
+	struct tty_struct	*tty;
+	
+	tty = info->tty;
+	if (!tty)
+		return;
+
+	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
+		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+		    tty->ldisc.write_wakeup)
+			(tty->ldisc.write_wakeup)(tty);
+		wake_up_interruptible(&tty->write_wait);
+#ifdef SERIAL_HAVE_POLL_WAIT
+		wake_up_interruptible(&tty->poll_wait);
+#endif
+	}
+}
+
+/*
+ * This subroutine is called when the RS_TIMER goes off.  It is used
+ * by the serial driver to handle ports that do not have an interrupt
+ * (irq=0).  This doesn't work very well for 16450's, but gives barely
+ * passable results for a 16550A.  (Although at the expense of much
+ * CPU overhead).
+ */
+static void rs_timer(unsigned long dummy)
+{
+	static unsigned long last_strobe;
+	struct async_struct *info;
+	unsigned int	i;
+	unsigned long flags;
+
+	if ((jiffies - last_strobe) >= RS_STROBE_TIME) {
+		for (i=0; i < NR_IRQS; i++) {
+			info = IRQ_ports[i];
+			if (!info)
+				continue;
+			save_flags(flags); cli();
+				rs_interrupt_single(i, NULL, NULL);
+			restore_flags(flags);
+		}
+	}
+	last_strobe = jiffies;
+	mod_timer(&serial_timer, jiffies + RS_STROBE_TIME);
+
+#if 0
+	if (IRQ_ports[0]) {
+		save_flags(flags); cli();
+		rs_interrupt_single(0, NULL, NULL);
+		restore_flags(flags);
+
+		mod_timer(&serial_timer, jiffies + IRQ_timeout[0]);
+	}
+#endif
+}
+
+/*
+ * ---------------------------------------------------------------
+ * Low level utility subroutines for the serial driver:  routines to
+ * figure out the appropriate timeout for an interrupt chain, routines
+ * to initialize and startup a serial port, and routines to shutdown a
+ * serial port.  Useful stuff like that.
+ * ---------------------------------------------------------------
+ */
+
+/*
+ * This routine figures out the correct timeout for a particular IRQ.
+ * It uses the smallest timeout of all of the serial ports in a
+ * particular interrupt chain.  Now only used for IRQ 0....
+ */
+static void figure_IRQ_timeout(int irq)
+{
+	struct	async_struct	*info;
+	int	timeout = 60*HZ;	/* 60 seconds === a long time :-) */
+
+	info = IRQ_ports[irq];
+	if (!info) {
+		IRQ_timeout[irq] = 60*HZ;
+		return;
+	}
+	while (info) {
+		if (info->timeout < timeout)
+			timeout = info->timeout;
+		info = info->next_port;
+	}
+	if (!irq)
+		timeout = timeout / 2;
+	IRQ_timeout[irq] = (timeout > 3) ? timeout-2 : 1;
+}
+
+
+static int startup(struct async_struct * info)
+{
+	unsigned long flags;
+	int	retval=0;
+	void (*handler)(int, void *, struct pt_regs *);
+	struct serial_state *state= info->state;
+	unsigned long page;
+
+	page = get_zeroed_page(GFP_KERNEL);
+	if (!page)
+		return -ENOMEM;
+
+	save_flags(flags); cli();
+
+	if (info->flags & ASYNC_INITIALIZED) {
+		free_page(page);
+		goto errout;
+	}
+
+	if (!CONFIGURED_SERIAL_PORT(state) || !state->type) {
+		if (info->tty)
+			set_bit(TTY_IO_ERROR, &info->tty->flags);
+		free_page(page);
+		goto errout;
+	}
+	if (info->xmit.buf)
+		free_page(page);
+	else
+		info->xmit.buf = (unsigned char *) page;
+
+
+	if (inl(UART_MOD_CNTRL + state->port) != 0x3) {
+		outl(3, UART_MOD_CNTRL + state->port);
+	}
+#ifdef SERIAL_DEBUG_OPEN
+	printk("starting up ttys%d (irq %d)...", info->line, state->irq);
+#endif
+
+
+	/*
+	 * Clear the FIFO buffers and disable them
+	 * (they will be reenabled in change_speed())
+	 */
+	if (uart_config[state->type].flags & UART_CLEAR_FIFO) {
+		serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO);
+		serial_outp(info, UART_FCR, (UART_FCR_ENABLE_FIFO |
+					     UART_FCR_CLEAR_RCVR |
+					     UART_FCR_CLEAR_XMIT));
+		serial_outp(info, UART_FCR, 0);
+	}
+
+	/*
+	 * Clear the interrupt registers.
+	 */
+	(void) serial_inp(info, UART_LSR);
+	(void) serial_inp(info, UART_RX);
+	(void) serial_inp(info, UART_IIR);
+	(void) serial_inp(info, UART_MSR);
+
+	/*
+	 * At this point there's no way the LSR could still be 0xFF;
+	 * if it is, then bail out, because there's likely no UART
+	 * here.
+	 */
+	if (!(info->flags & ASYNC_BUGGY_UART) &&
+	    (serial_inp(info, UART_LSR) == 0xff)) {
+		printk("LSR safety check engaged!\n");
+		if (capable(CAP_SYS_ADMIN)) {
+			if (info->tty)
+				set_bit(TTY_IO_ERROR, &info->tty->flags);
+		} else
+			retval = -ENODEV;
+		goto errout;
+	}
+	
+	/*
+	 * Allocate the IRQ if necessary
+	 */
+#if 0
+	/* au1000, uart0 irq is 0 */
+	if (state->irq && (!IRQ_ports[state->irq] || !IRQ_ports[state->irq]->next_port)) {
+#endif
+	if ((!IRQ_ports[state->irq] || !IRQ_ports[state->irq]->next_port)) {
+		if (IRQ_ports[state->irq]) {
+			retval = -EBUSY;
+			goto errout;
+		} else 
+			handler = rs_interrupt_single;
+
+		retval = request_irq(state->irq, handler, SA_SHIRQ,
+				     "serial", &IRQ_ports[state->irq]);
+		if (retval) {
+			if (capable(CAP_SYS_ADMIN)) {
+				if (info->tty)
+					set_bit(TTY_IO_ERROR,
+						&info->tty->flags);
+				retval = 0;
+			}
+			goto errout;
+		}
+	}
+
+	/*
+	 * Insert serial port into IRQ chain.
+	 */
+	info->prev_port = 0;
+	info->next_port = IRQ_ports[state->irq];
+	if (info->next_port)
+		info->next_port->prev_port = info;
+	IRQ_ports[state->irq] = info;
+	figure_IRQ_timeout(state->irq);
+
+	/*
+	 * Now, initialize the UART 
+	 */
+	serial_outp(info, UART_LCR, UART_LCR_WLEN8);
+
+	info->MCR = 0;
+	if (info->tty->termios->c_cflag & CBAUD)
+		info->MCR = UART_MCR_DTR | UART_MCR_RTS;
+	{
+		if (state->irq != 0)
+			info->MCR |= UART_MCR_OUT2;
+	}
+	info->MCR |= ALPHA_KLUDGE_MCR; 		/* Don't ask */
+	serial_outp(info, UART_MCR, info->MCR);
+	
+	/*
+	 * Finally, enable interrupts
+	 */
+	info->IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI;
+	serial_outp(info, UART_IER, info->IER);	/* enable interrupts */
+	
+
+	/*
+	 * And clear the interrupt registers again for luck.
+	 */
+	(void)serial_inp(info, UART_LSR);
+	(void)serial_inp(info, UART_RX);
+	(void)serial_inp(info, UART_IIR);
+	(void)serial_inp(info, UART_MSR);
+
+	if (info->tty)
+		clear_bit(TTY_IO_ERROR, &info->tty->flags);
+	info->xmit.head = info->xmit.tail = 0;
+
+	/*
+	 * Set up serial timers...
+	 */
+	mod_timer(&serial_timer, jiffies + 2*HZ/100);
+
+	/*
+	 * Set up the tty->alt_speed kludge
+	 */
+	if (info->tty) {
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+			info->tty->alt_speed = 57600;
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+			info->tty->alt_speed = 115200;
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
+			info->tty->alt_speed = 230400;
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
+			info->tty->alt_speed = 460800;
+	}
+	
+	/*
+	 * and set the speed of the serial port
+	 */
+	change_speed(info, 0);
+
+	info->flags |= ASYNC_INITIALIZED;
+	restore_flags(flags);
+	return 0;
+	
+errout:
+	restore_flags(flags);
+	return retval;
+}
+
+/*
+ * This routine will shutdown a serial port; interrupts are disabled, and
+ * DTR is dropped if the hangup on close termio flag is on.
+ */
+static void shutdown(struct async_struct * info)
+{
+	unsigned long	flags;
+	struct serial_state *state;
+	int		retval;
+
+	if (!(info->flags & ASYNC_INITIALIZED))
+		return;
+
+	state = info->state;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("Shutting down serial port %d (irq %d)....", info->line,
+	       state->irq);
+#endif
+	
+	save_flags(flags); cli(); /* Disable interrupts */
+
+	/*
+	 * clear delta_msr_wait queue to avoid mem leaks: we may free the irq
+	 * here so the queue might never be waken up
+	 */
+	wake_up_interruptible(&info->delta_msr_wait);
+	
+	/*
+	 * First unlink the serial port from the IRQ chain...
+	 */
+	if (info->next_port)
+		info->next_port->prev_port = info->prev_port;
+	if (info->prev_port)
+		info->prev_port->next_port = info->next_port;
+	else
+		IRQ_ports[state->irq] = info->next_port;
+	figure_IRQ_timeout(state->irq);
+	
+	/*
+	 * Free the IRQ, if necessary
+	 */
+//	if (state->irq && (!IRQ_ports[state->irq] ||
+	if ((!IRQ_ports[state->irq] ||
+			  !IRQ_ports[state->irq]->next_port)) {
+		if (IRQ_ports[state->irq]) {
+			free_irq(state->irq, &IRQ_ports[state->irq]);
+			retval = request_irq(state->irq, rs_interrupt_single,
+					     SA_SHIRQ, "serial",
+					     &IRQ_ports[state->irq]);
+			
+			if (retval)
+				printk("serial shutdown: request_irq: error %d"
+				       "  Couldn't reacquire IRQ.\n", retval);
+		} else
+			free_irq(state->irq, &IRQ_ports[state->irq]);
+	}
+
+	if (info->xmit.buf) {
+		unsigned long pg = (unsigned long) info->xmit.buf;
+		info->xmit.buf = 0;
+		free_page(pg);
+	}
+
+	info->IER = 0;
+	serial_outp(info, UART_IER, 0x00);	/* disable all intrs */
+		info->MCR &= ~UART_MCR_OUT2;
+	info->MCR |= ALPHA_KLUDGE_MCR; 		/* Don't ask */
+	
+	/* disable break condition */
+	serial_out(info, UART_LCR, serial_inp(info, UART_LCR) & ~UART_LCR_SBC);
+	
+	if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
+		info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS);
+	serial_outp(info, UART_MCR, info->MCR);
+
+	/* disable FIFO's */	
+	serial_outp(info, UART_FCR, (UART_FCR_ENABLE_FIFO |
+				     UART_FCR_CLEAR_RCVR |
+				     UART_FCR_CLEAR_XMIT));
+	serial_outp(info, UART_FCR, 0);
+
+	(void)serial_in(info, UART_RX);    /* read data port to reset things */
+	
+	if (info->tty)
+		set_bit(TTY_IO_ERROR, &info->tty->flags);
+
+	info->flags &= ~ASYNC_INITIALIZED;
+	restore_flags(flags);
+}
+
+
+/*
+ * This routine is called to set the UART divisor registers to match
+ * the specified baud rate for a serial port.
+ */
+static void change_speed(struct async_struct *info,
+			 struct termios *old_termios)
+{
+	int	quot = 0, baud_base, baud;
+	unsigned cflag, cval, fcr = 0;
+	int	bits;
+	unsigned long	flags;
+
+	if (!info->tty || !info->tty->termios)
+		return;
+	cflag = info->tty->termios->c_cflag;
+	if (!CONFIGURED_SERIAL_PORT(info))
+		return;
+
+	/* byte size and parity */
+	switch (cflag & CSIZE) {
+	      case CS5: cval = 0x00; bits = 7; break;
+	      case CS6: cval = 0x01; bits = 8; break;
+	      case CS7: cval = 0x02; bits = 9; break;
+	      case CS8: cval = 0x03; bits = 10; break;
+	      /* Never happens, but GCC is too dumb to figure it out */
+	      default:  cval = 0x00; bits = 7; break;
+	      }
+	if (cflag & CSTOPB) {
+		cval |= 0x04;
+		bits++;
+	}
+	if (cflag & PARENB) {
+		cval |= UART_LCR_PARITY;
+		bits++;
+	}
+	if (!(cflag & PARODD))
+		cval |= UART_LCR_EPAR;
+#ifdef CMSPAR
+	if (cflag & CMSPAR)
+		cval |= UART_LCR_SPAR;
+#endif
+
+	/* 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 &&
+	if (((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) {
+		quot = info->state->custom_divisor;
+	}
+	else {
+		if (baud == 134)
+			/* Special case since 134 is really 134.5 */
+			quot = (2*baud_base / 269);
+		else if (baud)
+			quot = baud_base / baud;
+	}
+	/* If the quotient is zero refuse the change */
+	if (!quot && old_termios) {
+		info->tty->termios->c_cflag &= ~CBAUD;
+		info->tty->termios->c_cflag |= (old_termios->c_cflag & CBAUD);
+		baud = tty_get_baud_rate(info->tty);
+		if (!baud)
+			baud = 9600;
+		if (baud == 38400 &&
+		    ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST))
+			quot = info->state->custom_divisor;
+		else {
+			if (baud == 134)
+				/* Special case since 134 is really 134.5 */
+				quot = (2*baud_base / 269);
+			else if (baud)
+				quot = baud_base / baud;
+		}
+	}
+	/* As a last resort, if the quotient is zero, default to 9600 bps */
+	if (!quot)
+		quot = baud_base / 9600;
+	
+	info->quot = quot;
+	info->timeout = ((info->xmit_fifo_size*HZ*bits*quot) / baud_base);
+	info->timeout += HZ/50;		/* Add .02 seconds of slop */
+
+	/* Set up FIFO's */
+	if (uart_config[info->state->type].flags & UART_USE_FIFO) {
+		if ((info->state->baud_base / quot) < 2400)
+			fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIGGER_1;
+		else
+			fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIGGER_8;
+	}
+	
+	/* CTS flow control flag and modem status interrupts */
+	info->IER &= ~UART_IER_MSI;
+	if (info->flags & ASYNC_HARDPPS_CD)
+		info->IER |= UART_IER_MSI;
+	if (cflag & CRTSCTS) {
+		info->flags |= ASYNC_CTS_FLOW;
+		info->IER |= UART_IER_MSI;
+	} else
+		info->flags &= ~ASYNC_CTS_FLOW;
+	if (cflag & CLOCAL)
+		info->flags &= ~ASYNC_CHECK_CD;
+	else {
+		info->flags |= ASYNC_CHECK_CD;
+		info->IER |= UART_IER_MSI;
+	}
+	serial_out(info, UART_IER, info->IER);
+
+	/*
+	 * Set up parity check flag
+	 */
+#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
+
+	info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
+	if (I_INPCK(info->tty))
+		info->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
+	if (I_BRKINT(info->tty) || I_PARMRK(info->tty))
+		info->read_status_mask |= UART_LSR_BI;
+	
+	/*
+	 * Characters to ignore
+	 */
+	info->ignore_status_mask = 0;
+	if (I_IGNPAR(info->tty))
+		info->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
+	if (I_IGNBRK(info->tty)) {
+		info->ignore_status_mask |= UART_LSR_BI;
+		/*
+		 * If we're ignore parity and break indicators, ignore 
+		 * overruns too.  (For real raw support).
+		 */
+		if (I_IGNPAR(info->tty))
+			info->ignore_status_mask |= UART_LSR_OE;
+	}
+	/*
+	 * !!! ignore all characters if CREAD is not set
+	 */
+	if ((cflag & CREAD) == 0)
+		info->ignore_status_mask |= UART_LSR_DR;
+	save_flags(flags); cli();
+
+	serial_outp(info, UART_CLK, quot & 0xffff);
+	serial_outp(info, UART_LCR, cval);
+	info->LCR = cval;				/* Save LCR */
+	restore_flags(flags);
+}
+
+static void rs_put_char(struct tty_struct *tty, unsigned char ch)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+
+	if (serial_paranoia_check(info, tty->device, "rs_put_char"))
+		return;
+
+	if (!tty || !info->xmit.buf)
+		return;
+
+	save_flags(flags); cli();
+	if (CIRC_SPACE(info->xmit.head,
+		       info->xmit.tail,
+		       SERIAL_XMIT_SIZE) == 0) {
+		restore_flags(flags);
+		return;
+	}
+
+	info->xmit.buf[info->xmit.head] = ch;
+	info->xmit.head = (info->xmit.head + 1) & (SERIAL_XMIT_SIZE-1);
+	restore_flags(flags);
+}
+
+static void rs_flush_chars(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+				
+	if (serial_paranoia_check(info, tty->device, "rs_flush_chars"))
+		return;
+
+	if (info->xmit.head == info->xmit.tail
+	    || tty->stopped
+	    || tty->hw_stopped
+	    || !info->xmit.buf)
+		return;
+
+	save_flags(flags); cli();
+	info->IER |= UART_IER_THRI;
+	serial_out(info, UART_IER, info->IER);
+	restore_flags(flags);
+}
+
+static int rs_write(struct tty_struct * tty, int from_user,
+		    const unsigned char *buf, int count)
+{
+	int	c, ret = 0;
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+				
+	if (serial_paranoia_check(info, tty->device, "rs_write"))
+		return 0;
+
+	if (!tty || !info->xmit.buf || !tmp_buf)
+		return 0;
+
+	save_flags(flags);
+	if (from_user) {
+		down(&tmp_buf_sem);
+		while (1) {
+			int c1;
+			c = CIRC_SPACE_TO_END(info->xmit.head,
+					      info->xmit.tail,
+					      SERIAL_XMIT_SIZE);
+			if (count < c)
+				c = count;
+			if (c <= 0)
+				break;
+
+			c -= copy_from_user(tmp_buf, buf, c);
+			if (!c) {
+				if (!ret)
+					ret = -EFAULT;
+				break;
+			}
+			cli();
+			c1 = CIRC_SPACE_TO_END(info->xmit.head,
+					       info->xmit.tail,
+					       SERIAL_XMIT_SIZE);
+			if (c1 < c)
+				c = c1;
+			memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c);
+			info->xmit.head = ((info->xmit.head + c) &
+					   (SERIAL_XMIT_SIZE-1));
+			restore_flags(flags);
+			buf += c;
+			count -= c;
+			ret += c;
+		}
+		up(&tmp_buf_sem);
+	} else {
+		cli();
+		while (1) {
+			c = CIRC_SPACE_TO_END(info->xmit.head,
+					      info->xmit.tail,
+					      SERIAL_XMIT_SIZE);
+			if (count < c)
+				c = count;
+			if (c <= 0) {
+				break;
+			}
+			memcpy(info->xmit.buf + info->xmit.head, buf, c);
+			info->xmit.head = ((info->xmit.head + c) &
+					   (SERIAL_XMIT_SIZE-1));
+			buf += c;
+			count -= c;
+			ret += c;
+		}
+		restore_flags(flags);
+	}
+	if (info->xmit.head != info->xmit.tail
+	    && !tty->stopped
+	    && !tty->hw_stopped
+	    && !(info->IER & UART_IER_THRI)) {
+		info->IER |= UART_IER_THRI;
+		serial_out(info, UART_IER, info->IER);
+	}
+	return ret;
+}
+
+static int rs_write_room(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+
+	if (serial_paranoia_check(info, tty->device, "rs_write_room"))
+		return 0;
+	return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+}
+
+static int rs_chars_in_buffer(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+				
+	if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer"))
+		return 0;
+	return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+}
+
+static void rs_flush_buffer(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+	
+	if (serial_paranoia_check(info, tty->device, "rs_flush_buffer"))
+		return;
+	save_flags(flags); cli();
+	info->xmit.head = info->xmit.tail = 0;
+	restore_flags(flags);
+	wake_up_interruptible(&tty->write_wait);
+#ifdef SERIAL_HAVE_POLL_WAIT
+	wake_up_interruptible(&tty->poll_wait);
+#endif
+	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+	    tty->ldisc.write_wakeup)
+		(tty->ldisc.write_wakeup)(tty);
+}
+
+/*
+ * This function is used to send a high-priority XON/XOFF character to
+ * the device
+ */
+static void rs_send_xchar(struct tty_struct *tty, char ch)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+
+	if (serial_paranoia_check(info, tty->device, "rs_send_char"))
+		return;
+
+	info->x_char = ch;
+	if (ch) {
+		/* Make sure transmit interrupts are on */
+		info->IER |= UART_IER_THRI;
+		serial_out(info, UART_IER, info->IER);
+	}
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_throttle()
+ * 
+ * This routine is called by the upper-layer tty layer to signal that
+ * incoming characters should be throttled.
+ * ------------------------------------------------------------
+ */
+static void rs_throttle(struct tty_struct * tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+#ifdef SERIAL_DEBUG_THROTTLE
+	char	buf[64];
+	
+	printk("throttle %s: %d....\n", tty_name(tty, buf),
+	       tty->ldisc.chars_in_buffer(tty));
+#endif
+
+	if (serial_paranoia_check(info, tty->device, "rs_throttle"))
+		return;
+	
+	if (I_IXOFF(tty))
+		rs_send_xchar(tty, STOP_CHAR(tty));
+
+	if (tty->termios->c_cflag & CRTSCTS)
+		info->MCR &= ~UART_MCR_RTS;
+
+	save_flags(flags); cli();
+	serial_out(info, UART_MCR, info->MCR);
+	restore_flags(flags);
+}
+
+static void rs_unthrottle(struct tty_struct * tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+#ifdef SERIAL_DEBUG_THROTTLE
+	char	buf[64];
+	
+	printk("unthrottle %s: %d....\n", tty_name(tty, buf),
+	       tty->ldisc.chars_in_buffer(tty));
+#endif
+
+	if (serial_paranoia_check(info, tty->device, "rs_unthrottle"))
+		return;
+	
+	if (I_IXOFF(tty)) {
+		if (info->x_char)
+			info->x_char = 0;
+		else
+			rs_send_xchar(tty, START_CHAR(tty));
+	}
+	if (tty->termios->c_cflag & CRTSCTS)
+		info->MCR |= UART_MCR_RTS;
+	save_flags(flags); cli();
+	serial_out(info, UART_MCR, info->MCR);
+	restore_flags(flags);
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_ioctl() and friends
+ * ------------------------------------------------------------
+ */
+
+static int get_serial_info(struct async_struct * info,
+			   struct serial_struct * retinfo)
+{
+	struct serial_struct tmp;
+	struct serial_state *state = info->state;
+   
+	if (!retinfo)
+		return -EFAULT;
+	memset(&tmp, 0, sizeof(tmp));
+	tmp.type = state->type;
+	tmp.line = state->line;
+	tmp.port = state->port;
+	if (HIGH_BITS_OFFSET)
+		tmp.port_high = state->port >> HIGH_BITS_OFFSET;
+	else
+		tmp.port_high = 0;
+	tmp.irq = state->irq;
+	tmp.flags = state->flags;
+	tmp.xmit_fifo_size = state->xmit_fifo_size;
+	tmp.baud_base = state->baud_base;
+	tmp.close_delay = state->close_delay;
+	tmp.closing_wait = state->closing_wait;
+	tmp.custom_divisor = state->custom_divisor;
+	tmp.hub6 = state->hub6;
+	tmp.io_type = state->io_type;
+	if (copy_to_user(retinfo,&tmp,sizeof(*retinfo)))
+		return -EFAULT;
+	return 0;
+}
+
+static int set_serial_info(struct async_struct * info,
+			   struct serial_struct * new_info)
+{
+	struct serial_struct new_serial;
+ 	struct serial_state old_state, *state;
+	unsigned int		i,change_irq,change_port;
+	int 			retval = 0;
+	unsigned long		new_port;
+
+	if (copy_from_user(&new_serial,new_info,sizeof(new_serial)))
+		return -EFAULT;
+	state = info->state;
+	old_state = *state;
+
+	new_port = new_serial.port;
+	if (HIGH_BITS_OFFSET)
+		new_port += (unsigned long) new_serial.port_high << HIGH_BITS_OFFSET;
+
+	change_irq = new_serial.irq != state->irq;
+	change_port = (new_port != ((int) state->port)) ||
+		(new_serial.hub6 != state->hub6);
+  
+	if (!capable(CAP_SYS_ADMIN)) {
+		if (change_irq || change_port ||
+		    (new_serial.baud_base != state->baud_base) ||
+		    (new_serial.type != state->type) ||
+		    (new_serial.close_delay != state->close_delay) ||
+		    (new_serial.xmit_fifo_size != state->xmit_fifo_size) ||
+		    ((new_serial.flags & ~ASYNC_USR_MASK) !=
+		     (state->flags & ~ASYNC_USR_MASK)))
+			return -EPERM;
+		state->flags = ((state->flags & ~ASYNC_USR_MASK) |
+			       (new_serial.flags & ASYNC_USR_MASK));
+		info->flags = ((info->flags & ~ASYNC_USR_MASK) |
+			       (new_serial.flags & ASYNC_USR_MASK));
+		state->custom_divisor = new_serial.custom_divisor;
+		goto check_and_exit;
+	}
+
+	new_serial.irq = irq_cannonicalize(new_serial.irq);
+
+	if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) || 
+	    (new_serial.baud_base < 9600)|| (new_serial.type < PORT_UNKNOWN) ||
+	    (new_serial.type > PORT_MAX) || (new_serial.type == PORT_CIRRUS) ||
+	    (new_serial.type == PORT_STARTECH)) {
+		return -EINVAL;
+	}
+
+	if ((new_serial.type != state->type) ||
+	    (new_serial.xmit_fifo_size <= 0))
+		new_serial.xmit_fifo_size =
+			uart_config[new_serial.type].dfl_xmit_fifo_size;
+
+	/* Make sure address is not already in use */
+	if (new_serial.type) {
+		for (i = 0 ; i < NR_PORTS; i++)
+			if ((state != &rs_table[i]) &&
+			    (rs_table[i].port == new_port) &&
+			    rs_table[i].type)
+				return -EADDRINUSE;
+	}
+
+	if ((change_port || change_irq) && (state->count > 1))
+		return -EBUSY;
+
+	/*
+	 * OK, past this point, all the error checking has been done.
+	 * At this point, we start making changes.....
+	 */
+
+	state->baud_base = new_serial.baud_base;
+	state->flags = ((state->flags & ~ASYNC_FLAGS) |
+			(new_serial.flags & ASYNC_FLAGS));
+	info->flags = ((state->flags & ~ASYNC_INTERNAL_FLAGS) |
+		       (info->flags & ASYNC_INTERNAL_FLAGS));
+	state->custom_divisor = new_serial.custom_divisor;
+	state->close_delay = new_serial.close_delay * HZ/100;
+	state->closing_wait = new_serial.closing_wait * HZ/100;
+	info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+	info->xmit_fifo_size = state->xmit_fifo_size =
+		new_serial.xmit_fifo_size;
+
+	if ((state->type != PORT_UNKNOWN) && state->port) {
+		release_region(state->port,8);
+	}
+	state->type = new_serial.type;
+	if (change_port || change_irq) {
+		/*
+		 * We need to shutdown the serial port at the old
+		 * port/irq combination.
+		 */
+		shutdown(info);
+		state->irq = new_serial.irq;
+		info->port = state->port = new_port;
+		info->hub6 = state->hub6 = new_serial.hub6;
+		if (info->hub6)
+			info->io_type = state->io_type = SERIAL_IO_HUB6;
+		else if (info->io_type == SERIAL_IO_HUB6)
+			info->io_type = state->io_type = SERIAL_IO_PORT;
+	}
+	if ((state->type != PORT_UNKNOWN) && state->port) {
+			request_region(state->port,8,"serial(set)");
+	}
+
+	
+check_and_exit:
+	if (!state->port || !state->type)
+		return 0;
+	if (info->flags & ASYNC_INITIALIZED) {
+		if (((old_state.flags & ASYNC_SPD_MASK) !=
+		     (state->flags & ASYNC_SPD_MASK)) ||
+		    (old_state.custom_divisor != state->custom_divisor)) {
+			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+				info->tty->alt_speed = 57600;
+			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+				info->tty->alt_speed = 115200;
+			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
+				info->tty->alt_speed = 230400;
+			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
+				info->tty->alt_speed = 460800;
+			change_speed(info, 0);
+		}
+	} else {
+		retval = startup(info);
+	}
+	return retval;
+}
+
+
+/*
+ * get_lsr_info - get line status register info
+ *
+ * Purpose: Let user call ioctl() to get info when the UART physically
+ * 	    is emptied.  On bus types like RS485, the transmitter must
+ * 	    release the bus after transmitting. This must be done when
+ * 	    the transmit shift register is empty, not be done when the
+ * 	    transmit holding register is empty.  This functionality
+ * 	    allows an RS485 driver to be written in user space. 
+ */
+static int get_lsr_info(struct async_struct * info, unsigned int *value)
+{
+	unsigned char status;
+	unsigned int result;
+	unsigned long flags;
+
+	save_flags(flags); cli();
+	status = serial_in(info, UART_LSR);
+	restore_flags(flags);
+	result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0);
+
+	/*
+	 * If we're about to load something into the transmit
+	 * register, we'll pretend the transmitter isn't empty to
+	 * avoid a race condition (depending on when the transmit
+	 * interrupt happens).
+	 */
+	if (info->x_char || 
+	    ((CIRC_CNT(info->xmit.head, info->xmit.tail,
+		       SERIAL_XMIT_SIZE) > 0) &&
+	     !info->tty->stopped && !info->tty->hw_stopped))
+		result &= TIOCSER_TEMT;
+
+	if (copy_to_user(value, &result, sizeof(int)))
+		return -EFAULT;
+	return 0;
+}
+
+
+static int get_modem_info(struct async_struct * info, unsigned int *value)
+{
+	unsigned char control, status;
+	unsigned int result;
+	unsigned long flags;
+
+	control = info->MCR;
+	save_flags(flags); cli();
+	status = serial_in(info, UART_MSR);
+	restore_flags(flags);
+	result =  ((control & UART_MCR_RTS) ? TIOCM_RTS : 0)
+		| ((control & UART_MCR_DTR) ? TIOCM_DTR : 0)
+#ifdef TIOCM_OUT1
+		| ((control & UART_MCR_OUT1) ? TIOCM_OUT1 : 0)
+		| ((control & UART_MCR_OUT2) ? TIOCM_OUT2 : 0)
+#endif
+		| ((status  & UART_MSR_DCD) ? TIOCM_CAR : 0)
+		| ((status  & UART_MSR_RI) ? TIOCM_RNG : 0)
+		| ((status  & UART_MSR_DSR) ? TIOCM_DSR : 0)
+		| ((status  & UART_MSR_CTS) ? TIOCM_CTS : 0);
+
+	if (copy_to_user(value, &result, sizeof(int)))
+		return -EFAULT;
+	return 0;
+}
+
+static int set_modem_info(struct async_struct * info, unsigned int cmd,
+			  unsigned int *value)
+{
+	unsigned int arg;
+	unsigned long flags;
+
+	if (copy_from_user(&arg, value, sizeof(int)))
+		return -EFAULT;
+
+	switch (cmd) {
+	case TIOCMBIS: 
+		if (arg & TIOCM_RTS)
+			info->MCR |= UART_MCR_RTS;
+		if (arg & TIOCM_DTR)
+			info->MCR |= UART_MCR_DTR;
+#ifdef TIOCM_OUT1
+		if (arg & TIOCM_OUT1)
+			info->MCR |= UART_MCR_OUT1;
+		if (arg & TIOCM_OUT2)
+			info->MCR |= UART_MCR_OUT2;
+#endif
+		if (arg & TIOCM_LOOP)
+			info->MCR |= UART_MCR_LOOP;
+		break;
+	case TIOCMBIC:
+		if (arg & TIOCM_RTS)
+			info->MCR &= ~UART_MCR_RTS;
+		if (arg & TIOCM_DTR)
+			info->MCR &= ~UART_MCR_DTR;
+#ifdef TIOCM_OUT1
+		if (arg & TIOCM_OUT1)
+			info->MCR &= ~UART_MCR_OUT1;
+		if (arg & TIOCM_OUT2)
+			info->MCR &= ~UART_MCR_OUT2;
+#endif
+		if (arg & TIOCM_LOOP)
+			info->MCR &= ~UART_MCR_LOOP;
+		break;
+	case TIOCMSET:
+		info->MCR = ((info->MCR & ~(UART_MCR_RTS |
+#ifdef TIOCM_OUT1
+					    UART_MCR_OUT1 |
+					    UART_MCR_OUT2 |
+#endif
+					    UART_MCR_LOOP |
+					    UART_MCR_DTR))
+			     | ((arg & TIOCM_RTS) ? UART_MCR_RTS : 0)
+#ifdef TIOCM_OUT1
+			     | ((arg & TIOCM_OUT1) ? UART_MCR_OUT1 : 0)
+			     | ((arg & TIOCM_OUT2) ? UART_MCR_OUT2 : 0)
+#endif
+			     | ((arg & TIOCM_LOOP) ? UART_MCR_LOOP : 0)
+			     | ((arg & TIOCM_DTR) ? UART_MCR_DTR : 0));
+		break;
+	default:
+		return -EINVAL;
+	}
+	save_flags(flags); cli();
+	info->MCR |= ALPHA_KLUDGE_MCR; 		/* Don't ask */
+	serial_out(info, UART_MCR, info->MCR);
+	restore_flags(flags);
+	return 0;
+}
+
+static int do_autoconfig(struct async_struct * info)
+{
+	int retval;
+	
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+	
+	if (info->state->count > 1)
+		return -EBUSY;
+	
+	shutdown(info);
+
+	autoconfig(info->state);
+	retval = startup(info);
+	if (retval)
+		return retval;
+	return 0;
+}
+
+/*
+ * rs_break() --- routine which turns the break handling on or off
+ */
+static void rs_break(struct tty_struct *tty, int break_state)
+{
+	struct async_struct * info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+	
+	if (serial_paranoia_check(info, tty->device, "rs_break"))
+		return;
+
+	if (!CONFIGURED_SERIAL_PORT(info))
+		return;
+	save_flags(flags); cli();
+	if (break_state == -1)
+		info->LCR |= UART_LCR_SBC;
+	else
+		info->LCR &= ~UART_LCR_SBC;
+	serial_out(info, UART_LCR, info->LCR);
+	restore_flags(flags);
+}
+
+
+static int rs_ioctl(struct tty_struct *tty, struct file * file,
+		    unsigned int cmd, unsigned long arg)
+{
+	struct async_struct * info = (struct async_struct *)tty->driver_data;
+	struct async_icount cprev, cnow;	/* kernel counter temps */
+	struct serial_icounter_struct icount;
+	unsigned long flags;
+	
+	if (serial_paranoia_check(info, tty->device, "rs_ioctl"))
+		return -ENODEV;
+
+	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) &&
+	    (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
+		if (tty->flags & (1 << TTY_IO_ERROR))
+		    return -EIO;
+	}
+	
+	switch (cmd) {
+		case TIOCMGET:
+			return get_modem_info(info, (unsigned int *) arg);
+		case TIOCMBIS:
+		case TIOCMBIC:
+		case TIOCMSET:
+			return set_modem_info(info, cmd, (unsigned int *) arg);
+		case TIOCGSERIAL:
+			return get_serial_info(info,
+					       (struct serial_struct *) arg);
+		case TIOCSSERIAL:
+			return set_serial_info(info,
+					       (struct serial_struct *) arg);
+		case TIOCSERCONFIG:
+			return do_autoconfig(info);
+
+		case TIOCSERGETLSR: /* Get line status register */
+			return get_lsr_info(info, (unsigned int *) arg);
+
+		case TIOCSERGSTRUCT:
+			if (copy_to_user((struct async_struct *) arg,
+					 info, sizeof(struct async_struct)))
+				return -EFAULT;
+			return 0;
+				
+			
+		/*
+		 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
+		 * - mask passed in arg for lines of interest
+ 		 *   (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
+		 * Caller should use TIOCGICOUNT to see which one it was
+		 */
+		case TIOCMIWAIT:
+			save_flags(flags); cli();
+			/* note the counters on entry */
+			cprev = info->state->icount;
+			restore_flags(flags);
+			/* Force modem status interrupts on */
+			info->IER |= UART_IER_MSI;
+			serial_out(info, UART_IER, info->IER);
+			while (1) {
+				interruptible_sleep_on(&info->delta_msr_wait);
+				/* see if a signal did it */
+				if (signal_pending(current))
+					return -ERESTARTSYS;
+				save_flags(flags); cli();
+				cnow = info->state->icount; /* atomic copy */
+				restore_flags(flags);
+				if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && 
+				    cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
+					return -EIO; /* no change => error */
+				if ( ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
+				     ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
+				     ((arg & TIOCM_CD)  && (cnow.dcd != cprev.dcd)) ||
+				     ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) {
+					return 0;
+				}
+				cprev = cnow;
+			}
+			/* NOTREACHED */
+
+		/* 
+		 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
+		 * Return: write counters to the user passed counter struct
+		 * NB: both 1->0 and 0->1 transitions are counted except for
+		 *     RI where only 0->1 is counted.
+		 */
+		case TIOCGICOUNT:
+			save_flags(flags); cli();
+			cnow = info->state->icount;
+			restore_flags(flags);
+			icount.cts = cnow.cts;
+			icount.dsr = cnow.dsr;
+			icount.rng = cnow.rng;
+			icount.dcd = cnow.dcd;
+			icount.rx = cnow.rx;
+			icount.tx = cnow.tx;
+			icount.frame = cnow.frame;
+			icount.overrun = cnow.overrun;
+			icount.parity = cnow.parity;
+			icount.brk = cnow.brk;
+			icount.buf_overrun = cnow.buf_overrun;
+			
+			if (copy_to_user((void *)arg, &icount, sizeof(icount)))
+				return -EFAULT;
+			return 0;
+		case TIOCSERGWILD:
+		case TIOCSERSWILD:
+			/* "setserial -W" is called in Debian boot */
+			printk ("TIOCSER?WILD ioctl obsolete, ignored.\n");
+			return 0;
+
+		default:
+			return -ENOIOCTLCMD;
+		}
+	return 0;
+}
+
+static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+	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;
+
+	change_speed(info, old_termios);
+
+	/* Handle transition to B0 status */
+	if ((old_termios->c_cflag & CBAUD) &&
+	    !(cflag & CBAUD)) {
+		info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS);
+		save_flags(flags); cli();
+		serial_out(info, UART_MCR, info->MCR);
+		restore_flags(flags);
+	}
+	
+	/* Handle transition away from B0 status */
+	if (!(old_termios->c_cflag & CBAUD) &&
+	    (cflag & CBAUD)) {
+		info->MCR |= UART_MCR_DTR;
+		if (!(tty->termios->c_cflag & CRTSCTS) || 
+		    !test_bit(TTY_THROTTLED, &tty->flags)) {
+			info->MCR |= UART_MCR_RTS;
+		}
+		save_flags(flags); cli();
+		serial_out(info, UART_MCR, info->MCR);
+		restore_flags(flags);
+	}
+	
+	/* Handle turning off CRTSCTS */
+	if ((old_termios->c_cflag & CRTSCTS) &&
+	    !(tty->termios->c_cflag & CRTSCTS)) {
+		tty->hw_stopped = 0;
+		rs_start(tty);
+	}
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_close()
+ * 
+ * This routine is called when the serial port gets closed.  First, we
+ * wait for the last remaining data to be sent.  Then, we unlink its
+ * async structure from the interrupt chain if necessary, and we free
+ * that IRQ if nothing is left in the chain.
+ * ------------------------------------------------------------
+ */
+static void rs_close(struct tty_struct *tty, struct file * filp)
+{
+	struct async_struct * info = (struct async_struct *)tty->driver_data;
+	struct serial_state *state;
+	unsigned long flags;
+
+	if (!info || serial_paranoia_check(info, tty->device, "rs_close"))
+		return;
+
+	state = info->state;
+	
+	save_flags(flags); cli();
+	
+	if (tty_hung_up_p(filp)) {
+		DBG_CNT("before DEC-hung");
+		MOD_DEC_USE_COUNT;
+		restore_flags(flags);
+		return;
+	}
+	
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_close ttys%d, count = %d\n", info->line, state->count);
+#endif
+	if ((tty->count == 1) && (state->count != 1)) {
+		/*
+		 * Uh, oh.  tty->count is 1, which means that the tty
+		 * structure will be freed.  state->count should always
+		 * be one in these conditions.  If it's greater than
+		 * one, we've got real problems, since it means the
+		 * serial port won't be shutdown.
+		 */
+		printk("rs_close: bad serial port count; tty->count is 1, "
+		       "state->count is %d\n", state->count);
+		state->count = 1;
+	}
+	if (--state->count < 0) {
+		printk("rs_close: bad serial port count for ttys%d: %d\n",
+		       info->line, state->count);
+		state->count = 0;
+	}
+	if (state->count) {
+		DBG_CNT("before DEC-2");
+		MOD_DEC_USE_COUNT;
+		restore_flags(flags);
+		return;
+	}
+	info->flags |= ASYNC_CLOSING;
+	restore_flags(flags);
+	/*
+	 * Save the termios structure, since this port may have
+	 * separate termios for callout and dialin.
+	 */
+	if (info->flags & ASYNC_NORMAL_ACTIVE)
+		info->state->normal_termios = *tty->termios;
+	if (info->flags & ASYNC_CALLOUT_ACTIVE)
+		info->state->callout_termios = *tty->termios;
+	/*
+	 * Now we wait for the transmit buffer to clear; and we notify 
+	 * the line discipline to only process XON/XOFF characters.
+	 */
+	tty->closing = 1;
+	if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
+		tty_wait_until_sent(tty, info->closing_wait);
+	/*
+	 * At this point we stop accepting input.  To do this, we
+	 * disable the receive line status interrupts, and tell the
+	 * interrupt driver to stop checking the data ready bit in the
+	 * line status register.
+	 */
+	info->IER &= ~UART_IER_RLSI;
+	info->read_status_mask &= ~UART_LSR_DR;
+	if (info->flags & ASYNC_INITIALIZED) {
+		serial_out(info, UART_IER, info->IER);
+		/*
+		 * Before we drop DTR, make sure the UART transmitter
+		 * has completely drained; this is especially
+		 * important if there is a transmit FIFO!
+		 */
+		rs_wait_until_sent(tty, info->timeout);
+	}
+	shutdown(info);
+	if (tty->driver.flush_buffer)
+		tty->driver.flush_buffer(tty);
+	if (tty->ldisc.flush_buffer)
+		tty->ldisc.flush_buffer(tty);
+	tty->closing = 0;
+	info->event = 0;
+	info->tty = 0;
+	if (info->blocked_open) {
+		if (info->close_delay) {
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout(info->close_delay);
+		}
+		wake_up_interruptible(&info->open_wait);
+	}
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
+			 ASYNC_CLOSING);
+	wake_up_interruptible(&info->close_wait);
+	MOD_DEC_USE_COUNT;
+}
+
+/*
+ * rs_wait_until_sent() --- wait until the transmitter is empty
+ */
+static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
+{
+	struct async_struct * info = (struct async_struct *)tty->driver_data;
+	unsigned long orig_jiffies, char_time;
+	int lsr;
+	
+	if (serial_paranoia_check(info, tty->device, "rs_wait_until_sent"))
+		return;
+
+	if (info->state->type == PORT_UNKNOWN)
+		return;
+
+	if (info->xmit_fifo_size == 0)
+		return; /* Just in case.... */
+
+	orig_jiffies = jiffies;
+	/*
+	 * Set the check interval to be 1/5 of the estimated time to
+	 * send a single character, and make it at least 1.  The check
+	 * interval should also be less than the timeout.
+	 * 
+	 * Note: we have to use pretty tight timings here to satisfy
+	 * the NIST-PCTS.
+	 */
+	char_time = (info->timeout - HZ/50) / info->xmit_fifo_size;
+	char_time = char_time / 5;
+	if (char_time == 0)
+		char_time = 1;
+	if (timeout && timeout < char_time)
+		char_time = timeout;
+	/*
+	 * If the transmitter hasn't cleared in twice the approximate
+	 * amount of time to send the entire FIFO, it probably won't
+	 * ever clear.  This assumes the UART isn't doing flow
+	 * control, which is currently the case.  Hence, if it ever
+	 * takes longer than info->timeout, this is probably due to a
+	 * UART bug of some kind.  So, we clamp the timeout parameter at
+	 * 2*info->timeout.
+	 */
+	if (!timeout || timeout > 2*info->timeout)
+		timeout = 2*info->timeout;
+#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
+	printk("In rs_wait_until_sent(%d) check=%lu...", timeout, char_time);
+	printk("jiff=%lu...", jiffies);
+#endif
+	while (!((lsr = serial_inp(info, UART_LSR)) & UART_LSR_TEMT)) {
+#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
+		printk("lsr = %d (jiff=%lu)...", lsr, jiffies);
+#endif
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(char_time);
+		if (signal_pending(current))
+			break;
+		if (timeout && time_after(jiffies, orig_jiffies + timeout))
+			break;
+	}
+	set_current_state(TASK_RUNNING);
+#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
+	printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies);
+#endif
+}
+
+/*
+ * rs_hangup() --- called by tty_hangup() when a hangup is signaled.
+ */
+static void rs_hangup(struct tty_struct *tty)
+{
+	struct async_struct * info = (struct async_struct *)tty->driver_data;
+	struct serial_state *state = info->state;
+	
+	if (serial_paranoia_check(info, tty->device, "rs_hangup"))
+		return;
+
+	state = info->state;
+	
+	rs_flush_buffer(tty);
+	if (info->flags & ASYNC_CLOSING)
+		return;
+	shutdown(info);
+	info->event = 0;
+	state->count = 0;
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+	info->tty = 0;
+	wake_up_interruptible(&info->open_wait);
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_open() and friends
+ * ------------------------------------------------------------
+ */
+static int block_til_ready(struct tty_struct *tty, struct file * filp,
+			   struct async_struct *info)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	struct serial_state *state = info->state;
+	int		retval;
+	int		do_clocal = 0, extra_count = 0;
+	unsigned long	flags;
+
+	/*
+	 * If the device is in the middle of being closed, then block
+	 * until it's done, and then try again.
+	 */
+	if (tty_hung_up_p(filp) ||
+	    (info->flags & ASYNC_CLOSING)) {
+		if (info->flags & ASYNC_CLOSING)
+			interruptible_sleep_on(&info->close_wait);
+#ifdef SERIAL_DO_RESTART
+		return ((info->flags & ASYNC_HUP_NOTIFY) ?
+			-EAGAIN : -ERESTARTSYS);
+#else
+		return -EAGAIN;
+#endif
+	}
+
+	/*
+	 * If this is a callout device, then just make sure the normal
+	 * device isn't being used.
+	 */
+	if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
+		if (info->flags & ASYNC_NORMAL_ACTIVE)
+			return -EBUSY;
+		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
+		    (info->flags & ASYNC_SESSION_LOCKOUT) &&
+		    (info->session != current->session))
+		    return -EBUSY;
+		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
+		    (info->flags & ASYNC_PGRP_LOCKOUT) &&
+		    (info->pgrp != current->pgrp))
+		    return -EBUSY;
+		info->flags |= ASYNC_CALLOUT_ACTIVE;
+		return 0;
+	}
+	
+	/*
+	 * If non-blocking mode is set, or the port is not enabled,
+	 * then make the check up front and then exit.
+	 */
+	if ((filp->f_flags & O_NONBLOCK) ||
+	    (tty->flags & (1 << TTY_IO_ERROR))) {
+		if (info->flags & ASYNC_CALLOUT_ACTIVE)
+			return -EBUSY;
+		info->flags |= ASYNC_NORMAL_ACTIVE;
+		return 0;
+	}
+
+	if (info->flags & ASYNC_CALLOUT_ACTIVE) {
+		if (state->normal_termios.c_cflag & CLOCAL)
+			do_clocal = 1;
+	} else {
+		if (tty->termios->c_cflag & CLOCAL)
+			do_clocal = 1;
+	}
+	
+	/*
+	 * Block waiting for the carrier detect and the line to become
+	 * free (i.e., not in use by the callout).  While we are in
+	 * this loop, state->count is dropped by one, so that
+	 * rs_close() knows when to free things.  We restore it upon
+	 * exit, either normal or abnormal.
+	 */
+	retval = 0;
+	add_wait_queue(&info->open_wait, &wait);
+#ifdef SERIAL_DEBUG_OPEN
+	printk("block_til_ready before block: ttys%d, count = %d\n",
+	       state->line, state->count);
+#endif
+	save_flags(flags); cli();
+	if (!tty_hung_up_p(filp)) {
+		extra_count = 1;
+		state->count--;
+	}
+	restore_flags(flags);
+	info->blocked_open++;
+	while (1) {
+		save_flags(flags); cli();
+		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
+		    (tty->termios->c_cflag & CBAUD))
+			serial_out(info, UART_MCR,
+				   serial_inp(info, UART_MCR) |
+				   (UART_MCR_DTR | UART_MCR_RTS));
+		restore_flags(flags);
+		set_current_state(TASK_INTERRUPTIBLE);
+		if (tty_hung_up_p(filp) ||
+		    !(info->flags & ASYNC_INITIALIZED)) {
+#ifdef SERIAL_DO_RESTART
+			if (info->flags & ASYNC_HUP_NOTIFY)
+				retval = -EAGAIN;
+			else
+				retval = -ERESTARTSYS;	
+#else
+			retval = -EAGAIN;
+#endif
+			break;
+		}
+		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
+		    !(info->flags & ASYNC_CLOSING) &&
+		    (do_clocal || (serial_in(info, UART_MSR) &
+				   UART_MSR_DCD)))
+			break;
+		if (signal_pending(current)) {
+			retval = -ERESTARTSYS;
+			break;
+		}
+#ifdef SERIAL_DEBUG_OPEN
+		printk("block_til_ready blocking: ttys%d, count = %d\n",
+		       info->line, state->count);
+#endif
+		schedule();
+	}
+	set_current_state(TASK_RUNNING);
+	remove_wait_queue(&info->open_wait, &wait);
+	if (extra_count)
+		state->count++;
+	info->blocked_open--;
+#ifdef SERIAL_DEBUG_OPEN
+	printk("block_til_ready after blocking: ttys%d, count = %d\n",
+	       info->line, state->count);
+#endif
+	if (retval)
+		return retval;
+	info->flags |= ASYNC_NORMAL_ACTIVE;
+	return 0;
+}
+
+static int get_async_struct(int line, struct async_struct **ret_info)
+{
+	struct async_struct *info;
+	struct serial_state *sstate;
+
+	sstate = rs_table + line;
+	sstate->count++;
+	if (sstate->info) {
+		*ret_info = sstate->info;
+		return 0;
+	}
+	info = kmalloc(sizeof(struct async_struct), GFP_KERNEL);
+	if (!info) {
+		sstate->count--;
+		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;
+	info->io_type = sstate->io_type;
+	info->iomem_base = sstate->iomem_base;
+	info->iomem_reg_shift = sstate->iomem_reg_shift;
+	info->xmit_fifo_size = sstate->xmit_fifo_size;
+	info->line = line;
+	info->tqueue.routine = do_softint;
+	info->tqueue.data = info;
+	info->state = sstate;
+	if (sstate->info) {
+		kfree(info);
+		*ret_info = sstate->info;
+		return 0;
+	}
+	*ret_info = sstate->info = info;
+	return 0;
+}
+
+/*
+ * This routine is called whenever a serial port is opened.  It
+ * enables interrupts for a serial port, linking in its async structure into
+ * the IRQ chain.   It also performs the serial-specific
+ * initialization for the tty structure.
+ */
+static int rs_open(struct tty_struct *tty, struct file * filp)
+{
+	struct async_struct	*info;
+	int 			retval, line;
+	unsigned long		page;
+
+	MOD_INC_USE_COUNT;
+	line = MINOR(tty->device) - tty->driver.minor_start;
+	if ((line < 0) || (line >= NR_PORTS)) {
+		MOD_DEC_USE_COUNT;
+		return -ENODEV;
+	}
+	retval = get_async_struct(line, &info);
+	if (retval) {
+		MOD_DEC_USE_COUNT;
+		return retval;
+	}
+	tty->driver_data = info;
+	info->tty = tty;
+	if (serial_paranoia_check(info, tty->device, "rs_open")) {
+		MOD_DEC_USE_COUNT;		
+		return -ENODEV;
+	}
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_open %s%d, count = %d\n", tty->driver.name, info->line,
+	       info->state->count);
+#endif
+	info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+
+	if (!tmp_buf) {
+		page = get_zeroed_page(GFP_KERNEL);
+		if (!page) {
+			MOD_DEC_USE_COUNT;
+			return -ENOMEM;
+		}
+		if (tmp_buf)
+			free_page(page);
+		else
+			tmp_buf = (unsigned char *) page;
+	}
+
+	/*
+	 * If the port is the middle of closing, bail out now
+	 */
+	if (tty_hung_up_p(filp) ||
+	    (info->flags & ASYNC_CLOSING)) {
+		if (info->flags & ASYNC_CLOSING)
+			interruptible_sleep_on(&info->close_wait);
+		MOD_DEC_USE_COUNT;
+#ifdef SERIAL_DO_RESTART
+		return ((info->flags & ASYNC_HUP_NOTIFY) ?
+			-EAGAIN : -ERESTARTSYS);
+#else
+		return -EAGAIN;
+#endif
+	}
+
+	/*
+	 * Start up serial port
+	 */
+	retval = startup(info);
+	if (retval) {
+		MOD_DEC_USE_COUNT;
+		return retval;
+	}
+
+	retval = block_til_ready(tty, filp, info);
+	if (retval) {
+#ifdef SERIAL_DEBUG_OPEN
+		printk("rs_open returning after block_til_ready with %d\n",
+		       retval);
+#endif
+		MOD_DEC_USE_COUNT;
+		return retval;
+	}
+
+	if ((info->state->count == 1) &&
+	    (info->flags & ASYNC_SPLIT_TERMIOS)) {
+		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
+			*tty->termios = info->state->normal_termios;
+		else 
+			*tty->termios = info->state->callout_termios;
+		change_speed(info, 0);
+	}
+#ifdef CONFIG_AU1000_SERIAL_CONSOLE
+	if (sercons.cflag && sercons.index == line) {
+		tty->termios->c_cflag = sercons.cflag;
+		sercons.cflag = 0;
+		change_speed(info, 0);
+	}
+#endif
+	info->session = current->session;
+	info->pgrp = current->pgrp;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_open ttys%d successful...", info->line);
+#endif
+	return 0;
+}
+
+/*
+ * /proc fs routines....
+ */
+
+static inline int line_info(char *buf, struct serial_state *state)
+{
+	struct async_struct *info = state->info, scr_info;
+	char	stat_buf[30], control, status;
+	int	ret;
+	unsigned long flags;
+
+	ret = sprintf(buf, "%d: uart:%s port:%lX irq:%d",
+		      state->line, uart_config[state->type].name, 
+		      state->port, state->irq);
+
+	if (!state->port || (state->type == PORT_UNKNOWN)) {
+		ret += sprintf(buf+ret, "\n");
+		return ret;
+	}
+
+	/*
+	 * Figure out the current RS-232 lines
+	 */
+	if (!info) {
+		info = &scr_info;	/* This is just for serial_{in,out} */
+
+		info->magic = SERIAL_MAGIC;
+		info->port = state->port;
+		info->flags = state->flags;
+		info->quot = 0;
+		info->tty = 0;
+	}
+	save_flags(flags); cli();
+	status = serial_in(info, UART_MSR);
+	control = info != &scr_info ? info->MCR : serial_in(info, UART_MCR);
+	restore_flags(flags); 
+
+	stat_buf[0] = 0;
+	stat_buf[1] = 0;
+	if (control & UART_MCR_RTS)
+		strcat(stat_buf, "|RTS");
+	if (status & UART_MSR_CTS)
+		strcat(stat_buf, "|CTS");
+	if (control & UART_MCR_DTR)
+		strcat(stat_buf, "|DTR");
+	if (status & UART_MSR_DSR)
+		strcat(stat_buf, "|DSR");
+	if (status & UART_MSR_DCD)
+		strcat(stat_buf, "|CD");
+	if (status & UART_MSR_RI)
+		strcat(stat_buf, "|RI");
+
+	if (info->quot) {
+		ret += sprintf(buf+ret, " baud:%d",
+			       state->baud_base / info->quot);
+	}
+
+	ret += sprintf(buf+ret, " tx:%d rx:%d",
+		      state->icount.tx, state->icount.rx);
+
+	if (state->icount.frame)
+		ret += sprintf(buf+ret, " fe:%d", state->icount.frame);
+	
+	if (state->icount.parity)
+		ret += sprintf(buf+ret, " pe:%d", state->icount.parity);
+	
+	if (state->icount.brk)
+		ret += sprintf(buf+ret, " brk:%d", state->icount.brk);	
+
+	if (state->icount.overrun)
+		ret += sprintf(buf+ret, " oe:%d", state->icount.overrun);
+
+	/*
+	 * Last thing is the RS-232 status lines
+	 */
+	ret += sprintf(buf+ret, " %s\n", stat_buf+1);
+	return ret;
+}
+
+int rs_read_proc(char *page, char **start, off_t off, int count,
+		 int *eof, void *data)
+{
+	int i, len = 0, l;
+	off_t	begin = 0;
+
+	len += sprintf(page, "serinfo:1.0 driver:%s%s revision:%s\n",
+		       serial_version, LOCAL_VERSTRING, serial_revdate);
+	for (i = 0; i < NR_PORTS && len < 4000; i++) {
+		l = line_info(page + len, &rs_table[i]);
+		len += l;
+		if (len+begin > off+count)
+			goto done;
+		if (len+begin < off) {
+			begin += len;
+			len = 0;
+		}
+	}
+	*eof = 1;
+done:
+	if (off >= len+begin)
+		return 0;
+	*start = page + (off-begin);
+	return ((count < begin+len-off) ? count : begin+len-off);
+}
+
+/*
+ * ---------------------------------------------------------------------
+ * rs_init() and friends
+ *
+ * rs_init() is called at boot-time to initialize the serial driver.
+ * ---------------------------------------------------------------------
+ */
+
+/*
+ * This routine prints out the appropriate serial driver version
+ * number, and identifies which options were configured into this
+ * driver.
+ */
+static char serial_options[] __initdata =
+       " no serial options enabled\n";
+#undef SERIAL_OPT
+
+static _INLINE_ void show_serial_version(void)
+{
+ 	printk(KERN_INFO "%s version %s%s (%s) with%s", serial_name,
+	       serial_version, LOCAL_VERSTRING, serial_revdate,
+	       serial_options);
+}
+
+
+/*
+ * This routine is called by rs_init() to initialize a specific serial
+ * port.  It determines what type of UART chip this serial port is
+ * using: 8250, 16450, 16550, 16550A.  The important question is
+ * whether or not this UART is a 16550A or not, since this will
+ * determine whether or not we can use its FIFO features or not.
+ */
+static void autoconfig(struct serial_state * state)
+{
+	struct async_struct *info, scr_info;
+	unsigned long flags;
+
+
+#ifdef SERIAL_DEBUG_AUTOCONF
+	printk("Testing ttyS%d (0x%04lx, 0x%04x)...\n", state->line,
+	       state->port, (unsigned) state->iomem_base);
+#endif
+	
+	if (!CONFIGURED_SERIAL_PORT(state))
+		return;
+
+	if (inl(UART_MOD_CNTRL + state->port) != 0x3) {
+		outl(3, UART_MOD_CNTRL + state->port);
+	}
+		
+	state->type = PORT_16550;
+	info = &scr_info;	/* This is just for serial_{in,out} */
+
+	info->magic = SERIAL_MAGIC;
+	info->state = state;
+	info->port = state->port;
+	info->flags = state->flags;
+	info->io_type = state->io_type;
+	info->iomem_base = state->iomem_base;
+	info->iomem_reg_shift = state->iomem_reg_shift;
+
+
+	save_flags(flags); cli();
+	state->xmit_fifo_size =	uart_config[state->type].dfl_xmit_fifo_size;
+
+	if (info->port) {
+			request_region(info->port,8,"serial(auto)");
+	}
+
+	/*
+	 * Reset the UART.
+	 */
+	serial_outp(info, UART_FCR, (UART_FCR_ENABLE_FIFO |
+				     UART_FCR_CLEAR_RCVR |
+				     UART_FCR_CLEAR_XMIT));
+	serial_outp(info, UART_FCR, 0);
+	(void)serial_in(info, UART_RX);
+	serial_outp(info, UART_IER, 0);
+	
+	restore_flags(flags);
+}
+
+int register_serial(struct serial_struct *req);
+void unregister_serial(int line);
+
+EXPORT_SYMBOL(register_serial);
+EXPORT_SYMBOL(unregister_serial);
+
+
+/*
+ * The serial driver boot-time initialization code!
+ */
+static int __init rs_init(void)
+{
+	int i;
+	struct serial_state * state;
+
+	init_bh(SERIAL_BH, do_serial_bh);
+	init_timer(&serial_timer);
+	serial_timer.function = rs_timer;
+	mod_timer(&serial_timer, jiffies + RS_STROBE_TIME);
+
+	for (i = 0; i < NR_IRQS; i++) {
+		IRQ_ports[i] = 0;
+		IRQ_timeout[i] = 0;
+	}
+#ifdef CONFIG_AU1000_SERIAL_CONSOLE
+	/*
+	 *	The interrupt of the serial console port
+	 *	can't be shared.
+	 */
+	if (sercons.flags & CON_CONSDEV) {
+		for(i = 0; i < NR_PORTS; i++)
+			if (i != sercons.index &&
+			    rs_table[i].irq == rs_table[sercons.index].irq)
+				rs_table[i].irq = 0;
+	}
+#endif
+	show_serial_version();
+
+	/* Initialize the tty_driver structure */
+	
+	memset(&serial_driver, 0, sizeof(struct tty_driver));
+	serial_driver.magic = TTY_DRIVER_MAGIC;
+	serial_driver.driver_name = "serial";
+#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))
+	serial_driver.name = "tts/%d";
+#else
+	serial_driver.name = "ttyS";
+#endif
+	serial_driver.major = TTY_MAJOR;
+	serial_driver.minor_start = 64 + SERIAL_DEV_OFFSET;
+	serial_driver.num = NR_PORTS;
+	serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
+	serial_driver.subtype = SERIAL_TYPE_NORMAL;
+	serial_driver.init_termios = tty_std_termios;
+	serial_driver.init_termios.c_cflag =
+		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+	serial_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
+	serial_driver.refcount = &serial_refcount;
+	serial_driver.table = serial_table;
+	serial_driver.termios = serial_termios;
+	serial_driver.termios_locked = serial_termios_locked;
+
+	serial_driver.open = rs_open;
+	serial_driver.close = rs_close;
+	serial_driver.write = rs_write;
+	serial_driver.put_char = rs_put_char;
+	serial_driver.flush_chars = rs_flush_chars;
+	serial_driver.write_room = rs_write_room;
+	serial_driver.chars_in_buffer = rs_chars_in_buffer;
+	serial_driver.flush_buffer = rs_flush_buffer;
+	serial_driver.ioctl = rs_ioctl;
+	serial_driver.throttle = rs_throttle;
+	serial_driver.unthrottle = rs_unthrottle;
+	serial_driver.set_termios = rs_set_termios;
+	serial_driver.stop = rs_stop;
+	serial_driver.start = rs_start;
+	serial_driver.hangup = rs_hangup;
+	serial_driver.break_ctl = rs_break;
+	serial_driver.send_xchar = rs_send_xchar;
+	serial_driver.wait_until_sent = rs_wait_until_sent;
+	serial_driver.read_proc = rs_read_proc;
+	
+	/*
+	 * The callout device is just like normal device except for
+	 * major number and the subtype code.
+	 */
+	callout_driver = serial_driver;
+#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))
+	callout_driver.name = "cua/%d";
+#else
+	callout_driver.name = "cua";
+#endif
+	callout_driver.major = TTYAUX_MAJOR;
+	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
+	callout_driver.read_proc = 0;
+	callout_driver.proc_entry = 0;
+
+	if (tty_register_driver(&serial_driver))
+		panic("Couldn't register serial driver\n");
+	if (tty_register_driver(&callout_driver))
+		panic("Couldn't register callout driver\n");
+	
+	for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
+		state->baud_base = get_au1000_uart_baud();
+		state->magic = SSTATE_MAGIC;
+		state->line = i;
+		state->type = PORT_UNKNOWN;
+		state->custom_divisor = 0;
+		state->close_delay = 5*HZ/10;
+		state->closing_wait = 30*HZ;
+		state->callout_termios = callout_driver.init_termios;
+		state->normal_termios = serial_driver.init_termios;
+		state->icount.cts = state->icount.dsr = 
+			state->icount.rng = state->icount.dcd = 0;
+		state->icount.rx = state->icount.tx = 0;
+		state->icount.frame = state->icount.parity = 0;
+		state->icount.overrun = state->icount.brk = 0;
+		state->irq = irq_cannonicalize(state->irq);
+		if (state->hub6)
+			state->io_type = SERIAL_IO_HUB6;
+		if (state->port && check_region(state->port,8)) {
+			continue;
+		}
+
+		if (state->flags & ASYNC_BOOT_AUTOCONF) {
+			autoconfig(state);
+		}
+	}
+	for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
+		if (state->type == PORT_UNKNOWN) {
+			continue;
+		}
+		printk(KERN_INFO "ttyS%02d%s at 0x%04lx (irq = %d) is a %s\n",
+		       state->line + SERIAL_DEV_OFFSET,
+		       (state->flags & ASYNC_FOURPORT) ? " FourPort" : "",
+		       state->port, state->irq,
+		       uart_config[state->type].name);
+		tty_register_devfs(&serial_driver, 0,
+				   serial_driver.minor_start + state->line);
+		tty_register_devfs(&callout_driver, 0,
+				   callout_driver.minor_start + state->line);
+	}
+	return 0;
+}
+
+/*
+ * register_serial and unregister_serial allows for 16x50 serial ports to be
+ * configured at run-time, to support PCMCIA modems.
+ */
+ 
+/**
+ *	register_serial - configure a 16x50 serial port at runtime
+ *	@req: request structure
+ *
+ *	Configure the serial port specified by the request. If the
+ *	port exists and is in use an error is returned. If the port
+ *	is not currently in the table it is added.
+ *
+ *	The port is then probed and if neccessary the IRQ is autodetected
+ *	If this fails an error is returned.
+ *
+ *	On success the port is ready to use and the line number is returned.
+ */
+ 
+int register_serial(struct serial_struct *req)
+{
+	int i;
+	unsigned long flags;
+	struct serial_state *state;
+	struct async_struct *info;
+	unsigned long port;
+
+	port = req->port;
+	if (HIGH_BITS_OFFSET)
+		port += (unsigned long) req->port_high << HIGH_BITS_OFFSET;
+
+	save_flags(flags); cli();
+	for (i = 0; i < NR_PORTS; i++) {
+		if ((rs_table[i].port == port) &&
+		    (rs_table[i].iomem_base == req->iomem_base))
+			break;
+	}
+	if (i == NR_PORTS) {
+		for (i = 0; i < NR_PORTS; i++)
+			if ((rs_table[i].type == PORT_UNKNOWN) &&
+			    (rs_table[i].count == 0))
+				break;
+	}
+	if (i == NR_PORTS) {
+		restore_flags(flags);
+		return -1;
+	}
+	state = &rs_table[i];
+	if (rs_table[i].count) {
+		restore_flags(flags);
+		printk("Couldn't configure serial #%d (port=%ld,irq=%d): "
+		       "device already open\n", i, port, req->irq);
+		return -1;
+	}
+	state->irq = req->irq;
+	state->port = port;
+	state->flags = req->flags;
+	state->io_type = req->io_type;
+	state->iomem_base = req->iomem_base;
+	state->iomem_reg_shift = req->iomem_reg_shift;
+	if (req->baud_base)
+		state->baud_base = req->baud_base;
+	if ((info = state->info) != NULL) {
+		info->port = port;
+		info->flags = req->flags;
+		info->io_type = req->io_type;
+		info->iomem_base = req->iomem_base;
+		info->iomem_reg_shift = req->iomem_reg_shift;
+	}
+	autoconfig(state);
+	if (state->type == PORT_UNKNOWN) {
+		restore_flags(flags);
+		printk("register_serial(): autoconfig failed\n");
+		return -1;
+	}
+	restore_flags(flags);
+
+       printk(KERN_INFO "ttyS%02d at %s 0x%04lx (irq = %d) is a %s\n",
+	      state->line + SERIAL_DEV_OFFSET,
+	      state->iomem_base ? "iomem" : "port",
+	      state->iomem_base ? (unsigned long)state->iomem_base :
+	      state->port, state->irq, uart_config[state->type].name);
+	tty_register_devfs(&serial_driver, 0,
+			   serial_driver.minor_start + state->line); 
+	tty_register_devfs(&callout_driver, 0,
+			   callout_driver.minor_start + state->line);
+	return state->line + SERIAL_DEV_OFFSET;
+}
+
+/**
+ *	unregister_serial - deconfigure a 16x50 serial port
+ *	@line: line to deconfigure
+ *
+ *	The port specified is deconfigured and its resources are freed. Any
+ *	user of the port is disconnected as if carrier was dropped. Line is
+ *	the port number returned by register_serial().
+ */
+
+void unregister_serial(int line)
+{
+	unsigned long flags;
+	struct serial_state *state = &rs_table[line];
+
+	save_flags(flags); cli();
+	if (state->info && state->info->tty)
+		tty_hangup(state->info->tty);
+	state->type = PORT_UNKNOWN;
+	printk(KERN_INFO "tty%02d unloaded\n", state->line);
+	/* These will be hidden, because they are devices that will no longer
+	 * be available to the system. (ie, PCMCIA modems, once ejected)
+	 */
+	tty_unregister_devfs(&serial_driver,
+			     serial_driver.minor_start + state->line);
+	tty_unregister_devfs(&callout_driver,
+			     callout_driver.minor_start + state->line);
+	restore_flags(flags);
+}
+
+static void __exit rs_fini(void) 
+{
+	unsigned long flags;
+	int e1, e2;
+	int i;
+	struct async_struct *info;
+
+	/* printk("Unloading %s: version %s\n", serial_name, serial_version); */
+	del_timer_sync(&serial_timer);
+	save_flags(flags); cli();
+        remove_bh(SERIAL_BH);
+	if ((e1 = tty_unregister_driver(&serial_driver)))
+		printk("serial: failed to unregister serial driver (%d)\n",
+		       e1);
+	if ((e2 = tty_unregister_driver(&callout_driver)))
+		printk("serial: failed to unregister callout driver (%d)\n", 
+		       e2);
+	restore_flags(flags);
+
+	for (i = 0; i < NR_PORTS; i++) {
+		if ((info = rs_table[i].info)) {
+			rs_table[i].info = NULL;
+			kfree(info);
+		}
+		if ((rs_table[i].type != PORT_UNKNOWN) && rs_table[i].port) {
+				release_region(rs_table[i].port, 8);
+		}
+	}
+	if (tmp_buf) {
+		unsigned long pg = (unsigned long) tmp_buf;
+		tmp_buf = NULL;
+		free_page(pg);
+	}
+}
+
+module_init(rs_init);
+module_exit(rs_fini);
+MODULE_DESCRIPTION("Au1000 serial driver");
+
+
+/*
+ * ------------------------------------------------------------
+ * Serial console driver
+ * ------------------------------------------------------------
+ */
+#ifdef CONFIG_AU1000_SERIAL_CONSOLE
+
+#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
+
+static struct async_struct async_sercons;
+
+/*
+ *	Wait for transmitter & holding register to empty
+ */
+static inline void wait_for_xmitr(struct async_struct *info)
+{
+	unsigned int status, tmout = 0xffffff;
+
+	do {
+		status = serial_in(info, UART_LSR);
+
+		if (status & UART_LSR_BI)
+			lsr_break_flag = UART_LSR_BI;
+		
+		if (--tmout == 0)
+			break;
+	} while((status & BOTH_EMPTY) != BOTH_EMPTY);
+}
+
+
+/*
+ *	Print a string to the serial port trying not to disturb
+ *	any possible real use of the port...
+ *
+ *	The console_lock must be held when we get here.
+ */
+static void serial_console_write(struct console *co, const char *s,
+				unsigned count)
+{
+	static struct async_struct *info = &async_sercons;
+	int ier;
+	unsigned i;
+
+	/*
+	 *	First save the IER then disable the interrupts
+	 */
+	ier = serial_in(info, UART_IER);
+	serial_out(info, UART_IER, 0x00);
+
+	/*
+	 *	Now, do each character
+	 */
+	for (i = 0; i < count; i++, s++) {
+		wait_for_xmitr(info);
+
+		/*
+		 *	Send the character out.
+		 *	If a LF, also do CR...
+		 */
+		serial_out(info, UART_TX, *s);
+		if (*s == 10) {
+			wait_for_xmitr(info);
+			serial_out(info, UART_TX, 13);
+		}
+	}
+
+	/*
+	 *	Finally, Wait for transmitter & holding register to empty
+	 * 	and restore the IER
+	 */
+	wait_for_xmitr(info);
+	serial_out(info, UART_IER, ier);
+}
+
+/*
+ *	Receive character from the serial port
+ */
+static int serial_console_wait_key(struct console *co)
+{
+	static struct async_struct *info;
+	int ier, c;
+
+	info = &async_sercons;
+
+	/*
+	 *	First save the IER then disable the interrupts so
+	 *	that the real driver for the port does not get the
+	 *	character.
+	 */
+	ier = serial_in(info, UART_IER);
+	serial_out(info, UART_IER, 0x00);
+ 
+	while ((serial_in(info, UART_LSR) & UART_LSR_DR) == 0);
+	c = serial_in(info, UART_RX);
+
+	/*
+	 *	Restore the interrupts
+	 */
+	serial_out(info, UART_IER, ier);
+
+	return c;
+}
+
+static kdev_t serial_console_device(struct console *c)
+{
+	return MKDEV(TTY_MAJOR, 64 + c->index);
+}
+
+/*
+ *	Setup initial baud/bits/parity. We do two things here:
+ *	- construct a cflag setting for the first rs_open()
+ *	- initialize the serial port
+ *	Return non-zero if we didn't find a serial port.
+ */
+static int __init serial_console_setup(struct console *co, char *options)
+{
+	static struct async_struct *info;
+	struct serial_state *state;
+	unsigned cval;
+	int	baud = 9600;
+	int	bits = 8;
+	int	parity = 'n';
+	int	cflag = CREAD | HUPCL | CLOCAL;
+	int	quot = 0;
+	char	*s;
+
+	if (options) {
+		baud = simple_strtoul(options, NULL, 10);
+		s = options;
+		while(*s >= '0' && *s <= '9')
+			s++;
+		if (*s) parity = *s++;
+		if (*s) bits   = *s - '0';
+	}
+
+	/*
+	 *	Now construct a cflag setting.
+	 */
+	switch(baud) {
+		case 1200:
+			cflag |= B1200;
+			break;
+		case 2400:
+			cflag |= B2400;
+			break;
+		case 4800:
+			cflag |= B4800;
+			break;
+		case 19200:
+			cflag |= B19200;
+			break;
+		case 38400:
+			cflag |= B38400;
+			break;
+		case 57600:
+			cflag |= B57600;
+			break;
+		case 115200:
+			cflag |= B115200;
+			break;
+		case 9600:
+		default:
+			cflag |= B9600;
+			break;
+	}
+	switch(bits) {
+		case 7:
+			cflag |= CS7;
+			break;
+		default:
+		case 8:
+			cflag |= CS8;
+			break;
+	}
+	switch(parity) {
+		case 'o': case 'O':
+			cflag |= PARODD;
+			break;
+		case 'e': case 'E':
+			cflag |= PARENB;
+			break;
+	}
+	co->cflag = cflag;
+
+	/*
+	 *	Divisor, bytesize and parity
+	 */
+	state = rs_table + co->index;
+	info = &async_sercons;
+	info->magic = SERIAL_MAGIC;
+	info->state = state;
+	info->port = state->port;
+	info->flags = state->flags;
+	info->io_type = state->io_type;
+	info->iomem_base = state->iomem_base;
+	info->iomem_reg_shift = state->iomem_reg_shift;
+	state->baud_base = get_au1000_uart_baud();
+	quot = state->baud_base / baud;
+
+	cval = cflag & (CSIZE | CSTOPB);
+	cval >>= 4;
+	if (cflag & PARENB)
+		cval |= UART_LCR_PARITY;
+	if (!(cflag & PARODD))
+		cval |= UART_LCR_EPAR;
+
+	/*
+	 *	Disable UART interrupts, set DTR and RTS high
+	 *	and set speed.
+	 */
+	serial_out(info, UART_CLK, quot & 0xffff);
+	serial_out(info, UART_IER, 0);
+	serial_out(info, UART_MCR, UART_MCR_DTR | UART_MCR_RTS);
+
+	/*
+	 *	If we read 0xff from the LSR, there is no UART here.
+	 */
+	if (serial_in(info, UART_LSR) == 0xff)
+		return -1;
+
+	return 0;
+}
+
+static struct console sercons = {
+	name:		"ttyS",
+	write:		serial_console_write,
+	device:		serial_console_device,
+	wait_key:	serial_console_wait_key,
+	setup:		serial_console_setup,
+	flags:		CON_PRINTBUFFER,
+	index:		-1,
+};
+
+/*
+ *	Register console.
+ */
+void __init au1000_serial_console_init(void)
+{
+	register_console(&sercons);
+}
+#endif
+
+/*
+  Local variables:
+  compile-command: "gcc -D__KERNEL__ -I../../include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strict-aliasing -pipe -fno-strength-reduce -march=i586 -DMODULE -DMODVERSIONS -include ../../include/linux/modversions.h   -DEXPORT_SYMTAB -c serial.c"
+  End:
+*/
diff -u --recursive --new-file v2.4.9/linux/arch/mips/au1000/common/time.c linux/arch/mips/au1000/common/time.c
--- v2.4.9/linux/arch/mips/au1000/common/time.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/au1000/common/time.c	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,286 @@
+/*
+ * Copyright (C) 2001 MontaVista Software, ppopov@mvista.com
+ * Copied and modified Carsten Langgaard's time.c
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope 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.
+ *
+ * ########################################################################
+ *
+ * Setting up the clock on the MIPS boards.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+
+#include <asm/mipsregs.h>
+#include <asm/ptrace.h>
+#include <asm/div64.h>
+#include <asm/au1000.h>
+
+#include <linux/mc146818rtc.h>
+#include <linux/timex.h>
+
+extern volatile unsigned long wall_jiffies;
+unsigned long missed_heart_beats = 0;
+unsigned long uart_baud_base;
+
+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;
+
+#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
+
+static inline void ack_r4ktimer(unsigned long newval)
+{
+	write_32bit_cp0_register(CP0_COMPARE, newval);
+}
+
+
+/*
+ * There are a lot of conceptually broken versions of the MIPS timer interrupt
+ * handler floating around.  This one is rather different, but the algorithm
+ * is provably more robust.
+ */
+unsigned long wtimer;
+void mips_timer_interrupt(struct pt_regs *regs)
+{
+	int irq = 7;
+
+	if (r4k_offset == 0)
+		goto null;
+
+	do {
+		kstat.irqs[0][irq]++;
+		do_timer(regs);
+		r4k_cur += r4k_offset;
+		ack_r4ktimer(r4k_cur);
+
+	} while (((unsigned long)read_32bit_cp0_register(CP0_COUNT)
+	         - r4k_cur) < 0x7fffffff);
+
+	return;
+
+null:
+	ack_r4ktimer(0);
+}
+
+/* 
+ * Figure out the r4k offset, the amount to increment the compare
+ * register for each time tick. 
+ * Use the Programmable Counter 1 to do this.
+ */
+unsigned long cal_r4koff(void)
+{
+	unsigned long count;
+	unsigned long cpu_pll;
+	unsigned long cpu_speed;
+	unsigned long start, end;
+	unsigned long counter;
+	int i;
+	int trim_divide = 16;
+
+	counter = inl(PC_COUNTER_CNTRL);
+	outl(counter | PC_CNTRL_EN1, PC_COUNTER_CNTRL);
+
+	while (inl(PC_COUNTER_CNTRL) & PC_CNTRL_T1S);
+	outl(trim_divide-1, PC1_TRIM);    /* RTC now ticks at 32.768/16 kHz */
+	while (inl(PC_COUNTER_CNTRL) & PC_CNTRL_T1S);
+
+	while (inl(PC_COUNTER_CNTRL) & PC_CNTRL_C1S);
+	outl (0, PC1_COUNTER_WRITE);
+	while (inl(PC_COUNTER_CNTRL) & PC_CNTRL_C1S);
+
+	start = inl(PC1_COUNTER_READ);
+	start += 2;
+	/* wait for the beginning of a new tick */
+	while (inl(PC1_COUNTER_READ) < start);
+
+	/* Start r4k counter. */
+	write_32bit_cp0_register(CP0_COUNT, 0);
+	end = start + (32768 / trim_divide)/2; /* wait 0.5 seconds */
+
+	while (end > inl(PC1_COUNTER_READ));
+
+	count = read_32bit_cp0_register(CP0_COUNT);
+	cpu_speed = count * 2;
+	uart_baud_base = (((cpu_speed) / 4) / 16);
+	return (cpu_speed / HZ);
+}
+
+static unsigned long __init get_mips_time(void)
+{
+	return inl(PC0_COUNTER_READ);
+}
+
+void __init time_init(void)
+{
+        unsigned int est_freq, flags;
+
+	printk("calculating r4koff... ");
+	r4k_offset = cal_r4koff();
+	printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset);
+
+	//est_freq = 2*r4k_offset*HZ;	
+	est_freq = r4k_offset*HZ;	
+	est_freq += 5000;    /* round */
+	est_freq -= est_freq%10000;
+	printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, 
+	       (est_freq%1000000)*100/1000000);
+	r4k_cur = (read_32bit_cp0_register(CP0_COUNT) + r4k_offset);
+
+	write_32bit_cp0_register(CP0_COMPARE, r4k_cur);
+	set_cp0_status(ALLINTS);
+
+	/* Read time from the RTC chipset. */
+	write_lock_irqsave (&xtime_lock, flags);
+	xtime.tv_sec = get_mips_time();
+	xtime.tv_usec = 0;
+	write_unlock_irqrestore(&xtime_lock, flags);
+}
+
+/* This is for machines which generate the exact clock. */
+#define USECS_PER_JIFFY (1000000/HZ)
+#define USECS_PER_JIFFY_FRAC ((1000000ULL << 32) / HZ & 0xffffffff)
+
+/* Cycle counter value at the previous timer interrupt.. */
+
+static unsigned int timerhi = 0, timerlo = 0;
+
+static unsigned long
+div64_32(unsigned long v1, unsigned long v2, unsigned long v3)
+{
+	unsigned long r0;
+	do_div64_32(r0, v1, v2, v3);
+	return r0;
+}
+
+
+/*
+ * FIXME: Does playing with the RP bit in c0_status interfere with this code?
+ */
+static unsigned long do_fast_gettimeoffset(void)
+{
+	u32 count;
+	unsigned long res, tmp;
+	unsigned long r0;
+
+	/* Last jiffy when do_fast_gettimeoffset() was called. */
+	static unsigned long last_jiffies=0;
+	unsigned long quotient;
+
+	/*
+	 * Cached "1/(clocks per usec)*2^32" value.
+	 * It has to be recalculated once each jiffy.
+	 */
+	static unsigned long cached_quotient=0;
+
+	tmp = jiffies;
+
+	quotient = cached_quotient;
+
+	if (tmp && last_jiffies != tmp) {
+		last_jiffies = tmp;
+		if (last_jiffies != 0) {
+			r0 = div64_32(timerhi, timerlo, tmp);
+			quotient = div64_32(USECS_PER_JIFFY, USECS_PER_JIFFY_FRAC, r0);
+			cached_quotient = quotient;
+		}
+	}
+
+	/* Get last timer tick in absolute kernel time */
+	count = read_32bit_cp0_register(CP0_COUNT);
+
+	/* .. relative to previous jiffy (32 bits is enough) */
+	count -= timerlo;
+
+	__asm__("multu\t%1,%2\n\t"
+		"mfhi\t%0"
+		:"=r" (res)
+		:"r" (count),
+		 "r" (quotient));
+
+	/*
+ 	 * Due to possible jiffies inconsistencies, we need to check 
+	 * the result so that we'll get a timer that is monotonic.
+	 */
+	if (res >= USECS_PER_JIFFY)
+		res = USECS_PER_JIFFY-1;
+
+	return res;
+}
+
+void do_gettimeofday(struct timeval *tv)
+{
+	unsigned int flags;
+
+	read_lock_irqsave (&xtime_lock, flags);
+	*tv = xtime;
+	tv->tv_usec += do_fast_gettimeoffset();
+
+	/*
+	 * xtime is atomically updated in timer_bh. jiffies - wall_jiffies
+	 * is nonzero if the timer bottom half hasnt executed yet.
+	 */
+	if (jiffies - wall_jiffies)
+		tv->tv_usec += USECS_PER_JIFFY;
+
+	read_unlock_irqrestore (&xtime_lock, flags);
+
+	if (tv->tv_usec >= 1000000) {
+		tv->tv_usec -= 1000000;
+		tv->tv_sec++;
+	}
+}
+
+void do_settimeofday(struct timeval *tv)
+{
+	write_lock_irq (&xtime_lock);
+
+	/* This is revolting. We need to set the xtime.tv_usec correctly.
+	 * However, the value in this location is is value at the last tick.
+	 * Discover what correction gettimeofday would have done, and then
+	 * undo it!
+	 */
+	tv->tv_usec -= do_fast_gettimeoffset();
+
+	if (tv->tv_usec < 0) {
+		tv->tv_usec += 1000000;
+		tv->tv_sec--;
+	}
+
+	xtime = *tv;
+	time_adjust = 0;		/* stop active adjtime() */
+	time_status |= STA_UNSYNC;
+	time_maxerror = NTP_PHASE_LIMIT;
+	time_esterror = NTP_PHASE_LIMIT;
+
+	write_unlock_irq (&xtime_lock);
+}
+
+/*
+ * The UART baud base is not known at compile time ... if
+ * we want to be able to use the same code on different
+ * speed CPUs.
+ */
+unsigned long get_au1000_uart_baud()
+{
+	return uart_baud_base;
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips/au1000/pb1000/Makefile linux/arch/mips/au1000/pb1000/Makefile
--- v2.4.9/linux/arch/mips/au1000/pb1000/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/au1000/pb1000/Makefile	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,24 @@
+#
+#  Copyright 2000 MontaVista Software Inc.
+#  Author: MontaVista Software, Inc.
+#     	ppopov@mvista.com or source@mvista.com
+#
+# Makefile for the Alchemy Semiconductor PB1000 board.
+#
+# 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.s:
+	$(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+	$(CC) $(CFLAGS) -c $< -o $*.o
+
+all: pb1000.o
+
+O_TARGET := pb1000.o
+
+obj-y := init.o setup.o
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.9/linux/arch/mips/au1000/pb1000/init.c linux/arch/mips/au1000/pb1000/init.c
--- v2.4.9/linux/arch/mips/au1000/pb1000/init.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/au1000/pb1000/init.c	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,59 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	PB1000 board setup
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ *  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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <linux/config.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+extern int prom_argc;
+extern char **prom_argv, **prom_envp;
+extern void  __init prom_init_cmdline(void);
+
+int __init prom_init(int argc, char **argv, char **envp, int *prom_vec)
+{
+	prom_argc = argc;
+	prom_argv = argv;
+	prom_envp = envp;
+
+	mips_machgroup = MACH_GROUP_ALCHEMY;
+	mips_machtype = MACH_PB1000;  
+
+	prom_init_cmdline();
+
+	add_memory_region(1, 64 << 20, BOOT_MEM_RAM);
+
+	return 0;
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips/au1000/pb1000/setup.c linux/arch/mips/au1000/pb1000/setup.c
--- v2.4.9/linux/arch/mips/au1000/pb1000/setup.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/au1000/pb1000/setup.c	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,117 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Au1000-based board setup.
+ *
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ *  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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/console.h>
+#include <linux/mc146818rtc.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+#include <asm/au1000.h>
+
+#if defined(CONFIG_AU1000_SERIAL_CONSOLE)
+extern void console_setup(char *, int *);
+char serial_console[20];
+#endif
+
+void (*__wbflush) (void);
+extern struct rtc_ops no_rtc_ops;
+extern char * __init prom_getcmdline(void);
+extern void au1000_restart(void);
+extern void au1000_halt(void);
+extern void au1000_power_off(void);
+
+struct {
+    struct resource ram;
+    struct resource io;
+    struct resource sram;
+    struct resource flash;
+    struct resource boot;
+    struct resource pcmcia;
+    struct resource lcd;
+} au1000_resources = {
+    { "RAM",           0,          0x3FFFFFF,  IORESOURCE_MEM },
+    { "I/O",           0x10000000, 0x119FFFFF                 },
+    { "SRAM",          0x1e000000, 0x1E03FFFF                 },
+    { "System Flash",  0x1F800000, 0x1FBFFFFF                 },
+    { "Boot ROM",      0x1FC00000, 0x1FFFFFFF                 },
+    { "PCMCIA",        0x20000000, 0x27FFFFFF                 },
+    { "LCD",           0x60000000, 0x603FFFFF                 },
+};
+
+void au1000_wbflush(void)
+{
+	__asm__ volatile ("sync");
+}
+
+void __init au1000_setup(void)
+{
+	char *argptr;
+
+	argptr = prom_getcmdline();
+
+#ifdef CONFIG_AU1000_SERIAL_CONSOLE
+	if ((argptr = strstr(argptr, "console=ttyS0")) == NULL) {
+		argptr = prom_getcmdline();
+		strcat(argptr, " console=ttyS0,115200");
+	}
+#endif	  
+
+	//set_cp0_status(ST0_FR,0);
+	rtc_ops = &no_rtc_ops;
+        __wbflush = au1000_wbflush;
+	_machine_restart = au1000_restart;
+	_machine_halt = au1000_halt;
+	_machine_power_off = au1000_power_off;
+
+	/*
+	 * IO/MEM resources. 
+	 */
+	mips_io_port_base = KSEG1;
+	ioport_resource.start = au1000_resources.io.start;
+	ioport_resource.end = au1000_resources.lcd.end;
+
+#ifdef CONFIG_BLK_DEV_INITRD
+	ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+#endif
+
+	outl(PC_CNTRL_E0 | PC_CNTRL_EN0 | PC_CNTRL_EN0, PC_COUNTER_CNTRL);
+	while (inl(PC_COUNTER_CNTRL) & PC_CNTRL_T0S);
+	outl(0x8000-1, PC0_TRIM);
+
+	printk("Alchemy Semi PB1000 Board\n");
+	printk("Au1000/PB1000 port (C) 2001 MontaVista Software, Inc. (source@mvista.com)\n");
+}
+
diff -u --recursive --new-file v2.4.9/linux/arch/mips/baget/irq.c linux/arch/mips/baget/irq.c
--- v2.4.9/linux/arch/mips/baget/irq.c	Tue Mar  6 19:44:36 2001
+++ linux/arch/mips/baget/irq.c	Sun Sep  9 10:43:01 2001
@@ -4,8 +4,6 @@
  * Copyright (C) 1998 Vladimir Roganov & Gleb Raiko
  *      Code (mostly sleleton and comments) derived from DECstation IRQ
  *      handling.
- *
- * $Id: irq.c,v 1.6 2000/02/04 07:40:23 ralf Exp $
  */
 #include <linux/errno.h>
 #include <linux/init.h>
@@ -180,7 +178,7 @@
 	int do_random, cpu;
 
 	cpu = smp_processor_id();
-	irq_enter(cpu);
+	irq_enter(cpu, irq);
 	kstat.irqs[cpu][irq]++;
 
 	mask_irq(irq);  
@@ -202,7 +200,7 @@
 		printk("do_IRQ: Unregistered IRQ (0x%X) occurred\n", irq);
 	}
 	unmask_irq(irq);
-	irq_exit(cpu);
+	irq_exit(cpu, irq);
 
 	/* unmasking and bottom half handling is done magically for us. */
 }
@@ -358,13 +356,6 @@
 	}
 	printk("Trying to free free IRQ%d\n",irq);
 }
-
-static int baget_irq_canonicalize(int irq) 
-{
-	return irq;
-}
-
-int (*irq_cannonicalize)(int irq) = baget_irq_canonicalize; 
 
 unsigned long probe_irq_on (void)
 {
diff -u --recursive --new-file v2.4.9/linux/arch/mips/baget/prom/init.c linux/arch/mips/baget/prom/init.c
--- v2.4.9/linux/arch/mips/baget/prom/init.c	Mon Feb 28 07:18:20 2000
+++ linux/arch/mips/baget/prom/init.c	Sun Sep  9 10:43:01 2001
@@ -2,25 +2,24 @@
  * init.c: PROM library initialisation code.
  *
  * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov 
- *
- * $Id: init.c,v 1.3 1999/10/09 00:00:57 ralf Exp $
  */
 #include <linux/init.h>
+#include <asm/addrspace.h>
 #include <asm/bootinfo.h>
 
-char arcs_cmdline[CL_SIZE];
+char arcs_cmdline[COMMAND_LINE_SIZE];
 
-int __init prom_init(unsigned int mem_upper)
+void __init prom_init(unsigned int mem_upper)
 {
-	mips_memory_upper = mem_upper;
+	mem_upper = PHYSADDR(mem_upper);
+
 	mips_machgroup  = MACH_GROUP_UNKNOWN;
 	mips_machtype   = MACH_UNKNOWN;
 	arcs_cmdline[0] = 0;
-	return 0;
-}
 
-void __init prom_fixup_mem_map(unsigned long start, unsigned long end)
-{
+	vac_memory_upper = mem_upper;
+
+	add_memory_region(0, mem_upper, BOOT_MEM_RAM);
 }
 
 void prom_free_prom_memory (void)
diff -u --recursive --new-file v2.4.9/linux/arch/mips/baget/setup.c linux/arch/mips/baget/setup.c
--- v2.4.9/linux/arch/mips/baget/setup.c	Mon Feb 28 07:18:20 2000
+++ linux/arch/mips/baget/setup.c	Sun Sep  9 10:43:01 2001
@@ -14,7 +14,7 @@
 
 #include <asm/baget/baget.h>
 
-extern long mips_memory_upper;
+long int vac_memory_upper;
 
 #define CACHEABLE_STR(val) ((val) ? "not cached" : "cached")
 #define MIN(a,b)           (((a)<(b)) ? (a):(b)) 
@@ -172,7 +172,7 @@
 
 static void __init vac_init(void)
 {
-	unsigned short mem_limit = ((mips_memory_upper-KSEG0) >> 16);
+	unsigned short mem_limit = (vac_memory_upper >> 16);
 
 	switch(vac_inw(VAC_ID)) {
 	case 0x1AC0:
diff -u --recursive --new-file v2.4.9/linux/arch/mips/baget/time.c linux/arch/mips/baget/time.c
--- v2.4.9/linux/arch/mips/baget/time.c	Sat May 13 08:29:14 2000
+++ linux/arch/mips/baget/time.c	Sun Sep  9 10:43:01 2001
@@ -1,4 +1,4 @@
-/* $Id: time.c,v 1.3 1999/08/17 22:18:37 ralf Exp $
+/*
  * time.c: Baget/MIPS specific time handling details
  *
  * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
@@ -13,7 +13,7 @@
 #include <linux/mm.h>
 #include <linux/interrupt.h>
 #include <linux/timex.h>
-#include <linux/kernel_stat.h>
+#include <linux/spinlock.h>
 
 #include <asm/bootinfo.h>
 #include <asm/io.h>
@@ -23,11 +23,14 @@
 
 #include <asm/baget/baget.h>
 
+extern rwlock_t xtime_lock;
+
 /* 
  *  To have precision clock, we need to fix available clock frequency
  */
 #define FREQ_NOM  79125  /* Baget frequency ratio */
 #define FREQ_DEN  10000
+
 static inline int timer_intr_valid(void) 
 {
 	static unsigned long long ticks, valid_ticks;
@@ -47,8 +50,8 @@
 void static timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 {
 	if (timer_intr_valid()) {
-	sti();
-	do_timer(regs);
+		sti();
+		do_timer(regs);
 	}
 }
 
@@ -76,21 +79,20 @@
 
 void do_gettimeofday(struct timeval *tv)
 {
-        unsigned long flags;
+	unsigned long flags;
 
-        save_and_cli(flags);
-        *tv = xtime;
-        restore_flags(flags);
+	read_lock_irqsave (&xtime_lock, flags);
+	*tv = xtime;
+	read_unlock_irqrestore (&xtime_lock, flags);
 }
 
 void do_settimeofday(struct timeval *tv)
 {
-        unsigned long flags;
-  
-        save_and_cli(flags);
-        xtime = *tv;
-        time_state = TIME_BAD;
-        time_maxerror = MAXPHASE;
-        time_esterror = MAXPHASE;
-        restore_flags(flags);
-} 
+	write_lock_irq (&xtime_lock);
+	xtime = *tv;
+	time_adjust = 0;		/* stop active adjtime() */
+	time_status |= STA_UNSYNC;
+	time_maxerror = NTP_PHASE_LIMIT;
+	time_esterror = NTP_PHASE_LIMIT;
+	write_unlock_irq (&xtime_lock);
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips/baget/vacserial.c linux/arch/mips/baget/vacserial.c
--- v2.4.9/linux/arch/mips/baget/vacserial.c	Fri Feb  9 11:29:44 2001
+++ linux/arch/mips/baget/vacserial.c	Sun Sep  9 10:43:01 2001
@@ -1,4 +1,4 @@
-/* $Id: vacserial.c,v 1.3 1999/08/17 22:18:37 ralf Exp $
+/*
  * vacserial.c: VAC UART serial driver
  *              This code stealed and adopted from linux/drivers/char/serial.c
  *              See that for author info
@@ -1300,7 +1300,7 @@
 		goto check_and_exit;
 	}
 
-	new_serial.irq = irq_cannonicalize(new_serial.irq);
+	new_serial.irq = new_serial.irq;
 
 	if ((new_serial.irq >= NR_IRQS) || (new_serial.port > 0xffff) ||
 	    (new_serial.baud_base == 0) || (new_serial.type < PORT_UNKNOWN) ||
@@ -1417,12 +1417,10 @@
 static int set_modem_info(struct async_struct * info, unsigned int cmd,
 			  unsigned int *value)
 {
-	int error;
 	unsigned int arg;
 
-	error = get_user(arg, value);
-	if (error)
-		return error;
+	if (get_user(arg, value))
+		return -EFAULT;
 	switch (cmd) {
 	default:
 		return -EINVAL;
@@ -2426,7 +2424,7 @@
 		state->icount.rx = state->icount.tx = 0;
 		state->icount.frame = state->icount.parity = 0;
 		state->icount.overrun = state->icount.brk = 0;
-		state->irq = irq_cannonicalize(state->irq);
+		state->irq = state->irq;
 		if (check_region(state->port,8))
 			continue;
 	        if (state->flags & ASYNC_BOOT_AUTOCONF)
diff -u --recursive --new-file v2.4.9/linux/arch/mips/boot/Makefile linux/arch/mips/boot/Makefile
--- v2.4.9/linux/arch/mips/boot/Makefile	Sun Jul  9 22:18:15 2000
+++ linux/arch/mips/boot/Makefile	Sun Sep  9 10:43:01 2001
@@ -1,10 +1,9 @@
-# $Id: Makefile,v 1.9 1999/04/07 18:45:23 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
 # for more details.
 #
-# Copyright (C) 1995, 1998 by Ralf Baechle
+# Copyright (C) 1995, 1998, 2001 by Ralf Baechle
 #
 
 .S.s:
@@ -46,25 +45,12 @@
 
 clean:
 	rm -f vmlinux.ecoff
-	rm -f zImage zImage.tmp mkboot
+	rm -f zImage zImage.tmp
 
 mrproper:
 	rm -f vmlinux.ecoff
 	rm -f addinitrd
 	rm -f elf2ecoff
-
-zImage:	$(CONFIGURE) mkboot $(TOPDIR)/vmlinux
-	$(OBJCOPY) $(strip-flags) $(TOPDIR)/vmlinux zImage.tmp
-	./mkboot zImage.tmp zImage
-	rm -f zImage.tmp
-
-mkboot: mkboot.c
-	$(HOSTCC) -o $@ $^
-
-zdisk: 	zImage
-	cp $(TOPDIR)/vmlinux $(TOPDIR)/vm
-	$(STRIP) $(TOPDIR)/vm
-	gzip -9f $(TOPDIR)/vm
 
 dummy:
 
diff -u --recursive --new-file v2.4.9/linux/arch/mips/boot/mkboot.c linux/arch/mips/boot/mkboot.c
--- v2.4.9/linux/arch/mips/boot/mkboot.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/mips/boot/mkboot.c	Wed Dec 31 16:00:00 1969
@@ -1,658 +0,0 @@
-/*
- * Make a bootable image from a Linux/MIPS kernel.
- *
- * This file 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, 2001 by Ralf Baechle
- *
- * This file is written in plain Kernighan & Ritchie C as it has to run
- * on all crosscompile hosts no matter how braindead.  This code might
- * also become part of Milo.  It's therefore important that we don't use
- * seek because the Seek() call of the Magnum 4000 ARC BIOS is broken.
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-/*
- * Define this for verbose debugging output.
- */
-#undef VERBOSE
-
-/*
- * Don't use the host's elf.h - it might be using incompatible defines
- */
-
-#define EI_NIDENT 16
-
-/*
- * Basic ELF types.
- */
-typedef unsigned short Elf32_Half;
-typedef unsigned short Elf32_Section;
-typedef unsigned int Elf32_Word;
-typedef unsigned int Elf32_Addr;
-typedef unsigned int Elf32_Off;
-
-typedef struct
-{
-  unsigned char e_ident[EI_NIDENT];     /* Magic number and other info */
-  Elf32_Half    e_type;                 /* Object file type */
-  Elf32_Half    e_machine;              /* Architecture */
-  Elf32_Word    e_version;              /* Object file version */
-  Elf32_Addr    e_entry;                /* Entry point virtual address */
-  Elf32_Off     e_phoff;                /* Program header table file offset */
-  Elf32_Off     e_shoff;                /* Section header table file offset */
-  Elf32_Word    e_flags;                /* Processor-specific flags */
-  Elf32_Half    e_ehsize;               /* ELF header size in bytes */
-  Elf32_Half    e_phentsize;            /* Program header table entry size */
-  Elf32_Half    e_phnum;                /* Program header table entry count */
-  Elf32_Half    e_shentsize;            /* Section header table entry size */
-  Elf32_Half    e_shnum;                /* Section header table entry count */
-  Elf32_Half    e_shstrndx;             /* Section header string table index */
-} Elf32_Ehdr;
-
-/*
- * ELF magic number
- */
-#define ELFMAG          "\177ELF"
-#define SELFMAG         4
-
-#define EI_CLASS        4               /* File class byte index */
-#define ELFCLASSNONE    0               /* Invalid class */
-#define ELFCLASS32      1               /* 32-bit objects */
-#define ELFCLASS64      2               /* 64-bit objects */
-
-#define EI_DATA         5               /* Data encoding byte index */
-#define ELFDATA2LSB     1               /* 2's complement, little endian */
-#define ELFDATA2MSB     2               /* 2's complement, big endian */
-
-#define EI_VERSION      6               /* File version byte index */
-#define EV_CURRENT      1               /* Current version */
-
-/*
- * Acceptable machine type in e_machine.
- */
-#define EM_MIPS         8               /* MIPS R3000 big-endian */
-
-/*
- * The type of ELF file we accept.
- */
-#define ET_EXEC         2               /* Executable file */
-
-/*
- * Definition of a single program header structure
- */
-typedef struct
-{
-  Elf32_Word    p_type;                 /* Segment type */
-  Elf32_Off     p_offset;               /* Segment file offset */
-  Elf32_Addr    p_vaddr;                /* Segment virtual address */
-  Elf32_Addr    p_paddr;                /* Segment physical address */
-  Elf32_Word    p_filesz;               /* Segment size in file */
-  Elf32_Word    p_memsz;                /* Segment size in memory */
-  Elf32_Word    p_flags;                /* Segment flags */
-  Elf32_Word    p_align;                /* Segment alignment */
-} Elf32_Phdr;
-
-/*
- * Legal values for p_type
- */
-#define PT_NULL         0               /* Program header table entry unused */
-#define PT_LOAD         1               /* Loadable program segment */
-#define PT_DYNAMIC      2               /* Dynamic linking information */
-#define PT_INTERP       3               /* Program interpreter */
-#define PT_NOTE         4               /* Auxiliary information */
-#define PT_SHLIB        5               /* Reserved */
-#define PT_PHDR         6               /* Entry for header table itself */
-#define PT_NUM          7               /* Number of defined types.  */
-#define PT_LOPROC       0x70000000      /* Start of processor-specific */
-#define PT_HIPROC       0x7fffffff      /* End of processor-specific */
-
-typedef struct
-{
-  Elf32_Word    sh_name;                /* Section name (string tbl index) */
-  Elf32_Word    sh_type;                /* Section type */
-  Elf32_Word    sh_flags;               /* Section flags */
-  Elf32_Addr    sh_addr;                /* Section virtual addr at execution */
-  Elf32_Off     sh_offset;              /* Section file offset */
-  Elf32_Word    sh_size;                /* Section size in bytes */
-  Elf32_Word    sh_link;                /* Link to another section */
-  Elf32_Word    sh_info;                /* Additional section information */
-  Elf32_Word    sh_addralign;           /* Section alignment */
-  Elf32_Word    sh_entsize;             /* Entry size if section holds table */
-} Elf32_Shdr;
-
-typedef struct
-{
-  Elf32_Word    st_name;                /* Symbol name (string tbl index) */
-  Elf32_Addr    st_value;               /* Symbol value */
-  Elf32_Word    st_size;                /* Symbol size */
-  unsigned char st_info;                /* Symbol type and binding */
-  unsigned char st_other;               /* No defined meaning, 0 */
-  Elf32_Section st_shndx;               /* Section index */
-} Elf32_Sym;
-
-/* How to extract and insert information held in the st_info field.  */
-#define ELF32_ST_BIND(val)              (((unsigned char) (val)) >> 4)
-#define ELF32_ST_TYPE(val)              ((val) & 0xf)
-
-/* Legal values for ST_BIND subfield of st_info (symbol binding).  */
-#define STB_GLOBAL      1               /* Global symbol */
-
-/* Legal values for ST_TYPE subfield of st_info (symbol type).  */
-#define STT_NOTYPE      0               /* Symbol type is unspecified */
-#define STT_OBJECT      1               /* Symbol is a data object */
-#define STT_FUNC        2               /* Symbol is a code object */
-
-static unsigned int
-get_Elf32_Half(unsigned char *p)
-{
-	return p[0] | (p[1] << 8);
-}
-#define get_Elf32_Section(p) get_Elf32_Half(p)
-
-static unsigned int
-get_Elf32_Word(unsigned char *p)
-{
-	return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
-}
-#define get_Elf32_Addr(p) get_Elf32_Word(p)
-#define get_Elf32_Off(p) get_Elf32_Word(p)
-
-static void
-put_byte(p, x)
-	unsigned char *p;
-	unsigned char x;
-{
-	p[0] = x;
-}
-
-static void
-put_half(p, x)
-	unsigned char *p;
-	unsigned short x;
-{
-	p[0] = x & 0xff;
-	p[1] = (x >> 8) & 0xff;
-}
-
-static void
-put_word(p, x)
-	unsigned char *p;
-	unsigned long x;
-{
-	p[0] = x & 0xff;
-	p[1] = (x >> 8) & 0xff;
-	p[2] = (x >> 16) & 0xff;
-	p[3] = (x >> 24) & 0xff;
-}
-
-/*
- * Swap a program header in.
- */
-static void
-get_elfph(p, ph)
-	unsigned char *p;
-	Elf32_Phdr *ph;
-{
-	ph->p_type   = get_Elf32_Word(p);
-	ph->p_offset = get_Elf32_Off(p + 4);
-	ph->p_vaddr  = get_Elf32_Addr(p + 8);
-	ph->p_paddr  = get_Elf32_Addr(p + 12);
-	ph->p_filesz = get_Elf32_Word(p + 16);
-	ph->p_memsz  = get_Elf32_Word(p + 20);
-	ph->p_flags  = get_Elf32_Word(p + 24);
-	ph->p_align  = get_Elf32_Word(p + 28);
-}
-
-/*
- * Swap a section header in.
- */
-static void
-get_elfsh(p, sh)
-	unsigned char *p;
-	Elf32_Shdr *sh;
-{
-	sh->sh_name      = get_Elf32_Word(p);
-	sh->sh_type      = get_Elf32_Word(p + 4);
-	sh->sh_flags     = get_Elf32_Word(p + 8);
-	sh->sh_addr      = get_Elf32_Addr(p + 12);
-	sh->sh_offset    = get_Elf32_Off(p + 16);
-	sh->sh_size      = get_Elf32_Word(p + 20);
-	sh->sh_link      = get_Elf32_Word(p + 24);
-	sh->sh_info      = get_Elf32_Word(p + 28);
-	sh->sh_addralign = get_Elf32_Word(p + 32);
-	sh->sh_entsize   = get_Elf32_Word(p + 36);
-}
-
-/*
- * Swap a section header in.
- */
-static void
-get_elfsym(p, sym)
-	unsigned char *p;
-	Elf32_Sym *sym;
-{
-	sym->st_name      = get_Elf32_Word(p);
-	sym->st_value     = get_Elf32_Addr(p + 4);
-	sym->st_size      = get_Elf32_Word(p + 8);
-	sym->st_info      = *(p + 12);
-	sym->st_other     = *(p + 13);
-	sym->st_shndx     = get_Elf32_Section(p + 14);
-}
-
-/*
- * The a.out magic number
- */
-#define OMAGIC 0407	/* Code indicating object file or impure executable. */
-#define M_MIPS1 151	/* MIPS R3000/R3000 binary */
-#define M_MIPS2 152	/* MIPS R6000/R4000 binary */
-
-/*
- * Compute and return an a.out magic number.
- */
-#define AOUT_INFO(magic, type, flags) \
-        (((magic) & 0xffff) | \
-         (((int)(type) & 0xff) << 16) | \
-         (((flags) & 0xff) << 24))
-
-/*
- * a.out symbols
- */
-#define N_UNDF 0
-#define N_ABS 2
-#define N_TEXT 4
-#define N_DATA 6
-#define N_BSS 8
-#define N_FN 15
-#define N_EXT 1
-
-#define min(x,y) (((x)<(y))?(x):(y))
-
-static void
-do_read(fd, buf, size)
-	int fd;
-	char *buf;
-	ssize_t size;
-{
-	ssize_t rd;
-
-	while(size != 0) {
-		rd = read(fd, buf, size);
-		if (rd == -1) {
-			perror("Can't read from file.");
-			exit(1);
-		}
-		size -= rd;
-	}
-}
-
-static void
-writepad(fd, size)
-	int fd;
-	size_t size;
-{
-	static void *zeropage = NULL;
-	ssize_t written;
-
-	if (zeropage == NULL) {
-		zeropage = malloc(4096);
-		if (zeropage == NULL) {
-			fprintf(stderr, "Couldn't allocate zero buffer.\n");
-			exit(1);
-		}
-		memset(zeropage, '\0', 4096);
-	}
-	while(size != 0) {
-		written = write(fd, zeropage, min(4096, size));
-		if (written == -1) {
-			perror("Can't write to boot image");
-			exit(1);
-		}
-		size -= written;
-	}
-}
-
-static void
-do_write(fd, buf, size)
-	int fd;
-	char *buf;
-	ssize_t size;
-{
-	ssize_t written;
-
-	while(size != 0) {
-		written = write(fd, buf, size);
-		if (written == -1) {
-			perror("Can't write to boot image");
-			exit(1);
-		}
-		size -= written;
-	}
-}
-
-static int
-usage(program_name)
-	char *program_name;
-{
-	fprintf(stderr, "Usage: %s infile outfile\n", program_name);
-	exit(0);
-}
-
-int
-main(argc, argv)
-	int argc;
-	char *argv[];
-{
-	char *infile, *outfile;
-	struct stat ifstat;
-	off_t ifsize;
-	char *image;
-	int ifd, ofd, i, symtabix, strtabix;
-	Elf32_Ehdr eh;
-	Elf32_Phdr *ph;
-	Elf32_Shdr *sh;
-	unsigned long vaddr, entry, bss, kernel_entry, kernel_end;
-	unsigned char ahdr[32];
-	Elf32_Sym sym;
-	int	symnum;
-	char *symname;
-
-	/*
-	 * Verify some basic assuptions about type sizes made in this code
-	 */
-	if (sizeof(Elf32_Half) != 2) {
-		fprintf(stderr, "Fix mkboot: sizeof(Elf32_Half) != 2\n");
-		exit(1);
-	}
-	if (sizeof(Elf32_Word) != 4) {
-		fprintf(stderr, "Fix mkboot: sizeof(Elf32_Word) != 4\n");
-		exit(1);
-	}
-	if (sizeof(Elf32_Addr) != 4) {
-		fprintf(stderr, "Fix mkboot: sizeof(Elf32_Addr) != 4\n");
-		exit(1);
-	}
-
-	if (argc != 3)
-		usage(argv[0]);
-
-	infile = argv[1];
-	outfile = argv[2];
-
-	if (stat(infile, &ifstat) < 0) {
-		perror("Can't stat kernel image.");
-		exit(1);
-	}
-
-	if (!S_ISREG(ifstat.st_mode)) {
-		fprintf(stderr, "Input file isn't a regular file.\n");
-		exit(1);
-	}
-	ifsize = ifstat.st_size;
-
-	image = malloc((size_t)ifsize);
-	if (image == NULL) {
-		fprintf(stderr, "Can't allocate memory to read file\n");
-		exit(1);
-	}
-
-	/*
-	 * Read the entire input file in.
-	 */
-	ifd = open(infile, O_RDONLY);
-	if(ifd == 0) {
-		fprintf(stderr, "Can't open input file\n");
-		exit(1);
-	}
-	do_read(ifd, image, ifsize);
-	close(ifd);
-
-	/*
-	 * Now swap the ELF header in.  This is ugly but we the file
-	 * we're reading might have different type sizes, byteorder
-	 * or alignment than the host.
-	 */
-	memcpy(eh.e_ident, (void *)image, sizeof(eh.e_ident));
-	if(memcmp(eh.e_ident, ELFMAG, SELFMAG)) {
-		fprintf(stderr, "Input file isn't a ELF file\n");
-		exit(1);
-	}
-	if(eh.e_ident[EI_CLASS] != ELFCLASS32) {
-		fprintf(stderr, "Input file isn't a 32 bit ELF file\n");
-		exit(1);
-	}
-	if(eh.e_ident[EI_DATA] != ELFDATA2LSB) {
-		fprintf(stderr, "Input file isn't a little endian ELF file\n");
-		exit(1);
-	}
-	if(eh.e_ident[EI_VERSION] != EV_CURRENT) {
-		fprintf(stderr, "Input file isn't a version %d ELF file\n",
-		        EV_CURRENT);
-		exit(1);
-	}
-
-	/*
-	 * Ok, so far the file looks ok.  Now swap the rest of the header in
-	 * and do some more paranoia checks.
-	 */
-	eh.e_type      = get_Elf32_Half(image + 16);
-	eh.e_machine   = get_Elf32_Half(image + 18);
-	eh.e_version   = get_Elf32_Word(image + 20);
-	eh.e_entry     = get_Elf32_Addr(image + 24);
-	eh.e_phoff     = get_Elf32_Off(image + 28);
-	eh.e_shoff     = get_Elf32_Off(image + 32);
-	eh.e_flags     = get_Elf32_Word(image + 36);
-	eh.e_ehsize    = get_Elf32_Half(image + 40);
-	eh.e_phentsize = get_Elf32_Half(image + 42);
-	eh.e_phnum     = get_Elf32_Half(image + 44);
-	eh.e_shentsize = get_Elf32_Half(image + 46);
-	eh.e_shnum     = get_Elf32_Half(image + 48);
-	eh.e_shstrndx  = get_Elf32_Half(image + 50);
-
-	if(eh.e_type != ET_EXEC) {
-		fprintf(stderr, "Input file isn't a executable.\n");
-		exit(1);
-	}
-	if(eh.e_machine != EM_MIPS) {
-		fprintf(stderr, "Input file isn't a MIPS executable.\n");
-		exit(1);
-	}
-
-	/*
-	 * Now read the program headers ...
-	 */
-	ph = malloc(sizeof(Elf32_Phdr) * eh.e_phnum);
-	if (ph == NULL) {
-		fprintf(stderr, "No memory for program header table.\n");
-		exit(1);
-	}
-	for(i = 0;i < eh.e_phnum; i++)
-		get_elfph((void *)(image + eh.e_phoff + i * 32), ph + i);
-
-	/*
-	 * ... and then the section headers.
-	 */
-	sh = malloc(sizeof(Elf32_Shdr) * eh.e_shnum);
-	if (sh == NULL) {
-		fprintf(stderr, "No memory for section header table.\n");
-		exit(1);
-	}
-	for(i = 0;i < eh.e_shnum; i++)
-		get_elfsh((void *)(image + eh.e_shoff + (i * 40)), sh + i);
-
-	/*
-	 * Find the symboltable and the stringtable in the file.
-	 */
-	for(i = 0;i < eh.e_shnum; i++) {
-		if (!strcmp (image + sh [eh.e_shstrndx].sh_offset + sh[i].sh_name,
-		             ".symtab")) {
-			symtabix = i;
-			continue;
-		}
-		if (!strcmp (image + sh [eh.e_shstrndx].sh_offset + sh[i].sh_name,
-		             ".strtab")) {
-			strtabix = i;
-			continue;
-		}
-	}
-
-	if (symtabix == -1) {
-		fprintf(stderr, "The executable doesn't have a symbol table\n");
-		exit(1);
-	}
-	if (strtabix == -1) {
-		fprintf(stderr, "The executable doesn't have a string table\n");
-		exit(1);
-	}
-
-	/*
-	 * Dig for the two required symbols in the symbol table.
-	 */
-	symnum = sh[symtabix].sh_size / 16;
-	for(i = 0;i < symnum;i++) {
-		get_elfsym(image + sh[symtabix].sh_offset + (i * 16), &sym);
-		symname = image + sh[strtabix].sh_offset + sym.st_name;
-		if (ELF32_ST_BIND(sym.st_info) != STB_GLOBAL)
-			continue;
-		if (ELF32_ST_TYPE(sym.st_info) != STT_NOTYPE &&
-		    ELF32_ST_TYPE(sym.st_info) != STT_OBJECT &&
-		    ELF32_ST_TYPE(sym.st_info) != STT_FUNC)
-			continue;
-		if (strcmp("kernel_entry", symname) == 0) {
-			kernel_entry = sym.st_value;
-			continue;
-		}
-		if (strcmp("_end", symname) == 0) {
-			kernel_end = sym.st_value;
-			continue;
-		}
-	}
-
-#ifdef VERBOSE
-	/*
-	 * And print what we will be loaded into memory.
-	 */
-	for(i = 0;i < eh.e_phnum; i++) {
-		if (ph[i].p_type != PT_LOAD) {
-			continue;
-		}
-		printf("  Offset: %08lx\n", ph[i].p_offset);
-		printf("  file size: %08lx\n", ph[i].p_filesz);
-		printf("  mem size: %08lx\n", ph[i].p_memsz);
-		printf("    Loading: %08lx - %08lx\n",
-		       ph[i].p_vaddr, ph[i].p_vaddr + ph[i].p_filesz);
-		printf("    Zero mapping: %08lx - %08lx\n",
-		       ph[i].p_vaddr + ph[i].p_filesz,
-		       ph[i].p_vaddr + ph[i].p_memsz);
-	}
-#endif
-
-	/*
-	 * Time to open the outputfile.
-	 */
-	ofd = open(outfile, O_WRONLY|O_CREAT|O_TRUNC, 0666);
-	if (ofd == -1) {
-		perror("Can't open boot image for output.");
-		exit(1);
-	}
-
-	/*
-	 * First compute the layout of the file.  We need to do this
-	 * first because we can't seek back to the beginning due to the
-	 * broken Seek() call in the Magnum firmware.
-	 */
-	entry = vaddr = 0xffffffff;
-	bss = 0;
-	for(i = 0;i < eh.e_phnum; i++) {
-		if (ph[i].p_type != PT_LOAD)
-			continue;
-		if (vaddr == 0xffffffff)
-			entry = vaddr = ph[i].p_vaddr;
-		vaddr = ph[i].p_vaddr + ph[i].p_filesz;
-		bss = ph[i].p_memsz - ph[i].p_filesz;
-	}
-
-	/*
-	 * In the next step we construct the boot image.  The boot file
-	 * looks essentially like a dump of the loaded kernel with a
-	 * minimal header.  Because Milo supports already a.out image
-	 * we simply dump the image in an a.out image ...  First let's
-	 * write the header.
-	 */
-
-	/*
-	 * Create and write the a.out header.
-	 */
-	put_word(ahdr, AOUT_INFO(OMAGIC, M_MIPS1, 0));
-	put_word(ahdr + 4, vaddr - entry);	/* text size */
-	put_word(ahdr + 8, 0);			/* data size */
-	put_word(ahdr + 12, bss);		/* bss size */
-	put_word(ahdr + 16, 2 * 12);		/* size of symbol table */
-	put_word(ahdr + 20, entry);		/* base address */
-	put_word(ahdr + 24, 0);			/* size of text relocations */
-	put_word(ahdr + 28, 0);			/* size of data relocations */
-	do_write(ofd, ahdr, 32);
-
-	/*
-	 * Write text and data segment combined into the a.out text segment
-	 * and a zero length data segment into the file.
-	 */
-	vaddr = 0xffffffff;
-	bss = 0;
-	for(i = 0;i < eh.e_phnum; i++) {
-		if (ph[i].p_type != PT_LOAD)
-			continue;
-		if (vaddr == 0xffffffff)
-			vaddr = ph[i].p_vaddr;
-		writepad(ofd, ph[i].p_vaddr - vaddr);	/* Write zero pad */
-		do_write(ofd, image + ph[i].p_offset, ph[i].p_filesz);
-		vaddr = ph[i].p_vaddr + ph[i].p_filesz;
-		bss = ph[i].p_memsz - ph[i].p_filesz;
-	}
-
-	/*
-	 * Now write the symbol table.  It has only two symbols,
-	 * kernel_entry and _end which we need for booting.
-	 */
-	put_word(ahdr    , 4);			/* n_un.n_strx */
-	put_byte(ahdr + 4, N_TEXT | N_EXT);	/* n_type */
-	put_byte(ahdr + 5, 0);			/* n_other */
-	put_half(ahdr + 6, 0);			/* n_desc */
-	put_word(ahdr + 8, kernel_entry);	/* n_value */
-	do_write(ofd, ahdr, 12);
-
-	put_word(ahdr    , 4 + 13);		/* n_un.n_strx */
-	put_byte(ahdr + 4, N_ABS | N_EXT);	/* n_type */
-	put_byte(ahdr + 5, 0);			/* n_other */
-	put_half(ahdr + 6, 0);			/* n_desc */
-	put_word(ahdr + 8, kernel_end);		/* n_value */
-	do_write(ofd, ahdr, 12);
-
-	/*
-	 * Now write stringtable size and the strings.
-	 */
-	put_word(ahdr, 4 + 20);
-	do_write(ofd, ahdr, 4);
-	do_write(ofd, "kernel_entry\0_end\0\0", 20);
-
-	/*
-	 * That's is all ...
-	 */
-	close(ofd);
-
-#ifdef VERBOSE
-	printf("Entry: %08lx\n", entry);
-	printf("Dumped image %08lx - %08lx\n", 0x80000000, vaddr);
-	printf("Extra bss at end: %08lx\n", bss);
-#endif
-
-	return 0;
-}
diff -u --recursive --new-file v2.4.9/linux/arch/mips/config.in linux/arch/mips/config.in
--- v2.4.9/linux/arch/mips/config.in	Tue Jul  3 17:08:18 2001
+++ linux/arch/mips/config.in	Sun Sep  9 10:43:02 2001
@@ -76,6 +76,7 @@
 #
 unset CONFIG_ARC32
 unset CONFIG_BOARD_SCACHE
+unset CONFIG_COHERENT_IO
 unset CONFIG_HAVE_STD_PC_SERIAL_PORT
 unset CONFIG_I8259
 unset CONFIG_ISA
@@ -92,6 +93,8 @@
    define_bool CONFIG_PCI y
    define_bool CONFIG_MIPS_GT96100 y
    define_bool CONFIG_SWAP_IO_SPACE y
+   define_bool CONFIG_NEW_PCI y
+   define_bool CONFIG_PCI_AUTO y
 fi
 if [ "$CONFIG_MIPS_EV64120" = "y" ]; then
    define_bool CONFIG_PCI y
@@ -132,6 +135,7 @@
    define_bool CONFIG_I8259 y
    define_bool CONFIG_PCI y
    define_bool CONFIG_HAVE_STD_PC_SERIAL_PORT y
+   define_bool CONFIG_NEW_IRQ y
    define_bool CONFIG_SWAP_IO_SPACE y
 fi
 if [ "$CONFIG_MOMENCO_OCELOT" = "y" ]; then
@@ -158,7 +162,7 @@
    define_bool CONFIG_ROTTEN_IRQ y
    define_bool CONFIG_OLD_TIME_C y
 fi
-if [ "$CONFIG_DDB5074" = "y"]; then
+if [ "$CONFIG_DDB5074" = "y" ]; then
    define_bool CONFIG_I8259 y
    define_bool CONFIG_ISA y
    define_bool CONFIG_PCI y
@@ -168,7 +172,6 @@
    define_bool CONFIG_OLD_TIME_C y
 fi
 if [ "$CONFIG_DDB5476"  = "y" ]; then
-   define_bool CONFIG_I8259 y
    define_bool CONFIG_ISA y
    define_bool CONFIG_PCI y
    define_bool CONFIG_PC_KEYB y
@@ -186,6 +189,8 @@
    define_bool CONFIG_PCI y
    define_bool CONFIG_IT8712 y
    define_bool CONFIG_PC_KEYB y
+   define_bool CONFIG_NEW_PCI y
+   define_bool CONFIG_PCI_AUTO y
 fi
 if [ "$CONFIG_MIPS_IVR" = "y" ]; then
    define_bool CONFIG_PCI y
@@ -229,33 +234,45 @@
 choice 'CPU type' \
 	"R3000 CONFIG_CPU_R3000	\
 	 R6000 CONFIG_CPU_R6000	\
+	 R41xx CONFIG_CPU_VR41XX \
 	 R4300 CONFIG_CPU_R4300	\
 	 R4x00 CONFIG_CPU_R4X00	\
 	 R5000 CONFIG_CPU_R5000	\
-         R5432 CONFIG_CPU_R5432 \
+	 R5432 CONFIG_CPU_R5432 \
 	 RM7000 CONFIG_CPU_RM7000 \
 	 R52xx CONFIG_CPU_NEVADA \
 	 R10000 CONFIG_CPU_R10000 \
 	 SB1    CONFIG_CPU_SB1    \
-	 MIPS32 CONFIG_CPU_MIPS32" R4x00
+	 MIPS32 CONFIG_CPU_MIPS32 \
+	 MIPS64 CONFIG_CPU_MIPS64" R4x00
 
 bool 'Override CPU Options' CONFIG_CPU_ADVANCED
 
 if [ "$CONFIG_CPU_ADVANCED" = "y" ]; then
    bool '  ll/sc Instructions available' CONFIG_CPU_HAS_LLSC
+   bool '  lld/scd Instructions available' CONFIG_CPU_HAS_LLDSCD
    bool '  Writeback Buffer available' CONFIG_CPU_HAS_WB
 else
-   if [ "$CONFIG_CPU_R3000" = "y" ]; then
-      if [ "$CONFIG_DECSTATION" = "y" ]; then
+   if [ "$CONFIG_CPU_R3000" = "y" -o "$CONFIG_CPU_VR41XX" = "y" ]; then
+      if [ "CONFIG_DECSTATION" = "y" ]; then
 	 define_bool CONFIG_CPU_HAS_LLSC n
+	 define_bool CONFIG_CPU_HAS_LLDSCD n
 	 define_bool CONFIG_CPU_HAS_WB y
       else
 	 define_bool CONFIG_CPU_HAS_LLSC n
+	 define_bool CONFIG_CPU_HAS_LLDSCD n
 	 define_bool CONFIG_CPU_HAS_WB n
       fi
    else
+      if [ "$CONFIG_CPU_MIPS32" = "y" ]; then
+	 define_bool CONFIG_CPU_HAS_LLSC y
+	 define_bool CONFIG_CPU_HAS_LLDSCD n
+	 define_bool CONFIG_CPU_HAS_WB n
+      else
 	 define_bool CONFIG_CPU_HAS_LLSC y
+	 define_bool CONFIG_CPU_HAS_LLDSCD y
 	 define_bool CONFIG_CPU_HAS_WB n
+      fi
    fi
 fi
 endmenu
@@ -270,7 +287,6 @@
 else
    bool 'Generate little endian code' CONFIG_CPU_LITTLE_ENDIAN
 fi
-bool 'Kernel floating-point emulation' CONFIG_MIPS_FPU_EMULATOR
 
 if [ "$CONFIG_PROC_FS" = "y" ]; then
    define_bool CONFIG_KCORE_ELF y
@@ -361,7 +377,7 @@
 
 if [ "$CONFIG_DECSTATION" != "y" -a \
      "$CONFIG_SGI_IP22" != "y" ]; then
-   source drivers/message/i2o/Config.in
+   source drivers/i2o/Config.in
 fi
 
 if [ "$CONFIG_NET" = "y" ]; then
@@ -492,9 +508,6 @@
 comment 'Kernel hacking'
 
 bool 'Are you using a crosscompiler' CONFIG_CROSSCOMPILE
-if [ "$CONFIG_MODULES" = "y" ]; then
-   bool ' Build fp execption handler module' CONFIG_MIPS_FPE_MODULE
-fi
 if [ "$CONFIG_SERIAL" = "y" -o "$CONFIG_AU1000_UART" = "y" ]; then
   bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG
   dep_bool 'Console output to GDB' CONFIG_GDB_CONSOLE $CONFIG_REMOTE_DEBUG
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ddb5074/pci.c linux/arch/mips/ddb5074/pci.c
--- v2.4.9/linux/arch/mips/ddb5074/pci.c	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/ddb5074/pci.c	Sun Sep  9 10:43:01 2001
@@ -417,5 +417,9 @@
 	}
 }
 
+unsigned __init int pcibios_assign_all_busses(void)
+{
+	return 1;
+}
 
 struct pci_fixup pcibios_fixups[] = { };
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ddb5476/int-handler.S linux/arch/mips/ddb5476/int-handler.S
--- v2.4.9/linux/arch/mips/ddb5476/int-handler.S	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/ddb5476/int-handler.S	Sun Sep  9 10:43:01 2001
@@ -68,6 +68,8 @@
 	and	s0, s1, t2		# isolate allowed ones
 #endif
 	/* First we check for r4k counter/timer IRQ. */
+	andi	a0, s0, CAUSEF_IP7	# cpu timer */
+	bnez	a0, cpu_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
@@ -119,6 +121,15 @@
 	/* phamtom interrupt */
 	move 	a0, s1
 	jal	ddb_phantom_irq
+	nop
+	j	ret_from_irq
+	nop
+
+cpu_timer_irq:
+	li	a0, 0
+	move	a1, sp
+	jal	do_IRQ 
+	/* jal	ll_timer_interrupt */
 	nop
 	j	ret_from_irq
 	nop
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ddb5476/pci.c linux/arch/mips/ddb5476/pci.c
--- v2.4.9/linux/arch/mips/ddb5476/pci.c	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/ddb5476/pci.c	Sun Sep  9 10:43:01 2001
@@ -14,7 +14,6 @@
 
 #include <asm-mips/nile4.h>
 
-
 static u32 nile4_pre_pci_access0(int slot_num)
 {
 	u32 pci_addr = 0;
@@ -490,6 +489,11 @@
 		start = (start + 1024 - 1) & ~(1024 - 1);
 		res->start = start;
 	}
+}
+
+unsigned __init int pcibios_assign_all_busses(void)
+{
+	return 1;
 }
 
 struct pci_fixup pcibios_fixups[] = { {0} };
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ddb5476/setup.c linux/arch/mips/ddb5476/setup.c
--- v2.4.9/linux/arch/mips/ddb5476/setup.c	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/ddb5476/setup.c	Sun Sep  9 10:43:01 2001
@@ -24,6 +24,7 @@
 #include <asm/reboot.h>
 #include <asm/gdb-stub.h>
 #include <asm/nile4.h>
+#include <asm/time.h>
 
 
 #ifdef CONFIG_REMOTE_DEBUG
@@ -71,13 +72,27 @@
 
 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);
+	printk("ddb_time_init invoked.\n");
+	mips_counter_frequency = 83000000;
+}
+
+static void __init ddb_timer_setup(struct irqaction *irq)
+{
+	unsigned int count;
+
+	/* we are using the cpu counter for timer interrupts */
+	i8259_setup_irq(0, irq);
+	set_cp0_status(IE_IRQ5);
+
+	/* to generate the first timer interrupt */
+	count = read_32bit_cp0_register(CP0_COUNT);
+	write_32bit_cp0_register(CP0_COMPARE, count + 1000);
+
+#if 0		/* the old way to do timer interrupt */
+	/* set the clock to 100 Hz */
+	nile4_out32(NILE4_T2CTRL, 830000);
 	/* enable the General-Purpose Timer */
 	nile4_out32(NILE4_T2CTRL + 4, 0x00000001);
 	/* reset timer */
@@ -85,6 +100,7 @@
 	/* enable interrupt */
 	nile4_enable_irq(NILE4_INT_GPT);
 	i8259_setup_irq(nile4_to_irq(NILE4_INT_GPT), irq);
+#endif
 }
 
 static struct {
@@ -119,7 +135,9 @@
 	irq_setup = ddb_irq_setup;
 	mips_io_port_base = NILE4_PCI_IO_BASE;
 	isa_slot_offset = NILE4_PCI_MEM_BASE;
+
 	board_time_init = ddb_time_init;
+	board_timer_setup = ddb_timer_setup;
 
 	_machine_restart = ddb_machine_restart;
 	_machine_halt = ddb_machine_halt;
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ddb5xxx/common/Makefile linux/arch/mips/ddb5xxx/common/Makefile
--- v2.4.9/linux/arch/mips/ddb5xxx/common/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/ddb5xxx/common/Makefile	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,18 @@
+#
+# Makefile for the common code of NEC DDB-Vrc5xxx board
+#
+# 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.s:
+	$(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+	$(CC) $(CFLAGS) -c $< -o $*.o
+
+O_TARGET:= ddb5xxx.o
+
+obj-y	 += irq.o irq_cpu.o nile4.o prom.o pci.o pci_auto.o rtc_ds1386.o
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ddb5xxx/common/irq.c linux/arch/mips/ddb5xxx/common/irq.c
--- v2.4.9/linux/arch/mips/ddb5xxx/common/irq.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/ddb5xxx/common/irq.c	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * arch/mips/ddb5xxx/common/irq.c
+ *     Common irq code for DDB boards.  This really should belong
+ *	arch/mips/kernel/irq.c.  Need to talk to Ralf.
+ *
+ * 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/config.h>
+#include <linux/init.h>
+
+void (*irq_setup)(void);
+
+void __init init_IRQ(void)
+{
+#ifdef CONFIG_REMOTE_DEBUG
+	extern void breakpoint(void);
+	extern void set_debug_traps(void);
+
+	printk("Wait for gdb client connection ...\n");
+	set_debug_traps();
+	breakpoint();
+#endif
+
+	/* invoke board-specific irq setup */
+	irq_setup();
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ddb5xxx/common/irq_cpu.c linux/arch/mips/ddb5xxx/common/irq_cpu.c
--- v2.4.9/linux/arch/mips/ddb5xxx/common/irq_cpu.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/ddb5xxx/common/irq_cpu.c	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,115 @@
+/***********************************************************************
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ *  arch/mips/ddb5xxx/common/irq_cpu.c
+ *     This file define the irq handler for MIPS CPU interrupts.
+ *
+ * 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.
+ ***********************************************************************
+ */
+
+/*
+ * Almost all MIPS CPUs define 8 interrupt sources.  They are typically
+ * level triggered (i.e., cannot be cleared from CPU; must be cleared from
+ * device).  The first two are software interrupts.  The last one is 
+ * usually cpu timer interrupt if coutner register is present.
+ *
+ * This file exports one global function:
+ *	mips_cpu_irq_init(u32 irq_base);
+ */
+
+#include <linux/irq.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+#include <asm/mipsregs.h>
+
+/* [jsun] sooner or later we should move this debug stuff to MIPS common */
+#include <asm/ddb5xxx/debug.h>
+
+static int mips_cpu_irq_base=-1;
+
+static void 
+mips_cpu_irq_enable(unsigned int irq)
+{
+	MIPS_ASSERT(mips_cpu_irq_base != -1);
+	MIPS_ASSERT(irq >= mips_cpu_irq_base);
+	MIPS_ASSERT(irq < mips_cpu_irq_base+8);
+
+	clear_cp0_cause( 1 << (irq - mips_cpu_irq_base + 8));
+	set_cp0_status(1 << (irq - mips_cpu_irq_base + 8));
+}
+
+static void 
+mips_cpu_irq_disable(unsigned int irq)
+{
+	MIPS_ASSERT(mips_cpu_irq_base != -1);
+	MIPS_ASSERT(irq >= mips_cpu_irq_base);
+	MIPS_ASSERT(irq < mips_cpu_irq_base+8);
+
+	clear_cp0_status(1 << (irq - mips_cpu_irq_base + 8));
+}
+
+static unsigned int mips_cpu_irq_startup(unsigned int irq)
+{
+	mips_cpu_irq_enable(irq);
+	return 0;
+}
+
+#define	mips_cpu_irq_shutdown	mips_cpu_irq_disable
+
+static void
+mips_cpu_irq_ack(unsigned int irq)
+{
+	MIPS_ASSERT(mips_cpu_irq_base != -1);
+	MIPS_ASSERT(irq >= mips_cpu_irq_base);
+	MIPS_ASSERT(irq < mips_cpu_irq_base+8);
+
+	/* although we attemp to clear the IP bit in cause reigster, I think
+	 * usually it is cleared by device (irq source)
+	 */
+	clear_cp0_cause( 1 << (irq - mips_cpu_irq_base + 8));
+
+	/* I am not fully convinced that I should disable irq here */
+}
+
+static void
+mips_cpu_irq_end(unsigned int irq)
+{
+	MIPS_ASSERT(mips_cpu_irq_base != -1);
+	MIPS_ASSERT(irq >= mips_cpu_irq_base);
+	MIPS_ASSERT(irq < mips_cpu_irq_base+8);
+	/* I am not fully convinced that I should enable irq here */
+}
+
+static hw_irq_controller mips_cpu_irq_controller = {
+	"CPU_irq",
+	mips_cpu_irq_startup,
+	mips_cpu_irq_shutdown,
+	mips_cpu_irq_enable,
+	mips_cpu_irq_disable,
+	mips_cpu_irq_ack,
+	mips_cpu_irq_end,
+	NULL			/* no affinity stuff for UP */
+};
+
+
+void 
+mips_cpu_irq_init(u32 irq_base)
+{
+	extern irq_desc_t irq_desc[];
+	u32 i;
+
+	for (i= irq_base; i< irq_base+8; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = NULL;
+		irq_desc[i].depth = 1;
+		irq_desc[i].handler = &mips_cpu_irq_controller;
+	}
+
+	mips_cpu_irq_base = irq_base;
+} 
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ddb5xxx/common/nile4.c linux/arch/mips/ddb5xxx/common/nile4.c
--- v2.4.9/linux/arch/mips/ddb5xxx/common/nile4.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/ddb5xxx/common/nile4.c	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,135 @@
+/***********************************************************************
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * arch/mips/ddb5xxx/common/nile4.c
+ *     misc low-level routines for vrc-5xxx controllers.
+ *
+ * derived from original code by Geert Uytterhoeven <geert@sonycom.com>
+ *
+ * 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/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+#include <asm/ddb5xxx/ddb5xxx.h>
+#include <asm/ddb5xxx/debug.h>
+
+u32
+ddb_calc_pdar(u32 phys, u32 size, int width, 
+	      int on_memory_bus, int pci_visible)
+{
+        u32 maskbits;
+        u32 widthbits;
+
+        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:
+                panic("nile4_set_pdar: unsupported size %p\n", (void *) size);
+        }
+        switch (width) {
+        case 8:
+                widthbits = 0;
+                break;
+        case 16:
+                widthbits = 1;
+                break;
+        case 32:
+                widthbits = 2;
+                break;
+        case 64:
+                widthbits = 3;
+                break;
+        default:
+                panic("nile4_set_pdar: unsupported width %d\n", width);
+        }
+
+	return maskbits | (on_memory_bus ? 0x10 : 0) |
+		(pci_visible ? 0x20 : 0) | (widthbits << 6) |
+		(phys & 0xffe00000);
+}
+
+void
+ddb_set_pdar(u32 pdar, u32 phys, u32 size, int width,
+	     int on_memory_bus, int pci_visible)
+{
+	u32 temp= ddb_calc_pdar(phys, size, width, on_memory_bus, pci_visible);
+	ddb_out32(pdar, temp);
+	ddb_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.
+	 * [jsun] is this really necesary?
+         */
+        ddb_in32(pdar);
+        ddb_in32(pdar + 4);
+}
+
+/*
+ * routines that mess with PCIINITx registers
+ */
+
+void ddb_set_pmr(u32 pmr, u32 type, u32 addr, u32 options)
+{
+        switch (type) {
+        case DDB_PCICMD_IACK: /* PCI Interrupt Acknowledge */
+        case DDB_PCICMD_IO:   /* PCI I/O Space */
+        case DDB_PCICMD_MEM:  /* PCI Memory Space */
+        case DDB_PCICMD_CFG:  /* PCI Configuration Space */
+                break;
+        default:
+                panic("nile4_set_pmr: invalid type %d\n", type);
+        }
+        ddb_out32(pmr, (type << 1) | (addr & 0xffe00000) | options );
+        ddb_out32(pmr + 4, 0);
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ddb5xxx/common/pci.c linux/arch/mips/ddb5xxx/common/pci.c
--- v2.4.9/linux/arch/mips/ddb5xxx/common/pci.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/ddb5xxx/common/pci.c	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,179 @@
+/***********************************************************************
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * arch/mips/ddb5xxx/common/pci.c
+ *     Common PCI routines for DDB5xxx - as a matter of fact, meant for all 
+ *	MIPS machines.
+ *
+ * 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 file contains common PCI routines meant to be shared for
+ * all MIPS machines.
+ *
+ * Strategies:
+ *
+ * . We rely on pci_auto.c file to assign PCI resources (MEM and IO)
+ *   TODO: this shold be optional for some machines where they do have
+ *   a real "pcibios" that does resource assignment.
+ *
+ * . We then use pci_scan_bus() to "discover" all the resources for
+ *   later use by Linux.
+ *
+ * . We finally reply on a board supplied function, pcibios_fixup_irq(), to 
+ *   to assign the interrupts.  We may use setup-irq.c under drivers/pci
+ *   later.
+ *
+ * . Specifically, we will *NOT* use pci_assign_unassigned_resources(),
+ *   because we assume all PCI devices should have the resources correctly
+ *   assigned and recorded.
+ *
+ * Limitations:
+ *
+ * . We "collapse" all IO and MEM spaces in sub-buses under a top-level bus 
+ *   into a contiguous range.  
+ * 
+ * . In the case of Memory space, the rnage is 1:1 mapping with CPU physical
+ *   address space.
+ *
+ * . In the case of IO space, it starts from 0, and the beginning address
+ *   is mapped to KSEG0ADDR(mips_io_port) in the CPU physical address.
+ *
+ * . These are the current MIPS limitations (by ioremap, etc).  In the
+ *   future, we may remove them.
+ *
+ * Credits:
+ *	Most of the code are derived from the pci routines from PPC and Alpha,
+ *	which were mostly writtne by
+ *		Cort Dougan, cort@fsmlabs.com
+ *		Matt Porter, mporter@mvista.com
+ *		Dave Rusling david.rusling@reo.mts.dec.com
+ *		David Mosberger davidm@cs.arizona.edu
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+
+#include <asm/ddb5xxx/pci.h>
+#include <asm/ddb5xxx/debug.h>
+
+
+struct pci_fixup pcibios_fixups[] = { {0} };
+
+
+extern int pciauto_assign_resources(int busno, struct pci_channel * hose);
+void __init pcibios_init(void)
+{
+	struct pci_channel *p;
+	struct pci_bus *bus;
+	int busno;
+
+	/* assign resources */
+	busno=0;
+	for (p= mips_pci_channels; p->pci_ops != NULL; p++) {
+		busno = pciauto_assign_resources(busno, p) + 1;
+	}
+
+	/* scan the buses */
+	busno = 0;
+	for (p= mips_pci_channels; p->pci_ops != NULL; p++) {
+		bus = pci_scan_bus(busno, p->pci_ops, p);
+		busno = bus->subordinate+1;
+	}
+
+	/* fixup irqs (board specific routines) */
+	pcibios_fixup_irqs();
+
+	/* 
+	 * should we do a fixup of ioport_resource and iomem_resource
+	 * based on mips_pci_channels?  
+	 * Let us wait and see if this is a common need and whether there
+	 * are exceptions.  Until then, each board should adjust them
+	 * perhaps in their setup() function.
+	 */
+}
+
+int pcibios_enable_device(struct pci_dev *dev)
+{
+	/* pciauto_assign_resources() will enable all devices found */
+	return 0;
+}
+
+unsigned long __init
+pci_bridge_check_io(struct pci_dev *bridge)
+{
+        u16 io;
+
+        pci_read_config_word(bridge, PCI_IO_BASE, &io);
+        if (!io) {
+                pci_write_config_word(bridge, PCI_IO_BASE, 0xf0f0);
+                pci_read_config_word(bridge, PCI_IO_BASE, &io);
+                pci_write_config_word(bridge, PCI_IO_BASE, 0x0);
+        }
+        if (io)
+                return IORESOURCE_IO;
+        printk(KERN_WARNING "PCI: bridge %s does not support I/O forwarding!\n",
+                                bridge->name);
+        return 0;
+}
+
+void __init pcibios_fixup_bus(struct pci_bus *bus)
+{
+        /* Propogate hose info into the subordinate devices.  */
+
+        struct pci_channel *hose = bus->sysdata;
+        struct pci_dev *dev = bus->self;
+
+        if (!dev) {
+                /* Root bus */
+                bus->resource[0] = hose->io_resource;
+                bus->resource[1] = hose->mem_resource;
+        } else {
+                /* This is a bridge. Do not care how it's initialized,
+                   just link its resources to the bus ones */
+                int i;
+
+                for(i=0; i<3; i++) {
+                        bus->resource[i] =
+                                &dev->resource[PCI_BRIDGE_RESOURCES+i];
+                        bus->resource[i]->name = bus->name;
+                }
+                bus->resource[0]->flags |= pci_bridge_check_io(dev);
+                bus->resource[1]->flags |= IORESOURCE_MEM;
+                /* For now, propogate hose limits to the bus;
+                   we'll adjust them later. */
+                bus->resource[0]->end = hose->io_resource->end;
+                bus->resource[1]->end = hose->mem_resource->end;
+                /* Turn off downstream PF memory address range by default */
+                bus->resource[2]->start = 1024*1024;
+                bus->resource[2]->end = bus->resource[2]->start - 1;
+        }
+}
+
+char *pcibios_setup(char *str)
+{
+	return str;
+}
+
+void
+pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+{
+	/* this should not be called */
+	MIPS_ASSERT(1 == 0);
+}
+
+void
+pcibios_update_resource(struct pci_dev *dev, struct resource *root,
+                             struct resource *res, int resource)
+{
+	/* this should not be called */
+	MIPS_ASSERT(1 == 0);
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ddb5xxx/common/pci_auto.c linux/arch/mips/ddb5xxx/common/pci_auto.c
--- v2.4.9/linux/arch/mips/ddb5xxx/common/pci_auto.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/ddb5xxx/common/pci_auto.c	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,396 @@
+/*
+ * arch/ppc/kernel/pci_auto.c
+ * 
+ * PCI autoconfiguration library
+ *
+ * Author: Matt Porter <mporter@mvista.com>
+ *
+ * Copyright 2000, 2001 MontaVista Software Inc.
+ *
+ * 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.
+ */
+
+/*
+ * Modified for MIPS by Jun Sun, jsun@mvista.com
+ *
+ * . Simplify the interface between pci_auto and the rest: a single function.
+ * . Assign resources from low address to upper address.
+ * . change most int to u32.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+
+#include <asm/ddb5xxx/pci.h>
+#include <asm/ddb5xxx/debug.h>
+
+#define	DEBUG
+#ifdef 	DEBUG
+#define	DBG(x...)	printk(x)
+#else
+#define	DBG(x...)	
+#endif
+
+/* These are used for config access before all the PCI probing
+   has been done. */
+int early_read_config_byte(struct pci_channel *hose, int bus, int dev_fn, int where, u8 *val);
+int early_read_config_word(struct pci_channel *hose, int bus, int dev_fn, int where, u16 *val);
+int early_read_config_dword(struct pci_channel *hose, int bus, int dev_fn, int where, u32 *val);
+int early_write_config_byte(struct pci_channel *hose, int bus, int dev_fn, int where, u8 val);
+int early_write_config_word(struct pci_channel *hose, int bus, int dev_fn, int where, u16 val);
+int early_write_config_dword(struct pci_channel *hose, int bus, int dev_fn, int where, u32 val);
+
+static u32 pciauto_lower_iospc;
+static u32 pciauto_upper_iospc;
+
+static u32 pciauto_lower_memspc;
+static u32 pciauto_upper_memspc;
+
+void __init 
+pciauto_setup_bars(struct pci_channel *hose,
+		   int current_bus,
+		   int pci_devfn)
+{
+	u32 bar_response, bar_size, bar_value;
+	u32 bar, addr_mask, bar_nr = 0;
+	u32 * upper_limit;
+	u32 * lower_limit;
+	int found_mem64 = 0;
+
+	DBG("PCI Autoconfig: Found Bus %d, Device %d, Function %d\n",
+	    current_bus, PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn) );
+
+	for (bar = PCI_BASE_ADDRESS_0; bar <= PCI_BASE_ADDRESS_5; bar+=4)
+	{
+		/* Tickle the BAR and get the response */
+		early_write_config_dword(hose,
+					 current_bus,
+					 pci_devfn,
+					 bar,
+					 0xffffffff);
+		early_read_config_dword(hose,
+					current_bus,
+					pci_devfn,
+					bar,
+					&bar_response);
+
+		/* If BAR is not implemented go to the next BAR */
+		if (!bar_response)
+			continue;
+
+		/* Check the BAR type and set our address mask */
+		if (bar_response & PCI_BASE_ADDRESS_SPACE)
+		{
+			addr_mask = PCI_BASE_ADDRESS_IO_MASK;
+			upper_limit = &pciauto_upper_iospc;
+			lower_limit = &pciauto_lower_iospc;
+			DBG("PCI Autoconfig: BAR %d, I/O, ", bar_nr);
+		}
+		else
+		{
+			if ( (bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
+			     PCI_BASE_ADDRESS_MEM_TYPE_64)
+				found_mem64 = 1;
+
+			addr_mask = PCI_BASE_ADDRESS_MEM_MASK;		
+			upper_limit = &pciauto_upper_memspc;
+			lower_limit = &pciauto_lower_memspc;
+			DBG("PCI Autoconfig: BAR %d, Mem, ", bar_nr);
+		}
+
+		/* Calculate requested size */
+		bar_size = ~(bar_response & addr_mask) + 1;
+
+		/* Allocate a base address */
+		bar_value = ((*lower_limit - 1) & ~(bar_size - 1)) + bar_size;
+		MIPS_ASSERT(bar_value + bar_size <= *upper_limit);
+
+		/* Write it out and update our limit */
+		early_write_config_dword(hose,
+					 current_bus,
+					 pci_devfn,
+					 bar,
+					 bar_value);
+
+		*lower_limit = bar_value + bar_size;
+
+		/*
+		 * If we are a 64-bit decoder then increment to the
+		 * upper 32 bits of the bar and force it to locate
+		 * in the lower 4GB of memory.
+		 */ 
+		if (found_mem64)
+		{
+			bar += 4;
+			early_write_config_dword(hose,
+						 current_bus,
+						 pci_devfn,
+						 bar,
+						 0x00000000);
+		}
+
+		bar_nr++;
+
+		DBG("size=0x%x, address=0x%x\n",
+		    bar_size, bar_value);
+	}
+
+}
+
+void __init
+pciauto_prescan_setup_bridge(struct pci_channel *hose,
+			     int current_bus,
+			     int pci_devfn,
+			     int sub_bus)
+{
+	int cmdstat;
+
+	/* Configure bus number registers */
+	early_write_config_byte(hose,
+				current_bus,
+				pci_devfn,
+				PCI_PRIMARY_BUS,
+				current_bus);
+	early_write_config_byte(hose,
+				current_bus,
+				pci_devfn,
+				PCI_SECONDARY_BUS,
+				sub_bus + 1);
+	early_write_config_byte(hose,
+				current_bus,
+				pci_devfn,
+				PCI_SUBORDINATE_BUS,
+				0xff);
+
+	/* Round memory allocator to 1MB boundary */
+	pciauto_upper_memspc &= ~(0x100000 - 1);
+
+	/* Round I/O allocator to 4KB boundary */
+	pciauto_upper_iospc &= ~(0x1000 - 1);
+
+	/* Set up memory and I/O filter limits, assume 32-bit I/O space */
+	early_write_config_word(hose,
+				current_bus,
+				pci_devfn,
+				PCI_MEMORY_LIMIT,
+				((pciauto_upper_memspc - 1) & 0xfff00000) >> 16);
+	early_write_config_byte(hose,
+				current_bus,
+				pci_devfn,
+				PCI_IO_LIMIT,
+				((pciauto_upper_iospc - 1) & 0x0000f000) >> 8);
+	early_write_config_word(hose,
+				current_bus,
+				pci_devfn,
+				PCI_IO_LIMIT_UPPER16,
+				((pciauto_upper_iospc - 1) & 0xffff0000) >> 16);
+			
+	/* We don't support prefetchable memory for now, so disable */
+	early_write_config_word(hose,
+				current_bus,
+				pci_devfn,
+				PCI_PREF_MEMORY_BASE,
+				0x1000);
+	early_write_config_word(hose,
+				current_bus,
+				pci_devfn,
+				PCI_PREF_MEMORY_LIMIT,
+				0x1000);
+
+	/* Enable memory and I/O accesses, enable bus master */
+	early_read_config_dword(hose,
+				current_bus,
+				pci_devfn,
+				PCI_COMMAND,
+				&cmdstat);
+	early_write_config_dword(hose,
+				 current_bus,
+				 pci_devfn,
+				 PCI_COMMAND,
+				 cmdstat |
+				 PCI_COMMAND_IO |
+				 PCI_COMMAND_MEMORY |
+				 PCI_COMMAND_MASTER);
+}
+
+void __init
+pciauto_postscan_setup_bridge(struct pci_channel *hose,
+			      int current_bus,
+			      int pci_devfn,
+			      int sub_bus)
+{
+	/* Configure bus number registers */
+	early_write_config_byte(hose,
+				current_bus,
+				pci_devfn,
+				PCI_SUBORDINATE_BUS,
+				sub_bus);
+
+	/* Round memory allocator to 1MB boundary */
+	pciauto_upper_memspc &= ~(0x100000 - 1);
+	early_write_config_word(hose,
+				current_bus,
+				pci_devfn,
+				PCI_MEMORY_BASE,
+				pciauto_upper_memspc >> 16);
+
+	/* Round I/O allocator to 4KB boundary */
+	pciauto_upper_iospc &= ~(0x1000 - 1);
+	early_write_config_byte(hose,
+				current_bus,
+				pci_devfn,
+				PCI_IO_BASE,
+				(pciauto_upper_iospc & 0x0000f000) >> 8);
+	early_write_config_word(hose,
+				current_bus,
+				pci_devfn,
+				PCI_IO_BASE_UPPER16,
+				pciauto_upper_iospc >> 16);
+}
+
+#define      PCIAUTO_IDE_MODE_MASK           0x05
+
+int __init
+pciauto_bus_scan(struct pci_channel *hose, int current_bus)
+{
+	int sub_bus;
+	u32 pci_devfn, pci_class, cmdstat, found_multi=0;
+	unsigned short vid;
+	unsigned char header_type;
+
+	sub_bus = current_bus;
+	
+	for (pci_devfn=0; pci_devfn<0xff; pci_devfn++) {
+
+		if (PCI_FUNC(pci_devfn) && !found_multi)
+			continue;
+
+		early_read_config_byte(hose,
+				       current_bus,
+				       pci_devfn,
+				       PCI_HEADER_TYPE,
+				       &header_type);
+
+		if (!PCI_FUNC(pci_devfn))
+			found_multi = header_type & 0x80;
+
+		early_read_config_word(hose,
+				       current_bus,
+				       pci_devfn,
+				       PCI_VENDOR_ID,
+				       &vid);
+
+		if (vid == 0xffff) continue;
+
+		early_read_config_dword(hose,
+					current_bus,
+					pci_devfn,
+					PCI_CLASS_REVISION, &pci_class);
+		if ( (pci_class >> 16) == PCI_CLASS_BRIDGE_PCI ) {
+			DBG("PCI Autoconfig: Found P2P bridge, device %d\n", PCI_SLOT(pci_devfn));
+			pciauto_prescan_setup_bridge(hose,
+						     current_bus,
+						     pci_devfn,
+						     sub_bus);
+			sub_bus = pciauto_bus_scan(hose, sub_bus+1);
+			pciauto_postscan_setup_bridge(hose,
+						      current_bus,
+						      pci_devfn,
+						      sub_bus);
+
+		} else if ((pci_class >> 16) == PCI_CLASS_STORAGE_IDE) {
+
+			unsigned char prg_iface;
+
+			early_read_config_byte(hose,
+					       current_bus,
+					       pci_devfn,
+					       PCI_CLASS_PROG,
+					       &prg_iface);
+			if (!(prg_iface & PCIAUTO_IDE_MODE_MASK)) {
+				DBG("PCI Autoconfig: Skipping legacy mode IDE controller\n");
+				continue;
+			}
+		}
+
+		/*
+		 * Found a peripheral, enable some standard
+		 * settings
+		 */
+		early_read_config_dword(hose,
+					current_bus,
+					pci_devfn,
+					PCI_COMMAND,
+					&cmdstat);
+		early_write_config_dword(hose,
+					 current_bus,
+					 pci_devfn,
+					 PCI_COMMAND,
+					 cmdstat |
+					 PCI_COMMAND_IO |
+					 PCI_COMMAND_MEMORY |
+					 PCI_COMMAND_MASTER);
+		early_write_config_byte(hose,
+					current_bus,
+					pci_devfn,
+					PCI_LATENCY_TIMER,
+					0x80);
+
+                /* Allocate PCI I/O and/or memory space */
+		pciauto_setup_bars(hose,
+				   current_bus,
+				   pci_devfn);
+	}
+	return sub_bus;
+}
+
+int __init
+pciauto_assign_resources(int busno, struct pci_channel *hose)
+{
+	/* setup resource limits */
+	pciauto_lower_iospc = hose->io_resource->start;
+	pciauto_upper_iospc = hose->io_resource->end + 1;
+	pciauto_lower_memspc = hose->mem_resource->start;
+	pciauto_upper_memspc = hose->mem_resource->end + 1;
+
+	return pciauto_bus_scan(hose, busno);
+}
+
+
+/*
+ * These functions are used early on before PCI scanning is done
+ * and all of the pci_dev and pci_bus structures have been created.
+ */
+static struct pci_dev *
+fake_pci_dev(struct pci_channel *hose, int busnr, int devfn)
+{
+        static struct pci_dev dev;
+        static struct pci_bus bus;
+
+        dev.bus = &bus;
+        dev.sysdata = hose;
+        dev.devfn = devfn;
+        bus.number = busnr;
+        bus.ops = hose->pci_ops;
+        return &dev;
+}
+
+#define EARLY_PCI_OP(rw, size, type)                                    \
+int early_##rw##_config_##size(struct pci_channel *hose, int bus,    \
+                               int devfn, int offset, type value)       \
+{                                                                       \
+        return pci_##rw##_config_##size(fake_pci_dev(hose, bus, devfn), \
+                                        offset, value);                 \
+}
+
+EARLY_PCI_OP(read, byte, u8 *)
+EARLY_PCI_OP(read, word, u16 *)
+EARLY_PCI_OP(read, dword, u32 *)
+EARLY_PCI_OP(write, byte, u8)
+EARLY_PCI_OP(write, word, u16)
+EARLY_PCI_OP(write, dword, u32)
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ddb5xxx/common/prom.c linux/arch/mips/ddb5xxx/common/prom.c
--- v2.4.9/linux/arch/mips/ddb5xxx/common/prom.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/ddb5xxx/common/prom.c	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,58 @@
+/***********************************************************************
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * arch/mips/ddb5xxx/common/prom.c
+ *     prom.c file.
+ *
+ * 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/config.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <asm/ddb5xxx/ddb5xxx.h>
+
+char arcs_cmdline[COMMAND_LINE_SIZE];
+
+/* [jsun@junsun.net] PMON passes arguments in C main() style */
+void __init prom_init(int argc, const char **arg)
+{
+	int i;
+
+	/* arg[0] is "g", the rest is boot parameters */
+	arcs_cmdline[0] = '\0';
+	for (i = 1; i < argc; i++) {
+		if (strlen(arcs_cmdline) + strlen(arg[i] + 1)
+		    >= sizeof(arcs_cmdline))
+			break;
+		strcat(arcs_cmdline, arg[i]);
+		strcat(arcs_cmdline, " ");
+	}
+
+	mips_machgroup = MACH_GROUP_NEC_DDB;
+
+#if defined(CONFIG_DDB5074)
+	mips_machtype = MACH_NEC_DDB5074;
+#elif defined(CONFIG_DDB5476)
+	mips_machtype = MACH_NEC_DDB5476;
+#elif defined(CONFIG_DDB5477)
+	mips_machtype = MACH_NEC_DDB5477;
+#endif
+
+	add_memory_region(0, DDB_SDRAM_SIZE, BOOT_MEM_RAM);
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ddb5xxx/common/rtc_ds1386.c linux/arch/mips/ddb5xxx/common/rtc_ds1386.c
--- v2.4.9/linux/arch/mips/ddb5xxx/common/rtc_ds1386.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/ddb5xxx/common/rtc_ds1386.c	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * arch/mips/ddb5xxx/common/rtc_ds1386.c
+ *     low-level RTC hookups for s for Dallas 1396 chip.
+ *
+ * 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 file exports a function, rtc_ds1386_init(), which expects an
+ * uncached base address as the argument.  It will set the two function
+ * pointers expected by the MIPS generic timer code.
+ */
+
+#include <linux/types.h>
+#include <linux/time.h>
+
+#include <asm/time.h>
+#include <asm/addrspace.h>
+
+#include <asm/ddb5xxx/debug.h>
+
+#define	EPOCH		2000
+
+#undef BCD_TO_BIN
+#define BCD_TO_BIN(val) (((val)&15) + ((val)>>4)*10)
+
+#undef BIN_TO_BCD
+#define BIN_TO_BCD(val) ((((val)/10)<<4) + (val)%10)
+
+#define	READ_RTC(x)	*(volatile unsigned char*)(rtc_base+x)
+#define	WRITE_RTC(x, y)	*(volatile unsigned char*)(rtc_base+x) = y
+
+static unsigned long rtc_base;
+
+static unsigned long
+rtc_ds1386_get_time(void)
+{	
+	u8 byte;
+	u8 temp;
+	unsigned int year, month, day, hour, minute, second;
+
+	/* let us freeze external registers */
+	byte = READ_RTC(0xB);
+	byte &= 0x3f;
+	WRITE_RTC(0xB, byte);
+
+	/* read time data */
+	year = BCD_TO_BIN(READ_RTC(0xA)) + EPOCH;
+	month = BCD_TO_BIN(READ_RTC(0x9) & 0x1f);
+	day = BCD_TO_BIN(READ_RTC(0x8));
+	minute = BCD_TO_BIN(READ_RTC(0x2));
+	second = BCD_TO_BIN(READ_RTC(0x1));
+
+	/* hour is special - deal with it later */
+	temp = READ_RTC(0x4);
+
+	/* enable time transfer */
+	byte |= 0x80;
+	WRITE_RTC(0xB, byte);
+
+	/* calc hour */
+	if (temp & 0x40) {
+		/* 12 hour format */
+		hour = BCD_TO_BIN(temp & 0x1f);
+		if (temp & 0x20) hour += 12; 		/* PM */
+	} else {
+		/* 24 hour format */
+		hour = BCD_TO_BIN(temp & 0x3f);
+	}
+
+	return mktime(year, month, day, hour, minute, second);
+}
+
+static int 
+rtc_ds1386_set_time(unsigned long t)
+{
+	struct rtc_time tm;
+	u8 byte;
+	u8 temp;
+	u8 year, month, day, hour, minute, second;
+
+	/* let us freeze external registers */
+	byte = READ_RTC(0xB);
+	byte &= 0x3f;
+	WRITE_RTC(0xB, byte);
+
+	/* convert */
+	to_tm(t, &tm);
+
+	/* check each field one by one */
+	year = BIN_TO_BCD(tm.tm_year - EPOCH);
+	if (year != READ_RTC(0xA)) {
+		WRITE_RTC(0xA, year);
+	}
+
+	temp = READ_RTC(0x9);
+	month = BIN_TO_BCD(tm.tm_mon);
+	if (month != (temp & 0x1f)) {
+		WRITE_RTC( 0x9,
+			   (month & 0x1f) | (temp & ~0x1f) );
+	}
+
+	day = BIN_TO_BCD(tm.tm_mday);
+	if (day != READ_RTC(0x8)) {
+		WRITE_RTC(0x8, day);
+	}
+
+	temp = READ_RTC(0x4);
+	if (temp & 0x40) {
+		/* 12 hour format */
+		hour = 0x40;
+		if (tm.tm_hour > 12) {
+			hour |= 0x20 | (BIN_TO_BCD(hour-12) & 0x1f);
+		} else {
+			hour |= BIN_TO_BCD(tm.tm_hour);
+		}
+	} else {
+		/* 24 hour format */
+		hour = BIN_TO_BCD(tm.tm_hour) & 0x3f;
+	}
+	if (hour != temp) WRITE_RTC(0x4, hour);
+
+	minute = BIN_TO_BCD(tm.tm_min);
+	if (minute != READ_RTC(0x2)) {
+		WRITE_RTC(0x2, minute);
+	}
+
+	second = BIN_TO_BCD(tm.tm_sec);
+	if (second != READ_RTC(0x1)) {
+		WRITE_RTC(0x1, second);
+	}
+	
+	return 0;
+}
+
+void
+rtc_ds1386_init(unsigned long base)
+{
+	unsigned char byte;
+	
+	/* remember the base */
+	rtc_base = base;
+	MIPS_ASSERT((rtc_base & 0xe0000000) == KSEG1);
+
+	/* turn on RTC if it is not on */
+	byte = READ_RTC(0x9);
+	if (byte & 0x80) {
+		byte &= 0x7f;
+		WRITE_RTC(0x9, byte);
+	}
+
+	/* enable time transfer */
+	byte = READ_RTC(0xB);
+	byte |= 0x80;
+	WRITE_RTC(0xB, byte);
+
+	/* set the function pointers */
+	rtc_get_time = rtc_ds1386_get_time;
+	rtc_set_time = rtc_ds1386_set_time;
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ddb5xxx/ddb5477/Makefile linux/arch/mips/ddb5xxx/ddb5477/Makefile
--- v2.4.9/linux/arch/mips/ddb5xxx/ddb5477/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/ddb5xxx/ddb5477/Makefile	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,22 @@
+#
+# Makefile for NEC DDB-Vrc5477 board
+#
+# 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.s:
+	$(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+	$(CC) $(CFLAGS) -c $< -o $*.o
+
+O_TARGET:= ddb5477.o
+
+obj-y	 += int-handler.o irq.o irq_5477.o setup.o pci.o pci_ops.o
+
+obj-$(CONFIG_LL_DEBUG) 		+= debug.o
+obj-$(CONFIG_REMOTE_DEBUG)	+= kgdb_io.o
+obj-$(CONFIG_BLK_DEV_INITRD)	+= ramdisk.o
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ddb5xxx/ddb5477/debug.c linux/arch/mips/ddb5xxx/ddb5477/debug.c
--- v2.4.9/linux/arch/mips/ddb5xxx/ddb5477/debug.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/ddb5xxx/ddb5477/debug.c	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,162 @@
+/***********************************************************************
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * arch/mips/ddb5xxx/ddb5477/debug.c
+ *     vrc5477 specific debug routines.
+ *
+ * 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/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/signal.h>		/* SA_INTERRUPT */
+
+#include <asm/mipsregs.h>
+#include <asm/ddb5xxx/ddb5xxx.h>
+
+typedef struct {
+       const char *regname;
+       unsigned regaddr;
+} Register;
+
+void jsun_show_regs(char *name, Register *regs)
+{
+	int i;
+
+	printk("\nshow regs: %s\n", name);
+	for(i=0;regs[i].regname!= NULL; i++) {
+		printk("%-16s= %08x\t\t(@%08x)\n", 
+		       regs[i].regname, 
+		       *(unsigned *)(regs[i].regaddr), 
+		       regs[i].regaddr);
+	}
+}
+
+static Register int_regs[] = {
+	{"DDB_INTCTRL0", DDB_BASE + DDB_INTCTRL0},
+	{"DDB_INTCTRL1", DDB_BASE + DDB_INTCTRL1},
+	{"DDB_INTCTRL2", DDB_BASE + DDB_INTCTRL2},
+	{"DDB_INTCTRL3", DDB_BASE + DDB_INTCTRL3},
+	{"DDB_INT0STAT", DDB_BASE + DDB_INT0STAT},
+	{"DDB_INT1STAT", DDB_BASE + DDB_INT1STAT},
+	{"DDB_INT2STAT", DDB_BASE + DDB_INT2STAT},
+	{"DDB_INT3STAT", DDB_BASE + DDB_INT3STAT},
+	{"DDB_INT4STAT", DDB_BASE + DDB_INT4STAT},
+	{"DDB_NMISTAT", DDB_BASE + DDB_NMISTAT},
+	{"DDB_INTPPES0", DDB_BASE + DDB_INTPPES0},
+	{"DDB_INTPPES1", DDB_BASE + DDB_INTPPES1},
+	{NULL, 0x0}
+};
+
+void vrc5477_show_int_regs()
+{
+	jsun_show_regs("interrupt registers", int_regs);
+	printk("CPU CAUSE = %08x\n", read_32bit_cp0_register(CP0_CAUSE));
+	printk("CPU STATUS = %08x\n", read_32bit_cp0_register(CP0_STATUS));
+}
+static Register pdar_regs[] = {
+        {"DDB_SDRAM0", DDB_BASE + DDB_SDRAM0},
+        {"DDB_SDRAM1", DDB_BASE + DDB_SDRAM1},
+        {"DDB_LDCS0", DDB_BASE + DDB_LDCS0},
+        {"DDB_LDCS1", DDB_BASE + DDB_LDCS1},
+        {"DDB_LDCS2", DDB_BASE + DDB_LDCS2},
+        {"DDB_INTCS", DDB_BASE + DDB_INTCS},
+        {"DDB_BOOTCS", DDB_BASE + DDB_BOOTCS},
+        {"DDB_PCIW0", DDB_BASE + DDB_PCIW0},
+        {"DDB_PCIW1", DDB_BASE + DDB_PCIW1},
+        {"DDB_IOPCIW0", DDB_BASE + DDB_IOPCIW0},
+        {"DDB_IOPCIW1", DDB_BASE + DDB_IOPCIW1},
+        {NULL, 0x0}
+};
+void vrc5477_show_pdar_regs(void)
+{
+        jsun_show_regs("PDAR regs", pdar_regs);
+}
+
+static Register bar_regs[] = {
+        {"DDB_BARC0", DDB_BASE + DDB_BARC0},
+        {"DDB_BARM010", DDB_BASE + DDB_BARM010},
+        {"DDB_BARM230", DDB_BASE + DDB_BARM230},
+        {"DDB_BAR00", DDB_BASE + DDB_BAR00},
+        {"DDB_BAR10", DDB_BASE + DDB_BAR10},
+        {"DDB_BAR20", DDB_BASE + DDB_BAR20},
+        {"DDB_BAR30", DDB_BASE + DDB_BAR30},
+        {"DDB_BAR40", DDB_BASE + DDB_BAR40},
+        {"DDB_BAR50", DDB_BASE + DDB_BAR50},
+        {"DDB_BARB0", DDB_BASE + DDB_BARB0},
+        {"DDB_BARC1", DDB_BASE + DDB_BARC1},
+        {"DDB_BARM011", DDB_BASE + DDB_BARM011},
+        {"DDB_BARM231", DDB_BASE + DDB_BARM231},
+        {"DDB_BAR01", DDB_BASE + DDB_BAR01},
+        {"DDB_BAR11", DDB_BASE + DDB_BAR11},
+        {"DDB_BAR21", DDB_BASE + DDB_BAR21},
+        {"DDB_BAR31", DDB_BASE + DDB_BAR31},
+        {"DDB_BAR41", DDB_BASE + DDB_BAR41},
+        {"DDB_BAR51", DDB_BASE + DDB_BAR51},
+        {"DDB_BARB1", DDB_BASE + DDB_BARB1},
+        {NULL, 0x0}
+};
+void vrc5477_show_bar_regs(void)
+{
+        jsun_show_regs("BAR regs", bar_regs);
+}
+
+static Register pci_regs[] = {
+        {"DDB_PCIW0", DDB_BASE + DDB_PCIW0},
+        {"DDB_PCIW1", DDB_BASE + DDB_PCIW1},
+        {"DDB_PCIINIT00", DDB_BASE + DDB_PCIINIT00},
+        {"DDB_PCIINIT10", DDB_BASE + DDB_PCIINIT10},
+        {"DDB_PCICTL0_L", DDB_BASE + DDB_PCICTL0_L},
+        {"DDB_PCICTL0_H", DDB_BASE + DDB_PCICTL0_H},
+        {"DDB_PCIARB0_L", DDB_BASE + DDB_PCIARB0_L},
+        {"DDB_PCIARB0_H", DDB_BASE + DDB_PCIARB0_H},
+        {"DDB_PCISWP0", DDB_BASE + DDB_PCISWP0},
+        {"DDB_PCIERR0", DDB_BASE + DDB_PCIERR0},
+        {"DDB_IOPCIW0", DDB_BASE + DDB_IOPCIW0},
+        {"DDB_IOPCIW1", DDB_BASE + DDB_IOPCIW1},
+        {"DDB_PCIINIT01", DDB_BASE + DDB_PCIINIT01},
+        {"DDB_PCIINIT11", DDB_BASE + DDB_PCIINIT11},
+        {"DDB_PCICTL1_L", DDB_BASE + DDB_PCICTL1_L},
+        {"DDB_PCICTL1_H", DDB_BASE + DDB_PCICTL1_H},
+        {"DDB_PCIARB1_L", DDB_BASE + DDB_PCIARB1_L},
+        {"DDB_PCIARB1_H", DDB_BASE + DDB_PCIARB1_H},
+        {"DDB_PCISWP1", DDB_BASE + DDB_PCISWP1},
+        {"DDB_PCIERR1", DDB_BASE + DDB_PCIERR1},
+        {NULL, 0x0}
+};
+void vrc5477_show_pci_regs(void)
+{
+        jsun_show_regs("PCI regs", pci_regs);
+}
+
+static Register lb_regs[] = {
+        {"DDB_LCNFG", DDB_BASE + DDB_LCNFG},
+        {"DDB_LCST0", DDB_BASE + DDB_LCST0},
+        {"DDB_LCST1", DDB_BASE + DDB_LCST1},
+        {"DDB_LCST2", DDB_BASE + DDB_LCST2},
+        {"DDB_ERRADR", DDB_BASE + DDB_ERRADR},
+        {"DDB_ERRCS", DDB_BASE + DDB_ERRCS},
+        {"DDB_BTM", DDB_BASE + DDB_BTM},
+        {"DDB_BCST", DDB_BASE + DDB_BCST},
+        {NULL, 0x0}
+};
+void vrc5477_show_lb_regs(void)
+{
+        jsun_show_regs("Local Bus regs", lb_regs);
+}
+
+void vrc5477_show_all_regs(void)
+{
+	vrc5477_show_pdar_regs();
+	vrc5477_show_pci_regs();
+	vrc5477_show_bar_regs();
+	vrc5477_show_int_regs();
+	vrc5477_show_lb_regs();
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ddb5xxx/ddb5477/int-handler.S linux/arch/mips/ddb5xxx/ddb5477/int-handler.S
--- v2.4.9/linux/arch/mips/ddb5xxx/ddb5477/int-handler.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/ddb5xxx/ddb5477/int-handler.S	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * First-level interrupt dispatcher for ddb5477
+ *
+ * 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/config.h>
+
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+/*
+ * first level interrupt dispatcher for ocelot board -
+ * We check for the timer first, then check PCI ints A and D.
+ * Then check for serial IRQ and fall through.
+ */
+	.align	5
+	NESTED(ddb5477_handle_int, PT_SIZE, sp)
+	SAVE_ALL
+	CLI
+	.set	at
+	.set	noreorder
+	mfc0	t0, CP0_CAUSE  
+	mfc0	t2, CP0_STATUS
+
+	and	t0, t2
+       
+	andi	t1, t0, STATUSF_IP7	/* cpu timer */
+	bnez	t1, ll_cputimer_irq
+	andi	t1, t0, (STATUSF_IP2 | STATUSF_IP3 | STATUSF_IP4 | STATUSF_IP5 | STATUSF_IP6 ) 
+	bnez	t1, ll_vrc5477_irq
+	andi	t1, t0, STATUSF_IP0	/* software int 0 */
+	bnez	t1, ll_cpu_ip0
+	andi	t1, t0, STATUSF_IP1	/* software int 1 */
+	bnez	t1, ll_cpu_ip1
+	nop
+	.set	reorder
+
+	/* wrong alarm or masked ... */
+	j	spurious_interrupt
+	nop
+	END(ddb5477_handle_int)
+
+	.align	5
+
+ll_vrc5477_irq:	
+	move	a0, sp
+	jal	vrc5477_irq_dispatch
+	j	ret_from_irq
+
+ll_cputimer_irq:
+	li	a0, 7
+	move	a1, sp
+	jal	do_IRQ
+	j	ret_from_irq
+
+
+ll_cpu_ip0:	
+	li	a0, 0
+	move	a1, sp
+	jal	do_IRQ
+	j	ret_from_irq
+
+ll_cpu_ip1:	
+	li	a0, 1
+	move	a1, sp
+	jal	do_IRQ
+	j	ret_from_irq
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ddb5xxx/ddb5477/irq.c linux/arch/mips/ddb5xxx/ddb5477/irq.c
--- v2.4.9/linux/arch/mips/ddb5xxx/ddb5477/irq.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/ddb5xxx/ddb5477/irq.c	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ *  arch/mips/ddb5xxx/ddb5477/irq.c
+ *     The irq setup and misc routines for DDB5476.
+ *
+ * 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/config.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+
+#include <asm/system.h>
+#include <asm/mipsregs.h>
+#include <asm/ddb5xxx/ddb5xxx.h>
+
+/* [jsun] sooner or later we should move this debug stuff to MIPS common */
+#include <asm/ddb5xxx/debug.h>
+
+/*
+ * IRQ mapping
+ *
+ *  0-7: 8 CPU interrupts
+ *	0 -	software interrupt 0
+ *	1 - 	software interrupt 1
+ *	2 - 	most Vrc5477 interrupts are routed to this pin
+ *	3 - 	(optional) some other interrupts routed to this pin for debugg
+ *	4 - 	not used
+ *	5 - 	not used
+ *	6 - 	not used
+ *	7 - 	cpu timer (used by default)
+ *
+ *  8-39: 32 Vrc5477 interrupt sources
+ *	(refer to the Vrc5477 manual)	
+ */
+
+#define	PCI0			DDB_INTPPES0
+#define	PCI1			DDB_INTPPES1
+
+#define	ACTIVE_LOW		1
+#define	ACTIVE_HIGH		0
+
+#define	LEVEL_SENSE		2
+#define	EDGE_TRIGGER		0
+
+#define	INTA			0
+#define	INTB			1
+#define	INTC			2
+#define	INTD			3
+#define	INTE			4
+
+static inline void 
+set_pci_int_attr(u32 pci, u32 intn, u32 active, u32 trigger)
+{
+	u32 reg_value;
+	u32 reg_bitmask;
+
+	reg_value = ddb_in32(pci);
+	reg_bitmask = 0x3 << (intn * 2);
+	
+	reg_value &= ~reg_bitmask;
+	reg_value |= (active | trigger) << (intn * 2);
+	ddb_out32(pci, reg_value);
+}
+
+extern void vrc5477_irq_init(u32 base);
+extern void mips_cpu_irq_init(u32 base);
+extern asmlinkage void ddb5477_handle_int(void);
+
+void
+ddb5477_irq_setup(void)
+{
+	MIPS_DEBUG(printk("ddb5477_irq_setup invoked.\n"));
+
+	/* by default, we disable all interrupts and route all vrc5477 
+	 * interrupts to pin 0 (irq 2) */
+	ddb_out32(DDB_INTCTRL0, 0);
+	ddb_out32(DDB_INTCTRL1, 0);
+	ddb_out32(DDB_INTCTRL2, 0);
+	ddb_out32(DDB_INTCTRL3, 0);
+
+	clear_cp0_status(0xff00);
+	set_cp0_status(0x0400);
+
+	/* setup PCI interrupt attributes */
+	set_pci_int_attr(PCI0, INTA, ACTIVE_LOW, LEVEL_SENSE);
+	set_pci_int_attr(PCI0, INTB, ACTIVE_LOW, LEVEL_SENSE);
+	set_pci_int_attr(PCI0, INTC, ACTIVE_LOW, LEVEL_SENSE);
+	set_pci_int_attr(PCI0, INTD, ACTIVE_LOW, LEVEL_SENSE);
+	set_pci_int_attr(PCI0, INTE, ACTIVE_LOW, LEVEL_SENSE);
+
+	set_pci_int_attr(PCI1, INTA, ACTIVE_LOW, LEVEL_SENSE);
+	set_pci_int_attr(PCI1, INTB, ACTIVE_LOW, LEVEL_SENSE);
+	set_pci_int_attr(PCI1, INTC, ACTIVE_LOW, LEVEL_SENSE);
+	set_pci_int_attr(PCI1, INTD, ACTIVE_LOW, LEVEL_SENSE);
+	set_pci_int_attr(PCI1, INTE, ACTIVE_LOW, LEVEL_SENSE);
+
+	/* 
+	 * for debugging purpose, we enable several error interrupts
+	 * and route them to pin 1. (IP3) 
+	 */
+	/* cpu parity check - 0 */
+	ll_vrc5477_irq_route(0, 1); ll_vrc5477_irq_enable(0);
+	/* cpu no-target decode - 1 */
+	ll_vrc5477_irq_route(1, 1); ll_vrc5477_irq_enable(1);
+	/* local bus read time-out - 7 */
+	ll_vrc5477_irq_route(7, 1); ll_vrc5477_irq_enable(7);
+	/* PCI SERR# - 14 */
+	ll_vrc5477_irq_route(14, 1); ll_vrc5477_irq_enable(14);
+	/* PCI internal error - 15 */
+	ll_vrc5477_irq_route(15, 1); ll_vrc5477_irq_enable(15);
+	/* IOPCI SERR# - 30 */
+	ll_vrc5477_irq_route(30, 1); ll_vrc5477_irq_enable(30);
+	/* IOPCI internal error - 31 */
+	ll_vrc5477_irq_route(31, 1); ll_vrc5477_irq_enable(31);
+
+	/* init all controllers */
+	mips_cpu_irq_init(0);
+	vrc5477_irq_init(8);
+
+	/* hook up the first-level interrupt handler */
+	set_except_vector(0, ddb5477_handle_int);
+}
+
+/*
+ * the first level int-handler will jump here if it is a vrc5477 irq
+ */
+#define	NUM_5477_IRQS	32
+asmlinkage void
+vrc5477_irq_dispatch(struct pt_regs *regs)
+{
+	extern unsigned int do_IRQ(int irq, struct pt_regs *regs);
+
+	u32 intStatus;
+	u32 bitmask;
+	u32 i;
+
+	MIPS_ASSERT(ddb_in32(DDB_INT2STAT) == 0);
+	MIPS_ASSERT(ddb_in32(DDB_INT3STAT) == 0);
+	MIPS_ASSERT(ddb_in32(DDB_INT4STAT) == 0);
+	MIPS_ASSERT(ddb_in32(DDB_NMISTAT) == 0);
+
+	if (ddb_in32(DDB_INT1STAT) != 0) {
+#if defined(CONFIG_LL_DEBUG)
+		vrc5477_show_int_regs();
+#endif
+		panic("error interrupt has happened.\n");
+	}
+
+	intStatus = ddb_in32(DDB_INT0STAT);
+	for (i=0, bitmask=1; i<= NUM_5477_IRQS; bitmask <<=1, i++) {
+		/* do we need to "and" with the int mask? */
+		if (intStatus & bitmask) {
+			do_IRQ(8 + i, regs);
+		}
+	}
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ddb5xxx/ddb5477/irq_5477.c linux/arch/mips/ddb5xxx/ddb5477/irq_5477.c
--- v2.4.9/linux/arch/mips/ddb5xxx/ddb5477/irq_5477.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/ddb5xxx/ddb5477/irq_5477.c	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,179 @@
+/***********************************************************************
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ *  arch/mips/ddb5xxx/ddb5477/irq_5477.c
+ *     This file defines the irq handler for Vrc5477.
+ *
+ * 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.
+ ***********************************************************************
+ */
+
+/*
+ * Vrc5477 defines 32 IRQs.
+ *
+ * This file exports one function:
+ *	vrc5477_irq_init(u32 irq_base);
+ */
+
+#include <linux/irq.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+
+#include <asm/ddb5xxx/ddb5xxx.h>
+
+/* [jsun] sooner or later we should move this debug stuff to MIPS common */
+#include <asm/ddb5xxx/debug.h>
+
+/* number of total irqs supported by Vrc5477 */
+#define	NUM_5477_IRQ		32
+
+static int vrc5477_irq_base=-1;
+
+
+static void 
+vrc5477_irq_enable(unsigned int irq)
+{
+	MIPS_ASSERT(vrc5477_irq_base != -1);
+	MIPS_ASSERT(irq >= vrc5477_irq_base);
+	MIPS_ASSERT(irq < vrc5477_irq_base+ NUM_5477_IRQ);
+
+	ll_vrc5477_irq_enable(irq - vrc5477_irq_base);
+}
+
+static void 
+vrc5477_irq_disable(unsigned int irq)
+{
+	MIPS_ASSERT(vrc5477_irq_base != -1);
+	MIPS_ASSERT(irq >= vrc5477_irq_base);
+	MIPS_ASSERT(irq < vrc5477_irq_base + NUM_5477_IRQ);
+
+	ll_vrc5477_irq_disable(irq - vrc5477_irq_base);
+}
+
+static unsigned int vrc5477_irq_startup(unsigned int irq)
+{
+	vrc5477_irq_enable(irq);
+	return 0;
+}
+
+#define	vrc5477_irq_shutdown	vrc5477_irq_disable
+
+static void
+vrc5477_irq_ack(unsigned int irq)
+{
+	MIPS_ASSERT(vrc5477_irq_base != -1);
+	MIPS_ASSERT(irq >= vrc5477_irq_base);
+	MIPS_ASSERT(irq < vrc5477_irq_base+ NUM_5477_IRQ);
+
+	/* clear the interrupt bit */
+	/* some irqs require the driver to clear the sources */
+	ddb_out32(DDB_INTCLR32, 1 << (irq - vrc5477_irq_base));
+
+	/* disable interrupt - some handler will re-enable the irq
+	 * and if the interrupt is leveled, we will have infinite loop
+	 */
+	ll_vrc5477_irq_disable(irq - vrc5477_irq_base);
+}
+
+static void
+vrc5477_irq_end(unsigned int irq)
+{
+	MIPS_ASSERT(vrc5477_irq_base != -1);
+	MIPS_ASSERT(irq >= vrc5477_irq_base);
+	MIPS_ASSERT(irq < vrc5477_irq_base + NUM_5477_IRQ);
+
+	ll_vrc5477_irq_enable( irq - vrc5477_irq_base);
+}
+
+hw_irq_controller vrc5477_irq_controller = {
+	"vrc5477_irq",
+	vrc5477_irq_startup,
+	vrc5477_irq_shutdown,
+	vrc5477_irq_enable,
+	vrc5477_irq_disable,
+	vrc5477_irq_ack,
+	vrc5477_irq_end,
+	NULL			/* no affinity stuff for UP */
+};
+
+void 
+vrc5477_irq_init(u32 irq_base)
+{
+	extern irq_desc_t irq_desc[];
+	u32 i;
+
+	for (i= irq_base; i< irq_base+ NUM_5477_IRQ; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = NULL;
+		irq_desc[i].depth = 1;
+		irq_desc[i].handler = &vrc5477_irq_controller;
+	}
+	
+	vrc5477_irq_base = irq_base;
+}
+
+
+int vrc5477_irq_to_irq(int irq)
+{
+	MIPS_ASSERT(irq >= 0);
+	MIPS_ASSERT(irq < NUM_5477_IRQ);
+
+	return irq + vrc5477_irq_base;
+}
+
+void ll_vrc5477_irq_route(int vrc5477_irq, int ip)
+{
+	u32 reg_value;
+	u32 reg_bitmask;
+	u32 reg_index;
+
+	MIPS_ASSERT(vrc5477_irq >= 0);
+	MIPS_ASSERT(vrc5477_irq < NUM_5477_IRQ);
+	MIPS_ASSERT(ip >= 0);
+	MIPS_ASSERT((ip < 5) || (ip == 6));
+
+	reg_index = DDB_INTCTRL0 + vrc5477_irq/8*4;
+	reg_value = ddb_in32(reg_index);
+	reg_bitmask = 7 << (vrc5477_irq % 8 * 4);
+	reg_value &= ~reg_bitmask;
+	reg_value |= ip << (vrc5477_irq % 8 * 4);
+	ddb_out32(reg_index, reg_value);
+}
+
+void ll_vrc5477_irq_enable(int vrc5477_irq)
+{
+	u32 reg_value;
+	u32 reg_bitmask;
+	u32 reg_index;
+
+	MIPS_ASSERT(vrc5477_irq >= 0);
+	MIPS_ASSERT(vrc5477_irq < NUM_5477_IRQ);
+
+	reg_index = DDB_INTCTRL0 + vrc5477_irq/8*4;
+	reg_value = ddb_in32(reg_index);
+	reg_bitmask = 8 << (vrc5477_irq % 8 * 4);
+	MIPS_ASSERT((reg_value & reg_bitmask) == 0);
+	ddb_out32(reg_index, reg_value | reg_bitmask);
+}
+
+void ll_vrc5477_irq_disable(int vrc5477_irq)
+{
+	u32 reg_value;
+	u32 reg_bitmask;
+	u32 reg_index;
+
+	MIPS_ASSERT(vrc5477_irq >= 0);
+	MIPS_ASSERT(vrc5477_irq < NUM_5477_IRQ);
+
+	reg_index = DDB_INTCTRL0 + vrc5477_irq/8*4;
+	reg_value = ddb_in32(reg_index);
+	reg_bitmask = 8 << (vrc5477_irq % 8 * 4);
+
+	/* we assert that the interrupt is enabled (perhaps over-zealous) */
+	MIPS_ASSERT( (reg_value & reg_bitmask) != 0);
+	ddb_out32(reg_index, reg_value & ~reg_bitmask);
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ddb5xxx/ddb5477/kgdb_io.c linux/arch/mips/ddb5xxx/ddb5477/kgdb_io.c
--- v2.4.9/linux/arch/mips/ddb5xxx/ddb5477/kgdb_io.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/ddb5xxx/ddb5477/kgdb_io.c	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,142 @@
+
+#include <linux/config.h>
+
+#if (defined(CONFIG_DDB5477) && defined(CONFIG_REMOTE_DEBUG))
+
+/* --- CONFIG --- */
+
+/* we need uint32 uint8 */
+/* #include "types.h" */
+typedef unsigned char uint8;
+typedef unsigned int uint32;
+
+/* --- END OF CONFIG --- */
+
+#define         UART16550_BAUD_2400             2400
+#define         UART16550_BAUD_4800             4800
+#define         UART16550_BAUD_9600             9600
+#define         UART16550_BAUD_19200            19200
+#define         UART16550_BAUD_38400            38400
+#define         UART16550_BAUD_57600            57600
+#define         UART16550_BAUD_115200           115200
+
+#define         UART16550_PARITY_NONE           0
+#define         UART16550_PARITY_ODD            0x08
+#define         UART16550_PARITY_EVEN           0x18
+#define         UART16550_PARITY_MARK           0x28
+#define         UART16550_PARITY_SPACE          0x38
+
+#define         UART16550_DATA_5BIT             0x0
+#define         UART16550_DATA_6BIT             0x1
+#define         UART16550_DATA_7BIT             0x2
+#define         UART16550_DATA_8BIT             0x3
+
+#define         UART16550_STOP_1BIT             0x0
+#define         UART16550_STOP_2BIT             0x4
+
+/* ----------------------------------------------------- */
+
+/* === CONFIG === */
+
+/* [jsun] we use the second serial port for kdb */
+#define         BASE                    0xbfa04240
+#define         MAX_BAUD                115200
+#define		REG_OFFSET		8
+
+/* === END OF CONFIG === */
+
+/* register offset */
+#define         OFS_RCV_BUFFER          (0*REG_OFFSET)
+#define         OFS_TRANS_HOLD          (0*REG_OFFSET)
+#define         OFS_SEND_BUFFER         (0*REG_OFFSET)
+#define         OFS_INTR_ENABLE         (1*REG_OFFSET)
+#define         OFS_INTR_ID             (2*REG_OFFSET)
+#define         OFS_DATA_FORMAT         (3*REG_OFFSET)
+#define         OFS_LINE_CONTROL        (3*REG_OFFSET)
+#define         OFS_MODEM_CONTROL       (4*REG_OFFSET)
+#define         OFS_RS232_OUTPUT        (4*REG_OFFSET)
+#define         OFS_LINE_STATUS         (5*REG_OFFSET)
+#define         OFS_MODEM_STATUS        (6*REG_OFFSET)
+#define         OFS_RS232_INPUT         (6*REG_OFFSET)
+#define         OFS_SCRATCH_PAD         (7*REG_OFFSET)
+
+#define         OFS_DIVISOR_LSB         (0*REG_OFFSET)
+#define         OFS_DIVISOR_MSB         (1*REG_OFFSET)
+
+
+/* memory-mapped read/write of the port */
+#define         UART16550_READ(y)    (*((volatile uint8*)(BASE + y)))
+#define         UART16550_WRITE(y, z)  ((*((volatile uint8*)(BASE + y))) = z)
+
+void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
+{
+	/* disable interrupts */
+	UART16550_WRITE(OFS_INTR_ENABLE, 0);
+
+	/* set up buad rate */
+	{
+		uint32 divisor;
+
+		/* set DIAB bit */
+		UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
+
+		/* set divisor */
+		divisor = MAX_BAUD / baud;
+		UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
+		UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8);
+
+		/* clear DIAB bit */
+		UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
+	}
+
+	/* set data format */
+	UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
+}
+
+static int remoteDebugInitialized = 0;
+
+int debug_state = -1;
+
+uint8 getDebugChar(void)
+{
+	uint8 c;
+	if (!remoteDebugInitialized) {
+		remoteDebugInitialized = 1;
+		debugInit(UART16550_BAUD_38400,
+			  UART16550_DATA_8BIT,
+			  UART16550_PARITY_NONE, UART16550_STOP_1BIT);
+	}
+
+	while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0);
+	c= UART16550_READ(OFS_RCV_BUFFER);
+/*
+	if (state != 1) {
+		state = 1;
+		debug_out("\ngetDebugChar: ", 15);
+	}
+	debug_out(&c, 1);
+*/
+	return c;
+}
+
+
+int putDebugChar(uint8 byte)
+{
+	if (!remoteDebugInitialized) {
+		remoteDebugInitialized = 1;
+		debugInit(UART16550_BAUD_9600,
+			  UART16550_DATA_8BIT,
+			  UART16550_PARITY_NONE, UART16550_STOP_1BIT);
+	}
+
+	while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0);
+	UART16550_WRITE(OFS_SEND_BUFFER, byte);
+	if (debug_state != 2) {
+		debug_state = 2;
+		// debug_out("\nputDebugChar: ", 15);
+	}
+	// debug_out(&byte, 1);
+	return 1;
+}
+
+#endif
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ddb5xxx/ddb5477/pci.c linux/arch/mips/ddb5xxx/ddb5477/pci.c
--- v2.4.9/linux/arch/mips/ddb5xxx/ddb5477/pci.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/ddb5xxx/ddb5477/pci.c	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,147 @@
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+
+#include <asm/ddb5xxx/ddb5xxx.h>
+#include <asm/ddb5xxx/debug.h>
+#include <asm/ddb5xxx/pci.h>
+
+static struct resource extpci_io_resource = {
+	"ext pci IO space", 
+	DDB_PCI0_IO_BASE - DDB_PCI_IO_BASE,
+	DDB_PCI0_IO_BASE - DDB_PCI_IO_BASE + DDB_PCI0_IO_SIZE -1,
+	IORESOURCE_IO};
+
+static struct resource extpci_mem_resource = {
+	"ext pci memory space", 
+	DDB_PCI0_MEM_BASE,
+	DDB_PCI0_MEM_BASE + DDB_PCI0_MEM_SIZE -1,
+	IORESOURCE_MEM};
+
+static struct resource iopci_io_resource = {
+	"io pci IO space", 
+	DDB_PCI1_IO_BASE - DDB_PCI_IO_BASE,
+	DDB_PCI1_IO_BASE - DDB_PCI_IO_BASE + DDB_PCI1_IO_SIZE -1,
+	IORESOURCE_IO};
+
+static struct resource iopci_mem_resource = {
+	"ext pci memory space", 
+	DDB_PCI1_MEM_BASE,
+	DDB_PCI1_MEM_BASE + DDB_PCI1_MEM_SIZE -1,
+	IORESOURCE_MEM};
+
+extern struct pci_ops ddb5477_ext_pci_ops;
+extern struct pci_ops ddb5477_io_pci_ops;
+
+struct pci_channel mips_pci_channels[] = {
+	{ &ddb5477_ext_pci_ops, &extpci_io_resource, &extpci_mem_resource },
+	{ &ddb5477_io_pci_ops, &iopci_io_resource, &iopci_mem_resource },
+	{ NULL, NULL, NULL}
+};
+
+
+/*
+ * we fix up irqs based on the slot number.
+ * The first entry is at AD:11.
+ * Fortunately this works because, although we have two pci buses,
+ * they all have different slot numbers.
+ * 
+ * This does not work for devices on sub-buses.
+ *
+ * Note that the irq number in the array is relative number in vrc5477.
+ * We need to translate it to global irq number.
+ */
+
+/*
+ * irq mapping : PCI int # -> vrc5477 irq #
+ * based on vrc5477 manual page 46
+ */
+#define		PCI_EXT_INTA		8
+#define		PCI_EXT_INTB		9
+#define		PCI_EXT_INTC		10
+#define		PCI_EXT_INTD		11
+#define		PCI_EXT_INTE		12
+
+#define		PCI_IO_INTA		16
+#define		PCI_IO_INTB		17
+#define		PCI_IO_INTC		18
+#define		PCI_IO_INTD		19
+
+/* 
+ * irq mapping : device -> pci int #, 
+ * ddb5477 board manual page 4  and vrc5477 manual page 46
+ */
+#define		INT_ONBOARD_TULIP	PCI_EXT_INTA
+#define		INT_SLOT1		PCI_EXT_INTB
+#define		INT_SLOT2		PCI_EXT_INTC
+#define		INT_SLOT3		PCI_EXT_INTD
+#define		INT_SLOT4		PCI_EXT_INTE
+
+#define		INT_USB_HOST		PCI_IO_INTA
+#define		INT_USB_PERI		PCI_IO_INTB
+#define		INT_AC97		PCI_IO_INTC
+
+/*
+ * based on ddb5477 manual page 11
+ */
+#define		MAX_SLOT_NUM		21
+static unsigned char irq_map[MAX_SLOT_NUM] = {
+	/* AD:11 */ 0xff, 0xff, 0xff, 0xff, 
+	/* AD:15 */ INT_ONBOARD_TULIP, INT_SLOT1, INT_SLOT2, INT_SLOT3,
+	/* AD:19 */ INT_SLOT4, 0xff, 0xff, 0xff,
+	/* AD:23 */ 0xff, 0xff, 0xff, 0xff,
+	/* AD:27 */ 0xff, 0xff, INT_AC97, INT_USB_PERI, 
+	/* AD:31 */ INT_USB_HOST
+};
+
+extern int vrc5477_irq_to_irq(int irq);
+void __init pcibios_fixup_irqs(void)
+{
+        struct pci_dev *dev;
+        int slot_num;
+
+	pci_for_each_dev(dev) {
+		slot_num = PCI_SLOT(dev->devfn);
+		MIPS_ASSERT(slot_num < MAX_SLOT_NUM);
+		MIPS_ASSERT(irq_map[slot_num] != 0xff);
+
+		pci_write_config_byte(dev, 
+				      PCI_INTERRUPT_LINE,
+				      irq_map[slot_num]);
+		dev->irq = vrc5477_irq_to_irq(irq_map[slot_num]);
+	}
+}
+
+#if defined(CONFIG_LL_DEBUG)
+extern void jsun_scan_pci_bus(void);
+extern void jsun_assign_pci_resource(void);
+#endif
+void __init ddb_pci_reset_bus(void)
+{	
+	u32 temp;
+
+	/*
+	 * I am not sure about the "official" procedure, the following
+	 * steps work as far as I know:
+	 * We first set PCI cold reset bit (bit 31) in PCICTRL-H.
+	 * Then we clear the PCI warm reset bit (bit 30) to 0 in PCICTRL-H.
+	 * The same is true for both PCI channels.
+	 */
+	temp = ddb_in32(DDB_PCICTL0_H);
+	temp |= 0x80000000;
+	ddb_out32(DDB_PCICTL0_H, temp);
+	temp &= ~0xc0000000;
+	ddb_out32(DDB_PCICTL0_H, temp);
+
+	temp = ddb_in32(DDB_PCICTL1_H);
+	temp |= 0x80000000;
+	ddb_out32(DDB_PCICTL1_H, temp);
+	temp &= ~0xc0000000;
+	ddb_out32(DDB_PCICTL1_H, temp);
+}
+
+unsigned __init int pcibios_assign_all_busses(void)
+{
+	return 1;
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ddb5xxx/ddb5477/pci_ops.c linux/arch/mips/ddb5xxx/ddb5477/pci_ops.c
--- v2.4.9/linux/arch/mips/ddb5xxx/ddb5477/pci_ops.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/ddb5xxx/ddb5477/pci_ops.c	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,416 @@
+/***********************************************************************
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * arch/mips/ddb5xxx/ddb5477/pci_ops.c
+ *     Define the pci_ops for DB5477.
+ *
+ * Much of the code is derived from the original DDB5074 port by 
+ * Geert Uytterhoeven <geert@sonycom.com>
+ *
+ * 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.
+ ***********************************************************************
+ */
+
+/*
+ * DDB5477 has two PCI channels, external PCI and IOPIC (internal)
+ * Therefore we provide two sets of pci_ops.
+ */
+
+#include <linux/config.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#include <asm/addrspace.h>
+#include <asm/ddb5xxx/debug.h>
+#include <asm/ddb5xxx/ddb5xxx.h>
+
+/*
+ * config_swap structure records what set of pdar/pmr are used
+ * to access pci config space.  It also provides a place hold the
+ * original values for future restoring.
+ */
+struct pci_config_swap {
+	u32 	pdar;
+	u32	pmr;
+	u32	config_base;
+	u32	config_size;
+	u32	pdar_backup;
+	u32	pmr_backup;
+};
+
+/*
+ * On DDB5477, we have two sets of swap registers, for ext PCI and IOPCI.
+ */
+struct pci_config_swap ext_pci_swap = {
+	DDB_PCIW0,  
+	DDB_PCIINIT00,
+	DDB_PCI0_CONFIG_BASE,
+	DDB_PCI0_CONFIG_SIZE
+};
+struct pci_config_swap io_pci_swap = {
+	DDB_IOPCIW0,  
+	DDB_PCIINIT01,
+	DDB_PCI1_CONFIG_BASE,
+	DDB_PCI1_CONFIG_SIZE
+};
+
+
+/*
+ * access config space
+ */	
+static inline u32 ddb_access_config_base(struct pci_config_swap *swap,
+					 u32 bus,/* 0 means top level bus */
+					 u32 slot_num)
+{
+	u32 pci_addr = 0;
+	u32 pciinit_offset = 0;
+        u32 virt_addr = swap->config_base;
+	u32 option;
+
+	/* [jsun] hack for testing */
+	// if (slot_num == 4) slot_num = 0;
+
+	/* minimum pdar (window) size is 2MB */
+	MIPS_ASSERT(swap->config_size >= (2 << 20));
+
+	MIPS_ASSERT(slot_num < (1 << 5));
+	MIPS_ASSERT(bus < (1 << 8));
+
+	/* backup registers */
+	swap->pdar_backup = ddb_in32(swap->pdar);
+	swap->pmr_backup = ddb_in32(swap->pmr);
+
+	/* set the pdar (pci window) register */
+	ddb_set_pdar(swap->pdar,
+		     swap->config_base,
+		     swap->config_size,
+		     32,	/* 32 bit wide */
+		     0,		/* not on local memory bus */
+		     0);	/* not visible from PCI bus (N/A) */
+
+	/* 
+	 * calcuate the absolute pci config addr; 
+	 * according to the spec, we start scanning from adr:11 (0x800)
+	 */ 
+	if (bus == 0) {
+		/* type 0 config */
+		pci_addr = 0x800 << slot_num;
+	} else {
+		/* type 1 config */
+		pci_addr = (bus << 16) | (slot_num << 11);
+		panic("ddb_access_config_base: we don't support type 1 config Yet");
+	}
+
+	/*
+	 * if pci_addr is less than pci config window size,  we set
+	 * pciinit_offset to 0 and adjust the virt_address.
+	 * Otherwise we will try to adjust pciinit_offset.
+	 */
+	if (pci_addr < swap->config_size) {
+		virt_addr = KSEG1ADDR(swap->config_base + pci_addr);
+		pciinit_offset = 0;
+	} else {
+		MIPS_ASSERT( (pci_addr & (swap->config_size - 1)) == 0);
+		virt_addr = KSEG1ADDR(swap->config_base);
+		pciinit_offset = pci_addr;
+	}
+
+	/* set the pmr register */
+	option = DDB_PCI_ACCESS_32;
+	if (bus != 0) option |= DDB_PCI_CFGTYPE1;
+	ddb_set_pmr(swap->pmr, DDB_PCICMD_CFG, pciinit_offset, option);
+
+	return virt_addr;
+}
+
+static inline void ddb_close_config_base(struct pci_config_swap *swap)
+{
+	ddb_out32(swap->pdar, swap->pdar_backup);
+	ddb_out32(swap->pmr, swap->pmr_backup);
+}
+
+static int read_config_dword(struct pci_config_swap *swap,
+			     struct pci_dev *dev,
+			     u32 where,
+			     u32 *val)
+{
+	u32 bus, slot_num, func_num;
+	u32 base;
+
+	MIPS_ASSERT((where & 3) == 0);
+	MIPS_ASSERT(where < (1 << 8));
+
+	/* check if the bus is top-level */
+	if (dev->bus->parent != NULL) {
+		bus = dev->bus->number;
+		MIPS_ASSERT(bus != 0);
+	} else {
+		bus = 0;
+	}
+
+	slot_num = PCI_SLOT(dev->devfn);
+	func_num = PCI_FUNC(dev->devfn);
+	base = ddb_access_config_base(swap, bus, slot_num);
+	*val = *(volatile u32*) (base + (func_num << 8) + where);
+	ddb_close_config_base(swap);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int read_config_word(struct pci_config_swap *swap,
+			    struct pci_dev *dev,
+			    u32 where,
+			    u16 *val)
+{
+        int status;
+        u32 result;
+
+	MIPS_ASSERT((where & 1) == 0);
+
+        status = read_config_dword(swap, dev, where & ~3, &result);
+        if (where & 2) result >>= 16;
+        *val = result & 0xffff;
+        return status;
+}
+
+static int read_config_byte(struct pci_config_swap *swap,
+			    struct pci_dev *dev,
+			    u32 where,
+			    u8 *val)
+{
+        int status;
+        u32 result;
+
+        status = read_config_dword(swap, dev, where & ~3, &result);
+        if (where & 1) result >>= 8;
+        if (where & 2) result >>= 16;
+        *val = result & 0xff;
+        return status;
+}
+
+static int write_config_dword(struct pci_config_swap *swap,
+			      struct pci_dev *dev,
+			      u32 where,
+			      u32 val)
+{
+	u32 bus, slot_num, func_num;
+	u32 base;
+
+	MIPS_ASSERT((where & 3) == 0);
+	MIPS_ASSERT(where < (1 << 8));
+
+	/* check if the bus is top-level */
+	if (dev->bus->parent != NULL) {
+		bus = dev->bus->number;
+		MIPS_ASSERT(bus != 0);
+	} else {
+		bus = 0;
+	}
+
+	slot_num = PCI_SLOT(dev->devfn);
+	func_num = PCI_FUNC(dev->devfn);
+	base = ddb_access_config_base(swap, bus, slot_num);
+	*(volatile u32*) (base + (func_num << 8) + where) = val; 
+	ddb_close_config_base(swap);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int write_config_word(struct pci_config_swap *swap,
+			     struct pci_dev *dev,
+			     u32 where,
+			     u16 val)
+{
+	int status, shift=0;
+	u32 result;
+
+	MIPS_ASSERT((where & 1) == 0);
+
+	status = read_config_dword(swap, dev, where & ~3, &result);
+	if (status != PCIBIOS_SUCCESSFUL) return status;
+
+        if (where & 2)
+                shift += 16;
+        result &= ~(0xffff << shift);
+        result |= val << shift;
+        return write_config_dword(swap, dev, where & ~3, result);
+}
+
+static int write_config_byte(struct pci_config_swap *swap,
+			     struct pci_dev *dev,
+			     u32 where,
+			     u8 val)
+{
+	int status, shift=0;
+	u32 result;
+
+	status = read_config_dword(swap, dev, where & ~3, &result);
+	if (status != PCIBIOS_SUCCESSFUL) return status;
+
+        if (where & 2)
+                shift += 16;
+        if (where & 1)
+                shift += 8;
+        result &= ~(0xff << shift);
+        result |= val << shift;
+        return write_config_dword(swap, dev, where & ~3, result);
+}
+
+#define	MAKE_PCI_OPS(prefix, rw, unitname, unittype, pciswap) \
+static int prefix##_##rw##_config_##unitname(struct pci_dev *dev, int where, unittype val) \
+{ \
+     return rw##_config_##unitname(pciswap, \
+                                   dev, \
+                                   where, \
+                                   val); \
+}
+
+MAKE_PCI_OPS(extpci, read, byte, u8 *, &ext_pci_swap)
+MAKE_PCI_OPS(extpci, read, word, u16 *, &ext_pci_swap)
+MAKE_PCI_OPS(extpci, read, dword, u32 *, &ext_pci_swap)
+
+MAKE_PCI_OPS(iopci, read, byte, u8 *, &io_pci_swap)
+MAKE_PCI_OPS(iopci, read, word, u16 *, &io_pci_swap)
+MAKE_PCI_OPS(iopci, read, dword, u32 *, &io_pci_swap)
+
+MAKE_PCI_OPS(extpci, write, byte, u8, &ext_pci_swap)
+MAKE_PCI_OPS(extpci, write, word, u16, &ext_pci_swap)
+MAKE_PCI_OPS(extpci, write, dword, u32, &ext_pci_swap)
+
+MAKE_PCI_OPS(iopci, write, byte, u8, &io_pci_swap)
+MAKE_PCI_OPS(iopci, write, word, u16, &io_pci_swap)
+MAKE_PCI_OPS(iopci, write, dword, u32, &io_pci_swap)
+
+struct pci_ops ddb5477_ext_pci_ops ={
+	extpci_read_config_byte,
+	extpci_read_config_word,
+	extpci_read_config_dword,
+	extpci_write_config_byte,
+	extpci_write_config_word,
+	extpci_write_config_dword
+};
+
+
+struct pci_ops ddb5477_io_pci_ops ={
+	iopci_read_config_byte,
+	iopci_read_config_word,
+	iopci_read_config_dword,
+	iopci_write_config_byte,
+	iopci_write_config_word,
+	iopci_write_config_dword
+};
+
+#if defined(CONFIG_LL_DEBUG)
+void jsun_scan_pci_bus(void)
+{
+	struct pci_bus bus;
+	struct pci_dev dev;
+	unsigned int devfn;
+	int j;
+
+	bus.parent = NULL;	/* we scan the top level only */
+	dev.bus = &bus;
+	dev.sysdata = NULL;
+
+	/* scan ext pci bus and io pci bus*/
+	for (j=0; j< 2; j++) {
+		if (j ==  0) {
+			printk("scan ddb5477 external PCI bus:\n");
+			bus.ops = &ddb5477_ext_pci_ops;
+		} else {
+			printk("scan ddb5477 IO PCI bus:\n");
+			bus.ops = &ddb5477_io_pci_ops;
+		}
+	
+		for (devfn = 0; devfn < 0x100; devfn += 8) {
+			u32 temp;
+			u16 temp16;
+			u8 temp8;
+			int i;
+
+			dev.devfn = devfn;
+			MIPS_VERIFY(pci_read_config_dword(&dev, 0, &temp),
+				    == PCIBIOS_SUCCESSFUL);
+			if (temp == 0xffffffff) continue;
+
+			printk("slot %d: (addr %d) \n", devfn/8, 11+devfn/8);
+
+			/* verify read word and byte */
+			MIPS_VERIFY(pci_read_config_word(&dev, 2, &temp16),
+				    == PCIBIOS_SUCCESSFUL);
+			MIPS_ASSERT(temp16 == (temp >> 16));
+			MIPS_VERIFY(pci_read_config_byte(&dev, 3, &temp8),
+				    == PCIBIOS_SUCCESSFUL);
+			MIPS_ASSERT(temp8 == (temp >> 24));
+			MIPS_VERIFY(pci_read_config_byte(&dev, 1, &temp8),
+				    == PCIBIOS_SUCCESSFUL);
+			MIPS_ASSERT(temp8 == ((temp >> 8) & 0xff));
+
+			for (i=0; i < 16; i++) {
+				MIPS_VERIFY(pci_read_config_dword(&dev, i*4, &temp),
+					    == PCIBIOS_SUCCESSFUL);
+				printk("\t%08X", temp);
+				if ((i%4) == 3) printk("\n");
+			}
+		}
+	}
+}
+
+
+static void jsun_hardcode_pci_resources_eepro(void)
+{
+	struct pci_bus bus;
+	struct pci_dev dev;
+	u32 temp;
+
+	bus.parent = NULL;	/* we scan the top level only */
+	bus.ops = &ddb5477_ext_pci_ops;
+	dev.bus = &bus;
+	dev.sysdata = NULL;
+
+	/* for slot 5 (ext pci 1) eepro card */
+	dev.devfn = 5*8;
+	pci_read_config_dword(&dev, 0, &temp);
+	MIPS_ASSERT(temp == 0x12298086);
+
+	pci_write_config_dword(&dev, PCI_BASE_ADDRESS_0, DDB_PCI0_MEM_BASE);
+	pci_write_config_dword(&dev, PCI_BASE_ADDRESS_1, 0);
+	pci_write_config_dword(&dev, PCI_BASE_ADDRESS_2, DDB_PCI0_MEM_BASE+0x100000);
+	pci_write_config_dword(&dev, PCI_INTERRUPT_LINE, 17);
+}
+
+static void jsun_hardcode_pci_resources_onboard_tulip(void)
+{
+	struct pci_bus bus;
+	struct pci_dev dev;
+	u32 temp;
+
+	bus.parent = NULL;	/* we scan the top level only */
+	bus.ops = &ddb5477_ext_pci_ops;
+	dev.bus = &bus;
+	dev.sysdata = NULL;
+
+	/* for slot 4 on board ether chip */
+	dev.devfn = 4*8;
+	pci_read_config_dword(&dev, 0, &temp);
+	MIPS_ASSERT(temp == 0x00191011);
+
+	pci_write_config_dword(&dev, PCI_BASE_ADDRESS_0, 0x1000);
+	pci_write_config_dword(&dev, PCI_BASE_ADDRESS_1, DDB_PCI0_MEM_BASE);
+	pci_write_config_dword(&dev, PCI_INTERRUPT_LINE, 16);
+}
+
+static void jsun_hardcode_pci_resources(void)
+{
+	jsun_hardcode_pci_resources_onboard_tulip();
+}
+
+void jsun_assign_pci_resource(void)
+{
+	jsun_hardcode_pci_resources();
+}
+
+#endif
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ddb5xxx/ddb5477/setup.c linux/arch/mips/ddb5xxx/ddb5477/setup.c
--- v2.4.9/linux/arch/mips/ddb5xxx/ddb5477/setup.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/ddb5xxx/ddb5477/setup.c	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,251 @@
+/***********************************************************************
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * arch/mips/ddb5xxx/ddb5477/setup.c
+ *     Setup file for DDB5477.
+ *
+ * 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/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/kdev_t.h>
+#include <linux/types.h>
+#include <linux/console.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/ide.h>
+#include <linux/fs.h>		/* for ROOT_DEV */
+#include <linux/ioport.h>
+#include <linux/param.h>	/* for HZ */
+
+#include <asm/addrspace.h>
+#include <asm/time.h>
+#include <asm/bcache.h>
+#include <asm/irq.h>
+#include <asm/reboot.h>
+#include <asm/gdb-stub.h>
+
+#include <asm/ddb5xxx/ddb5xxx.h>
+
+
+
+#define	USE_CPU_COUNTER_TIMER	/* whether we use cpu counter */
+
+#ifdef USE_CPU_COUNTER_TIMER
+#define	CPU_COUNTER_FREQUENCY		83000000
+#else
+/* otherwise we use special timer 1 */
+#define	SP_TIMER_FREQUENCY		83000000
+#define	SP_TIMER_BASE			DDB_SPT1CTRL_L
+#define	SP_TIMER_IRQ			(8 + 6)
+#endif
+
+static void ddb_machine_restart(char *command)
+{
+	static void (*back_to_prom) (void) = (void (*)(void)) 0xbfc00000;
+
+	u32 t;
+
+	/* PCI cold reset */
+	ddb_pci_reset_bus();
+
+	/* CPU cold reset */
+	t = ddb_in32(DDB_CPUSTAT);
+	MIPS_ASSERT((t&1));
+	ddb_out32(DDB_CPUSTAT, t);
+
+	/* Call the PROM */
+	back_to_prom();
+}
+
+static void ddb_machine_halt(void)
+{
+	printk("DDB Vrc-5477 halted.\n");
+	while (1);
+}
+
+static void ddb_machine_power_off(void)
+{
+	printk("DDB Vrc-5477 halted. Please turn off the power.\n");
+	while (1);
+}
+
+extern void rtc_ds1386_init(unsigned long base);
+static void __init ddb_time_init(void)
+{
+#if defined(USE_CPU_COUNTER_TIMER)
+	mips_counter_frequency = CPU_COUNTER_FREQUENCY;
+#endif
+
+	/* we have ds1396 RTC chip */
+	rtc_ds1386_init(KSEG1ADDR(DDB_LCS1_BASE));
+}
+
+#if defined(CONFIG_LL_DEBUG)
+int  board_init_done_flag = 0;
+#endif
+
+extern int setup_irq(unsigned int irq, struct irqaction *irqaction);
+static void __init ddb_timer_setup(struct irqaction *irq)
+{
+#if defined(USE_CPU_COUNTER_TIMER)
+	unsigned int count;
+
+        /* we are using the cpu counter for timer interrupts */
+	setup_irq(7, irq);
+
+        /* to generate the first timer interrupt */
+        count = read_32bit_cp0_register(CP0_COUNT);
+        write_32bit_cp0_register(CP0_COMPARE, count + 1000);
+
+#else
+
+	/* if we don't use Special purpose timer 1 */
+	ddb_out32(SP_TIMER_BASE, SP_TIMER_FREQUENCY/HZ);
+	ddb_out32(SP_TIMER_BASE+4, 0x1);
+	setup_irq(SP_TIMER_IRQ, irq);
+
+#endif
+	
+	/* this is the last board dependent code */
+	MIPS_DEBUG(board_init_done_flag = 1);
+}
+
+static void ddb5477_board_init(void);
+extern void ddb5477_irq_setup(void);
+
+#if defined(CONFIG_BLK_DEV_INITRD)
+extern unsigned long __rd_start, __rd_end, initrd_start, initrd_end;
+#endif 
+
+void __init ddb_setup(void)
+{
+	extern int panic_timeout;
+
+	irq_setup = ddb5477_irq_setup;
+	mips_io_port_base = KSEG1ADDR(DDB_PCI_IO_BASE);
+
+	board_time_init = ddb_time_init;
+	board_timer_setup = ddb_timer_setup;
+
+	_machine_restart = ddb_machine_restart;
+	_machine_halt = ddb_machine_halt;
+	_machine_power_off = ddb_machine_power_off;
+
+	/* setup resource limits */
+	ioport_resource.end = DDB_PCI0_IO_SIZE + DDB_PCI1_IO_SIZE - 1;
+	iomem_resource.end = 0xffffffff;
+	
+	/* Reboot on panic */
+	panic_timeout = 180;
+
+	/* initialize board - we don't trust the loader */
+	ddb5477_board_init();
+
+#if defined(CONFIG_BLK_DEV_INITRD)
+	ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+	initrd_start = (unsigned long)&__rd_start;
+	initrd_end = (unsigned long)&__rd_end;
+#endif
+
+}
+
+static void __init ddb5477_board_init()
+{
+	/* ----------- setup PDARs ------------ */
+
+	/* SDRAM should have been set */
+	MIPS_ASSERT(ddb_in32(DDB_SDRAM0) == 
+		    ddb_calc_pdar(DDB_SDRAM_BASE, DDB_SDRAM_SIZE, 32, 0, 1));
+
+	/* SDRAM1 should be turned off.  What is this for anyway ? */
+	MIPS_ASSERT( (ddb_in32(DDB_SDRAM1) & 0xf) == 0);
+
+	/* Set LDCSs */
+	/* flash */
+	ddb_set_pdar(DDB_LCS0, DDB_LCS0_BASE, DDB_LCS0_SIZE, 16, 0, 0);
+	/* misc */
+	ddb_set_pdar(DDB_LCS1, DDB_LCS1_BASE, DDB_LCS1_SIZE, 8, 0, 0);
+	/* mezzanie (?) */
+	ddb_set_pdar(DDB_LCS2, DDB_LCS2_BASE, DDB_LCS2_SIZE, 16, 0, 0);
+
+	/* verify VRC5477 base addr */
+	MIPS_ASSERT(ddb_in32(DDB_VRC5477) == 
+		    ddb_calc_pdar(DDB_VRC5477_BASE, DDB_VRC5477_SIZE, 32, 0, 1));
+	
+	/* verify BOOT ROM addr */
+	MIPS_ASSERT(ddb_in32(DDB_BOOTCS) == 
+		    ddb_calc_pdar(DDB_BOOTCS_BASE, DDB_BOOTCS_SIZE, 8, 0, 0));
+
+	/* setup PCI windows - window0 for MEM/config, window1 for IO */
+	ddb_set_pdar(DDB_PCIW0, DDB_PCI0_MEM_BASE, DDB_PCI0_MEM_SIZE, 32, 0, 1);
+	ddb_set_pdar(DDB_PCIW1, DDB_PCI0_IO_BASE, DDB_PCI0_IO_SIZE, 32, 0, 1);
+	ddb_set_pdar(DDB_IOPCIW0, DDB_PCI1_MEM_BASE, DDB_PCI1_MEM_SIZE, 32, 0, 1);
+	ddb_set_pdar(DDB_IOPCIW1, DDB_PCI1_IO_BASE, DDB_PCI1_IO_SIZE, 32, 0, 1);
+
+	/* ------------ reset PCI bus and BARs ----------------- */
+	ddb_pci_reset_bus();
+
+	ddb_out32(DDB_BARM010, 0x00000008);
+	ddb_out32(DDB_BARM011, 0x00000008);
+
+	ddb_out32(DDB_BARC0, 0xffffffff);
+	ddb_out32(DDB_BARM230, 0xffffffff);
+	ddb_out32(DDB_BAR00, 0xffffffff);
+	ddb_out32(DDB_BAR10, 0xffffffff);
+	ddb_out32(DDB_BAR20, 0xffffffff);
+	ddb_out32(DDB_BAR30, 0xffffffff);
+	ddb_out32(DDB_BAR40, 0xffffffff);
+	ddb_out32(DDB_BAR50, 0xffffffff);
+	ddb_out32(DDB_BARB0, 0xffffffff);
+
+	ddb_out32(DDB_BARC1, 0xffffffff);
+	ddb_out32(DDB_BARM231, 0xffffffff);
+	ddb_out32(DDB_BAR01, 0xffffffff);
+	ddb_out32(DDB_BAR11, 0xffffffff);
+	ddb_out32(DDB_BAR21, 0xffffffff);
+	ddb_out32(DDB_BAR31, 0xffffffff);
+	ddb_out32(DDB_BAR41, 0xffffffff);
+	ddb_out32(DDB_BAR51, 0xffffffff);
+	ddb_out32(DDB_BARB1, 0xffffffff);
+
+	/* 
+	 * We use pci master register 0  for memory space / config space
+	 * And we use register 1 for IO space.
+	 * Note that for memory space, we bump up the pci base address
+	 * so that we have 1:1 mapping between PCI memory and cpu physical.
+	 * For PCI IO space, it starts from 0 in PCI IO space but with
+	 * DDB_xx_IO_BASE in CPU physical address space.
+	 */
+	ddb_set_pmr(DDB_PCIINIT00, DDB_PCICMD_MEM, DDB_PCI0_MEM_BASE, 
+		    DDB_PCI_ACCESS_32);
+	ddb_set_pmr(DDB_PCIINIT10, DDB_PCICMD_IO, 0, DDB_PCI_ACCESS_32);
+
+	ddb_set_pmr(DDB_PCIINIT01, DDB_PCICMD_MEM, DDB_PCI1_MEM_BASE, 
+		    DDB_PCI_ACCESS_32);
+	ddb_set_pmr(DDB_PCIINIT11, DDB_PCICMD_IO, DDB_PCI0_IO_SIZE, 
+                    DDB_PCI_ACCESS_32);
+
+	
+	/* PCI cross window should be set properly */
+	ddb_set_pdar(DDB_BARP00, DDB_PCI1_MEM_BASE, DDB_PCI1_MEM_SIZE, 32, 0, 1);
+	ddb_set_pdar(DDB_BARP10, DDB_PCI1_IO_BASE, DDB_PCI1_IO_SIZE, 32, 0, 1);
+	ddb_set_pdar(DDB_BARP01, DDB_PCI0_MEM_BASE, DDB_PCI0_MEM_SIZE, 32, 0, 1);
+	ddb_set_pdar(DDB_BARP11, DDB_PCI0_IO_BASE, DDB_PCI0_IO_SIZE, 32, 0, 1);
+
+	/* enable USB input buffers */
+	ddb_out32(DDB_PIBMISC, 0x00000007);
+
+	/* For dual-function pins, make them all non-GPIO */
+	ddb_out32(DDB_GIUFUNSEL, 0x0);
+	// ddb_out32(DDB_GIUFUNSEL, 0xfe0fcfff);  /* NEC recommanded value */
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips/dec/Makefile linux/arch/mips/dec/Makefile
--- v2.4.9/linux/arch/mips/dec/Makefile	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/dec/Makefile	Sun Sep  9 10:43:01 2001
@@ -19,7 +19,6 @@
 obj-y	 := int-handler.o setup.o irq.o time.o reset.o rtc-dec.o wbflush.o
 
 obj-$(CONFIG_PROM_CONSOLE)	+= promcon.o
-obj-$(CONFIG_SERIAL)		+= serial.o
 
 int-handler.o:	int-handler.S
 
diff -u --recursive --new-file v2.4.9/linux/arch/mips/dec/int-handler.S linux/arch/mips/dec/int-handler.S
--- v2.4.9/linux/arch/mips/dec/int-handler.S	Fri Jun 25 17:40:12 1999
+++ linux/arch/mips/dec/int-handler.S	Sun Sep  9 10:43:01 2001
@@ -2,6 +2,7 @@
  * arch/mips/dec/int-handler.S
  *
  * Copyright (C) 1995, 1996, 1997 Paul M. Antoine and Harald Koerfgen
+ * Copyright (C) 2000  Maciej W. Rozycki
  *
  * Written by Ralf Baechle and Andreas Busse, modified for DECStation
  * support by Paul Antoine and Harald Koerfgen.
@@ -16,6 +17,11 @@
 #include <asm/stackframe.h>
 #include <asm/addrspace.h>
 
+#include <asm/dec/kn01.h>
+#include <asm/dec/kn02.h>
+#include <asm/dec/kn02xa.h>
+#include <asm/dec/kn03.h>
+#include <asm/dec/ioasic_addrs.h>
 #include <asm/dec/interrupts.h>
 
 
@@ -24,8 +30,6 @@
 /*
  * decstation_handle_int: Interrupt handler for DECStations
  *
- * FIXME: Detection of spurious interrupts not yet implemented!
- *
  * We follow the model in the Indy interrupt code by David Miller, where he
  * says: a lot of complication here is taken away because:
  *
@@ -139,12 +143,12 @@
 		la	t1,cpu_mask_tbl
 		and	t0,t2			# isolate allowed ones
 
-		/* insert detection of spurious interrupts here */
+		beqz	t0,spurious
 
 		/*
 		 * Find irq with highest priority
 		 */
-1:		lw	t2,(t1)
+1:		 lw	t2,(t1)
 		move	t3,t0
 		and	t3,t2
 		beq	t3,zero,1b
@@ -156,18 +160,18 @@
 		lw	a0,%lo(cpu_irq_nr-cpu_mask_tbl-PTRSIZE)(t1)
 		lw	t0,%lo(cpu_ivec_tbl-cpu_mask_tbl-PTRSIZE)(t1)
 		bgez	a0, handle_it		# irq_nr >= 0?
-						# irq_nr < 0: a0 contains an address
-		nop
+						# irq_nr < 0: t0 contains an address
+		 nop
 		jr	t0
 		 nop				# delay slot
 
 /*
  * Handle "IRQ Controller" Interrupts
  * Masked Interrupts are still visible and have to be masked "by hand".
- * %hi(KN02_CSR_ADDR) does not work so all addresses are hardcoded :-(.
  */
 		EXPORT(kn02_io_int)
-kn02_io_int:	lui	t0,0xbff0		# get interrupt status and mask
+kn02_io_int:					# 3max
+		lui	t0,KN02_CSR_ADDR>>16	# get interrupt status and mask
 		lw	t0,(t0)
 		la	t1,asic_mask_tbl
 		move	t3,t0
@@ -176,27 +180,32 @@
 		 and	t0,t3			# mask out allowed ones
 
 		EXPORT(kn03_io_int)
-kn03_io_int:	lui	t2,0xbf84		# upper part of IOASIC Address
-		lw	t0,0x0110(t2)		# get status: IOASIC isr
-		lw	t3,0x0120(t2)		# get mask:   IOASIC isrm
+kn03_io_int:					# 3max+
+		lui	t2,KN03_IOASIC_BASE>>16	# upper part of IOASIC Address
+		lw	t0,SIR(t2)		# get status: IOASIC isr
+		lw	t3,SIMR(t2)		# get mask:   IOASIC isrm
 		la	t1,asic_mask_tbl
 		b	find_int
 		 and	t0,t3			# mask out allowed ones
 
-		EXPORT(kn02ba_io_int)
-kn02ba_io_int:	lui	t2,0xbc04		
-		lw	t0,0x0110(t2)		# IOASIC isr, works for maxine also
-		lw	t3,0x0120(t2)		# IOASIC isrm
+		EXPORT(kn02xa_io_int)
+kn02xa_io_int:					# 3min/maxine
+		lui	t2,KN02XA_IOASIC_BASE>>16		
+						# upper part of IOASIC Address
+		lw	t0,SIR(t2)		# get status: IOASIC isr
+		lw	t3,SIMR(t2)		# get mask:   IOASIC isrm
 		la	t1,asic_mask_tbl
 		and	t0,t3
 
 		/*
 		 * Find irq with highest priority
 		 */
-find_int:	lw	t2,(t1)
+find_int:	beqz	t0,spurious
+
+1:		 lw	t2,(t1)
 		move	t3,t0
 		and	t3,t2
-		beq	zero,t3,find_int
+		beq	zero,t3,1b
 		 addu	t1,PTRSIZE		# delay slot
 
 		/*
@@ -209,7 +218,10 @@
 		 move	a1,sp
 		j	ret_from_irq
 		 nop
-		
+
+spurious:
+		j	spurious_interrupt
+		 nop
 		END(decstation_handle_int)
 /*
   * Interrupt routines common to all DECStations first.
@@ -218,14 +230,6 @@
 dec_intr_fpu:	PANIC("Unimplemented FPU interrupt handler")
 
 /*
- * Halt interrupt
- */
-		EXPORT(intr_halt)
-intr_halt:	la	k0,0xbc000000
-		jr	k0
-		 nop
-
-/*
  * Generic unimplemented interrupt routines - ivec_tbl is initialised to
  * point all interrupts here.  The table is then filled in by machine-specific
  * initialisation in dec_setup().
@@ -358,5 +362,3 @@
 		.word	0
 		.word	0
 		.word	0xffffffff		# EOL
-
-
diff -u --recursive --new-file v2.4.9/linux/arch/mips/dec/irq.c linux/arch/mips/dec/irq.c
--- v2.4.9/linux/arch/mips/dec/irq.c	Fri Feb  9 11:29:44 2001
+++ linux/arch/mips/dec/irq.c	Sun Sep  9 10:43:01 2001
@@ -2,9 +2,7 @@
  * Code to handle DECstation IRQs plus some generic interrupt stuff.
  *
  * Copyright (C) 1992 Linus Torvalds
- * Copyright (C) 1994, 1995, 1996, 1997 Ralf Baechle
- *
- * $Id: irq.c,v 1.6 2000/02/04 07:40:23 ralf Exp $
+ * Copyright (C) 1994, 1995, 1996, 1997, 2000 Ralf Baechle
  */
 #include <linux/errno.h>
 #include <linux/init.h>
@@ -27,9 +25,14 @@
 
 #include <asm/dec/interrupts.h>
 
-extern volatile unsigned int *isr;	/* address of the interrupt status register     */
-extern volatile unsigned int *imr;	/* address of the interrupt mask register       */
-extern decint_t dec_interrupt[NR_INTS];
+extern void dec_init_kn01(void);
+extern void dec_init_kn230(void);
+extern void dec_init_kn02(void);
+extern void dec_init_kn02ba(void);
+extern void dec_init_kn02ca(void);
+extern void dec_init_kn03(void);
+
+extern asmlinkage void decstation_handle_int(void);
 
 unsigned long spurious_count = 0;
 
@@ -42,7 +45,7 @@
 	dummy = *imr;
 	dummy = *imr;
     } else			/* This is a cpu interrupt        */
-	set_cp0_status(ST0_IM, read_32bit_cp0_register(CP0_STATUS) & ~dec_interrupt[irq_nr].cpu_mask);
+	change_cp0_status(ST0_IM, read_32bit_cp0_register(CP0_STATUS) & ~dec_interrupt[irq_nr].cpu_mask);
 }
 
 static inline void unmask_irq(unsigned int irq_nr)
@@ -54,7 +57,7 @@
 	dummy = *imr;
 	dummy = *imr;
     }
-    set_cp0_status(ST0_IM, read_32bit_cp0_register(CP0_STATUS) | dec_interrupt[irq_nr].cpu_mask);
+    change_cp0_status(ST0_IM, read_32bit_cp0_register(CP0_STATUS) | dec_interrupt[irq_nr].cpu_mask);
 }
 
 void disable_irq(unsigned int irq_nr)
@@ -125,7 +128,7 @@
     int do_random, cpu;
 
     cpu = smp_processor_id();
-    irq_enter(cpu);
+    irq_enter(cpu, irq);
     kstat.irqs[cpu][irq]++;
 
     mask_irq(irq);
@@ -142,10 +145,10 @@
 	} while (action);
 	if (do_random & SA_SAMPLE_RANDOM)
 	    add_interrupt_randomness(irq);
-	unmask_irq(irq);
 	__cli();
+	unmask_irq(irq);
     }
-    irq_exit(cpu);
+    irq_exit(cpu, irq);
 
     /* unmasking and bottom half handling is done magically for us. */
 }
@@ -261,5 +264,34 @@
 
 void __init init_IRQ(void)
 {
-    irq_setup();
+    switch (mips_machtype) {
+    case MACH_DS23100:
+	dec_init_kn01();
+	break;
+    case MACH_DS5100:		/*  DS5100 MIPSMATE */
+	dec_init_kn230();
+	break;
+    case MACH_DS5000_200:	/* DS5000 3max */
+	dec_init_kn02();
+	break;
+    case MACH_DS5000_1XX:	/* DS5000/100 3min */
+	dec_init_kn02ba();
+	break;
+    case MACH_DS5000_2X0:	/* DS5000/240 3max+ */
+	dec_init_kn03();
+	break;
+    case MACH_DS5000_XX:	/* Personal DS5000/2x */
+	dec_init_kn02ca();
+	break;
+    case MACH_DS5800:		/* DS5800 Isis */
+	panic("Don't know how to set this up!");
+	break;
+    case MACH_DS5400:		/* DS5400 MIPSfair */
+	panic("Don't know how to set this up!");
+	break;
+    case MACH_DS5500:		/* DS5500 MIPSfair-2 */
+	panic("Don't know how to set this up!");
+	break;
+    }
+    set_except_vector(0, decstation_handle_int);
 }
diff -u --recursive --new-file v2.4.9/linux/arch/mips/dec/prom/cmdline.c linux/arch/mips/dec/prom/cmdline.c
--- v2.4.9/linux/arch/mips/dec/prom/cmdline.c	Mon Feb 28 07:18:20 2000
+++ linux/arch/mips/dec/prom/cmdline.c	Sun Sep  9 10:43:01 2001
@@ -2,8 +2,6 @@
  * cmdline.c: read the command line passed to us by the PROM.
  *
  * Copyright (C) 1998 Harald Koerfgen
- *
- * $Id: cmdline.c,v 1.2 1999/10/09 00:00:57 ralf Exp $
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -19,7 +17,7 @@
 extern int (*prom_printf)(char *, ...);
 #endif
 
-char arcs_cmdline[CL_SIZE];
+char arcs_cmdline[COMMAND_LINE_SIZE];
 
 void __init prom_init_cmdline(int argc, char **argv, unsigned long magic)
 {
diff -u --recursive --new-file v2.4.9/linux/arch/mips/dec/prom/init.c linux/arch/mips/dec/prom/init.c
--- v2.4.9/linux/arch/mips/dec/prom/init.c	Sat May 13 08:29:14 2000
+++ linux/arch/mips/dec/prom/init.c	Sun Sep  9 10:43:01 2001
@@ -2,12 +2,11 @@
  * init.c: PROM library initialisation code.
  *
  * Copyright (C) 1998 Harald Koerfgen
- *
- * $Id: init.c,v 1.3 1999/08/09 19:43:13 harald Exp $
  */
 #include <linux/init.h>
 #include <linux/config.h>
 #include <asm/bootinfo.h>
+#include <asm/cpu.h>
 #include "prom.h"
 
 /*
@@ -93,15 +92,17 @@
 
 	/* Were we compiled with the right CPU option? */
 #if defined(CONFIG_CPU_R3000)
-	if ((mips_cputype == CPU_R4000SC) || (mips_cputype == CPU_R4400SC)) {
+	if ((mips_cpu.cputype == CPU_R4000SC) ||
+	    (mips_cpu.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)) {
+#if defined(CONFIG_CPU_R4X00)
+	if ((mips_cpu.cputype == CPU_R3000) ||
+	    (mips_cpu.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();
@@ -114,3 +115,4 @@
 
 	return 0;
 }
+
diff -u --recursive --new-file v2.4.9/linux/arch/mips/dec/prom/memory.c linux/arch/mips/dec/prom/memory.c
--- v2.4.9/linux/arch/mips/dec/prom/memory.c	Tue Mar  6 19:44:36 2001
+++ linux/arch/mips/dec/prom/memory.c	Sun Sep  9 10:43:01 2001
@@ -2,6 +2,7 @@
  * memory.c: memory initialisation code.
  *
  * Copyright (C) 1998 Harald Koerfgen, Frieder Streffer and Paul M. Antoine
+ * Copyright (C) 2000 Maciej W. Rozycki
  *
  * $Id: memory.c,v 1.3 1999/10/09 00:00:58 ralf Exp $
  */
@@ -14,6 +15,8 @@
 #include <asm/addrspace.h>
 #include <asm/page.h>
 
+#include <asm/bootinfo.h>
+
 #include <asm/dec/machtype.h>
 
 #include "prom.h"
@@ -33,11 +36,6 @@
 
 volatile unsigned long mem_err = 0;	/* So we know an error occurred */
 
-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).
@@ -45,7 +43,7 @@
 
 #define CHUNK_SIZE 0x400000
 
-unsigned long __init pmax_get_memory_size(void)
+static void __init pmax_setup_memory_region(void)
 {
 	volatile unsigned char *memory_page, dummy;
 	char	old_handler[0x80];
@@ -66,17 +64,19 @@
 		dummy = *memory_page;
 	}
 	memcpy((void *)(KSEG0 + 0x80), &old_handler, 0x80);
-	return (unsigned long)memory_page - KSEG1 - CHUNK_SIZE;
+
+	add_memory_region(0, (unsigned long)memory_page - KSEG1 - CHUNK_SIZE,
+			  BOOT_MEM_RAM);
 }
 
 /*
  * Use the REX prom calls to get hold of the memory bitmap, and thence
  * determine memory size.
  */
-unsigned long __init rex_get_memory_size(void)
+static void __init rex_setup_memory_region(void)
 {
 	int i, bitmap_size;
-	unsigned long mem_size = 0;
+	unsigned long mem_start = 0, mem_size = 0;
 	memmap *bm;
 
 	/* some free 64k */
@@ -88,46 +88,30 @@
 		/* FIXME: very simplistically only add full sets of pages */
 		if (bm->bitmap[i] == 0xff)
 			mem_size += (8 * bm->pagesize);
+		else if (!mem_size)
+			mem_start += (8 * bm->pagesize);
+		else {
+			add_memory_region(mem_start, mem_size, BOOT_MEM_RAM);
+			mem_start += mem_size + (8 * bm->pagesize);
+			mem_size = 0;
+		}
 	}
-
-	return (mem_size);
+	if (mem_size)
+		add_memory_region(mem_start, mem_size, BOOT_MEM_RAM);
 }
 
 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)
-		mem_size = pmax_get_memory_size();
+		pmax_setup_memory_region();
 	else
-		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("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);
-}
-
-int __init page_is_ram(unsigned long pagenr)
-{
-        return 1;
+		rex_setup_memory_region();
 }
 
-void prom_free_prom_memory (void)
+void __init prom_free_prom_memory (void)
 {
 	unsigned long addr, end;
-	extern	char _ftext;
+	extern char _ftext;
 
 	/*
 	 * Free everything below the kernel itself but leave
@@ -142,16 +126,16 @@
 	 * XXX: save this address for use in dec_lance.c?
 	 */
 	if (IOASIC)
-		end = PHYSADDR(&_ftext) - 0x00020000;
+		end = __pa(&_ftext) - 0x00020000;
 	else
 #endif
-		end = PHYSADDR(&_ftext);
+		end = __pa(&_ftext);
 
 	addr = PAGE_SIZE;
 	while (addr < end) {
-		ClearPageReserved(virt_to_page(addr));
-		set_page_count(virt_to_page(addr), 1);
-		free_page(addr);
+		ClearPageReserved(virt_to_page(__va(addr)));
+		set_page_count(virt_to_page(__va(addr)), 1);
+		free_page((unsigned long)__va(addr));
 		addr += PAGE_SIZE;
 	}
 
diff -u --recursive --new-file v2.4.9/linux/arch/mips/dec/reset.c linux/arch/mips/dec/reset.c
--- v2.4.9/linux/arch/mips/dec/reset.c	Sat May 13 08:29:14 2000
+++ linux/arch/mips/dec/reset.c	Sun Sep  9 10:43:01 2001
@@ -23,3 +23,7 @@
 	back_to_prom();
 }
 
+void dec_intr_halt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	dec_machine_halt();
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips/dec/rtc-dec.c linux/arch/mips/dec/rtc-dec.c
--- v2.4.9/linux/arch/mips/dec/rtc-dec.c	Sat May 13 08:29:14 2000
+++ linux/arch/mips/dec/rtc-dec.c	Sun Sep  9 10:43:01 2001
@@ -1,13 +1,12 @@
-
-/* $Id: rtc-jazz.c,v 1.2 1998/06/25 20:19: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.
  *
  * RTC routines for DECstation style attached Dallas chip.
  *
- * Copyright (C) 1998 by Ralf Baechle, Harald Koerfgen
+ * Copyright (C) 1998, 2001 by Ralf Baechle
+ * Copyright (C) 1998 by Harald Koerfgen
  */
 #include <linux/mc146818rtc.h>
 
diff -u --recursive --new-file v2.4.9/linux/arch/mips/dec/serial.c linux/arch/mips/dec/serial.c
--- v2.4.9/linux/arch/mips/dec/serial.c	Sat May 13 08:29:14 2000
+++ linux/arch/mips/dec/serial.c	Wed Dec 31 16:00:00 1969
@@ -1,98 +0,0 @@
-/*
- * sercons.c
- *      choose the right serial device at boot time
- *
- * triemer 6-SEP-1998
- *      sercons.c is designed to allow the three different kinds 
- *      of serial devices under the decstation world to co-exist
- *      in the same kernel.  The idea here is to abstract 
- *      the pieces of the drivers that are common to this file
- *      so that they do not clash at compile time and runtime.
- *
- * HK 16-SEP-1998 v0.002
- *      removed the PROM console as this is not a real serial
- *      device. Added support for PROM console in drivers/char/tty_io.c
- *      instead. Although it may work to enable more than one 
- *      console device I strongly recommend to use only one.
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <asm/dec/machtype.h>
-
-#ifdef CONFIG_ZS
-extern int zs_init(void);
-#endif
-
-#ifdef CONFIG_DZ
-extern int dz_init(void);
-#endif
-
-#ifdef CONFIG_SERIAL_CONSOLE
-
-#ifdef CONFIG_ZS
-extern void zs_serial_console_init(void);
-#endif
-
-#ifdef CONFIG_DZ
-extern void dz_serial_console_init(void);
-#endif
-
-#endif
-
-/* rs_init - starts up the serial interface -
-   handle normal case of starting up the serial interface */
-
-#ifdef CONFIG_SERIAL
-
-int __init rs_init(void)
-{
-
-#if defined(CONFIG_ZS) && defined(CONFIG_DZ)
-    if (IOASIC)
-	return zs_init();
-    else
-	return dz_init();
-#else
-
-#ifdef CONFIG_ZS
-    return zs_init();
-#endif
-
-#ifdef CONFIG_DZ
-    return dz_init();
-#endif
-
-#endif
-}
-
-__initcall(rs_init);
-
-#endif
-
-#ifdef CONFIG_SERIAL_CONSOLE
-
-/* serial_console_init handles the special case of starting
- *   up the console on the serial port
- */
-void __init serial_console_init(void)
-{
-#if defined(CONFIG_ZS) && defined(CONFIG_DZ)
-    if (IOASIC)
-	zs_serial_console_init();
-    else
-	dz_serial_console_init();
-#else
-
-#ifdef CONFIG_ZS
-    zs_serial_console_init();
-#endif
-
-#ifdef CONFIG_DZ
-    dz_serial_console_init();
-#endif
-
-#endif
-}
-
-#endif
diff -u --recursive --new-file v2.4.9/linux/arch/mips/dec/setup.c linux/arch/mips/dec/setup.c
--- v2.4.9/linux/arch/mips/dec/setup.c	Thu Aug 26 12:42:31 1999
+++ linux/arch/mips/dec/setup.c	Sun Sep  9 10:43:01 2001
@@ -6,11 +6,13 @@
  * for more details.
  *
  * Copyright (C) 1998 Harald Koerfgen
+ * Copyright (C) 2000 Maciej W. Rozycki
  */
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/mc146818rtc.h>
 #include <linux/param.h>
+#include <linux/console.h>
 #include <asm/mipsregs.h>
 #include <asm/bootinfo.h>
 #include <linux/init.h>
@@ -22,25 +24,19 @@
 #include <asm/dec/kn02.h>
 #include <asm/dec/kn02xa.h>
 #include <asm/dec/kn03.h>
+#include <asm/dec/ioasic.h>
+#include <asm/dec/ioasic_addrs.h>
 #include <asm/dec/ioasic_ints.h>
 
-extern asmlinkage void decstation_handle_int(void);
 
-void dec_init_kn01(void);
-void dec_init_kn230(void);
-void dec_init_kn02(void);
-void dec_init_kn02ba(void);
-void dec_init_kn02ca(void);
-void dec_init_kn03(void);
+char *dec_rtc_base = (void *) KN01_RTC_BASE;	/* Assume DS2100/3100 initially */
 
-char *dec_rtc_base = (char *) KN01_RTC_BASE;	/* Assume DS2100/3100 initially */
+volatile unsigned int *ioasic_base;
 
 decint_t dec_interrupt[NR_INTS];
 
-/* 
+/*
  * Information regarding the IRQ Controller
- *
- * isr and imr are also hardcoded for different machines in int_handler.S
  */
 
 volatile unsigned int *isr = 0L;	/* address of the interrupt status register     */
@@ -49,50 +45,17 @@
 extern void dec_machine_restart(char *command);
 extern void dec_machine_halt(void);
 extern void dec_machine_power_off(void);
+extern void dec_intr_halt(int irq, void *dev_id, struct pt_regs *regs);
 
 extern void wbflush_setup(void);
 
 extern struct rtc_ops dec_rtc_ops;
 
-extern void intr_halt(void);
-
 extern int setup_dec_irq(int, struct irqaction *);
 
 void (*board_time_init) (struct irqaction * irq);
 
-static void __init dec_irq_setup(void)
-{
-    switch (mips_machtype) {
-    case MACH_DS23100:
-	dec_init_kn01();
-	break;
-    case MACH_DS5100:		/*  DS5100 MIPSMATE */
-	dec_init_kn230();
-	break;
-    case MACH_DS5000_200:	/* DS5000 3max */
-	dec_init_kn02();
-	break;
-    case MACH_DS5000_1XX:	/* DS5000/100 3min */
-	dec_init_kn02ba();
-	break;
-    case MACH_DS5000_2X0:	/* DS5000/240 3max+ */
-	dec_init_kn03();
-	break;
-    case MACH_DS5000_XX:	/* Personal DS5000/2x */
-	dec_init_kn02ca();
-	break;
-    case MACH_DS5800:		/* DS5800 Isis */
-	panic("Don't know how to set this up!");
-	break;
-    case MACH_DS5400:		/* DS5400 MIPSfair */
-	panic("Don't know how to set this up!");
-	break;
-    case MACH_DS5500:		/* DS5500 MIPSfair-2 */
-	panic("Don't know how to set this up!");
-	break;
-    }
-    set_except_vector(0, decstation_handle_int);
-}
+static struct irqaction irq10 = {dec_intr_halt, 0, 0, "halt", NULL, NULL};
 
 /*
  * enable the periodic interrupts
@@ -112,9 +75,16 @@
     setup_dec_irq(CLOCK, irq);
 }
 
+/*
+ * Enable the halt interrupt.
+ */
+static void __init dec_halt_init(struct irqaction *irq)
+{
+    setup_dec_irq(HALT, irq);
+}
+
 void __init decstation_setup(void)
 {
-    irq_setup = dec_irq_setup;
     board_time_init = dec_time_init;
 
     wbflush_setup();
@@ -123,6 +93,10 @@
     _machine_halt = dec_machine_halt;
     _machine_power_off = dec_machine_power_off;
 
+#ifdef CONFIG_FB
+    conswitchp = &dummy_con;
+#endif
+
     rtc_ops = &dec_rtc_ops;
 }
 
@@ -206,8 +180,8 @@
      * Setup some memory addresses. FIXME: probably incomplete!
      */
     dec_rtc_base = (char *) KN02_RTC_BASE;
-    isr = (volatile unsigned int *) KN02_CSR_ADDR;
-    imr = (volatile unsigned int *) KN02_CSR_ADDR;
+    isr = (void *) KN02_CSR_ADDR;
+    imr = (void *) KN02_CSR_ADDR;
 
     /*
      * Setup IOASIC interrupt
@@ -275,16 +249,17 @@
     /*
      * Setup some memory addresses.
      */
+    ioasic_base = (void *) KN02XA_IOASIC_BASE;
     dec_rtc_base = (char *) KN02XA_RTC_BASE;
-    isr = (volatile unsigned int *) KN02XA_SIR_ADDR;
-    imr = (volatile unsigned int *) KN02XA_SIRM_ADDR;
+    isr = (void *) KN02XA_IOASIC_REG(SIR);
+    imr = (void *) KN02XA_IOASIC_REG(SIMR);
 
     /*
      * Setup IOASIC interrupt
      */
     cpu_mask_tbl[0] = IE_IRQ3;
     cpu_irq_nr[0] = -1;
-    cpu_ivec_tbl[0] = kn02ba_io_int;
+    cpu_ivec_tbl[0] = kn02xa_io_int;
     *imr = 0;
 
     /*
@@ -345,6 +320,7 @@
     cpu_mask_tbl[5] = IE_IRQ5;
     cpu_irq_nr[5] = FPU;
 
+    dec_halt_init(&irq10);
 }				/* dec_init_kn02ba */
 
 /*
@@ -355,14 +331,15 @@
     /*
      * Setup some memory addresses. FIXME: probably incomplete!
      */
+    ioasic_base = (void *) KN02XA_IOASIC_BASE;
     dec_rtc_base = (char *) KN02XA_RTC_BASE;
-    isr = (volatile unsigned int *) KN02XA_SIR_ADDR;
-    imr = (volatile unsigned int *) KN02XA_SIRM_ADDR;
+    isr = (void *) KN02XA_IOASIC_REG(SIR);
+    imr = (void *) KN02XA_IOASIC_REG(SIMR);
 
     /*
      * Setup IOASIC interrupt
      */
-    cpu_ivec_tbl[1] = kn02ba_io_int;
+    cpu_ivec_tbl[1] = kn02xa_io_int;
     cpu_irq_nr[1] = -1;
     cpu_mask_tbl[1] = IE_IRQ3;
     *imr = 0;
@@ -420,6 +397,7 @@
     cpu_mask_tbl[4] = IE_IRQ5;
     cpu_irq_nr[4] = FPU;
 
+    dec_halt_init(&irq10);
 }				/* dec_init_kn02ca */
 
 /*
@@ -430,9 +408,10 @@
     /*
      * Setup some memory addresses. FIXME: probably incomplete!
      */
+    ioasic_base = (void *) KN03_IOASIC_BASE;
     dec_rtc_base = (char *) KN03_RTC_BASE;
-    isr = (volatile unsigned int *) KN03_SIR_ADDR;
-    imr = (volatile unsigned int *) KN03_SIRM_ADDR;
+    isr = (void *) KN03_IOASIC_REG(SIR);
+    imr = (void *) KN03_IOASIC_REG(SIMR);
 
     /*
      * Setup IOASIC interrupt
@@ -500,4 +479,5 @@
     cpu_mask_tbl[4] = IE_IRQ5;
     cpu_irq_nr[4] = FPU;
 
+    dec_halt_init(&irq10);
 }				/* dec_init_kn03 */
diff -u --recursive --new-file v2.4.9/linux/arch/mips/dec/time.c linux/arch/mips/dec/time.c
--- v2.4.9/linux/arch/mips/dec/time.c	Mon Oct 16 12:58:51 2000
+++ linux/arch/mips/dec/time.c	Sun Sep  9 10:43:01 2001
@@ -1,8 +1,8 @@
-
 /*
- *  linux/arch/mips/kernel/time.c
+ *  linux/arch/mips/dec/time.c
  *
  *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
+ *  Copyright (C) 2000  Maciej W. Rozycki
  *
  * This file contains the time handling details for PC-style clocks as
  * found in some MIPS systems.
@@ -17,14 +17,22 @@
 #include <linux/mm.h>
 #include <linux/interrupt.h>
 
+#include <asm/cpu.h>
 #include <asm/bootinfo.h>
 #include <asm/mipsregs.h>
 #include <asm/io.h>
 #include <asm/irq.h>
+#include <asm/dec/machtype.h>
+#include <asm/dec/ioasic.h>
+#include <asm/dec/ioasic_addrs.h>
 
 #include <linux/mc146818rtc.h>
 #include <linux/timex.h>
 
+#include <asm/div64.h>
+
+extern void (*board_time_init)(struct irqaction *irq);
+
 extern volatile unsigned long wall_jiffies;
 extern rwlock_t xtime_lock;
 
@@ -36,12 +44,22 @@
 
 /* This is for machines which generate the exact clock. */
 #define USECS_PER_JIFFY (1000000/HZ)
+#define USECS_PER_JIFFY_FRAC ((1000000ULL << 32) / HZ & 0xffffffff)
 
 /* Cycle counter value at the previous timer interrupt.. */
 
 static unsigned int timerhi, timerlo;
 
 /*
+ * Cached "1/(clocks per usec)*2^32" value.
+ * It has to be recalculated once each jiffy.
+ */
+static unsigned long cached_quotient = 0;
+
+/* Last jiffy when do_fast_gettimeoffset() was called. */
+static unsigned long last_jiffies = 0;
+
+/*
  * On MIPS only R4000 and better have a cycle counter.
  *
  * FIXME: Does playing with the RP bit in c0_status interfere with this code?
@@ -50,45 +68,34 @@
 {
 	u32 count;
 	unsigned long res, tmp;
-
-	/* Last jiffy when do_fast_gettimeoffset() was called. */
-	static unsigned long last_jiffies = 0;
 	unsigned long quotient;
 
-	/*
-	 * Cached "1/(clocks per usec)*2^32" value.
-	 * It has to be recalculated once each jiffy.
-	 */
-	static unsigned long cached_quotient = 0;
-
 	tmp = jiffies;
 
 	quotient = cached_quotient;
 
-	if (tmp && last_jiffies != tmp) {
-		last_jiffies = tmp;
-		__asm__(".set\tnoreorder\n\t"
-			".set\tnoat\n\t"
-			".set\tmips3\n\t"
-			"lwu\t%0,%2\n\t"
-			"dsll32\t$1,%1,0\n\t"
-			"or\t$1,$1,%0\n\t"
-			"ddivu\t$0,$1,%3\n\t"
-			"mflo\t$1\n\t"
-			"dsll32\t%0,%4,0\n\t"
-			"nop\n\t"
-			"ddivu\t$0,%0,$1\n\t"
-			"mflo\t%0\n\t"
-			".set\tmips0\n\t"
-			".set\tat\n\t"
-			".set\treorder"
-			:"=&r"(quotient)
-			:"r"(timerhi),
-			"m"(timerlo),
-			"r"(tmp),
-			"r"(USECS_PER_JIFFY)
-			:"$1");
+	if (last_jiffies != tmp) {
+	    last_jiffies = tmp;
+	    if (last_jiffies != 0) {
+		unsigned long r0;
+		__asm__(".set	push\n\t"
+			".set	mips3\n\t"
+			"lwu	%0,%3\n\t"
+			"dsll32	%1,%2,0\n\t"
+			"or	%1,%1,%0\n\t"
+			"ddivu	$0,%1,%4\n\t"
+			"mflo	%1\n\t"
+			"dsll32	%0,%5,0\n\t"
+			"or	%0,%0,%6\n\t"
+			"ddivu	$0,%0,%1\n\t"
+			"mflo	%0\n\t"
+			".set	pop"
+			: "=&r" (quotient), "=&r" (r0)
+			: "r" (timerhi), "m" (timerlo),
+			  "r" (tmp), "r" (USECS_PER_JIFFY),
+			  "r" (USECS_PER_JIFFY_FRAC));
 		cached_quotient = quotient;
+	    }
 	}
 	/* Get last timer tick in absolute kernel time */
 	count = read_32bit_cp0_register(CP0_COUNT);
@@ -97,11 +104,9 @@
 	count -= timerlo;
 //printk("count: %08lx, %08lx:%08lx\n", count, timerhi, timerlo);
 
-	__asm__("multu\t%1,%2\n\t"
-		"mfhi\t%0"
-		:"=r"(res)
-		:"r"(count),
-		"r"(quotient));
+	__asm__("multu	%2,%3"
+		: "=l" (tmp), "=h" (res)
+		: "r" (count), "r" (quotient));
 
 	/*
 	 * Due to possible jiffies inconsistencies, we need to check 
@@ -113,6 +118,47 @@
 	return res;
 }
 
+static unsigned long do_ioasic_gettimeoffset(void)
+{
+	u32 count;
+	unsigned long res, tmp;
+	unsigned long quotient;
+
+	tmp = jiffies;
+
+	quotient = cached_quotient;
+
+	if (last_jiffies != tmp) {
+		last_jiffies = tmp;
+		if (last_jiffies != 0) {
+			unsigned long r0;
+			do_div64_32(r0, timerhi, timerlo, tmp);
+			do_div64_32(quotient, USECS_PER_JIFFY,
+				    USECS_PER_JIFFY_FRAC, r0);
+			cached_quotient = quotient;
+		}
+	}
+	/* Get last timer tick in absolute kernel time */
+	count = ioasic_read(FCTR);
+
+	/* .. relative to previous jiffy (32 bits is enough) */
+	count -= timerlo;
+//printk("count: %08x, %08x:%08x\n", count, timerhi, timerlo);
+
+	__asm__("multu	%2,%3"
+		: "=l" (tmp), "=h" (res)
+		: "r" (count), "r" (quotient));
+
+	/*
+	 * Due to possible jiffies inconsistencies, we need to check
+	 * the result so that we'll get a timer that is monotonic.
+	 */
+	if (res >= USECS_PER_JIFFY)
+        	res = USECS_PER_JIFFY - 1;
+
+	return res;
+}
+
 /* This function must be called with interrupts disabled 
  * It was inspired by Steve McCanne's microtime-i386 for BSD.  -- jrs
  * 
@@ -170,8 +216,8 @@
 	tv->tv_usec += do_gettimeoffset();
 
 	/*
-	 * xtime is atomically updated in timer_bh. lost_ticks is
-	 * nonzero if the timer bottom half hasnt executed yet.
+	 * xtime is atomically updated in timer_bh. jiffies - wall_jiffies
+	 * is nonzero if the timer bottom half hasnt executed yet.
 	 */
 	if (jiffies - wall_jiffies)
 		tv->tv_usec += USECS_PER_JIFFY;
@@ -187,6 +233,7 @@
 void do_settimeofday(struct timeval *tv)
 {
 	write_lock_irq(&xtime_lock);
+
 	/* This is revolting. We need to set the xtime.tv_usec
 	 * correctly. However, the value in this location is
 	 * is value at the last tick.
@@ -199,10 +246,13 @@
 		tv->tv_usec += 1000000;
 		tv->tv_sec--;
 	}
+
 	xtime = *tv;
-	time_state = TIME_BAD;
-	time_maxerror = MAXPHASE;
-	time_esterror = MAXPHASE;
+	time_adjust = 0;		/* stop active adjtime() */
+	time_status |= STA_UNSYNC;
+	time_maxerror = NTP_PHASE_LIMIT;
+	time_esterror = NTP_PHASE_LIMIT;
+
 	write_unlock_irq(&xtime_lock);
 }
 
@@ -307,13 +357,16 @@
 	 * called as close as possible to 500 ms before the new second starts.
 	 */
 	read_lock(&xtime_lock);
-	if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 &&
-	    xtime.tv_usec > 500000 - (tick >> 1) &&
-	    xtime.tv_usec < 500000 + (tick >> 1))
+	if ((time_status & STA_UNSYNC) == 0
+	    && xtime.tv_sec > last_rtc_update + 660
+	    && xtime.tv_usec >= 500000 - tick / 2
+	    && xtime.tv_usec <= 500000 + tick / 2) {
 		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 */
+			/* do it again in 60 s */
+			last_rtc_update = xtime.tv_sec - 600;
+	}
 	/* As we return to user mode fire off the other CPU schedulers.. this is
 	   basically because we don't yet share IRQ's around. This message is
 	   rigged to be safe on the 386 - basically it's a hack, so don't look
@@ -334,66 +387,50 @@
 	timerhi += (count < timerlo);	/* Wrap around */
 	timerlo = count;
 
-	timer_interrupt(irq, dev_id, regs);
-
-	if (!jiffies) {
+	if (jiffies == ~0) {
 		/*
-		 * If jiffies has overflowed in this timer_interrupt we must
+		 * If jiffies is to overflow in this timer_interrupt we must
 		 * update the timer[hi]/[lo] to make do_fast_gettimeoffset()
 		 * quotient calc still valid. -arca
 		 */
+		write_32bit_cp0_register(CP0_COUNT, 0);
 		timerhi = timerlo = 0;
 	}
-}
 
-char cyclecounter_available;
+	timer_interrupt(irq, dev_id, regs);
+}
 
-static inline void init_cycle_counter(void)
+static void ioasic_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	switch (mips_cputype) {
-	case CPU_UNKNOWN:
-	case CPU_R2000:
-	case CPU_R3000:
-	case CPU_R3000A:
-	case CPU_R3041:
-	case CPU_R3051:
-	case CPU_R3052:
-	case CPU_R3081:
-	case CPU_R3081E:
-	case CPU_R6000:
-	case CPU_R6000A:
-	case CPU_R8000:	/* Not shure about that one, play safe */
-		cyclecounter_available = 0;
-		break;
-	case CPU_R4000PC:
-	case CPU_R4000SC:
-	case CPU_R4000MC:
-	case CPU_R4200:
-	case CPU_R4400PC:
-	case CPU_R4400SC:
-	case CPU_R4400MC:
-	case CPU_R4600:
-	case CPU_R10000:
-	case CPU_R4300:
-	case CPU_R4650:
-	case CPU_R4700:
-	case CPU_R5000:
-	case CPU_R5000A:
-	case CPU_R4640:
-	case CPU_NEVADA:
-		cyclecounter_available = 1;
-		break;
+	unsigned int count;
+
+	/*
+	 * The free-running counter is 32 bit which is good for about
+	 * 2 minutes, 50 seconds at possible count rates of upto 25MHz.
+	 */
+	count = ioasic_read(FCTR);
+	timerhi += (count < timerlo);	/* Wrap around */
+	timerlo = count;
+
+	if (jiffies == ~0) {
+		/*
+		 * If jiffies is to overflow in this timer_interrupt we must
+		 * update the timer[hi]/[lo] to make do_fast_gettimeoffset()
+		 * quotient calc still valid. -arca
+		 */
+		ioasic_write(FCTR, 0);
+		timerhi = timerlo = 0;
 	}
+
+	timer_interrupt(irq, dev_id, regs);
 }
 
 struct irqaction irq0 = {timer_interrupt, SA_INTERRUPT, 0,
 			 "timer", NULL, NULL};
 
-void (*board_time_init) (struct irqaction * irq);
-
 void __init time_init(void)
 {
-	unsigned int year, mon, day, hour, min, sec;
+	unsigned int year, mon, day, hour, min, sec, real_year;
 	int i;
 
 	/* The Linux interpretation of the CMOS clock register contents:
@@ -425,23 +462,26 @@
 		BCD_TO_BIN(year);
 	}
 	/*
-	 * The DECstation RTC is used as a TOY (Time Of Year).
-	 * The PROM will reset the year to either '70, '71 or '72.
-	 * This hack will only work until Dec 31 2001.
+	 * The PROM will reset the year to either '72 or '73.
+	 * Therefore we store the real year separately, in one
+	 * of unused BBU RAM locations.
 	 */
-	year += 1928;
+	real_year = CMOS_READ(RTC_DEC_YEAR);
+	year += real_year - 72 + 2000;
 
 	write_lock_irq(&xtime_lock);
 	xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
 	xtime.tv_usec = 0;
 	write_unlock_irq(&xtime_lock);
 
-	init_cycle_counter();
-
-	if (cyclecounter_available) {
+	if (mips_cpu.options & MIPS_CPU_COUNTER) {
 		write_32bit_cp0_register(CP0_COUNT, 0);
 		do_gettimeoffset = do_fast_gettimeoffset;
 		irq0.handler = r4k_timer_interrupt;
-	}
+	} else if (IOASIC) {
+		ioasic_write(FCTR, 0);
+		do_gettimeoffset = do_ioasic_gettimeoffset;
+		irq0.handler = ioasic_timer_interrupt;
+        }
 	board_time_init(&irq0);
 }
diff -u --recursive --new-file v2.4.9/linux/arch/mips/defconfig linux/arch/mips/defconfig
--- v2.4.9/linux/arch/mips/defconfig	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/defconfig	Sun Sep  9 10:43:02 2001
@@ -1,6 +1,8 @@
 #
 # Automatically generated make config: don't edit
 #
+CONFIG_MIPS=y
+# CONFIG_SMP is not set
 
 #
 # Code maturity level options
@@ -13,21 +15,37 @@
 # CONFIG_ACER_PICA_61 is not set
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
-# CONFIG_COBALT_MICRO_SERVER is not set
 # CONFIG_DECSTATION is not set
 # CONFIG_DDB5074 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_NINO is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
 # CONFIG_OLIVETTI_M700 is not set
 CONFIG_SGI_IP22=y
 # CONFIG_SNI_RM200_PCI is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_MIPS_PB1000 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 # CONFIG_MCA is not set
 # CONFIG_SBUS is not set
 CONFIG_ARC32=y
+CONFIG_BOARD_SCACHE=y
 CONFIG_PC_KEYB=y
 CONFIG_SGI=y
+CONFIG_NEW_IRQ=y
+CONFIG_OLD_TIME_C=y
 # CONFIG_ISA is not set
 # CONFIG_EISA is not set
 # CONFIG_PCI is not set
+# CONFIG_I8259 is not set
 
 #
 # Loadable module support
@@ -41,14 +59,20 @@
 #
 # CONFIG_CPU_R3000 is not set
 # CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
 CONFIG_CPU_R5000=y
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_NEVADA is not set
-# CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_SB1 is not set
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
 # CONFIG_CPU_HAS_WB is not set
 
 #
@@ -59,24 +83,26 @@
 CONFIG_ELF_KERNEL=y
 CONFIG_BINFMT_IRIX=y
 CONFIG_FORWARD_KEYBOARD=y
+# CONFIG_ARC_CONSOLE is not set
 # CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 CONFIG_NET=y
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 
 #
-# Parallel port support
+# Memory Technology Devices (MTD)
 #
-# CONFIG_PARPORT is not set
-# CONFIG_PCMCIA is not set
+# CONFIG_MTD is not set
 
 #
-# Memory Technology Devices (MTD)
+# Parallel port support
 #
-# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
 
 #
 # Block devices
@@ -107,19 +133,24 @@
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK is not set
+CONFIG_PACKET_MMAP=y
+CONFIG_NETLINK=y
+CONFIG_RTNETLINK=y
+CONFIG_NETLINK_DEV=y
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
 CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
+CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
 CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
 CONFIG_IP_PNP_BOOTP=y
 # CONFIG_IP_PNP_RARP is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
 # CONFIG_IPV6 is not set
@@ -148,6 +179,13 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA is not set
+
+#
 # SCSI support
 #
 CONFIG_SCSI=y
@@ -175,7 +213,7 @@
 #
 # SCSI low-level drivers
 #
-CONFIG_SCSI_SGIWD93=y
+CONFIG_SGIWD93_SCSI=y
 # CONFIG_SCSI_7000FASST is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AHA152X is not set
@@ -183,6 +221,7 @@
 # CONFIG_SCSI_AHA1740 is not set
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
 # CONFIG_SCSI_AM53C974 is not set
@@ -199,6 +238,7 @@
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_NCR_D700 is not set
 # CONFIG_SCSI_NCR53C7xx is not set
 # CONFIG_SCSI_PAS16 is not set
 # CONFIG_SCSI_PCI2000 is not set
@@ -215,20 +255,159 @@
 # Network device support
 #
 CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
 # CONFIG_DUMMY is not set
-# CONFIG_SLIP is not set
-# CONFIG_PPP is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNGEM is not set
+# 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_PCI is not set
+# CONFIG_NET_POCKET is not set
 CONFIG_SGISEEQ=y
 
 #
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI 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 devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER 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=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=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_SONYPI is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # SGI Character devices
 #
 CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
 CONFIG_SGI_NEWPORT_CONSOLE=y
 CONFIG_FONT_8x16=y
-# CONFIG_SGI_PROM_CONSOLE is not set
-# CONFIG_UNIX98_PTYS is not set
+# CONFIG_PSMOUSE is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
 
 #
 # File systems
@@ -238,22 +417,30 @@
 CONFIG_AUTOFS4_FS=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_BFS_FS is not set
+# CONFIG_CMS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG 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_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
 # CONFIG_RAMFS is not set
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
 # CONFIG_MINIX_FS is not set
+# CONFIG_FREEVXFS_FS is not set
 # CONFIG_NTFS_FS is not set
 # CONFIG_NTFS_RW is not set
 # CONFIG_HPFS_FS is not set
@@ -261,13 +448,12 @@
 # CONFIG_DEVFS_FS is not set
 # CONFIG_DEVFS_MOUNT is not set
 # CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS is not set
+CONFIG_DEVPTS_FS=y
 # 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
@@ -277,6 +463,7 @@
 # Network File Systems
 #
 # CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 is not set
 CONFIG_ROOT_NFS=y
@@ -309,6 +496,7 @@
 # CONFIG_MINIX_SUBPARTITION is not set
 # CONFIG_SOLARIS_X86_PARTITION is not set
 # CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
 CONFIG_SGI_PARTITION=y
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
@@ -319,7 +507,7 @@
 # Console drivers
 #
 # CONFIG_VGA_CONSOLE is not set
-# CONFIG_FB is not set
+# CONFIG_MDA_CONSOLE is not set
 
 #
 # Frame-buffer support
@@ -345,13 +533,111 @@
 # CONFIG_USB is not set
 
 #
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# USB Network adaptors
+#
+# CONFIG_USB_PLUSB is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# Miscellaneous USB drivers
+#
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_ID75 is not set
+
+#
 # Input core support
 #
 # CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
 
 #
 # Kernel hacking
 #
 CONFIG_CROSSCOMPILE=y
-# CONFIG_MIPS_FPE_MODULE is not set
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_MIPS_UNCACHED is not set
diff -u --recursive --new-file v2.4.9/linux/arch/mips/defconfig-atlas linux/arch/mips/defconfig-atlas
--- v2.4.9/linux/arch/mips/defconfig-atlas	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/defconfig-atlas	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,604 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_MIPS=y
+# CONFIG_SMP is not set
+
+#
+# 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_EV96100 is not set
+# CONFIG_MIPS_EV64120 is not set
+CONFIG_MIPS_ATLAS=y
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_NINO is not set
+# CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_MIPS_PB1000 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+CONFIG_PCI=y
+CONFIG_SWAP_IO_SPACE=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_I8259 is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# CPU selection
+#
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+CONFIG_CPU_R5000=y
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_SB1 is not set
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=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 is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_NET=y
+# CONFIG_PCI_NAMES is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_BLK_DEV_LVM 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_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES 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_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT 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
+# CONFIG_PHONE_IXJ_PCMCIA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD 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_CHR_DEV_OSST is not set
+# 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_BLK_DEV_3W_XXXX_RAID is not set
+# 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_AIC7XXX_OLD is not set
+# CONFIG_SCSI_DPT_I2O 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_CPQFCTS is not set
+# CONFIG_SCSI_DMX3191D 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_NCR53C406A is not set
+# CONFIG_SCSI_NCR_D700 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 is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNGEM is not set
+# 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_HP100 is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI 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 devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER 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=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+CONFIG_RTC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_SONYPI is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+CONFIG_AUTOFS_FS=y
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_CMS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG 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=y
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_FREEVXFS_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_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# 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_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_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+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
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# USB Network adaptors
+#
+# CONFIG_USB_PLUSB is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# Miscellaneous USB drivers
+#
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_ID75 is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Kernel hacking
+#
+CONFIG_CROSSCOMPILE=y
+# CONFIG_REMOTE_DEBUG is not set
+# CONFIG_GDB_CONSOLE is not set
+# CONFIG_LL_DEBUG is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_MIPS_UNCACHED is not set
diff -u --recursive --new-file v2.4.9/linux/arch/mips/defconfig-cobalt linux/arch/mips/defconfig-cobalt
--- v2.4.9/linux/arch/mips/defconfig-cobalt	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/defconfig-cobalt	Wed Dec 31 16:00:00 1969
@@ -1,598 +0,0 @@
-#
-# 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_COBALT_MICRO_SERVER=y
-CONFIG_COBALT_28=y
-# 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 is not set
-# CONFIG_SNI_RM200_PCI is not set
-# CONFIG_MCA is not set
-# CONFIG_SBUS is not set
-CONFIG_COBALT_27=y
-CONFIG_COBALT_LCD=y
-CONFIG_COBALT_SERIAL=y
-CONFIG_PCI=y
-# CONFIG_ISA is not set
-# CONFIG_EISA is not set
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODVERSIONS=y
-CONFIG_KMOD=y
-
-#
-# 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 is not set
-CONFIG_CPU_NEVADA=y
-# 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=y
-CONFIG_KCORE_ELF=y
-CONFIG_ELF_KERNEL=y
-# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_ELF=y
-CONFIG_BINFMT_MISC=m
-CONFIG_NET=y
-CONFIG_PCI_NAMES=y
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-# CONFIG_PCMCIA is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
-# CONFIG_PARIDE is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-CONFIG_BLK_DEV_LOOP=m
-# CONFIG_BLK_DEV_NBD is not set
-CONFIG_BLK_DEV_RAM=m
-CONFIG_BLK_DEV_RAM_SIZE=4096
-# CONFIG_BLK_DEV_INITRD is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-# CONFIG_BLK_DEV_MD is not set
-# CONFIG_MD_LINEAR is not set
-# CONFIG_MD_RAID0 is not set
-# CONFIG_MD_RAID1 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_BLK_DEV_LVM 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 is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-CONFIG_IP_MROUTE=y
-# CONFIG_IP_PIMSM_V1 is not set
-# CONFIG_IP_PIMSM_V2 is not set
-# CONFIG_INET_ECN is not set
-CONFIG_SYN_COOKIES=y
-# CONFIG_IPV6 is not set
-# CONFIG_KHTTPD is not set
-# CONFIG_ATM is not set
-
-#
-#  
-#
-CONFIG_IPX=m
-# CONFIG_IPX_INTERN is not set
-CONFIG_ATALK=m
-# CONFIG_DECNET is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_LLC is not set
-# CONFIG_NET_DIVERT 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
-
-#
-# ATA/IDE/MFM/RLL support
-#
-# CONFIG_IDE is not set
-# CONFIG_BLK_DEV_IDE_MODES is not set
-# CONFIG_BLK_DEV_HD 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=m
-# CONFIG_CHR_DEV_OSST is not set
-CONFIG_BLK_DEV_SR=m
-# CONFIG_BLK_DEV_SR_VENDOR is not set
-CONFIG_SR_EXTRA_DEVS=2
-CONFIG_CHR_DEV_SG=m
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_DEBUG_QUEUES is not set
-CONFIG_SCSI_MULTI_LUN=y
-CONFIG_SCSI_CONSTANTS=y
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# 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=y
-CONFIG_AIC7XXX_CMDS_PER_DEVICE=8
-CONFIG_AIC7XXX_RESET_DELAY=5
-# 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_CPQFCTS is not set
-# CONFIG_SCSI_DMX3191D 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_NCR53C406A 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=4
-CONFIG_SCSI_NCR53C8XX_SYNC=5
-# CONFIG_SCSI_NCR53C8XX_PROFILE is not set
-CONFIG_SCSI_NCR53C8XX_IOMAPPED=y
-# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT 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_QLOGIC_1280 is not set
-# CONFIG_SCSI_SIM710 is not set
-# CONFIG_SCSI_SYM53C416 is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_DEBUG 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
-
-#
-# Appletalk devices
-#
-# CONFIG_APPLETALK is not set
-CONFIG_DUMMY=m
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_NET_SB1000 is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-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_AT1700 is not set
-# CONFIG_DEPCA is not set
-# CONFIG_HP100 is not set
-# CONFIG_NET_ISA is not set
-# CONFIG_NET_PCI is not set
-# CONFIG_NET_POCKET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-CONFIG_PPP=m
-# CONFIG_PPP_MULTILINK is not set
-# CONFIG_PPP_ASYNC is not set
-# CONFIG_PPP_SYNC_TTY is not set
-# CONFIG_PPP_DEFLATE is not set
-# CONFIG_PPP_BSDCOMP is not set
-# CONFIG_PPPOE is not set
-CONFIG_SLIP=m
-CONFIG_SLIP_COMPRESSED=y
-CONFIG_SLIP_SMART=y
-# CONFIG_SLIP_MODE_SLIP6 is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-# CONFIG_NET_FC is not set
-# CONFIG_RCPCI is not set
-# CONFIG_SHAPER is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-
-#
-# ISDN subsystem
-#
-CONFIG_ISDN=m
-CONFIG_ISDN_PPP=y
-CONFIG_ISDN_PPP_VJ=y
-CONFIG_ISDN_MPP=y
-# CONFIG_ISDN_PPP_BSDCOMP is not set
-CONFIG_ISDN_AUDIO=y
-# CONFIG_ISDN_TTY_FAX is not set
-
-#
-# ISDN feature submodules
-#
-# CONFIG_ISDN_DRV_LOOP is not set
-# CONFIG_ISDN_DIVERSION is not set
-
-#
-# low-level hardware drivers
-#
-
-#
-# Passive ISDN cards
-#
-CONFIG_ISDN_DRV_HISAX=m
-
-#
-#   D-channel protocol features
-#
-CONFIG_HISAX_EURO=y
-CONFIG_DE_AOC=y
-# CONFIG_HISAX_NO_SENDCOMPLETE is not set
-# CONFIG_HISAX_NO_LLC is not set
-# CONFIG_HISAX_NO_KEYPAD is not set
-CONFIG_HISAX_1TR6=y
-# CONFIG_HISAX_NI1 is not set
-
-#
-#   HiSax supported cards
-#
-# CONFIG_HISAX_16_0 is not set
-# CONFIG_HISAX_16_3 is not set
-# CONFIG_HISAX_TELESPCI is not set
-# CONFIG_HISAX_S0BOX is not set
-# CONFIG_HISAX_AVM_A1 is not set
-# CONFIG_HISAX_FRITZPCI is not set
-# CONFIG_HISAX_AVM_A1_PCMCIA is not set
-CONFIG_HISAX_ELSA=y
-# CONFIG_HISAX_IX1MICROR2 is not set
-# CONFIG_HISAX_DIEHLDIVA is not set
-# CONFIG_HISAX_ASUSCOM is not set
-# CONFIG_HISAX_TELEINT is not set
-# CONFIG_HISAX_HFCS is not set
-# CONFIG_HISAX_SEDLBAUER is not set
-# CONFIG_HISAX_SPORTSTER is not set
-# CONFIG_HISAX_MIC is not set
-# CONFIG_HISAX_NETJET is not set
-# CONFIG_HISAX_NETJET_U is not set
-# CONFIG_HISAX_NICCY is not set
-# CONFIG_HISAX_ISURF is not set
-# CONFIG_HISAX_HSTSAPHIR is not set
-# CONFIG_HISAX_BKM_A4T is not set
-# CONFIG_HISAX_SCT_QUADRO is not set
-# CONFIG_HISAX_GAZEL is not set
-# CONFIG_HISAX_HFC_PCI is not set
-# CONFIG_HISAX_W6692 is not set
-# CONFIG_HISAX_HFC_SX is not set
-# CONFIG_HISAX_SEDLBAUER_CS is not set
-
-#
-# Active ISDN cards
-#
-# CONFIG_ISDN_DRV_ICN is not set
-# CONFIG_ISDN_DRV_PCBIT is not set
-# CONFIG_ISDN_DRV_SC is not set
-# CONFIG_ISDN_DRV_ACT2000 is not set
-# CONFIG_ISDN_DRV_EICON is not set
-# CONFIG_ISDN_CAPI is not set
-# CONFIG_HYSDN is not set
-# CONFIG_HYSDN_CAPI 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 is not set
-# CONFIG_SERIAL_EXTENDED is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_UNIX98_PTYS 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
-
-#
-# Input core support is needed for joysticks
-#
-# CONFIG_QIC02_TAPE is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_INTEL_RNG is not set
-# CONFIG_NVRAM is not set
-CONFIG_RTC=y
-# 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_AGP is not set
-# CONFIG_DRM is not set
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# File systems
-#
-CONFIG_QUOTA=y
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_ADFS_FS is not set
-# CONFIG_ADFS_FS_RW is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_BFS_FS is not set
-CONFIG_FAT_FS=m
-CONFIG_MSDOS_FS=m
-# CONFIG_UMSDOS_FS is not set
-CONFIG_VFAT_FS=m
-# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_RAMFS is not set
-CONFIG_ISO9660_FS=m
-# 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_DEVFS_FS is not set
-# CONFIG_DEVFS_MOUNT is not set
-# CONFIG_DEVFS_DEBUG is not set
-# 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_NFS_V3 is not set
-# CONFIG_ROOT_NFS is not set
-# CONFIG_NFSD is not set
-# CONFIG_NFSD_V3 is not set
-CONFIG_SUNRPC=y
-CONFIG_LOCKD=y
-CONFIG_SMB_FS=m
-# CONFIG_SMB_NLS_DEFAULT is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_NCPFS_PACKET_SIGNING is not set
-# CONFIG_NCPFS_IOCTL_LOCKING is not set
-# CONFIG_NCPFS_STRONG is not set
-# CONFIG_NCPFS_NFS_NS is not set
-# CONFIG_NCPFS_OS2_NS is not set
-# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_NLS is not set
-# CONFIG_NCPFS_EXTRAS is not set
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-CONFIG_SMB_NLS=y
-CONFIG_NLS=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS_DEFAULT="iso8859-1"
-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_CODEPAGE_932=m
-CONFIG_NLS_CODEPAGE_936=m
-CONFIG_NLS_CODEPAGE_949=m
-CONFIG_NLS_CODEPAGE_950=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_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-CONFIG_NLS_KOI8_R=m
-CONFIG_NLS_UTF8=m
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# USB support
-#
-# CONFIG_USB is not set
-
-#
-# Input core support
-#
-# CONFIG_INPUT is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_CROSSCOMPILE is not set
-# CONFIG_MIPS_FPE_MODULE is not set
-# CONFIG_MAGIC_SYSRQ is not set
diff -u --recursive --new-file v2.4.9/linux/arch/mips/defconfig-ddb5476 linux/arch/mips/defconfig-ddb5476
--- v2.4.9/linux/arch/mips/defconfig-ddb5476	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/defconfig-ddb5476	Sun Sep  9 10:43:01 2001
@@ -25,19 +25,25 @@
 # CONFIG_MIPS_MAGNUM_4000 is not set
 # CONFIG_MOMENCO_OCELOT is not set
 CONFIG_DDB5476=y
+# CONFIG_DDB5477 is not set
 # CONFIG_OLIVETTI_M700 is not set
 # CONFIG_SGI_IP22 is not set
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MIPS_IVR is not set
+# CONFIG_MIPS_PB1000 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 # CONFIG_MCA is not set
 # CONFIG_SBUS is not set
-CONFIG_I8259=y
 CONFIG_ISA=y
 CONFIG_PCI=y
 CONFIG_PC_KEYB=y
 CONFIG_ROTTEN_IRQ=y
+CONFIG_HAVE_STD_PC_SERIAL_PORT=y
+CONFIG_NEW_TIME_C=y
 CONFIG_EISA=y
+# CONFIG_I8259 is not set
 
 #
 # Loadable module support
@@ -48,26 +54,27 @@
 # CPU selection
 #
 # CONFIG_CPU_R3000 is not set
-# CONFIG_CPU_R3912 is not set
 # CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
 # CONFIG_CPU_R5000 is not set
 CONFIG_CPU_R5432=y
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_NEVADA is not set
-# CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_SB1 is not set
 # CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
 # CONFIG_CPU_HAS_WB is not set
 
 #
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_MIPS_FPU_EMULATOR=y
 CONFIG_KCORE_ELF=y
 CONFIG_ELF_KERNEL=y
 # CONFIG_BINFMT_AOUT is not set
@@ -75,21 +82,18 @@
 # CONFIG_BINFMT_MISC is not set
 CONFIG_NET=y
 # CONFIG_PCI_NAMES is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 
 #
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
 # Plug and Play configuration
 #
 # CONFIG_PNP is not set
 # CONFIG_ISAPNP is not set
-# CONFIG_PCMCIA is not set
+# CONFIG_PNPBIOS is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -97,6 +101,11 @@
 # CONFIG_MTD is not set
 
 #
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
 # Block devices
 #
 # CONFIG_BLK_DEV_FD is not set
@@ -134,6 +143,7 @@
 # CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
 CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
 CONFIG_IP_PNP_BOOTP=y
 # CONFIG_IP_PNP_RARP is not set
 # CONFIG_NET_IPIP is not set
@@ -170,6 +180,7 @@
 #
 # CONFIG_PHONE is not set
 # CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA is not set
 
 #
 # ATA/IDE/MFM/RLL support
@@ -213,6 +224,7 @@
 CONFIG_BLK_DEV_IDEPCI=y
 # CONFIG_IDEPCI_SHARE_IRQ is not set
 # CONFIG_BLK_DEV_IDEDMA_PCI is not set
+# CONFIG_BLK_DEV_ADMA is not set
 # CONFIG_BLK_DEV_OFFBOARD is not set
 # CONFIG_IDEDMA_PCI_AUTO is not set
 # CONFIG_BLK_DEV_IDEDMA is not set
@@ -222,8 +234,8 @@
 # CONFIG_AEC62XX_TUNING is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
 # CONFIG_WDC_ALI15X3 is not set
-# CONFIG_BLK_DEV_AMD7409 is not set
-# CONFIG_AMD7409_OVERRIDE is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_AMD74XX_OVERRIDE is not set
 # CONFIG_BLK_DEV_CMD64X is not set
 # CONFIG_BLK_DEV_CY82C693 is not set
 # CONFIG_BLK_DEV_CS5530 is not set
@@ -234,7 +246,8 @@
 # CONFIG_BLK_DEV_OPTI621 is not set
 # CONFIG_BLK_DEV_PDC202XX is not set
 # CONFIG_PDC202XX_BURST is not set
-# CONFIG_BLK_DEV_OSB4 is not set
+# CONFIG_PDC202XX_FORCE is not set
+# CONFIG_BLK_DEV_SVWKS is not set
 # CONFIG_BLK_DEV_SIS5513 is not set
 # CONFIG_BLK_DEV_SLC90E66 is not set
 # CONFIG_BLK_DEV_TRM290 is not set
@@ -243,6 +256,9 @@
 # CONFIG_IDEDMA_AUTO is not set
 # CONFIG_DMA_NONPCI is not set
 # CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
 
 #
 # SCSI support
@@ -250,16 +266,6 @@
 # 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
@@ -272,12 +278,17 @@
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
-# CONFIG_NET_SB1000 is not set
 
 #
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNGEM is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_LANCE is not set
 # CONFIG_NET_VENDOR_SMC is not set
@@ -293,25 +304,28 @@
 # CONFIG_APRICOT is not set
 # CONFIG_CS89x0 is not set
 CONFIG_TULIP=y
+# CONFIG_TULIP_MWI is not set
+# CONFIG_TULIP_MMIO is not set
 # CONFIG_DE4X5 is not set
 # CONFIG_DGRS is not set
 # CONFIG_DM9102 is not set
 CONFIG_EEPRO100=y
-# CONFIG_EEPRO100_PM is not set
 # CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 CONFIG_NE2K_PCI=y
 # CONFIG_NE3210 is not set
 # CONFIG_ES3210 is not set
 # CONFIG_8139TOO is not set
-# CONFIG_RTL8129 is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_WINBOND_840 is not set
-# CONFIG_HAPPYMEAL is not set
 # CONFIG_LAN_SAA9730 is not set
 # CONFIG_NET_POCKET is not set
 
@@ -319,11 +333,15 @@
 # Ethernet (1000 Mbit)
 #
 # CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
 
@@ -346,6 +364,16 @@
 # 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
@@ -364,7 +392,8 @@
 CONFIG_SERIAL_CONSOLE=y
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_UNIX98_PTYS is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
 
 #
 # I2C support
@@ -383,7 +412,11 @@
 #
 # Joysticks
 #
-# CONFIG_JOYSTICK is not set
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
 
 #
 # Input core support is needed for joysticks
@@ -400,6 +433,7 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
+# CONFIG_SONYPI is not set
 
 #
 # Ftape, the floppy tape device driver
@@ -421,22 +455,30 @@
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_BFS_FS is not set
+# CONFIG_CMS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG 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_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
 # CONFIG_RAMFS is not set
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
 # CONFIG_MINIX_FS is not set
+# CONFIG_FREEVXFS_FS is not set
 # CONFIG_NTFS_FS is not set
 # CONFIG_NTFS_RW is not set
 # CONFIG_HPFS_FS is not set
@@ -444,13 +486,12 @@
 # CONFIG_DEVFS_FS is not set
 # CONFIG_DEVFS_MOUNT is not set
 # CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS is not set
+CONFIG_DEVPTS_FS=y
 # 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
@@ -460,6 +501,7 @@
 # Network File Systems
 #
 # CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 is not set
 CONFIG_ROOT_NFS=y
@@ -490,7 +532,7 @@
 # Console drivers
 #
 # CONFIG_VGA_CONSOLE is not set
-CONFIG_FB=y
+# CONFIG_MDA_CONSOLE is not set
 
 #
 # Frame-buffer support
@@ -501,11 +543,13 @@
 # CONFIG_FB_CLGEN is not set
 # CONFIG_FB_PM2 is not set
 # CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_E1355 is not set
 # CONFIG_FB_MATROX is not set
 # CONFIG_FB_ATY is not set
+# CONFIG_FB_RADEON is not set
 # CONFIG_FB_ATY128 is not set
-CONFIG_FB_3DFX=y
 # CONFIG_FB_SIS is not set
+CONFIG_FB_3DFX=y
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FBCON_ADVANCED is not set
 CONFIG_FBCON_CFB8=y
@@ -527,15 +571,114 @@
 # CONFIG_USB is not set
 
 #
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# USB Network adaptors
+#
+# CONFIG_USB_PLUSB is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# Miscellaneous USB drivers
+#
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_ID75 is not set
+
+#
 # Input core support
 #
 # CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
 
 #
 # Kernel hacking
 #
 CONFIG_CROSSCOMPILE=y
 # CONFIG_REMOTE_DEBUG is not set
+# CONFIG_GDB_CONSOLE is not set
 # CONFIG_LL_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
diff -u --recursive --new-file v2.4.9/linux/arch/mips/defconfig-ddb5477 linux/arch/mips/defconfig-ddb5477
--- v2.4.9/linux/arch/mips/defconfig-ddb5477	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/defconfig-ddb5477	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,565 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_MIPS=y
+# CONFIG_SMP is not set
+
+#
+# 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_EV96100 is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_NINO is not set
+# CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_DDB5476 is not set
+CONFIG_DDB5477=y
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_MIPS_PB1000 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_PCI=y
+CONFIG_NEW_TIME_C=y
+CONFIG_NEW_IRQ=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_I8259 is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# CPU selection
+#
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_R5000 is not set
+CONFIG_CPU_R5432=y
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_SB1 is not set
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+# CONFIG_CPU_HAS_WB is not set
+
+#
+# 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
+# CONFIG_PCI_NAMES is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_BLK_DEV_LVM 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_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES 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_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT 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
+# CONFIG_PHONE_IXJ_PCMCIA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNGEM is not set
+# 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_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+CONFIG_TULIP=y
+# CONFIG_TULIP_MWI is not set
+# CONFIG_TULIP_MMIO is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_LAN_SAA9730 is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI 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 devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER 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
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_SONYPI is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_CMS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG 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_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_FREEVXFS_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_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+# 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_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_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+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
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# USB Network adaptors
+#
+# CONFIG_USB_PLUSB is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# Miscellaneous USB drivers
+#
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_ID75 is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Kernel hacking
+#
+CONFIG_CROSSCOMPILE=y
+# CONFIG_REMOTE_DEBUG is not set
+# CONFIG_GDB_CONSOLE is not set
+CONFIG_LL_DEBUG=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_MIPS_UNCACHED is not set
diff -u --recursive --new-file v2.4.9/linux/arch/mips/defconfig-decstation linux/arch/mips/defconfig-decstation
--- v2.4.9/linux/arch/mips/defconfig-decstation	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/defconfig-decstation	Sun Sep  9 10:43:01 2001
@@ -1,6 +1,8 @@
 #
 # Automatically generated make config: don't edit
 #
+CONFIG_MIPS=y
+# CONFIG_SMP is not set
 
 #
 # Code maturity level options
@@ -13,18 +15,31 @@
 # CONFIG_ACER_PICA_61 is not set
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
-# CONFIG_COBALT_MICRO_SERVER is not set
 CONFIG_DECSTATION=y
 # CONFIG_DDB5074 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_NINO is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
 # CONFIG_OLIVETTI_M700 is not set
 # CONFIG_SGI_IP22 is not set
 # CONFIG_SNI_RM200_PCI is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_MIPS_PB1000 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 # CONFIG_MCA is not set
 # CONFIG_SBUS is not set
 # CONFIG_ISA is not set
 # CONFIG_EISA is not set
 # CONFIG_PCI is not set
+# CONFIG_I8259 is not set
 
 #
 # Loadable module support
@@ -38,15 +53,21 @@
 #
 CONFIG_CPU_R3000=y
 # CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
 # CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_NEVADA is not set
-# CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_SB1 is not set
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
 # CONFIG_CPU_ADVANCED is not set
 # CONFIG_CPU_HAS_LLSC is not set
-CONFIG_CPU_HAS_WB=y
+# CONFIG_CPU_HAS_LLDSCD is not set
+# CONFIG_CPU_HAS_WB is not set
 
 #
 # General setup
@@ -58,16 +79,12 @@
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 CONFIG_NET=y
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
 CONFIG_TC=y
-# CONFIG_PCMCIA is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -75,6 +92,11 @@
 # CONFIG_MTD is not set
 
 #
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
 # Block devices
 #
 # CONFIG_BLK_DEV_FD is not set
@@ -112,6 +134,7 @@
 # CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
 CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
 CONFIG_IP_PNP_BOOTP=y
 # CONFIG_IP_PNP_RARP is not set
 # CONFIG_NET_IPIP is not set
@@ -144,6 +167,13 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA is not set
+
+#
 # SCSI support
 #
 CONFIG_SCSI=y
@@ -178,6 +208,7 @@
 # CONFIG_SCSI_AHA1740 is not set
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
 # CONFIG_SCSI_AM53C974 is not set
@@ -194,6 +225,7 @@
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_NCR_D700 is not set
 # CONFIG_SCSI_NCR53C7xx is not set
 # CONFIG_SCSI_PAS16 is not set
 # CONFIG_SCSI_PCI2000 is not set
@@ -210,12 +242,149 @@
 # Network device support
 #
 CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
 # CONFIG_DUMMY is not set
-# CONFIG_SLIP is not set
-# CONFIG_PPP is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNGEM is not set
+# 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_PCI is not set
+# CONFIG_NET_POCKET is not set
 CONFIG_DECLANCE=y
 
 #
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI 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 devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER 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=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_SONYPI is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # DECStation Character devices
 #
 # CONFIG_VT is not set
@@ -223,7 +392,8 @@
 # CONFIG_DZ is not set
 CONFIG_ZS=y
 CONFIG_SERIAL_CONSOLE=y
-# CONFIG_UNIX98_PTYS is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
 # CONFIG_RTC is not set
 
 #
@@ -234,22 +404,30 @@
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_BFS_FS is not set
+# CONFIG_CMS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG 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_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
 # CONFIG_RAMFS is not set
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
 # CONFIG_MINIX_FS is not set
+# CONFIG_FREEVXFS_FS is not set
 # CONFIG_NTFS_FS is not set
 # CONFIG_NTFS_RW is not set
 # CONFIG_HPFS_FS is not set
@@ -257,13 +435,12 @@
 # CONFIG_DEVFS_FS is not set
 # CONFIG_DEVFS_MOUNT is not set
 # CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS is not set
+CONFIG_DEVPTS_FS=y
 # 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
@@ -273,6 +450,7 @@
 # Network File Systems
 #
 # CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
 # CONFIG_NFS_FS is not set
 # CONFIG_NFS_V3 is not set
 # CONFIG_ROOT_NFS is not set
@@ -305,6 +483,7 @@
 # CONFIG_MINIX_SUBPARTITION is not set
 # CONFIG_SOLARIS_X86_PARTITION is not set
 # CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
 # CONFIG_SGI_PARTITION is not set
 CONFIG_ULTRIX_PARTITION=y
 # CONFIG_SUN_PARTITION is not set
@@ -317,14 +496,114 @@
 # CONFIG_USB is not set
 
 #
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# USB Network adaptors
+#
+# CONFIG_USB_PLUSB is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# Miscellaneous USB drivers
+#
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_ID75 is not set
+
+#
 # Input core support
 #
 # CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
 
 #
 # Kernel hacking
 #
 CONFIG_CROSSCOMPILE=y
-# CONFIG_MIPS_FPE_MODULE is not set
 # CONFIG_REMOTE_DEBUG is not set
+# CONFIG_GDB_CONSOLE is not set
+# CONFIG_LL_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_MIPS_UNCACHED is not set
diff -u --recursive --new-file v2.4.9/linux/arch/mips/defconfig-ip22 linux/arch/mips/defconfig-ip22
--- v2.4.9/linux/arch/mips/defconfig-ip22	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/defconfig-ip22	Sun Sep  9 10:43:02 2001
@@ -1,6 +1,8 @@
 #
 # Automatically generated make config: don't edit
 #
+CONFIG_MIPS=y
+# CONFIG_SMP is not set
 
 #
 # Code maturity level options
@@ -13,21 +15,37 @@
 # CONFIG_ACER_PICA_61 is not set
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
-# CONFIG_COBALT_MICRO_SERVER is not set
 # CONFIG_DECSTATION is not set
 # CONFIG_DDB5074 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_NINO is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
 # CONFIG_OLIVETTI_M700 is not set
 CONFIG_SGI_IP22=y
 # CONFIG_SNI_RM200_PCI is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_MIPS_PB1000 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 # CONFIG_MCA is not set
 # CONFIG_SBUS is not set
 CONFIG_ARC32=y
+CONFIG_BOARD_SCACHE=y
 CONFIG_PC_KEYB=y
 CONFIG_SGI=y
+CONFIG_NEW_IRQ=y
+CONFIG_OLD_TIME_C=y
 # CONFIG_ISA is not set
 # CONFIG_EISA is not set
 # CONFIG_PCI is not set
+# CONFIG_I8259 is not set
 
 #
 # Loadable module support
@@ -41,14 +59,20 @@
 #
 # CONFIG_CPU_R3000 is not set
 # CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
 CONFIG_CPU_R5000=y
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_NEVADA is not set
-# CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_SB1 is not set
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
 # CONFIG_CPU_HAS_WB is not set
 
 #
@@ -59,24 +83,26 @@
 CONFIG_ELF_KERNEL=y
 CONFIG_BINFMT_IRIX=y
 CONFIG_FORWARD_KEYBOARD=y
+# CONFIG_ARC_CONSOLE is not set
 # CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 CONFIG_NET=y
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 
 #
-# Parallel port support
+# Memory Technology Devices (MTD)
 #
-# CONFIG_PARPORT is not set
-# CONFIG_PCMCIA is not set
+# CONFIG_MTD is not set
 
 #
-# Memory Technology Devices (MTD)
+# Parallel port support
 #
-# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
 
 #
 # Block devices
@@ -107,19 +133,24 @@
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK is not set
+CONFIG_PACKET_MMAP=y
+CONFIG_NETLINK=y
+CONFIG_RTNETLINK=y
+CONFIG_NETLINK_DEV=y
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
 CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
+CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
 CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
 CONFIG_IP_PNP_BOOTP=y
 # CONFIG_IP_PNP_RARP is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
 # CONFIG_IPV6 is not set
@@ -148,6 +179,13 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA is not set
+
+#
 # SCSI support
 #
 CONFIG_SCSI=y
@@ -175,7 +213,7 @@
 #
 # SCSI low-level drivers
 #
-CONFIG_SCSI_SGIWD93=y
+CONFIG_SGIWD93_SCSI=y
 # CONFIG_SCSI_7000FASST is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AHA152X is not set
@@ -183,6 +221,7 @@
 # CONFIG_SCSI_AHA1740 is not set
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
 # CONFIG_SCSI_AM53C974 is not set
@@ -199,6 +238,7 @@
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_NCR_D700 is not set
 # CONFIG_SCSI_NCR53C7xx is not set
 # CONFIG_SCSI_PAS16 is not set
 # CONFIG_SCSI_PCI2000 is not set
@@ -215,20 +255,159 @@
 # Network device support
 #
 CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
 # CONFIG_DUMMY is not set
-# CONFIG_SLIP is not set
-# CONFIG_PPP is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNGEM is not set
+# 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_PCI is not set
+# CONFIG_NET_POCKET is not set
 CONFIG_SGISEEQ=y
 
 #
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI 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 devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER 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=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=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_SONYPI is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # SGI Character devices
 #
 CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
 CONFIG_SGI_NEWPORT_CONSOLE=y
 CONFIG_FONT_8x16=y
-# CONFIG_SGI_PROM_CONSOLE is not set
-# CONFIG_UNIX98_PTYS is not set
+# CONFIG_PSMOUSE is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
 
 #
 # File systems
@@ -238,22 +417,30 @@
 CONFIG_AUTOFS4_FS=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_BFS_FS is not set
+# CONFIG_CMS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG 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_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
 # CONFIG_RAMFS is not set
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
 # CONFIG_MINIX_FS is not set
+# CONFIG_FREEVXFS_FS is not set
 # CONFIG_NTFS_FS is not set
 # CONFIG_NTFS_RW is not set
 # CONFIG_HPFS_FS is not set
@@ -261,13 +448,12 @@
 # CONFIG_DEVFS_FS is not set
 # CONFIG_DEVFS_MOUNT is not set
 # CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS is not set
+CONFIG_DEVPTS_FS=y
 # 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
@@ -277,6 +463,7 @@
 # Network File Systems
 #
 # CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 is not set
 CONFIG_ROOT_NFS=y
@@ -309,6 +496,7 @@
 # CONFIG_MINIX_SUBPARTITION is not set
 # CONFIG_SOLARIS_X86_PARTITION is not set
 # CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
 CONFIG_SGI_PARTITION=y
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
@@ -319,7 +507,7 @@
 # Console drivers
 #
 # CONFIG_VGA_CONSOLE is not set
-# CONFIG_FB is not set
+# CONFIG_MDA_CONSOLE is not set
 
 #
 # Frame-buffer support
@@ -345,13 +533,111 @@
 # CONFIG_USB is not set
 
 #
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# USB Network adaptors
+#
+# CONFIG_USB_PLUSB is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# Miscellaneous USB drivers
+#
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_ID75 is not set
+
+#
 # Input core support
 #
 # CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
 
 #
 # Kernel hacking
 #
 CONFIG_CROSSCOMPILE=y
-# CONFIG_MIPS_FPE_MODULE is not set
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_MIPS_UNCACHED is not set
diff -u --recursive --new-file v2.4.9/linux/arch/mips/defconfig-it8172 linux/arch/mips/defconfig-it8172
--- v2.4.9/linux/arch/mips/defconfig-it8172	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/defconfig-it8172	Sun Sep  9 10:43:02 2001
@@ -25,6 +25,7 @@
 # CONFIG_MIPS_MAGNUM_4000 is not set
 # CONFIG_MOMENCO_OCELOT is not set
 # CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
 # CONFIG_OLIVETTI_M700 is not set
 # CONFIG_SGI_IP22 is not set
 # CONFIG_SNI_RM200_PCI is not set
@@ -35,11 +36,16 @@
 # CONFIG_IT8172_SCR0 is not set
 # CONFIG_IT8172_SCR1 is not set
 # CONFIG_MIPS_IVR is not set
+# CONFIG_MIPS_PB1000 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 # CONFIG_MCA is not set
 # CONFIG_SBUS is not set
 CONFIG_PCI=y
 CONFIG_IT8712=y
 CONFIG_PC_KEYB=y
+CONFIG_NEW_PCI=y
+CONFIG_PCI_AUTO=y
 # CONFIG_ISA is not set
 # CONFIG_EISA is not set
 # CONFIG_I8259 is not set
@@ -55,26 +61,27 @@
 # CPU selection
 #
 # CONFIG_CPU_R3000 is not set
-# CONFIG_CPU_R3912 is not set
 # CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
 # CONFIG_CPU_R5000 is not set
 # CONFIG_CPU_R5432 is not set
 # CONFIG_CPU_RM7000 is not set
 CONFIG_CPU_NEVADA=y
-# CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_SB1 is not set
 # CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
 # CONFIG_CPU_HAS_WB is not set
 
 #
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_MIPS_FPU_EMULATOR=y
 CONFIG_KCORE_ELF=y
 CONFIG_ELF_KERNEL=y
 # CONFIG_BINFMT_AOUT is not set
@@ -82,68 +89,87 @@
 # CONFIG_BINFMT_MISC is not set
 CONFIG_NET=y
 CONFIG_PCI_NAMES=y
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
 CONFIG_SYSVIPC=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_SYSCTL=y
 
 #
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-# CONFIG_PCMCIA is not set
-
-#
 # Memory Technology Devices (MTD)
 #
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_PARTITIONS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_BOOTLDR_PARTS is not set
 
 #
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC1000 is not set
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOCPROBE is not set
-
+# User Modules And Translation Layers
 #
-# RAM/ROM Device Drivers
-#
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_PMC551 is not set
-# CONFIG_MTD_MTDRAM is not set
+CONFIG_MTD_CHAR=y
+# CONFIG_MTD_BLOCK is not set
+# CONFIG_MTD_BLOCK_RO is not set
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
 
 #
-# Linearly Mapped Flash Device Drivers
+# RAM/ROM/Flash chip drivers
 #
 CONFIG_MTD_CFI=y
+# CONFIG_MTD_CFI_VIRTUAL_ER is not set
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
 CONFIG_MTD_CFI_INTELEXT=y
 # CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
 CONFIG_MTD_PHYSMAP=y
 CONFIG_MTD_PHYSMAP_START=8000000
 CONFIG_MTD_PHYSMAP_LEN=2000000
 CONFIG_MTD_PHYSMAP_BUSWIDTH=4
-
-#
-# Drivers for chip mappings
-#
-# CONFIG_MTD_MIXMEM is not set
-# CONFIG_MTD_NORA is not set
-# CONFIG_MTD_OCTAGON is not set
 # CONFIG_MTD_PNC2000 is not set
 # CONFIG_MTD_RPXLITE is not set
+# CONFIG_MTD_SBC_GXX is not set
+# CONFIG_MTD_ELAN_104NC is not set
+# CONFIG_MTD_DBOX2 is not set
+# CONFIG_MTD_CSTM_MIPS_IXX is not set
+# CONFIG_MTD_CFI_FLAGADM is not set
+# CONFIG_MTD_MIXMEM is not set
+# CONFIG_MTD_OCTAGON is not set
 # CONFIG_MTD_VMAX is not set
+# CONFIG_MTD_OCELOT is not set
 
 #
-# User modules and translation layers for MTD devices
+# Self-contained MTD device drivers
 #
-CONFIG_MTD_CHAR=y
-# CONFIG_MTD_BLOCK is not set
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
 
 #
 # Block devices
@@ -182,6 +208,7 @@
 # CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
 CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
 CONFIG_IP_PNP_BOOTP=y
 # CONFIG_IP_PNP_RARP is not set
 # CONFIG_NET_IPIP is not set
@@ -218,6 +245,7 @@
 #
 # CONFIG_PHONE is not set
 # CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA is not set
 
 #
 # ATA/IDE/MFM/RLL support
@@ -261,6 +289,7 @@
 CONFIG_BLK_DEV_IDEPCI=y
 CONFIG_IDEPCI_SHARE_IRQ=y
 CONFIG_BLK_DEV_IDEDMA_PCI=y
+CONFIG_BLK_DEV_ADMA=y
 # CONFIG_BLK_DEV_OFFBOARD is not set
 CONFIG_IDEDMA_PCI_AUTO=y
 CONFIG_BLK_DEV_IDEDMA=y
@@ -270,8 +299,8 @@
 # CONFIG_AEC62XX_TUNING is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
 # CONFIG_WDC_ALI15X3 is not set
-# CONFIG_BLK_DEV_AMD7409 is not set
-# CONFIG_AMD7409_OVERRIDE is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_AMD74XX_OVERRIDE is not set
 # CONFIG_BLK_DEV_CMD64X is not set
 # CONFIG_BLK_DEV_CY82C693 is not set
 # CONFIG_BLK_DEV_CS5530 is not set
@@ -280,11 +309,14 @@
 # CONFIG_BLK_DEV_HPT366 is not set
 CONFIG_BLK_DEV_IT8172=y
 CONFIG_IT8172_TUNING=y
+CONFIG_BLK_DEV_IT8172=y
+CONFIG_IT8172_TUNING=y
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_OPTI621 is not set
 # CONFIG_BLK_DEV_PDC202XX is not set
 # CONFIG_PDC202XX_BURST is not set
-# CONFIG_BLK_DEV_OSB4 is not set
+# CONFIG_PDC202XX_FORCE is not set
+# CONFIG_BLK_DEV_SVWKS is not set
 # CONFIG_BLK_DEV_SIS5513 is not set
 # CONFIG_BLK_DEV_SLC90E66 is not set
 # CONFIG_BLK_DEV_TRM290 is not set
@@ -299,12 +331,15 @@
 # CONFIG_BLK_DEV_DTC2278 is not set
 # CONFIG_BLK_DEV_HT6560B is not set
 # CONFIG_BLK_DEV_PDC4030 is not set
-# CONFIG_BLK_DEV_QD6580 is not set
+# CONFIG_BLK_DEV_QD65XX is not set
 # CONFIG_BLK_DEV_UMC8672 is not set
 CONFIG_IDEDMA_AUTO=y
 # CONFIG_IDEDMA_IVB is not set
 # CONFIG_DMA_NONPCI is not set
 CONFIG_BLK_DEV_IDE_MODES=y
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
 
 #
 # SCSI support
@@ -312,16 +347,6 @@
 # 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
@@ -334,18 +359,21 @@
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
-# CONFIG_NET_SB1000 is not set
 
 #
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNGEM is not set
 # 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_AT1700 is not set
-# CONFIG_DEPCA is not set
 # CONFIG_HP100 is not set
 # CONFIG_NET_ISA is not set
 CONFIG_NET_PCI=y
@@ -354,25 +382,28 @@
 # CONFIG_APRICOT is not set
 # CONFIG_CS89x0 is not set
 CONFIG_TULIP=y
+# CONFIG_TULIP_MWI is not set
+# CONFIG_TULIP_MMIO is not set
 # CONFIG_DE4X5 is not set
 # CONFIG_DGRS is not set
 # CONFIG_DM9102 is not set
 # CONFIG_EEPRO100 is not set
-# CONFIG_EEPRO100_PM is not set
 # CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 # CONFIG_NE2K_PCI is not set
 # CONFIG_NE3210 is not set
 # CONFIG_ES3210 is not set
 CONFIG_8139TOO=y
-# CONFIG_RTL8129 is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_WINBOND_840 is not set
-# CONFIG_HAPPYMEAL is not set
 # CONFIG_LAN_SAA9730 is not set
 # CONFIG_NET_POCKET is not set
 
@@ -380,11 +411,15 @@
 # Ethernet (1000 Mbit)
 #
 # CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
 
@@ -407,6 +442,16 @@
 # 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
@@ -424,7 +469,12 @@
 CONFIG_SERIAL_CONSOLE=y
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_UNIX98_PTYS is not set
+CONFIG_QTRONIX_KEYBOARD=y
+CONFIG_IT8172_CIR=y
+# CONFIG_IT8172_SCR0 is not set
+# CONFIG_IT8172_SCR1 is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
 
 #
 # I2C support
@@ -440,7 +490,11 @@
 #
 # Joysticks
 #
-# CONFIG_JOYSTICK is not set
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
 
 #
 # Input core support is needed for joysticks
@@ -457,6 +511,7 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
+# CONFIG_SONYPI is not set
 
 #
 # Ftape, the floppy tape device driver
@@ -464,6 +519,7 @@
 # CONFIG_FTAPE is not set
 # CONFIG_AGP is not set
 # CONFIG_DRM is not set
+# CONFIG_ITE_GPIO is not set
 
 #
 # Multimedia devices
@@ -478,22 +534,30 @@
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_BFS_FS is not set
+# CONFIG_CMS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG 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_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
 # CONFIG_RAMFS is not set
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
 # CONFIG_MINIX_FS is not set
+# CONFIG_FREEVXFS_FS is not set
 # CONFIG_NTFS_FS is not set
 # CONFIG_NTFS_RW is not set
 # CONFIG_HPFS_FS is not set
@@ -501,13 +565,12 @@
 # CONFIG_DEVFS_FS is not set
 # CONFIG_DEVFS_MOUNT is not set
 # CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS is not set
+CONFIG_DEVPTS_FS=y
 # 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
@@ -517,6 +580,7 @@
 # Network File Systems
 #
 # CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 is not set
 CONFIG_ROOT_NFS=y
@@ -554,16 +618,114 @@
 # CONFIG_USB is not set
 
 #
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# USB Network adaptors
+#
+# CONFIG_USB_PLUSB is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# Miscellaneous USB drivers
+#
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_ID75 is not set
+
+#
 # Input core support
 #
 # CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
 
 #
 # Kernel hacking
 #
 CONFIG_CROSSCOMPILE=y
-# CONFIG_MIPS_FPE_MODULE is not set
 # CONFIG_REMOTE_DEBUG is not set
+# CONFIG_GDB_CONSOLE is not set
 # CONFIG_LL_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
diff -u --recursive --new-file v2.4.9/linux/arch/mips/defconfig-malta linux/arch/mips/defconfig-malta
--- v2.4.9/linux/arch/mips/defconfig-malta	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/defconfig-malta	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,630 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_MIPS=y
+# CONFIG_SMP is not set
+
+#
+# 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_EV96100 is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_ATLAS is not set
+CONFIG_MIPS_MALTA=y
+# CONFIG_NINO is not set
+# CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_MIPS_PB1000 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+CONFIG_I8259=y
+CONFIG_PCI=y
+CONFIG_HAVE_STD_PC_SERIAL_PORT=y
+CONFIG_NEW_IRQ=y
+CONFIG_SWAP_IO_SPACE=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# CPU selection
+#
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+# CONFIG_CPU_HAS_LLDSCD is not set
+# CONFIG_CPU_HAS_WB is not set
+
+#
+# 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
+# CONFIG_PCI_NAMES is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=y
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_BLK_DEV_LVM 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_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES 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_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT 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
+# CONFIG_PHONE_IXJ_PCMCIA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD 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_CHR_DEV_OSST is not set
+# 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_BLK_DEV_3W_XXXX_RAID is not set
+# 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_AIC7XXX_OLD is not set
+# CONFIG_SCSI_DPT_I2O 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_CPQFCTS is not set
+# CONFIG_SCSI_DMX3191D 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_NCR53C406A is not set
+# CONFIG_SCSI_NCR_D700 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 is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNGEM is not set
+# 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_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=y
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_TULIP is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_LAN_SAA9730 is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI 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 devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER 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=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+CONFIG_RTC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_SONYPI is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+CONFIG_AUTOFS_FS=y
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_CMS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG 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=y
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_FREEVXFS_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_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# 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_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_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+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
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# USB Network adaptors
+#
+# CONFIG_USB_PLUSB is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# Miscellaneous USB drivers
+#
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_ID75 is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Kernel hacking
+#
+CONFIG_CROSSCOMPILE=y
+# CONFIG_REMOTE_DEBUG is not set
+# CONFIG_GDB_CONSOLE is not set
+# CONFIG_LL_DEBUG is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_MIPS_UNCACHED is not set
diff -u --recursive --new-file v2.4.9/linux/arch/mips/defconfig-nino linux/arch/mips/defconfig-nino
--- v2.4.9/linux/arch/mips/defconfig-nino	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/defconfig-nino	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,415 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_MIPS=y
+# CONFIG_SMP is not set
+
+#
+# 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_EV96100 is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+CONFIG_NINO=y
+# CONFIG_NINO_4MB is not set
+CONFIG_NINO_8MB=y
+# CONFIG_NINO_16MB is not set
+# CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_MIPS_PB1000 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+CONFIG_PC_KEYB=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_PCI is not set
+# CONFIG_I8259 is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# CPU selection
+#
+CONFIG_CPU_R3000=y
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_SB1 is not set
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_ADVANCED is not set
+# CONFIG_CPU_HAS_LLSC is not set
+# CONFIG_CPU_HAS_LLDSCD is not set
+# CONFIG_CPU_HAS_WB is not set
+
+#
+# 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=y
+# CONFIG_NET is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=2048
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# ISDN subsystem
+#
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+# CONFIG_CYCLADES is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_DIGI is not set
+# CONFIG_ESPSERIAL is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+# CONFIG_SYNCLINK is not set
+# CONFIG_N_HDLC is not set
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+CONFIG_SERIAL_TX3912=y
+CONFIG_SERIAL_TX3912_CONSOLE=y
+# CONFIG_AU1000_UART is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_SONYPI is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_CMS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG 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_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_FREEVXFS_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_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# 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_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_SMB_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# USB Network adaptors
+#
+
+#
+#   Networking support is needed for USB Networking device support
+#
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# Miscellaneous USB drivers
+#
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_ID75 is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Kernel hacking
+#
+CONFIG_CROSSCOMPILE=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_MIPS_UNCACHED is not set
diff -u --recursive --new-file v2.4.9/linux/arch/mips/defconfig-ocelot linux/arch/mips/defconfig-ocelot
--- v2.4.9/linux/arch/mips/defconfig-ocelot	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/defconfig-ocelot	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,566 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_MIPS=y
+# CONFIG_SMP is not set
+
+#
+# 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_EV96100 is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_NINO is not set
+# CONFIG_MIPS_MAGNUM_4000 is not set
+CONFIG_MOMENCO_OCELOT=y
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_MIPS_PB1000 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+CONFIG_PCI=y
+CONFIG_SYSCLK_100=y
+CONFIG_SWAP_IO_SPACE=y
+CONFIG_NEW_IRQ=y
+CONFIG_OLD_TIME_C=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_I8259 is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# CPU selection
+#
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+CONFIG_CPU_RM7000=y
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_SB1 is not set
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=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 is not set
+# CONFIG_FORWARD_KEYBOARD is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_NET=y
+CONFIG_PCI_NAMES=y
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_BLK_DEV_LVM 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_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES 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_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT 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
+# CONFIG_PHONE_IXJ_PCMCIA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNGEM is not set
+# 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_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_TULIP is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+CONFIG_EEPRO100=y
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_LAN_SAA9730 is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI 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 devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER 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=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_SONYPI is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_CMS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG 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_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_FREEVXFS_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_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# 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_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_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+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
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# USB Network adaptors
+#
+# CONFIG_USB_PLUSB is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# Miscellaneous USB drivers
+#
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_ID75 is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Kernel hacking
+#
+CONFIG_CROSSCOMPILE=y
+# CONFIG_REMOTE_DEBUG is not set
+# CONFIG_GDB_CONSOLE is not set
+# CONFIG_LL_DEBUG is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_MIPS_UNCACHED is not set
diff -u --recursive --new-file v2.4.9/linux/arch/mips/defconfig-orion linux/arch/mips/defconfig-orion
--- v2.4.9/linux/arch/mips/defconfig-orion	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/defconfig-orion	Wed Dec 31 16:00:00 1969
@@ -1,304 +0,0 @@
-#
-# 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_COBALT_MICRO_SERVER 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 is not set
-# CONFIG_SNI_RM200_PCI is not set
-# CONFIG_MCA is not set
-# CONFIG_SBUS is not set
-# CONFIG_ISA is not set
-# CONFIG_EISA is not set
-# CONFIG_PCI is not set
-
-#
-# Loadable module support
-#
-# CONFIG_MODULES 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 is not set
-# CONFIG_FORWARD_KEYBOARD is not set
-# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
-CONFIG_NET=y
-# CONFIG_SYSVIPC is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-# CONFIG_PCMCIA is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
-# CONFIG_PARIDE is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_INITRD=y
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-# CONFIG_BLK_DEV_MD is not set
-# CONFIG_MD_LINEAR is not set
-# CONFIG_MD_RAID0 is not set
-# CONFIG_MD_RAID1 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_BLK_DEV_LVM 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 is not set
-# CONFIG_INET is not set
-# CONFIG_ATM is not set
-
-#
-#  
-#
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_DECNET is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_LLC is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET_AUNUDP is not set
-# CONFIG_ECONET_NATIVE 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
-
-#
-# ATA/IDE/MFM/RLL support
-#
-# CONFIG_IDE is not set
-# CONFIG_BLK_DEV_IDE_MODES is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# SCSI support
-#
-# CONFIG_SCSI is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O 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 is not set
-
-#
-# Character devices
-#
-# CONFIG_VT is not set
-# CONFIG_SERIAL is not set
-# CONFIG_SERIAL_EXTENDED is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_UNIX98_PTYS 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
-
-#
-# Input core support is needed for joysticks
-#
-# CONFIG_QIC02_TAPE is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_INTEL_RNG is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC 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_AGP is not set
-# CONFIG_DRM is not set
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# File systems
-#
-# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_ADFS_FS is not set
-# CONFIG_ADFS_FS_RW 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_JFFS_FS is not set
-# CONFIG_CRAMFS is not set
-CONFIG_RAMFS=y
-# 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_DEVFS_FS is not set
-# CONFIG_DEVFS_MOUNT is not set
-# CONFIG_DEVFS_DEBUG is not set
-# 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_NFS_V3 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_NCPFS_NLS is not set
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_SMB_NLS is not set
-# CONFIG_NLS is not set
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# USB support
-#
-# CONFIG_USB is not set
-
-#
-# Input core support
-#
-# CONFIG_INPUT is not set
-
-#
-# Kernel hacking
-#
-CONFIG_CROSSCOMPILE=y
-# CONFIG_MAGIC_SYSRQ is not set
diff -u --recursive --new-file v2.4.9/linux/arch/mips/defconfig-pb1000 linux/arch/mips/defconfig-pb1000
--- v2.4.9/linux/arch/mips/defconfig-pb1000	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/defconfig-pb1000	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,565 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_MIPS=y
+# CONFIG_SMP is not set
+
+#
+# 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_EV96100 is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_NINO is not set
+# CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_IVR is not set
+CONFIG_MIPS_PB1000=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+CONFIG_MIPS_AU1000=y
+CONFIG_NEW_IRQ=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_PCI is not set
+# CONFIG_I8259 is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# CPU selection
+#
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS64 is not set
+CONFIG_CPU_ADVANCED=y
+CONFIG_CPU_HAS_LLSC=y
+# CONFIG_CPU_HAS_LLDSCD 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
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_BLK_DEV_LVM 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_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES 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_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT 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
+# CONFIG_PHONE_IXJ_PCMCIA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MIPS_AU1000_ENET=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNGEM is not set
+# 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_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI 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 devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER 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 is not set
+# CONFIG_SERIAL_EXTENDED is not set
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+# CONFIG_CYCLADES is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_DIGI is not set
+# CONFIG_ESPSERIAL is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_SYNCLINK is not set
+# CONFIG_N_HDLC is not set
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+# CONFIG_SERIAL_TX3912 is not set
+# CONFIG_SERIAL_TX3912_CONSOLE is not set
+CONFIG_AU1000_UART=y
+CONFIG_AU1000_SERIAL_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_SONYPI is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_CMS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG 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_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+# CONFIG_RAMFS is not set
+CONFIG_ISO9660_FS=y
+# CONFIG_JOLIET is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_FREEVXFS_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_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+# 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_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_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+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
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# 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_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# USB Network adaptors
+#
+# CONFIG_USB_PLUSB is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# Miscellaneous USB drivers
+#
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_ID75 is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Kernel hacking
+#
+CONFIG_CROSSCOMPILE=y
+# CONFIG_REMOTE_DEBUG is not set
+# CONFIG_GDB_CONSOLE is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_MIPS_UNCACHED is not set
diff -u --recursive --new-file v2.4.9/linux/arch/mips/defconfig-rm200 linux/arch/mips/defconfig-rm200
--- v2.4.9/linux/arch/mips/defconfig-rm200	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/defconfig-rm200	Sun Sep  9 10:43:02 2001
@@ -1,6 +1,8 @@
 #
 # Automatically generated make config: don't edit
 #
+CONFIG_MIPS=y
+# CONFIG_SMP is not set
 
 #
 # Code maturity level options
@@ -13,19 +15,34 @@
 # CONFIG_ACER_PICA_61 is not set
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
-# CONFIG_COBALT_MICRO_SERVER is not set
 # CONFIG_DECSTATION is not set
 # CONFIG_DDB5074 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_NINO is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
 # CONFIG_OLIVETTI_M700 is not set
 # CONFIG_SGI_IP22 is not set
 CONFIG_SNI_RM200_PCI=y
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_MIPS_PB1000 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 # CONFIG_MCA is not set
 # CONFIG_SBUS is not set
 CONFIG_ARC32=y
-CONFIG_PCI=y
+CONFIG_I8259=y
 CONFIG_ISA=y
 CONFIG_PC_KEYB=y
+CONFIG_PCI=y
+CONFIG_ROTTEN_IRQ=y
+CONFIG_OLD_TIME_C=y
 CONFIG_EISA=y
 
 #
@@ -40,14 +57,20 @@
 #
 # CONFIG_CPU_R3000 is not set
 # CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
 CONFIG_CPU_R5000=y
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_NEVADA is not set
-# CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_SB1 is not set
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
 # CONFIG_CPU_HAS_WB is not set
 
 #
@@ -56,26 +79,24 @@
 CONFIG_CPU_LITTLE_ENDIAN=y
 CONFIG_KCORE_ELF=y
 CONFIG_ELF_KERNEL=y
+# CONFIG_ARC_CONSOLE is not set
 # CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 CONFIG_NET=y
 # CONFIG_PCI_NAMES is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
 # CONFIG_SYSVIPC is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 
 #
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
 # Plug and Play configuration
 #
 # CONFIG_PNP is not set
 # CONFIG_ISAPNP is not set
-# CONFIG_PCMCIA is not set
+# CONFIG_PNPBIOS is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -83,6 +104,11 @@
 # CONFIG_MTD is not set
 
 #
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
 # Block devices
 #
 CONFIG_BLK_DEV_FD=y
@@ -154,6 +180,7 @@
 #
 # CONFIG_PHONE is not set
 # CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA is not set
 
 #
 # ATA/IDE/MFM/RLL support
@@ -168,19 +195,19 @@
 # CONFIG_SCSI is not set
 
 #
-# I2O device support
+# Network 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
+# CONFIG_NETDEVICES is not set
 
 #
-# Network device support
+# Amateur Radio support
 #
-# CONFIG_NETDEVICES is not set
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
 
 #
 # ISDN subsystem
@@ -200,7 +227,8 @@
 # CONFIG_SERIAL is not set
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_UNIX98_PTYS is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
 
 #
 # I2C support
@@ -216,7 +244,11 @@
 #
 # Joysticks
 #
-# CONFIG_JOYSTICK is not set
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
 
 #
 # Input core support is needed for joysticks
@@ -233,6 +265,7 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
+# CONFIG_SONYPI is not set
 
 #
 # Ftape, the floppy tape device driver
@@ -254,22 +287,30 @@
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_BFS_FS is not set
+# CONFIG_CMS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG 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_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
 # CONFIG_RAMFS is not set
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
 # CONFIG_MINIX_FS is not set
+# CONFIG_FREEVXFS_FS is not set
 # CONFIG_NTFS_FS is not set
 # CONFIG_NTFS_RW is not set
 # CONFIG_HPFS_FS is not set
@@ -277,13 +318,12 @@
 # CONFIG_DEVFS_FS is not set
 # CONFIG_DEVFS_MOUNT is not set
 # CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS is not set
+CONFIG_DEVPTS_FS=y
 # 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
@@ -293,6 +333,7 @@
 # Network File Systems
 #
 # CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
 # CONFIG_NFS_FS is not set
 # CONFIG_NFS_V3 is not set
 # CONFIG_ROOT_NFS is not set
@@ -325,6 +366,7 @@
 # CONFIG_MINIX_SUBPARTITION is not set
 # CONFIG_SOLARIS_X86_PARTITION is not set
 # CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
 CONFIG_SGI_PARTITION=y
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
@@ -335,7 +377,7 @@
 # Console drivers
 #
 CONFIG_VGA_CONSOLE=y
-# CONFIG_FB is not set
+# CONFIG_MDA_CONSOLE is not set
 
 #
 # Frame-buffer support
@@ -353,13 +395,111 @@
 # CONFIG_USB is not set
 
 #
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# USB Network adaptors
+#
+# CONFIG_USB_PLUSB is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# Miscellaneous USB drivers
+#
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_ID75 is not set
+
+#
 # Input core support
 #
 # CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
 
 #
 # Kernel hacking
 #
 CONFIG_CROSSCOMPILE=y
-# CONFIG_MIPS_FPE_MODULE is not set
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_MIPS_UNCACHED is not set
diff -u --recursive --new-file v2.4.9/linux/arch/mips/gt64120/common/Makefile linux/arch/mips/gt64120/common/Makefile
--- v2.4.9/linux/arch/mips/gt64120/common/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/gt64120/common/Makefile	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,18 @@
+#
+# Makefile for common code of gt64120-based boards.
+#
+# 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.s:
+	$(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+	$(CC) $(CFLAGS) -c $< -o $*.o
+
+O_TARGET:= gt64120.o
+
+obj-y	 := gt_irq.o pci.o
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.9/linux/arch/mips/gt64120/common/gt_irq.c linux/arch/mips/gt64120/common/gt_irq.c
--- v2.4.9/linux/arch/mips/gt64120/common/gt_irq.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/gt64120/common/gt_irq.c	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,250 @@
+/*
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * arch/mips/gt64120/common/gt_irq.c
+ *     Interrupt routines for gt64120.  Currently it only handles timer irq.
+ *
+ * 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/interrupt.h>
+#include <linux/kernel.h>
+#include <asm/ptrace.h>
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <asm/io.h>
+#include <asm/gt64120/gt64120.h>
+
+/*
+ * These are interrupt handlers for the GT on-chip interrupts.  They
+ * all come in to the MIPS on a single interrupt line, and have to
+ * be handled and ack'ed differently than other MIPS interrupts.
+ */
+
+#if CURRENTLY_UNUSED
+
+struct tq_struct irq_handlers[MAX_CAUSE_REGS][MAX_CAUSE_REG_WIDTH];
+void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr);
+
+/*
+ * Hooks IRQ handler to the system. When the system is interrupted
+ * the interrupt service routine is called.
+ *
+ * Inputs :
+ * int_cause - The interrupt cause number. In EVB64120 two parameters 
+ *             are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH. 
+ * bit_num   - Indicates which bit number in the cause register
+ * isr_ptr   - Pointer to the interrupt service routine
+ */
+void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr)
+{
+	irq_handlers[int_cause][bit_num].routine = isr_ptr;
+}
+
+
+/*
+ * Enables the IRQ on Galileo Chip
+ *
+ * Inputs :
+ * int_cause - The interrupt cause number. In EVB64120 two parameters 
+ *             are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH.
+ * bit_num   - Indicates which bit number in the cause register
+ *
+ * Outputs :
+ * 1 if succesful, 0 if failure
+ */
+int enable_galileo_irq(int int_cause, int bit_num)
+{
+	if (int_cause == INT_CAUSE_MAIN)
+		SET_REG_BITS(CPU_INTERRUPT_MASK_REGISTER, (1 << bit_num));
+	else if (int_cause == INT_CAUSE_HIGH)
+		SET_REG_BITS(CPU_HIGH_INTERRUPT_MASK_REGISTER,
+			     (1 << bit_num));
+	else
+		return 0;
+
+	return 1;
+}
+
+/*
+ * Disables the IRQ on Galileo Chip
+ *
+ * Inputs :
+ * int_cause - The interrupt cause number. In EVB64120 two parameters 
+ *             are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH.
+ * bit_num   - Indicates which bit number in the cause register
+ *
+ * Outputs :
+ * 1 if succesful, 0 if failure
+ */
+int disable_galileo_irq(int int_cause, int bit_num)
+{
+	if (int_cause == INT_CAUSE_MAIN)
+		RESET_REG_BITS(CPU_INTERRUPT_MASK_REGISTER,
+			       (1 << bit_num));
+	else if (int_cause == INT_CAUSE_HIGH)
+		RESET_REG_BITS(CPU_HIGH_INTERRUPT_MASK_REGISTER,
+			       (1 << bit_num));
+	else
+		return 0;
+	return 1;
+}
+#endif				/*  UNUSED  */
+
+/*
+ * Interrupt handler for interrupts coming from the Galileo chip.
+ * It could be timer interrupt, built in ethernet ports etc...
+ */
+static void gt64120_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned int irq_src, int_high_src, irq_src_mask,
+	    int_high_src_mask;
+	int handled;
+
+	GT_READ(GT_INTRCAUSE_OFS, &irq_src);
+	GT_READ(GT_INTRMASK_OFS, &irq_src_mask);
+	GT_READ(GT_HINTRCAUSE_OFS, &int_high_src);
+	GT_READ(GT_HINTRMASK_OFS, &int_high_src_mask);
+	irq_src = irq_src & irq_src_mask;
+	int_high_src = int_high_src & int_high_src_mask;
+
+	handled = 0;
+
+	/* Execute all interrupt handlers */
+	/* Check for timer interrupt */
+	if (irq_src & 0x00000800) {
+		handled = 1;
+		irq_src &= ~0x00000800;
+		//    RESET_REG_BITS (INTERRUPT_CAUSE_REGISTER,BIT8);
+		do_timer(regs);
+	}
+
+	if (irq_src) {
+		printk(KERN_INFO
+		       "Other Galileo interrupt received irq_src %x\n",
+		       irq_src);
+#if CURRENTLY_UNUSED
+		for (count = 0; count < MAX_CAUSE_REG_WIDTH; count++) {
+			if (irq_src & (1 << count)) {
+				if (irq_handlers[INT_CAUSE_MAIN][count].
+				    routine) {
+					queue_task(&irq_handlers
+						   [INT_CAUSE_MAIN][count],
+						   &tq_immediate);
+					mark_bh(IMMEDIATE_BH);
+					handled = 1;
+				}
+			}
+		}
+#endif				/*  UNUSED  */
+	}
+	GT_WRITE(GT_INTRCAUSE_OFS, 0);
+	GT_WRITE(GT_HINTRCAUSE_OFS, 0);
+
+#undef GALILEO_I2O
+#ifdef GALILEO_I2O
+	/*
+	 * Future I2O support.  We currently attach I2O interrupt handlers to
+	 * the Galileo interrupt (int 4) and handle them in do_IRQ.
+	 */
+	if (isInBoundDoorBellInterruptSet()) {
+		printk(KERN_INFO "I2O doorbell interrupt received.\n");
+		handled = 1;
+	}
+
+	if (isInBoundPostQueueInterruptSet()) {
+		printk(KERN_INFO "I2O Queue interrupt received.\n");
+		handled = 1;
+	}
+
+	/*
+	 * This normally would be outside of the ifdef, but since we're
+	 * handling I2O outside of this handler, this printk shows up every
+	 * time we get a valid I2O interrupt.  So turn this off for now.
+	 */
+	if (handled == 0) {
+		if (counter < 50) {
+			printk("Spurious Galileo interrupt...\n");
+			counter++;
+		}
+	}
+#endif
+}
+
+/*
+ * Initializes timer using galileo's built in timer.
+ */
+#ifdef CONFIG_SYSCLK_100
+#define Sys_clock (100 * 1000000)	// 100 MHz
+#endif
+#ifdef CONFIG_SYSCLK_83
+#define Sys_clock (83.333 * 1000000)	// 83.333 MHz
+#endif
+#ifdef CONFIG_SYSCLK_75
+#define Sys_clock (75 * 1000000)	// 75 MHz
+#endif
+
+/*
+ * This will ignore the standard MIPS timer interrupt handler
+ * that is passed in as *irq (=irq0 in ../kernel/time.c).
+ * We will do our own timer interrupt handling.
+ */
+void gt64120_time_init(void)
+{
+	extern irq_desc_t irq_desc[NR_IRQS];
+	static struct irqaction timer;
+
+	/* Disable timer first */
+	GT_WRITE(GT_TC_CONTROL_OFS, 0);
+	/* Load timer value for 100 Hz */
+	GT_WRITE(GT_TC3_OFS, Sys_clock / 100);
+
+	/*
+	 * Create the IRQ structure entry for the timer.  Since we're too early
+	 * in the boot process to use the "request_irq()" call, we'll hard-code
+	 * the values to the correct interrupt line.
+	 */
+	timer.handler = &gt64120_irq;
+	timer.flags = SA_SHIRQ | SA_INTERRUPT;
+	timer.name = "timer";
+	timer.dev_id = NULL;
+	timer.next = NULL;
+	timer.mask = 0;
+	irq_desc[TIMER].action = &timer;
+
+	enable_irq(TIMER);
+
+	/* Enable timer ints */
+	GT_WRITE(GT_TC_CONTROL_OFS, 0xc0);
+	/* clear Cause register first */
+	GT_WRITE(GT_INTRCAUSE_OFS, 0x0);
+	/* Unmask timer int */
+	GT_WRITE(GT_INTRMASK_OFS, 0x800);
+	/* Clear High int register */
+	GT_WRITE(GT_HINTRCAUSE_OFS, 0x0);
+	/* Mask All interrupts at High cause interrupt */
+	GT_WRITE(GT_HINTRMASK_OFS, 0x0);
+}
+
+void gt64120_irq_init(void)
+{
+#if CURRENTLY_UNUSED
+	int i, j;
+
+	/* Reset irq handlers pointers to NULL */
+	for (i = 0; i < MAX_CAUSE_REGS; i++) {
+		for (j = 0; j < MAX_CAUSE_REG_WIDTH; j++) {
+			irq_handlers[i][j].next = NULL;
+			irq_handlers[i][j].sync = 0;
+			irq_handlers[i][j].routine = NULL;
+			irq_handlers[i][j].data = NULL;
+		}
+	}
+#endif
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips/gt64120/common/pci.c linux/arch/mips/gt64120/common/pci.c
--- v2.4.9/linux/arch/mips/gt64120/common/pci.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/gt64120/common/pci.c	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,1145 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ * Galileo Evaluation Boards PCI support.
+ *
+ * The general-purpose functions to read/write and configure the GT64120A's
+ * PCI registers (function names start with pci0 or pci1) are either direct
+ * copies of functions written by Galileo Technology, or are modifications
+ * of their functions to work with Linux 2.4 vs Linux 2.2.  These functions
+ * are Copyright - Galileo Technology.
+ *
+ * Other functions are derived from other MIPS PCI implementations, or were
+ * written by RidgeRun, Inc,  Copyright (C) 2000 RidgeRun, Inc.
+ *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.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.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/version.h>
+#include <asm/pci.h>
+#include <asm/io.h>
+#include <asm/gt64120/gt64120.h>
+
+#include <linux/init.h>
+
+#ifdef CONFIG_PCI
+
+#define SELF 0
+
+/*
+ * These functions and structures provide the BIOS scan and mapping of the PCI
+ * devices.
+ */
+
+#define MAX_PCI_DEVS 10
+
+struct pci_device {
+	u32 slot;
+	u32 BARtype[6];
+	u32 BARsize[6];
+};
+
+static void __init scan_and_initialize_pci(void);
+static u32 __init scan_pci_bus(struct pci_device *pci_devices);
+static void __init allocate_pci_space(struct pci_device *pci_devices);
+
+/*
+ * The functions that actually read and write to the controller.
+ *
+ *  Copied from or modified from Galileo Technology code.
+ */
+static unsigned int pci0ReadConfigReg(int offset, struct pci_dev *device);
+static void pci0WriteConfigReg(unsigned int offset,
+			       struct pci_dev *device, unsigned int data);
+static unsigned int pci1ReadConfigReg(int offset, struct pci_dev *device);
+static void pci1WriteConfigReg(unsigned int offset,
+			       struct pci_dev *device, unsigned int data);
+
+static void pci0MapIOspace(unsigned int pci0IoBase,
+			   unsigned int pci0IoLength);
+static void pci1MapIOspace(unsigned int pci1IoBase,
+			   unsigned int pci1IoLength);
+static void pci0MapMemory0space(unsigned int pci0Mem0Base,
+				unsigned int pci0Mem0Length);
+static void pci1MapMemory0space(unsigned int pci1Mem0Base,
+				unsigned int pci1Mem0Length);
+static void pci0MapMemory1space(unsigned int pci0Mem1Base,
+				unsigned int pci0Mem1Length);
+static void pci1MapMemory1space(unsigned int pci1Mem1Base,
+				unsigned int pci1Mem1Length);
+static unsigned int pci0GetIOspaceBase(void);
+static unsigned int pci0GetIOspaceSize(void);
+static unsigned int pci0GetMemory0Base(void);
+static unsigned int pci0GetMemory0Size(void);
+static unsigned int pci0GetMemory1Base(void);
+static unsigned int pci0GetMemory1Size(void);
+static unsigned int pci1GetIOspaceBase(void);
+static unsigned int pci1GetIOspaceSize(void);
+static unsigned int pci1GetMemory0Base(void);
+static unsigned int pci1GetMemory0Size(void);
+static unsigned int pci1GetMemory1Base(void);
+static unsigned int pci1GetMemory1Size(void);
+
+
+/*  Functions to implement "pci ops"  */
+static int galileo_pcibios_read_config_word(struct pci_dev *dev,
+					    int offset, u16 * val);
+static int galileo_pcibios_read_config_byte(struct pci_dev *dev,
+					    int offset, u8 * val);
+static int galileo_pcibios_read_config_dword(struct pci_dev *dev,
+					     int offset, u32 * val);
+static int galileo_pcibios_write_config_byte(struct pci_dev *dev,
+					     int offset, u8 val);
+static int galileo_pcibios_write_config_word(struct pci_dev *dev,
+					     int offset, u16 val);
+static int galileo_pcibios_write_config_dword(struct pci_dev *dev,
+					      int offset, u32 val);
+static void galileo_pcibios_set_master(struct pci_dev *dev);
+
+/*
+ *  General-purpose PCI functions.
+ */
+
+/*
+ * pci0MapIOspace - Maps PCI0 IO space for the master.
+ * Inputs: base and length of pci0Io
+ */
+
+static void pci0MapIOspace(unsigned int pci0IoBase,
+			   unsigned int pci0IoLength)
+{
+	unsigned int pci0IoTop =
+	    (unsigned int) (pci0IoBase + pci0IoLength);
+
+	if (pci0IoLength == 0)
+		pci0IoTop++;
+
+	pci0IoBase = (unsigned int) (pci0IoBase >> 21);
+	pci0IoTop = (unsigned int) (((pci0IoTop - 1) & 0x0fffffff) >> 21);
+	GT_WRITE(GT_PCI0IOLD_OFS, pci0IoBase);
+	GT_WRITE(GT_PCI0IOHD_OFS, pci0IoTop);
+}
+
+/*
+ * pci1MapIOspace - Maps PCI1 IO space for the master.
+ * Inputs: base and length of pci1Io
+ */
+
+static void pci1MapIOspace(unsigned int pci1IoBase,
+			   unsigned int pci1IoLength)
+{
+	unsigned int pci1IoTop =
+	    (unsigned int) (pci1IoBase + pci1IoLength);
+
+	if (pci1IoLength == 0)
+		pci1IoTop++;
+
+	pci1IoBase = (unsigned int) (pci1IoBase >> 21);
+	pci1IoTop = (unsigned int) (((pci1IoTop - 1) & 0x0fffffff) >> 21);
+	GT_WRITE(GT_PCI1IOLD_OFS, pci1IoBase);
+	GT_WRITE(GT_PCI1IOHD_OFS, pci1IoTop);
+}
+
+/*
+ * pci0MapMemory0space - Maps PCI0 memory0 space for the master.
+ * Inputs: base and length of pci0Mem0
+ */
+
+static void pci0MapMemory0space(unsigned int pci0Mem0Base,
+				unsigned int pci0Mem0Length)
+{
+	unsigned int pci0Mem0Top = pci0Mem0Base + pci0Mem0Length;
+
+	if (pci0Mem0Length == 0)
+		pci0Mem0Top++;
+
+	pci0Mem0Base = pci0Mem0Base >> 21;
+	pci0Mem0Top = ((pci0Mem0Top - 1) & 0x0fffffff) >> 21;
+	GT_WRITE(GT_PCI0M0LD_OFS, pci0Mem0Base);
+	GT_WRITE(GT_PCI0M0HD_OFS, pci0Mem0Top);
+}
+
+/*
+ * pci1MapMemory0space - Maps PCI1 memory0 space for the master.
+ * Inputs: base and length of pci1Mem0
+ */
+
+static void pci1MapMemory0space(unsigned int pci1Mem0Base,
+				unsigned int pci1Mem0Length)
+{
+	unsigned int pci1Mem0Top = pci1Mem0Base + pci1Mem0Length;
+
+	if (pci1Mem0Length == 0)
+		pci1Mem0Top++;
+
+	pci1Mem0Base = pci1Mem0Base >> 21;
+	pci1Mem0Top = ((pci1Mem0Top - 1) & 0x0fffffff) >> 21;
+	GT_WRITE(GT_PCI1M0LD_OFS, pci1Mem0Base);
+	GT_WRITE(GT_PCI1M0HD_OFS, pci1Mem0Top);
+}
+
+/*
+ * pci0MapMemory1space - Maps PCI0 memory1 space for the master.
+ * Inputs: base and length of pci0Mem1
+ */
+
+static void pci0MapMemory1space(unsigned int pci0Mem1Base,
+				unsigned int pci0Mem1Length)
+{
+	unsigned int pci0Mem1Top = pci0Mem1Base + pci0Mem1Length;
+
+	if (pci0Mem1Length == 0)
+		pci0Mem1Top++;
+
+	pci0Mem1Base = pci0Mem1Base >> 21;
+	pci0Mem1Top = ((pci0Mem1Top - 1) & 0x0fffffff) >> 21;
+	GT_WRITE(GT_PCI0M1LD_OFS, pci0Mem1Base);
+	GT_WRITE(GT_PCI0M1HD_OFS, pci0Mem1Top);
+
+}
+
+/*
+ * pci1MapMemory1space - Maps PCI1 memory1 space for the master.
+ * Inputs: base and length of pci1Mem1
+ */
+
+static void pci1MapMemory1space(unsigned int pci1Mem1Base,
+				unsigned int pci1Mem1Length)
+{
+	unsigned int pci1Mem1Top = pci1Mem1Base + pci1Mem1Length;
+
+	if (pci1Mem1Length == 0)
+		pci1Mem1Top++;
+
+	pci1Mem1Base = pci1Mem1Base >> 21;
+	pci1Mem1Top = ((pci1Mem1Top - 1) & 0x0fffffff) >> 21;
+	GT_WRITE(GT_PCI1M1LD_OFS, pci1Mem1Base);
+	GT_WRITE(GT_PCI1M1HD_OFS, pci1Mem1Top);
+}
+
+/*
+ * pci0GetIOspaceBase - Return PCI0 IO Base Address.
+ * Inputs: N/A
+ * Returns: PCI0 IO Base Address.
+ */
+
+static unsigned int pci0GetIOspaceBase(void)
+{
+	unsigned int base;
+	GT_READ(GT_PCI0IOLD_OFS, &base);
+	base = base << 21;
+	return base;
+}
+
+/*
+ * pci0GetIOspaceSize - Return PCI0 IO Bar Size.
+ * Inputs: N/A
+ * Returns: PCI0 IO Bar Size.
+ */
+
+static unsigned int pci0GetIOspaceSize(void)
+{
+	unsigned int top, base, size;
+	GT_READ(GT_PCI0IOLD_OFS, &base);
+	base = base << 21;
+	GT_READ(GT_PCI0IOHD_OFS, &top);
+	top = (top << 21);
+	size = ((top - base) & 0xfffffff);
+	size = size | 0x1fffff;
+	return (size + 1);
+}
+
+/*
+ * pci0GetMemory0Base - Return PCI0 Memory 0 Base Address.
+ * Inputs: N/A
+ * Returns: PCI0 Memory 0 Base Address.
+ */
+
+static unsigned int pci0GetMemory0Base(void)
+{
+	unsigned int base;
+	GT_READ(GT_PCI0M0LD_OFS, &base);
+	base = base << 21;
+	return base;
+}
+
+/*
+ * pci0GetMemory0Size - Return PCI0 Memory 0 Bar Size.
+ * Inputs: N/A
+ * Returns: PCI0 Memory 0 Bar Size.
+ */
+
+static unsigned int pci0GetMemory0Size(void)
+{
+	unsigned int top, base, size;
+	GT_READ(GT_PCI0M0LD_OFS, &base);
+	base = base << 21;
+	GT_READ(GT_PCI0M0HD_OFS, &top);
+	top = (top << 21);
+	size = ((top - base) & 0xfffffff);
+	size = size | 0x1fffff;
+	return (size + 1);
+}
+
+/*
+ * pci0GetMemory1Base - Return PCI0 Memory 1 Base Address.
+ * Inputs: N/A
+ * Returns: PCI0 Memory 1 Base Address.
+ */
+
+static unsigned int pci0GetMemory1Base(void)
+{
+	unsigned int base;
+	GT_READ(GT_PCI0M1LD_OFS, &base);
+	base = base << 21;
+	return base;
+}
+
+/*
+ * pci0GetMemory1Size - Return PCI0 Memory 1 Bar Size.
+ * Inputs: N/A
+ * Returns: PCI0 Memory 1 Bar Size.
+ */
+
+static unsigned int pci0GetMemory1Size(void)
+{
+	unsigned int top, base, size;
+	GT_READ(GT_PCI0M1LD_OFS, &base);
+	base = base << 21;
+	GT_READ(GT_PCI0M1HD_OFS, &top);
+	top = (top << 21);
+	size = ((top - base) & 0xfffffff);
+	size = size | 0x1fffff;
+	return (size + 1);
+}
+
+/*
+ * pci1GetIOspaceBase - Return PCI1 IO Base Address.
+ * Inputs: N/A
+ * Returns: PCI1 IO Base Address.
+ */
+
+static unsigned int pci1GetIOspaceBase(void)
+{
+	unsigned int base;
+	GT_READ(GT_PCI1IOLD_OFS, &base);
+	base = base << 21;
+	return base;
+}
+
+/*
+ * pci1GetIOspaceSize - Return PCI1 IO Bar Size.
+ * Inputs: N/A
+ * Returns: PCI1 IO Bar Size.
+ */
+
+static unsigned int pci1GetIOspaceSize(void)
+{
+	unsigned int top, base, size;
+	GT_READ(GT_PCI1IOLD_OFS, &base);
+	base = base << 21;
+	GT_READ(GT_PCI1IOHD_OFS, &top);
+	top = (top << 21);
+	size = ((top - base) & 0xfffffff);
+	size = size | 0x1fffff;
+	return (size + 1);
+}
+
+/*
+ * pci1GetMemory0Base - Return PCI1 Memory 0 Base Address.
+ * Inputs: N/A
+ * Returns: PCI1 Memory 0 Base Address.
+ */
+
+static unsigned int pci1GetMemory0Base(void)
+{
+	unsigned int base;
+	GT_READ(GT_PCI1M0LD_OFS, &base);
+	base = base << 21;
+	return base;
+}
+
+/*
+ * pci1GetMemory0Size - Return PCI1 Memory 0 Bar Size.
+ * Inputs: N/A
+ * Returns: PCI1 Memory 0 Bar Size.
+ */
+
+static unsigned int pci1GetMemory0Size(void)
+{
+	unsigned int top, base, size;
+	GT_READ(GT_PCI1M1LD_OFS, &base);
+	base = base << 21;
+	GT_READ(GT_PCI1M1HD_OFS, &top);
+	top = (top << 21);
+	size = ((top - base) & 0xfffffff);
+	size = size | 0x1fffff;
+	return (size + 1);
+}
+
+/*
+ * pci1GetMemory1Base - Return PCI1 Memory 1 Base Address.
+ * Inputs: N/A
+ * Returns: PCI1 Memory 1 Base Address.
+ */
+
+static unsigned int pci1GetMemory1Base(void)
+{
+	unsigned int base;
+	GT_READ(GT_PCI1M1LD_OFS, &base);
+	base = base << 21;
+	return base;
+}
+
+/*
+ * pci1GetMemory1Size - Return PCI1 Memory 1 Bar Size.
+ * Inputs: N/A
+ * Returns: PCI1 Memory 1 Bar Size.
+ */
+
+static unsigned int pci1GetMemory1Size(void)
+{
+	unsigned int top, base, size;
+	GT_READ(GT_PCI1M1LD_OFS, &base);
+	base = base << 21;
+	GT_READ(GT_PCI1M1HD_OFS, &top);
+	top = (top << 21);
+	size = ((top - base) & 0xfffffff);
+	size = size | 0x1fffff;
+	return (size + 1);
+}
+
+
+
+/*
+ * pci_range_ck -
+ *
+ * Check if the pci device that are trying to access does really exists
+ * on the evaluation board.  
+ *
+ * Inputs :
+ * bus - bus number (0 for PCI 0 ; 1 for PCI 1)
+ * dev - number of device on the specific pci bus
+ *
+ * Outpus :
+ * 0 - if OK , 1 - if failure
+ */
+static __inline__ int pci_range_ck(unsigned char bus, unsigned char dev)
+{
+	/*
+	 * We don't even pretend to handle other busses than bus 0 correctly.
+	 * Accessing device 31 crashes the CP7000 for some reason.
+	 */
+	if ((bus == 0) && (dev != 31))
+		return 0;
+	return -1;
+}
+
+/*
+ * pciXReadConfigReg  - Read from a PCI configuration register
+ *                    - Make sure the GT is configured as a master before 
+ *                      reading from another device on the PCI.
+ *                   - The function takes care of Big/Little endian conversion.
+ * INPUTS:   regOffset: The register offset as it apears in the GT spec (or PCI
+ *                        spec)
+ *           pciDevNum: The device number needs to be addressed.                
+ * RETURNS: data , if the data == 0xffffffff check the master abort bit in the 
+ *                 cause register to make sure the data is valid
+ *
+ *  Configuration Address 0xCF8:
+ *
+ *       31 30    24 23  16 15  11 10     8 7      2  0     <=bit Number
+ *  |congif|Reserved|  Bus |Device|Function|Register|00|
+ *  |Enable|        |Number|Number| Number | Number |  |    <=field Name
+ *
+ */
+static unsigned int pci0ReadConfigReg(int offset, struct pci_dev *device)
+{
+	unsigned int DataForRegCf8;
+	unsigned int data;
+
+	DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) |
+			 (PCI_FUNC(device->devfn) << 8) |
+			 (offset & ~0x3)) | 0x80000000;
+	GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8);
+
+	/*
+	 * The casual observer might wonder why the READ is duplicated here,
+	 * rather than immediately following the WRITE, and just have the swap
+	 * in the "if".  That's because there is a latency problem with trying
+	 * to read immediately after setting up the address register.  The "if"
+	 * check gives enough time for the address to stabilize, so the READ
+	 * can work.
+	 */
+	if (PCI_SLOT(device->devfn) == SELF) {	/* This board */
+		GT_READ(GT_PCI0_CFGDATA_OFS, &data);
+		return data;
+	} else { /* The PCI is working in LE Mode so swap the Data. */
+		GT_READ(GT_PCI0_CFGDATA_OFS, &data);
+		return cpu_to_le32(data);
+	}
+}
+
+static unsigned int pci1ReadConfigReg(int offset, struct pci_dev *device)
+{
+	unsigned int DataForRegCf8;
+	unsigned int data;
+
+	DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) |
+			 (PCI_FUNC(device->devfn) << 8) |
+			 (offset & ~0x3)) | 0x80000000;
+	/*
+	 * The casual observer might wonder why the READ is duplicated here,
+	 * rather than immediately following the WRITE, and just have the
+	 * swap in the "if".  That's because there is a latency problem
+	 * with trying to read immediately after setting up the address
+	 * register.  The "if" check gives enough time for the address
+	 * to stabilize, so the READ can work.
+	 */
+	if (PCI_SLOT(device->devfn) == SELF) {	/* This board */
+		/* when configurating our own PCI 1 L-unit the access is through  
+		   the PCI 0 interface with reg number = reg number + 0x80 */
+		DataForRegCf8 |= 0x80;
+		GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8);
+	} else {		/* The PCI is working in LE Mode so swap the Data. */
+		GT_WRITE(GT_PCI1_CFGADDR_OFS, DataForRegCf8);
+	}
+	if (PCI_SLOT(device->devfn) == SELF) {	/* This board */
+		GT_READ(GT_PCI0_CFGDATA_OFS, &data);
+		return data;
+	} else {
+		GT_READ(GT_PCI1_CFGDATA_OFS, &data);
+		return cpu_to_le32(data);
+	}
+}
+
+
+
+/*
+ * pciXWriteConfigReg - Write to a PCI configuration register
+ *                    - Make sure the GT is configured as a master before 
+ *                      writingto another device on the PCI.
+ *                    - The function takes care of Big/Little endian conversion.
+ * Inputs:   unsigned int regOffset: The register offset as it apears in the
+ *           GT spec 
+ *                   (or any other PCI device spec)
+ *           pciDevNum: The device number needs to be addressed.                
+ *
+ *  Configuration Address 0xCF8:
+ *
+ *       31 30    24 23  16 15  11 10     8 7      2  0     <=bit Number
+ *  |congif|Reserved|  Bus |Device|Function|Register|00|
+ *  |Enable|        |Number|Number| Number | Number |  |    <=field Name
+ *
+ */
+static void pci0WriteConfigReg(unsigned int offset,
+			       struct pci_dev *device, unsigned int data)
+{
+	unsigned int DataForRegCf8;
+
+	DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) |
+			 (PCI_FUNC(device->devfn) << 8) |
+			 (offset & ~0x3)) | 0x80000000;
+	GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8);
+	if (PCI_SLOT(device->devfn) == SELF) {	/* This board */
+		GT_WRITE(GT_PCI0_CFGDATA_OFS, data);
+	} else {		/* configuration Transaction over the pci. */
+		/* The PCI is working in LE Mode so swap the Data. */
+		GT_WRITE(GT_PCI0_CFGDATA_OFS, le32_to_cpu(data));
+	}
+}
+
+static void pci1WriteConfigReg(unsigned int offset,
+			       struct pci_dev *device, unsigned int data)
+{
+	unsigned int DataForRegCf8;
+
+	DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) |
+			 (PCI_FUNC(device->devfn) << 8) |
+			 (offset & ~0x3)) | 0x80000000;
+	/*
+	 * There is a latency problem
+	 * with trying to read immediately after setting up the address
+	 * register.  The "if" check gives enough time for the address
+	 * to stabilize, so the WRITE can work.
+	 */
+	if (PCI_SLOT(device->devfn) == SELF) {	/* This board */
+		/*
+		 * when configurating our own PCI 1 L-unit the access is through
+		 * the PCI 0 interface with reg number = reg number + 0x80
+		 */
+		DataForRegCf8 |= 0x80;
+		GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8);
+	} else {	/* configuration Transaction over the pci. */
+		/* The PCI is working in LE Mode so swap the Data. */
+		GT_WRITE(GT_PCI1_CFGADDR_OFS, DataForRegCf8);
+	}
+	if (PCI_SLOT(device->devfn) == SELF) {	/* This board */
+		GT_WRITE(GT_PCI0_CFGDATA_OFS, data);
+	} else {		/* configuration Transaction over the pci. */
+		GT_WRITE(GT_PCI1_CFGADDR_OFS, le32_to_cpu(data));
+	}
+}
+
+
+/*
+ * galileo_pcibios_(read/write)_config_(dword/word/byte) -
+ *
+ * reads/write a dword/word/byte register from the configuration space
+ * of a device.
+ *
+ * Inputs :
+ * bus - bus number
+ * dev - device number
+ * offset - register offset in the configuration space
+ * val - value to be written / read
+ *
+ * Outputs :
+ * PCIBIOS_SUCCESSFUL when operation was succesfull
+ * PCIBIOS_DEVICE_NOT_FOUND when the bus or dev is errorneous
+ * PCIBIOS_BAD_REGISTER_NUMBER when accessing non aligned
+ */
+
+static int galileo_pcibios_read_config_dword(struct pci_dev *device,
+					     int offset, u32 * val)
+{
+	int dev, bus;
+	bus = device->bus->number;
+	dev = PCI_SLOT(device->devfn);
+
+	if (pci_range_ck(bus, dev)) {
+		*val = 0xffffffff;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+	if (offset & 0x3)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	if (bus == 0)
+		*val = pci0ReadConfigReg(offset, device);
+
+	/*  This is so that the upper PCI layer will get the correct return value if
+	   we're not attached to anything.  */
+	if ((offset == 0) && (*val == 0xffffffff)) {
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int galileo_pcibios_read_config_word(struct pci_dev *device,
+					    int offset, u16 * val)
+{
+	int dev, bus;
+
+	bus = device->bus->number;
+	dev = PCI_SLOT(device->devfn);
+
+	if (pci_range_ck(bus, dev)) {
+		*val = 0xffff;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+	if (offset & 0x1)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	if (bus == 0)
+		*val =
+		    (unsigned short) (pci0ReadConfigReg(offset, device) >>
+				      ((offset & ~0x3) * 8));
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int galileo_pcibios_read_config_byte(struct pci_dev *device,
+					    int offset, u8 * val)
+{
+	int dev, bus;
+
+	bus = device->bus->number;
+	dev = PCI_SLOT(device->devfn);
+
+	if (pci_range_ck(bus, dev)) {
+		*val = 0xff;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	if (bus == 0)
+		*val =
+		    (unsigned char) (pci0ReadConfigReg(offset, device) >>
+				     ((offset & ~0x3) * 8));
+
+	/*
+	 *  This is so that the upper PCI layer will get the correct return
+	 * value if we're not attached to anything.
+	 */
+	if ((offset == 0xe) && (*val == 0xff)) {
+		u32 MasterAbort;
+		GT_READ(GT_INTRCAUSE_OFS, &MasterAbort);
+		if (MasterAbort & 0x40000) {
+			GT_WRITE(GT_INTRCAUSE_OFS,
+				 (MasterAbort & 0xfffbffff));
+			return PCIBIOS_DEVICE_NOT_FOUND;
+		}
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int galileo_pcibios_write_config_dword(struct pci_dev *device,
+					      int offset, u32 val)
+{
+	int dev, bus;
+
+	bus = device->bus->number;
+	dev = PCI_SLOT(device->devfn);
+
+	if (pci_range_ck(bus, dev))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	if (offset & 0x3)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	if (bus == 0)
+		pci0WriteConfigReg(offset, device, val);
+//  if (bus == 1) pci1WriteConfigReg (offset,device,val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int galileo_pcibios_write_config_word(struct pci_dev *device,
+					     int offset, u16 val)
+{
+	int dev, bus;
+	unsigned long tmp;
+
+	bus = device->bus->number;
+	dev = PCI_SLOT(device->devfn);
+
+	if (pci_range_ck(bus, dev))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	if (offset & 0x1)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	if (bus == 0)
+		tmp = pci0ReadConfigReg(offset, device);
+//  if (bus == 1) tmp = pci1ReadConfigReg (offset,device);
+
+	if ((offset % 4) == 0)
+		tmp = (tmp & 0xffff0000) | (val & 0xffff);
+	if ((offset % 4) == 2)
+		tmp = (tmp & 0x0000ffff) | ((val & 0xffff) << 16);
+
+	if (bus == 0)
+		pci0WriteConfigReg(offset, device, tmp);
+//  if (bus == 1) pci1WriteConfigReg (offset,device,tmp);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int galileo_pcibios_write_config_byte(struct pci_dev *device,
+					     int offset, u8 val)
+{
+	int dev, bus;
+	unsigned long tmp;
+
+	bus = device->bus->number;
+	dev = PCI_SLOT(device->devfn);
+
+	if (pci_range_ck(bus, dev))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	if (bus == 0)
+		tmp = pci0ReadConfigReg(offset, device);
+//  if (bus == 1) tmp = pci1ReadConfigReg (offset,device);
+
+	if ((offset % 4) == 0)
+		tmp = (tmp & 0xffffff00) | (val & 0xff);
+	if ((offset % 4) == 1)
+		tmp = (tmp & 0xffff00ff) | ((val & 0xff) << 8);
+	if ((offset % 4) == 2)
+		tmp = (tmp & 0xff00ffff) | ((val & 0xff) << 16);
+	if ((offset % 4) == 3)
+		tmp = (tmp & 0x00ffffff) | ((val & 0xff) << 24);
+
+	if (bus == 0)
+		pci0WriteConfigReg(offset, device, tmp);
+//  if (bus == 1) pci1WriteConfigReg (offset,device,tmp);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static void galileo_pcibios_set_master(struct pci_dev *dev)
+{
+	u16 cmd;
+
+	galileo_pcibios_read_config_word(dev, PCI_COMMAND, &cmd);
+	cmd |= PCI_COMMAND_MASTER;
+	galileo_pcibios_write_config_word(dev, PCI_COMMAND, cmd);
+}
+
+/*  Externally-expected functions.  Do not change function names  */
+
+int pcibios_enable_resources(struct pci_dev *dev)
+{
+	u16 cmd, old_cmd;
+	u8 tmp1;
+	int idx;
+	struct resource *r;
+
+	galileo_pcibios_read_config_word(dev, PCI_COMMAND, &cmd);
+	old_cmd = cmd;
+	for (idx = 0; idx < 6; idx++) {
+		r = &dev->resource[idx];
+		if (!r->start && r->end) {
+			printk(KERN_ERR
+			       "PCI: Device %s not available because of "
+			       "resource collisions\n", dev->slot_name);
+			return -EINVAL;
+		}
+		if (r->flags & IORESOURCE_IO)
+			cmd |= PCI_COMMAND_IO;
+		if (r->flags & IORESOURCE_MEM)
+			cmd |= PCI_COMMAND_MEMORY;
+	}
+	if (cmd != old_cmd) {
+		galileo_pcibios_write_config_word(dev, PCI_COMMAND, cmd);
+	}
+
+	/*
+	 * Let's fix up the latency timer and cache line size here.  Cache
+	 * line size = 32 bytes / sizeof dword (4) = 8.
+	 * Latency timer must be > 8.  32 is random but appears to work.
+	 */
+	galileo_pcibios_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &tmp1);
+	if (tmp1 != 8) {
+		printk(KERN_WARNING "PCI setting cache line size to 8 from "
+		       "%d\n", tmp1);
+		galileo_pcibios_write_config_byte(dev, PCI_CACHE_LINE_SIZE,
+						  8);
+	}
+	galileo_pcibios_read_config_byte(dev, PCI_LATENCY_TIMER, &tmp1);
+	if (tmp1 < 32) {
+		printk(KERN_WARNING "PCI setting latency timer to 32 from %d\n",
+		       tmp1);
+		galileo_pcibios_write_config_byte(dev, PCI_LATENCY_TIMER,
+						  32);
+	}
+
+	return 0;
+}
+
+int pcibios_enable_device(struct pci_dev *dev)
+{
+	return pcibios_enable_resources(dev);
+}
+
+void pcibios_update_resource(struct pci_dev *dev, struct resource *root,
+			     struct resource *res, int resource)
+{
+	u32 new, check;
+	int reg;
+
+	return;
+
+	new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
+	if (resource < 6) {
+		reg = PCI_BASE_ADDRESS_0 + 4 * resource;
+	} else if (resource == PCI_ROM_RESOURCE) {
+		res->flags |= PCI_ROM_ADDRESS_ENABLE;
+		reg = dev->rom_base_reg;
+	} else {
+		/*
+		 * Somebody might have asked allocation of a non-standard
+		 * resource
+		 */
+		return;
+	}
+
+	pci_write_config_dword(dev, reg, new);
+	pci_read_config_dword(dev, reg, &check);
+	if ((new ^ check) &
+	    ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK :
+	     PCI_BASE_ADDRESS_MEM_MASK)) {
+		printk(KERN_ERR "PCI: Error while updating region "
+		       "%s/%d (%08x != %08x)\n", dev->slot_name, resource,
+		       new, check);
+	}
+}
+
+void pcibios_align_resource(void *data, struct resource *res,
+			    unsigned long size)
+{
+	struct pci_dev *dev = data;
+
+	if (res->flags & IORESOURCE_IO) {
+		unsigned long start = res->start;
+
+		/* We need to avoid collisions with `mirrored' VGA ports
+		   and other strange ISA hardware, so we always want the
+		   addresses kilobyte aligned.  */
+		if (size > 0x100) {
+			printk(KERN_ERR "PCI: I/O Region %s/%d too large"
+			       " (%ld bytes)\n", dev->slot_name,
+			        dev->resource - res, size);
+		}
+
+		start = (start + 1024 - 1) & ~(1024 - 1);
+		res->start = start;
+	}
+}
+
+struct pci_ops galileo_pci_ops = {
+	galileo_pcibios_read_config_byte,
+	galileo_pcibios_read_config_word,
+	galileo_pcibios_read_config_dword,
+	galileo_pcibios_write_config_byte,
+	galileo_pcibios_write_config_word,
+	galileo_pcibios_write_config_dword
+};
+
+struct pci_fixup pcibios_fixups[] = {
+	{0}
+};
+
+void __init pcibios_fixup_bus(struct pci_bus *c)
+{
+	gt64120_board_pcibios_fixup_bus(c);
+}
+
+/*
+ * This code was derived from Galileo Technology's example
+ * and significantly reworked.
+ *
+ * This is very simple.  It does not scan multiple function devices.  It does
+ * not scan behind bridges.  Those would be simple to implement, but we don't
+ * currently need this.
+ */
+
+static void __init scan_and_initialize_pci(void)
+{
+	struct pci_device pci_devices[MAX_PCI_DEVS];
+
+	if (scan_pci_bus(pci_devices)) {
+		allocate_pci_space(pci_devices);
+	}
+}
+
+/*
+ * This is your basic PCI scan.  It goes through each slot and checks to
+ * see if there's something that responds.  If so, then get the size and
+ * type of each of the responding BARs.  Save them for later.
+ */
+
+static u32 __init scan_pci_bus(struct pci_device *pci_devices)
+{
+	u32 arrayCounter = 0;
+	u32 memType;
+	u32 memSize;
+	u32 pci_slot, bar;
+	u32 id;
+	u32 c18RegValue;
+	struct pci_dev device;
+
+	/*
+	 * According to PCI REV 2.1 MAX agents on the bus are 21.
+	 * We don't bother scanning ourselves (slot 0).
+	 */
+	for (pci_slot = 1; pci_slot < 22; pci_slot++) {
+
+		device.devfn = PCI_DEVFN(pci_slot, 0);
+		id = pci0ReadConfigReg(PCI_VENDOR_ID, &device);
+
+		/*
+		 *  Check for a PCI Master Abort (nothing responds in the
+		 * slot)
+		 */
+		GT_READ(GT_INTRCAUSE_OFS, &c18RegValue);
+		/*
+		 * Clearing bit 18 of in the Cause Register 0xc18 by
+		 * writting 0.
+		 */
+		GT_WRITE(GT_INTRCAUSE_OFS, (c18RegValue & 0xfffbffff));
+		if ((id != 0xffffffff) && !(c18RegValue & 0x40000)) {
+			pci_devices[arrayCounter].slot = pci_slot;
+			for (bar = 0; bar < 6; bar++) {
+				memType =
+				    pci0ReadConfigReg(PCI_BASE_ADDRESS_0 +
+						      (bar * 4), &device);
+				pci_devices[arrayCounter].BARtype[bar] =
+				    memType & 1;
+				pci0WriteConfigReg(PCI_BASE_ADDRESS_0 +
+						   (bar * 4), &device,
+						   0xffffffff);
+				memSize =
+				    pci0ReadConfigReg(PCI_BASE_ADDRESS_0 +
+						      (bar * 4), &device);
+				if (memType & 1) {	/*  IO space  */
+					pci_devices[arrayCounter].
+					    BARsize[bar] =
+					    ~(memSize & 0xfffffffc) + 1;
+				} else {	/*  memory space */
+					pci_devices[arrayCounter].
+					    BARsize[bar] =
+					    ~(memSize & 0xfffffff0) + 1;
+				}
+			}	/*  BAR counter  */
+
+			arrayCounter++;
+		}
+		/*  found a device  */
+	} /*  slot counter  */
+
+	if (arrayCounter < MAX_PCI_DEVS)
+		pci_devices[arrayCounter].slot = -1;
+
+	return arrayCounter;
+}
+
+#define ALIGN(val,align)        (((val) + ((align) - 1)) & ~((align) - 1))
+#define MAX(val1, val2) ((val1) > (val2) ? (val1) : (val2))
+
+/*
+ * This function goes through the list of devices and allocates the BARs in
+ * either IO or MEM space.  It does it in order of size, which will limit the
+ * amount of fragmentation we have in the IO and MEM spaces.
+ */
+
+static void __init allocate_pci_space(struct pci_device *pci_devices)
+{
+	u32 count, maxcount, bar;
+	u32 maxSize, maxDevice, maxBAR;
+	u32 alignto;
+	u32 base;
+	u32 pci0_mem_base = pci0GetMemory0Base();
+	u32 pci0_io_base = pci0GetIOspaceBase();
+	struct pci_dev device;
+
+	/*  How many PCI devices do we have?  */
+	maxcount = MAX_PCI_DEVS;
+	for (count = 0; count < MAX_PCI_DEVS; count++) {
+		if (pci_devices[count].slot == -1) {
+			maxcount = count;
+			break;
+		}
+	}
+
+	do {
+		/*  Find the largest size BAR we need to allocate  */
+		maxSize = 0;
+		for (count = 0; count < maxcount; count++) {
+			for (bar = 0; bar < 6; bar++) {
+				if (pci_devices[count].BARsize[bar] >
+				    maxSize) {
+					maxSize =
+					    pci_devices[count].
+					    BARsize[bar];
+					maxDevice = count;
+					maxBAR = bar;
+				}
+			}
+		}
+
+		/*
+		 * We've found the largest BAR.  Allocate it into IO or
+		 * mem space.  We don't idiot check the bases to make
+		 * sure they haven't overflowed the current size for that
+		 * aperture.  
+		 * Don't bother to enable the device's IO or MEM space here.
+		 * That will be done in pci_enable_resources if the device is
+		 * activated by a driver.
+		 */
+		if (maxSize) {
+			device.devfn =
+			    PCI_DEVFN(pci_devices[maxDevice].slot, 0);
+			if (pci_devices[maxDevice].BARtype[maxBAR] == 1) {
+				alignto = MAX(0x1000, maxSize);
+				base = ALIGN(pci0_io_base, alignto);
+				pci0WriteConfigReg(PCI_BASE_ADDRESS_0 +
+						   (maxBAR * 4), &device,
+						   base | 0x1);
+				pci0_io_base = base + alignto;
+			} else {
+				alignto = MAX(0x1000, maxSize);
+				base = ALIGN(pci0_mem_base, alignto);
+				pci0WriteConfigReg(PCI_BASE_ADDRESS_0 +
+						   (maxBAR * 4), &device,
+						   base);
+				pci0_mem_base = base + alignto;
+			}
+			/*
+			 * This entry is finished.  Remove it from the list
+			 * we'll scan.
+			 */
+			pci_devices[maxDevice].BARsize[maxBAR] = 0;
+		}
+	} while (maxSize);
+}
+
+void __init pcibios_init(void)
+{
+	u32 tmp;
+	struct pci_dev controller;
+
+	controller.devfn = SELF;
+
+	GT_READ(GT_PCI0_CMD_OFS, &tmp);
+	GT_READ(GT_PCI0_BARE_OFS, &tmp);
+
+	/*
+	 * You have to enable bus mastering to configure any other
+	 * card on the bus.
+	 */
+	tmp = pci0ReadConfigReg(PCI_COMMAND, &controller);
+	tmp |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
+	pci0WriteConfigReg(PCI_COMMAND, &controller, tmp);
+
+	/*  This scans the PCI bus and sets up initial values.  */
+	scan_and_initialize_pci();
+
+	/*
+	 *  Reset PCI I/O and PCI MEM values to ones supported by EVM.
+	 */
+	ioport_resource.start = GT_PCI_IO_BASE;
+	ioport_resource.end   = GT_PCI_IO_BASE + GT_PCI_IO_SIZE - 1;
+	iomem_resource.start  = GT_PCI_MEM_BASE;
+	iomem_resource.end    = GT_PCI_MEM_BASE + GT_PCI_MEM_BASE - 1;
+
+	pci_scan_bus(0, &galileo_pci_ops, NULL);
+}
+
+/*
+ * for parsing "pci=" kernel boot arguments.
+ */
+char *pcibios_setup(char *str)
+{
+        printk(KERN_INFO "rr: pcibios_setup\n");
+        /* Nothing to do for now.  */
+
+        return str;
+}
+
+unsigned __init int pcibios_assign_all_busses(void)
+{
+	return 1;
+}
+
+#endif	/* CONFIG_PCI */
diff -u --recursive --new-file v2.4.9/linux/arch/mips/gt64120/momenco_ocelot/Makefile linux/arch/mips/gt64120/momenco_ocelot/Makefile
--- v2.4.9/linux/arch/mips/gt64120/momenco_ocelot/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/gt64120/momenco_ocelot/Makefile	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,20 @@
+#
+# Makefile for Momentum's Ocelot board.
+#
+# 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.s:
+	$(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+	$(CC) $(CFLAGS) -c $< -o $*.o
+
+O_TARGET:= momenco_ocelot.o
+
+obj-y	 += int-handler.o irq.o pci.o prom.o reset.o setup.o
+
+obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.9/linux/arch/mips/gt64120/momenco_ocelot/dbg_io.c linux/arch/mips/gt64120/momenco_ocelot/dbg_io.c
--- v2.4.9/linux/arch/mips/gt64120/momenco_ocelot/dbg_io.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/gt64120/momenco_ocelot/dbg_io.c	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,124 @@
+#include <linux/config.h>
+
+#if defined(CONFIG_REMOTE_DEBUG)
+
+/* --- CONFIG --- */
+
+typedef unsigned char uint8;
+typedef unsigned int uint32;
+
+/* --- END OF CONFIG --- */
+
+#define         UART16550_BAUD_2400             2400
+#define         UART16550_BAUD_4800             4800
+#define         UART16550_BAUD_9600             9600
+#define         UART16550_BAUD_19200            19200
+#define         UART16550_BAUD_38400            38400
+#define         UART16550_BAUD_57600            57600
+#define         UART16550_BAUD_115200           115200
+
+#define         UART16550_PARITY_NONE           0
+#define         UART16550_PARITY_ODD            0x08
+#define         UART16550_PARITY_EVEN           0x18
+#define         UART16550_PARITY_MARK           0x28
+#define         UART16550_PARITY_SPACE          0x38
+
+#define         UART16550_DATA_5BIT             0x0
+#define         UART16550_DATA_6BIT             0x1
+#define         UART16550_DATA_7BIT             0x2
+#define         UART16550_DATA_8BIT             0x3
+
+#define         UART16550_STOP_1BIT             0x0
+#define         UART16550_STOP_2BIT             0x4
+
+/* ----------------------------------------------------- */
+
+/* === CONFIG === */
+
+/* [jsun] we use the second serial port for kdb */
+#define         BASE                    0xbd000020
+#define         MAX_BAUD                115200
+
+/* === END OF CONFIG === */
+
+#define         REG_OFFSET              4
+
+/* register offset */
+#define         OFS_RCV_BUFFER          0
+#define         OFS_TRANS_HOLD          0
+#define         OFS_SEND_BUFFER         0
+#define         OFS_INTR_ENABLE         (1*REG_OFFSET)
+#define         OFS_INTR_ID             (2*REG_OFFSET)
+#define         OFS_DATA_FORMAT         (3*REG_OFFSET)
+#define         OFS_LINE_CONTROL        (3*REG_OFFSET)
+#define         OFS_MODEM_CONTROL       (4*REG_OFFSET)
+#define         OFS_RS232_OUTPUT        (4*REG_OFFSET)
+#define         OFS_LINE_STATUS         (5*REG_OFFSET)
+#define         OFS_MODEM_STATUS        (6*REG_OFFSET)
+#define         OFS_RS232_INPUT         (6*REG_OFFSET)
+#define         OFS_SCRATCH_PAD         (7*REG_OFFSET)
+
+#define         OFS_DIVISOR_LSB         (0*REG_OFFSET)
+#define         OFS_DIVISOR_MSB         (1*REG_OFFSET)
+
+
+/* memory-mapped read/write of the port */
+#define         UART16550_READ(y)    (*((volatile uint8*)(BASE + y)))
+#define         UART16550_WRITE(y, z)  ((*((volatile uint8*)(BASE + y))) = z)
+
+void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
+{
+	/* disable interrupts */
+	UART16550_WRITE(OFS_INTR_ENABLE, 0);
+
+	/* set up buad rate */
+	{
+		uint32 divisor;
+
+		/* set DIAB bit */
+		UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
+
+		/* set divisor */
+		divisor = MAX_BAUD / baud;
+		UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
+		UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8);
+
+		/* clear DIAB bit */
+		UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
+	}
+
+	/* set data format */
+	UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
+}
+
+static int remoteDebugInitialized = 0;
+
+uint8 getDebugChar(void)
+{
+	if (!remoteDebugInitialized) {
+		remoteDebugInitialized = 1;
+		debugInit(UART16550_BAUD_38400,
+			  UART16550_DATA_8BIT,
+			  UART16550_PARITY_NONE, UART16550_STOP_1BIT);
+	}
+
+	while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0);
+	return UART16550_READ(OFS_RCV_BUFFER);
+}
+
+
+int putDebugChar(uint8 byte)
+{
+	if (!remoteDebugInitialized) {
+		remoteDebugInitialized = 1;
+		debugInit(UART16550_BAUD_9600,
+			  UART16550_DATA_8BIT,
+			  UART16550_PARITY_NONE, UART16550_STOP_1BIT);
+	}
+
+	while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0);
+	UART16550_WRITE(OFS_SEND_BUFFER, byte);
+	return 1;
+}
+
+#endif
diff -u --recursive --new-file v2.4.9/linux/arch/mips/gt64120/momenco_ocelot/int-handler.S linux/arch/mips/gt64120/momenco_ocelot/int-handler.S
--- v2.4.9/linux/arch/mips/gt64120/momenco_ocelot/int-handler.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/gt64120/momenco_ocelot/int-handler.S	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * First-level interrupt dispatcher for ocelot board.
+ *
+ * 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/config.h>
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+/*
+ * first level interrupt dispatcher for ocelot board -
+ * We check for the timer first, then check PCI ints A and D.
+ * Then check for serial IRQ and fall through.
+ */
+		.align	5
+		NESTED(ocelot_handle_int, PT_SIZE, sp)
+		SAVE_ALL
+		CLI
+		.set	at
+		mfc0	t0, CP0_CAUSE  
+		mfc0	t2, CP0_STATUS
+
+		and	t0, t2
+        
+		 andi	t1, t0, STATUSF_IP2	/* int0 hardware line */
+		bnez	t1, ll_pri_enet_irq
+		 andi	t1, t0, STATUSF_IP3	/* int1 hardware line */
+		bnez	t1, ll_sec_enet_irq
+		 andi	t1, t0, STATUSF_IP4	/* int2 hardware line */
+		bnez	t1, ll_uart1_irq
+		 andi	t1, t0, STATUSF_IP5	/* int3 hardware line */
+		bnez	t1, ll_cpci_irq
+		 andi	t1, t0, STATUSF_IP6	/* int4 hardware line */
+		bnez	t1, ll_galileo_irq
+		 andi	t1, t0, STATUSF_IP7	/* cpu timer */
+		bnez	t1, ll_cputimer_irq
+
+                /* now look at the extended interrupts */
+		mfc0	t0, CP0_CAUSE  
+		cfc0	t1, CP0_S1_INTCONTROL
+
+		/* shift the mask 8 bits left to line up the bits */
+		 sll	t2, t1, 8
+
+		 and	t0, t2
+		 srl	t0, t0, 16
+
+		 andi	t1, t0, STATUSF_IP8	/* int6 hardware line */
+		bnez	t1, ll_pmc1_irq
+		 andi	t1, t0, STATUSF_IP9	/* int7 hardware line */
+		bnez	t1, ll_pmc2_irq
+		 andi	t1, t0, STATUSF_IP10	/* int8 hardware line */
+		bnez	t1, ll_cpci_abcd_irq
+		 andi	t1, t0, STATUSF_IP11	/* int9 hardware line */
+		bnez	t1, ll_uart2_irq
+
+		.set	reorder
+
+		/* wrong alarm or masked ... */
+		j	spurious_interrupt
+		nop
+		END(ocelot_handle_int)
+
+		.align	5
+ll_pri_enet_irq:
+		li	a0, 2
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_sec_enet_irq:
+		li	a0, 3
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_uart1_irq:
+		li	a0, 4
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+	
+ll_cpci_irq:
+		li	a0, 5
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_galileo_irq:
+		li	a0, 6
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_cputimer_irq:
+		li	a0, 7
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+	
+ll_pmc1_irq:
+		li	a0, 8
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_pmc2_irq:
+		li	a0, 9
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_cpci_abcd_irq:
+		li	a0, 10
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_uart2_irq:
+		li	a0, 11
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
diff -u --recursive --new-file v2.4.9/linux/arch/mips/gt64120/momenco_ocelot/irq.c linux/arch/mips/gt64120/momenco_ocelot/irq.c
--- v2.4.9/linux/arch/mips/gt64120/momenco_ocelot/irq.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/gt64120/momenco_ocelot/irq.c	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Author: RidgeRun, Inc.
+ *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.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.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.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/slab.h>
+#include <linux/random.h>
+#include <linux/irq.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>
+
+
+static spinlock_t rm7000_irq_lock = SPIN_LOCK_UNLOCKED;
+
+/* Function for careful CP0 interrupt mask access */
+static inline void modify_cp0_intmask(unsigned clr_mask_in, unsigned set_mask_in)
+{
+	unsigned long status;
+	unsigned clr_mask;
+	unsigned set_mask;
+
+	/* do the low 8 bits first */
+	clr_mask = 0xff & clr_mask_in;
+	set_mask = 0xff & set_mask_in;
+	status = read_32bit_cp0_register(CP0_STATUS);
+	status &= ~((clr_mask & 0xFF) << 8);
+	status |= (set_mask & 0xFF) << 8;
+	write_32bit_cp0_register(CP0_STATUS, status);
+
+	/* do the high 8 bits */
+	clr_mask = 0xff & (clr_mask_in >> 8);
+	set_mask = 0xff & (set_mask_in >> 8);
+	status = read_32bit_cp0_set1_register(CP0_S1_INTCONTROL);
+	status &= ~((clr_mask & 0xFF) << 8);
+	status |= (set_mask & 0xFF) << 8;
+	write_32bit_cp0_set1_register(CP0_S1_INTCONTROL, status);
+}
+
+static inline void mask_irq(unsigned int irq)
+{
+	modify_cp0_intmask(irq, 0);
+}
+
+static inline void unmask_irq(unsigned int irq)
+{
+	modify_cp0_intmask(0, irq);
+}
+
+static void enable_cp7000_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&rm7000_irq_lock, flags);
+	unmask_irq(1 << irq);
+	spin_unlock_irqrestore(&rm7000_irq_lock, flags);
+}
+
+static unsigned int startup_cp7000_irq(unsigned int irq)
+{
+	enable_cp7000_irq(irq);
+
+	return 0;				/* never anything pending */
+}
+
+static void disable_cp7000_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&rm7000_irq_lock, flags);
+	mask_irq(1 << irq);
+	spin_unlock_irqrestore(&rm7000_irq_lock, flags);
+}
+
+#define shutdown_cp7000_irq disable_cp7000_irq
+
+static void mask_and_ack_cp7000_irq(unsigned int irq)
+{
+	mask_irq(1 << irq);
+}
+
+static void end_cp7000_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		unmask_irq(1 << irq);
+}
+
+static struct hw_interrupt_type cp7000_hpcdma_irq_type = {
+	"CP7000",
+	startup_cp7000_irq,
+	shutdown_cp7000_irq,
+	enable_cp7000_irq,
+	disable_cp7000_irq,
+	mask_and_ack_cp7000_irq,
+	end_cp7000_irq,
+	NULL
+};
+
+
+extern asmlinkage void ocelot_handle_int(void);
+extern void gt64120_irq_init(void);
+
+void __init init_IRQ(void)
+{
+	int i;
+
+	/*
+	 * Clear all of the interrupts while we change the able around a bit.
+	 * int-handler is not on bootstrap
+	 */
+	clear_cp0_status(ST0_IM | ST0_BEV);
+	__cli();
+
+	/* Sets the first-level interrupt dispatcher. */
+	set_except_vector(0, ocelot_handle_int);
+	init_generic_irq();
+
+	for (i = 0; i <= 15; i++) {
+		irq_desc[i].status	= IRQ_DISABLED;
+		irq_desc[i].action	= 0;
+		irq_desc[i].depth	= 1;
+		irq_desc[i].handler	= &cp7000_hpcdma_irq_type;
+	}
+
+	gt64120_irq_init();
+
+#ifdef CONFIG_REMOTE_DEBUG
+	printk("start kgdb ...\n");
+	set_debug_traps();
+	breakpoint();	/* you may move this line to whereever you want :-) */
+#endif
+#ifdef CONFIG_GDB_CONSOLE
+	register_gdb_console();
+#endif
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips/gt64120/momenco_ocelot/ocelot_pld.h linux/arch/mips/gt64120/momenco_ocelot/ocelot_pld.h
--- v2.4.9/linux/arch/mips/gt64120/momenco_ocelot/ocelot_pld.h	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/gt64120/momenco_ocelot/ocelot_pld.h	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,34 @@
+/*
+ * $Id$
+ *
+ * Ocelot Board Register Definitions
+ *
+ * (C) 2001 Red Hat, Inc.
+ *
+ * GPL'd
+ *
+ */
+
+#ifndef __MOMENCO_OCELOT_PLD_H__
+#define __MOMENCO_OCELOT_PLD_H__
+
+#define OCELOT_CS0_ADDR (0xe0020000)
+
+#define OCELOT_REG_BOARDREV (0)
+#define OCELOT_REG_PLD1_ID (1)
+#define OCELOT_REG_PLD2_ID (2)
+#define OCELOT_REG_RESET_STATUS (3)
+#define OCELOT_REG_BOARD_STATUS (4)
+#define OCELOT_REG_CPCI_ID (5)
+#define OCELOT_REG_I2C_CTRL (8)
+#define OCELOT_REG_EEPROM_MODE (9)
+#define OCELOT_REG_INTMASK (10)
+#define OCELOT_REG_INTSTATUS (11)
+#define OCELOT_REG_INTSET (12)
+#define OCELOT_REG_INTCLR (13)
+
+#define OCELOT_PLD_WRITE(x, y) writeb(x, OCELOT_CS0_ADDR + OCELOT_REG_##y)
+#define OCELOT_PLD_READ(x) readb(OCELOT_CS0_ADDR + OCELOT_REG_##x)
+
+
+#endif /* __MOMENCO_OCELOT_PLD_H__ */
diff -u --recursive --new-file v2.4.9/linux/arch/mips/gt64120/momenco_ocelot/pci.c linux/arch/mips/gt64120/momenco_ocelot/pci.c
--- v2.4.9/linux/arch/mips/gt64120/momenco_ocelot/pci.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/gt64120/momenco_ocelot/pci.c	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * arch/mips/gt64120/momenco_ocelot/pci.c
+ *     Board-specific PCI routines for gt64120 controller.
+ *
+ * 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/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/init.h>
+#include <asm/pci.h>
+
+
+void __init gt64120_board_pcibios_fixup_bus(struct pci_bus *bus)
+{
+	struct pci_bus *current_bus = bus;
+	struct pci_dev *devices;
+	struct list_head *devices_link;
+	u16 cmd;
+
+	list_for_each(devices_link, &(current_bus->devices)) {
+
+		devices = pci_dev_b(devices_link);
+		if (devices == NULL)
+			continue;
+
+		if (PCI_SLOT(devices->devfn) == 1) {
+			/*
+			 * Slot 1 is primary ether port, i82559
+			 * we double-check against that assumption
+			 */
+			if ((devices->vendor != 0x8086) ||
+			    (devices->device != 0x1209) ) {
+				panic("gt64120_board_pcibios_fixup_bus: found "
+				      "unexpected PCI device in slot 1.");
+			}
+			devices->irq = 2;       /* irq_nr is 2 for INT0 */
+		} else if (PCI_SLOT(devices->devfn) == 2) {
+			/*
+			 * Slot 2 is secondary ether port, i21143 
+			 * we double-check against that assumption
+			 */
+			if ((devices->vendor != 0x1011) ||
+			    (devices->device != 0x19) ) {
+				panic("galileo_pcibios_fixup_bus: "
+				      "found unexpected PCI device in slot 2.");
+			}
+			devices->irq = 3;       /* irq_nr is 3 for INT1 */
+		} else if (PCI_SLOT(devices->devfn) == 4) {
+			/* PMC Slot 1 */
+			devices->irq = 8;       /* irq_nr is 8 for INT6 */
+		} else if (PCI_SLOT(devices->devfn) == 5) {
+			/* PMC Slot 1 */
+			devices->irq = 9;       /* irq_nr is 9 for INT7 */
+		} else {
+			/* We don't have assign interrupts for other devices. */
+			devices->irq = 0xff;
+		}
+
+		/* Assign an interrupt number for the device */
+		bus->ops->write_byte(devices, PCI_INTERRUPT_LINE, devices->irq);
+
+		/* enable master */
+		bus->ops->read_word(devices, PCI_COMMAND, &cmd);
+		cmd |= PCI_COMMAND_MASTER;
+		bus->ops->write_word(devices, PCI_COMMAND, cmd);
+	}
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips/gt64120/momenco_ocelot/prom.c linux/arch/mips/gt64120/momenco_ocelot/prom.c
--- v2.4.9/linux/arch/mips/gt64120/momenco_ocelot/prom.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/gt64120/momenco_ocelot/prom.c	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.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/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+
+#define PLD_BASE	0xbc000000
+
+#define REV             0x0     /* Board Assembly Revision */
+#define PLD1ID          0x1     /* PLD 1 ID */
+#define PLD2ID          0x2     /* PLD 2 ID */
+#define RESET_STAT      0x3     /* Reset Status Register */
+#define BOARD_STAT      0x4     /* Board Status Register */
+#define CPCI_ID         0x5     /* Compact PCI ID Register */
+#define CONTROL         0x8     /* Control Register */
+#define CPU_EEPROM      0x9     /* CPU Configuration EEPROM Register */
+#define INTMASK         0xA     /* Interrupt Mask Register */
+#define INTSTAT         0xB     /* Interrupt Status Register */
+#define INTSET          0xC     /* Interrupt Set Register */
+#define INTCLR          0xD     /* Interrupt Clear Register */
+
+#define PLD_REG(x)	((uint8_t*)(PLD_BASE+(x)))
+
+char arcs_cmdline[COMMAND_LINE_SIZE];
+
+/* [jsun@junsun.net] PMON passes arguments in C main() style */
+void __init prom_init(int argc, const char **arg)
+{
+	int i;
+
+	/* arg[0] is "g", the rest is boot parameters */
+	arcs_cmdline[0] = '\0';
+	for (i = 1; i < argc; i++) {
+		if (strlen(arcs_cmdline) + strlen(arg[i] + 1)
+		    >= sizeof(arcs_cmdline))
+			break;
+		strcat(arcs_cmdline, arg[i]);
+		strcat(arcs_cmdline, " ");
+	}
+
+	mips_machgroup = MACH_GROUP_MOMENCO;
+	mips_machtype = MACH_MOMENCO_OCELOT;
+
+	/* turn off the Bit Error LED, which comes on automatically
+	 * at power-up reset */
+	*PLD_REG(INTCLR) = 0x80;
+
+	/* All the boards have at least 64MiB. If there's more, we
+	   detect and register it later */
+	add_memory_region(0, 64 << 20, BOOT_MEM_RAM);
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
+
+void __init prom_fixup_mem_map(unsigned long start, unsigned long end)
+{
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips/gt64120/momenco_ocelot/reset.c linux/arch/mips/gt64120/momenco_ocelot/reset.c
--- v2.4.9/linux/arch/mips/gt64120/momenco_ocelot/reset.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/gt64120/momenco_ocelot/reset.c	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 1997, 2001 Ralf Baechle
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+
+void momenco_ocelot_restart(char *command)
+{
+	*(volatile char *) 0xbc000000 = 0x0f;
+
+	/*
+	 * Ouch, we're still alive ... This time we take the silver bullet ...
+	 * ... and find that we leave the hardware in a state in which the
+	 * kernel in the flush locks up somewhen during of after the PCI
+	 * detection stuff.
+	 */
+	clear_cp0_status(ST0_BEV | ST0_ERL);
+	change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
+	flush_cache_all();
+	write_32bit_cp0_register(CP0_WIRED, 0);
+	__asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
+}
+
+void momenco_ocelot_halt(void)
+{
+	printk(KERN_NOTICE "\n** You can safely turn off the power\n");
+	while (1)
+		__asm__(".set\tmips3\n\t"
+	                "wait\n\t"
+			".set\tmips0");
+}
+
+void momenco_ocelot_power_off(void)
+{
+	momenco_ocelot_halt();
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips/gt64120/momenco_ocelot/setup.c linux/arch/mips/gt64120/momenco_ocelot/setup.c
--- v2.4.9/linux/arch/mips/gt64120/momenco_ocelot/setup.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/gt64120/momenco_ocelot/setup.c	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,282 @@
+/*
+ * setup.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ * Galileo Evaluation Boards - board dependent boot routines
+ *
+ * Copyright (C) 1996, 1997, 2001  Ralf Baechle
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Copyright (C) 2001 Red Hat, Inc.
+ *
+ * Author: RidgeRun, Inc.
+ *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.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.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mc146818rtc.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/timex.h>
+#include <linux/vmalloc.h>
+#include <asm/time.h>
+#include <asm/bootinfo.h>
+#include <asm/page.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/pci.h>
+#include <asm/processor.h>
+#include <asm/ptrace.h>
+#include <asm/reboot.h>
+#include <asm/mc146818rtc.h>
+#include <linux/version.h>
+#include <linux/bootmem.h>
+#include <linux/blk.h>
+#include <asm/gt64120/gt64120.h>
+#include "ocelot_pld.h"
+
+extern struct rtc_ops no_rtc_ops;
+
+unsigned long gt64120_base = KSEG1ADDR(GT_DEF_BASE);
+
+/* These functions are used for rebooting or halting the machine*/
+extern void momenco_ocelot_restart(char *command);
+extern void momenco_ocelot_halt(void);
+extern void momenco_ocelot_power_off(void);
+
+extern void gt64120_time_init(void);
+extern void momenco_ocelot_irq_setup(void);
+
+static char reset_reason;
+
+#define ENTRYLO(x) ((pte_val(mk_pte_phys((x), PAGE_KERNEL_UNCACHED)) >> 6)|1)
+
+static void __init setup_l3cache(unsigned long size);
+
+void __init momenco_ocelot_setup(void)
+{
+	void (*l3func)(unsigned long)=KSEG1ADDR(&setup_l3cache);
+	unsigned int tmpword;
+
+	board_time_init = gt64120_time_init;
+
+	_machine_restart = momenco_ocelot_restart;
+	_machine_halt = momenco_ocelot_halt;
+	_machine_power_off = momenco_ocelot_power_off;
+
+	/*
+	 * initrd_start = (ulong)ocelot_initrd_start;
+	 * initrd_end = (ulong)ocelot_initrd_start + (ulong)ocelot_initrd_size;
+	 * initrd_below_start_ok = 1;
+	 */
+	rtc_ops = &no_rtc_ops;
+
+
+	/* A wired TLB entry for the GT64120A and the serial port. The
+	   GT64120A is going to be hit on every IRQ anyway - there's
+	   absolutely no point in letting it be a random TLB entry, as
+	   it'll just cause needless churning of the TLB. And we use
+	   the other half for the serial port, which is just a PITA
+	   otherwise :)
+
+		Device			Physical	Virtual
+		GT64120 Internal Regs	0x24000000	0xe0000000
+		UARTs (CS2)		0x2d000000	0xe0001000
+	*/
+	add_wired_entry(ENTRYLO(0x24000000), ENTRYLO(0x2D000000), 0xe0000000, PM_4K);
+
+	/* Also a temporary entry to let us talk to the Ocelot PLD and NVRAM
+	   in the CS[012] region. We can't use ioremap() yet. The NVRAM
+	   appears to be one of the variants of ST M48T35 - see 
+	   http://www.st.com/stonline/bin/sftab.exe?table=172&filter0=M48T35
+
+		Ocelot PLD (CS0)	0x2c000000	0xe0020000
+		NVRAM			0x2c800000	0xe0030000
+	*/
+		
+	add_temporary_entry(ENTRYLO(0x2C000000), ENTRYLO(0x2d000000), 0xe0020000, PM_64K);
+
+
+	/* Relocate the CS3/BootCS region */
+  	GT_WRITE( GT_CS3BOOTLD_OFS, 0x2f000000 >> 21);
+
+	/* Relocate CS[012] */
+ 	GT_WRITE(GT_CS20LD_OFS, 0x2c000000 >> 21);
+
+	/* Relocate the GT64120A itself... */
+	GT_WRITE(GT_ISD_OFS, 0x24000000 >> 21);
+	mb();
+	gt64120_base = 0xe0000000;
+
+	/* ...and the PCI0 view of it. */
+	GT_WRITE(GT_PCI0_CFGADDR_OFS, 0x80000020);
+	GT_WRITE(GT_PCI0_CFGDATA_OFS, 0x24000000);
+	GT_WRITE(GT_PCI0_CFGADDR_OFS, 0x80000024);
+	GT_WRITE(GT_PCI0_CFGDATA_OFS, 0x24000001);
+
+	/* Relocate PCI0 I/O and Mem0 */
+	GT_WRITE(GT_PCI0IOLD_OFS, 0x20000000 >> 21);
+	GT_WRITE(GT_PCI0M0LD_OFS, 0x22000000 >> 21);
+
+	/* Relocate PCI0 Mem1 */
+	GT_WRITE(GT_PCI0M1LD_OFS, 0x36000000 >> 21);
+
+	/* Relocate all the PCI1 stuff, not that we use it */
+	GT_WRITE(GT_PCI1IOLD_OFS, 0x30000000 >> 21);
+	GT_WRITE(GT_PCI1M0LD_OFS, 0x32000000 >> 21);
+	GT_WRITE(GT_PCI1M1LD_OFS, 0x34000000 >> 21);
+
+	/* Relocate the CPU's view of the RAM... */
+	GT_WRITE(GT_SCS10LD_OFS, 0);
+	GT_WRITE(GT_SCS10HD_OFS, 0x0fe00000 >> 21);
+	GT_WRITE(GT_SCS32LD_OFS, 0x10000000 >> 21);
+	GT_WRITE(GT_SCS32HD_OFS, 0x0fe00000 >> 21);
+
+	GT_WRITE(GT_SCS1LD_OFS, 0xff);
+	GT_WRITE(GT_SCS1HD_OFS, 0x00);
+	GT_WRITE(GT_SCS0LD_OFS, 0);
+	GT_WRITE(GT_SCS0HD_OFS, 0xff);
+	GT_WRITE(GT_SCS3LD_OFS, 0xff);
+	GT_WRITE(GT_SCS3HD_OFS, 0x00);
+	GT_WRITE(GT_SCS2LD_OFS, 0);
+	GT_WRITE(GT_SCS2HD_OFS, 0xff);
+
+	/* ...and the PCI0 view of it. */
+	GT_WRITE(GT_PCI0_CFGADDR_OFS, 0x80000010);
+	GT_WRITE(GT_PCI0_CFGDATA_OFS, 0x00000000);
+	GT_WRITE(GT_PCI0_CFGADDR_OFS, 0x80000014);
+	GT_WRITE(GT_PCI0_CFGDATA_OFS, 0x10000000);
+	GT_WRITE(GT_PCI0_BS_SCS10_OFS, 0x0ffff000);
+	GT_WRITE(GT_PCI0_BS_SCS32_OFS, 0x0ffff000);
+
+	tmpword = OCELOT_PLD_READ(BOARDREV);
+	if (tmpword < 26)
+		printk("Momenco Ocelot: Board Assembly Rev. %c\n", 'A'+tmpword);
+	else
+		printk("Momenco Ocelot: Board Assembly Revision #0x%x\n", tmpword);
+
+	tmpword = OCELOT_PLD_READ(PLD1_ID);
+	printk("PLD 1 ID: %d.%d\n", tmpword>>4, tmpword&15);
+	tmpword = OCELOT_PLD_READ(PLD2_ID);
+	printk("PLD 2 ID: %d.%d\n", tmpword>>4, tmpword&15);
+	tmpword = OCELOT_PLD_READ(RESET_STATUS);
+	printk("Reset reason: 0x%x\n", tmpword);
+	reset_reason = tmpword;
+	OCELOT_PLD_WRITE(0xff, RESET_STATUS);
+
+	tmpword = OCELOT_PLD_READ(BOARD_STATUS);
+	printk("Board Status register: 0x%02x\n", tmpword);
+	printk("  - User jumper: %s\n", (tmpword & 0x80)?"installed":"absent");
+	printk("  - Boot flash write jumper: %s\n", (tmpword&0x40)?"installed":"absent");
+	printk("  - Tulip PHY %s connected\n", (tmpword&0x10)?"is":"not");
+	printk("  - L3 Cache size: %d MiB\n", (1<<((tmpword&12) >> 2))&~1);
+	printk("  - SDRAM size: %d MiB\n", 1<<(6+(tmpword&3)));
+
+	if (tmpword&12)
+		l3func((1<<(((tmpword&12) >> 2)+20)));
+
+	switch(tmpword &3) {
+	case 3:
+		/* 512MiB */
+		add_memory_region(256<<20, 256<<20, BOOT_MEM_RAM);
+	case 2:
+		/* 256MiB */
+		/* FIXME: Is it actually here, or at 0x10000000? */
+		add_memory_region(128<<20, 128<<20, BOOT_MEM_RAM);
+	case 1:
+		/* 128MiB */
+		add_memory_region(64<<20, 64<<20, BOOT_MEM_RAM);
+	case 0:
+		/* 64MiB */
+		;
+	}
+
+	/* Fix up the DiskOnChip mapping */
+	GT_WRITE(0x468, 0xfef73);
+}
+
+extern int rm7k_tcache_enabled;
+/*
+ * This runs in KSEG1. See the verbiage in rm7k.c::probe_scache()
+ */
+#define Page_Invalidate_T 0x16
+static void __init setup_l3cache(unsigned long size)
+{
+	int register i;
+	unsigned long tmp;
+	
+	printk("Enabling L3 cache...");
+
+	/* Enable the L3 cache in the GT64120A's CPU Configuration register */
+	GT_READ(0, &tmp);
+	GT_WRITE(0, tmp | (1<<14));
+
+	/* Enable the L3 cache in the CPU */
+	set_cp0_config(1<<12 /* CONF_TE */);
+
+	/* Clear the cache */
+	set_taglo(0);
+	set_taghi(0);
+
+	for (i=0; i < size; i+= 4096) {
+		__asm__ __volatile__ (
+			".set noreorder\n\t"
+			".set mips3\n\t"
+			"cache %1, (%0)\n\t"
+			".set mips0\n\t"
+			".set reorder"
+			:
+			: "r" (KSEG0ADDR(i)),
+			  "i" (Page_Invalidate_T));
+	}
+
+	/* Let the RM7000 MM code know that the tertiary cache is enabled */
+	rm7k_tcache_enabled = 1;
+
+	printk("Done\n");
+}
+
+
+/* This needs to be one of the first initcalls, because no I/O port access
+   can work before this */
+
+static int io_base_ioremap(void)
+{
+	void *io_remap_range = ioremap(GT_PCI_IO_BASE, GT_PCI_IO_SIZE);
+	if (!io_remap_range) {
+		panic("Could not ioremap I/O port range\n");
+	}
+	mips_io_port_base = io_remap_range - GT_PCI_IO_BASE;
+	return 0;
+}
+module_init(io_base_ioremap);
+
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ite-boards/generic/Makefile linux/arch/mips/ite-boards/generic/Makefile
--- v2.4.9/linux/arch/mips/ite-boards/generic/Makefile	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/ite-boards/generic/Makefile	Sun Sep  9 10:43:01 2001
@@ -1,7 +1,7 @@
 #
 #  Copyright 2000 MontaVista Software Inc.
 #  Author: MontaVista Software, Inc.
-#     	ppopov@mvista.com or support@mvista.com
+#     	ppopov@mvista.com or source@mvista.com
 #
 # Makefile for the ITE 8172 (qed-4n-s01b) board, generic files.
 #
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ite-boards/generic/dbg_io.c linux/arch/mips/ite-boards/generic/dbg_io.c
--- v2.4.9/linux/arch/mips/ite-boards/generic/dbg_io.c	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/ite-boards/generic/dbg_io.c	Sun Sep  9 10:43:01 2001
@@ -7,8 +7,8 @@
 
 /* we need uint32 uint8 */
 /* #include "types.h" */
-typedef         unsigned char uint8;
-typedef         unsigned int  uint32;
+typedef unsigned char uint8;
+typedef unsigned int uint32;
 
 /* --- END OF CONFIG --- */
 
@@ -39,7 +39,7 @@
 /* === CONFIG === */
 
 /* [stevel] we use the IT8712 serial port for kgdb */
-#define	DEBUG_BASE  0xB40003F8 /* 8712 serial port 1 base address */
+#define	DEBUG_BASE  0xB40003F8	/* 8712 serial port 1 base address */
 #define MAX_BAUD    115200
 
 /* === END OF CONFIG === */
@@ -69,59 +69,57 @@
 
 void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
 {
-    /* disable interrupts */
-    UART16550_WRITE(OFS_INTR_ENABLE, 0);
+	/* disable interrupts */
+	UART16550_WRITE(OFS_INTR_ENABLE, 0);
 
-    /* set up buad rate */
-    { 
-        uint32 divisor;
-       
-        /* set DIAB bit */
-        UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
-        
-        /* set divisor */
-        divisor = MAX_BAUD / baud;
-        UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
-        UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00)>>8);
-
-        /* clear DIAB bit */
-        UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
-    }
+	/* set up buad rate */
+	{
+		uint32 divisor;
+
+		/* set DIAB bit */
+		UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
+
+		/* set divisor */
+		divisor = MAX_BAUD / baud;
+		UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
+		UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8);
+
+		/* clear DIAB bit */
+		UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
+	}
 
-    /* set data format */
-    UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
+	/* set data format */
+	UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
 }
 
 static int remoteDebugInitialized = 0;
 
 uint8 getDebugChar(void)
 {
-    if (!remoteDebugInitialized) {
-	remoteDebugInitialized = 1;
-	debugInit(UART16550_BAUD_115200,
-		  UART16550_DATA_8BIT,
-		  UART16550_PARITY_NONE,
-		  UART16550_STOP_1BIT);
-    }
+	if (!remoteDebugInitialized) {
+		remoteDebugInitialized = 1;
+		debugInit(UART16550_BAUD_115200,
+			  UART16550_DATA_8BIT,
+			  UART16550_PARITY_NONE, UART16550_STOP_1BIT);
+	}
 
-    while((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0);
-    return UART16550_READ(OFS_RCV_BUFFER);
+	while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0);
+	return UART16550_READ(OFS_RCV_BUFFER);
 }
 
 
 int putDebugChar(uint8 byte)
 {
-    if (!remoteDebugInitialized) {
-	remoteDebugInitialized = 1;
-	debugInit(UART16550_BAUD_115200,
-		  UART16550_DATA_8BIT,
-		  UART16550_PARITY_NONE,
-		  UART16550_STOP_1BIT);
-    }
-
-    while ((UART16550_READ(OFS_LINE_STATUS) &0x20) == 0);
-    UART16550_WRITE(OFS_SEND_BUFFER, byte);
-    return 1;
+	if (!remoteDebugInitialized) {
+		remoteDebugInitialized = 1;
+		debugInit(UART16550_BAUD_115200,
+			  UART16550_DATA_8BIT,
+			  UART16550_PARITY_NONE, UART16550_STOP_1BIT);
+	}
+
+	while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0);
+	UART16550_WRITE(OFS_SEND_BUFFER, byte);
+	return 1;
 }
 
 #endif
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ite-boards/generic/irq.c linux/arch/mips/ite-boards/generic/irq.c
--- v2.4.9/linux/arch/mips/ite-boards/generic/irq.c	Mon Aug 27 12:41:39 2001
+++ linux/arch/mips/ite-boards/generic/irq.c	Sun Sep  9 10:43:01 2001
@@ -5,7 +5,7 @@
  *
  * Copyright 2000,2001 MontaVista Software Inc.
  * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or support@mvista.com
+ *         	ppopov@mvista.com or source@mvista.com
  *
  * Part of this file was derived from Carsten Langgaard's 
  * arch/mips/mips-boards/atlas/atlas_int.c.
@@ -33,7 +33,6 @@
  *  with this program; if not, write  to the Free Software Foundation, Inc.,
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  */
-#include <linux/config.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/kernel_stat.h>
@@ -76,12 +75,13 @@
 extern void set_debug_traps(void);
 extern void mips_timer_interrupt(int irq, struct pt_regs *regs);
 extern asmlinkage void it8172_IRQ(void);
-irq_cpustat_t irq_stat [NR_CPUS];
 unsigned int local_bh_count[NR_CPUS];
 unsigned int local_irq_count[NR_CPUS];
 unsigned long spurious_count = 0;
 irq_desc_t irq_desc[NR_IRQS];
 irq_desc_t *irq_desc_base=&irq_desc[0];
+void disable_it8172_irq(unsigned int irq_nr);
+void enable_it8172_irq(unsigned int irq_nr);
 
 struct it8172_intc_regs volatile *it8172_hw0_icregs
 	= (struct it8172_intc_regs volatile *)(KSEG1ADDR(IT8172_PCI_IO_BASE + IT_INTC_BASE));
@@ -110,7 +110,7 @@
         unsigned long flags;
 
         save_and_cli(flags);
-        mask_irq(irq_nr);
+	disable_it8172_irq(irq_nr);
         restore_flags(flags);
 }
 
@@ -119,15 +119,13 @@
 	unsigned long flags;
 
         save_and_cli(flags);
-        unmask_irq(irq_nr);
+	enable_it8172_irq(irq_nr);
         restore_flags(flags);
 }
 
 
 void disable_it8172_irq(unsigned int irq_nr)
 {
-	unsigned short mask;
-
 	DPRINTK("disable_it8172_irq %d\n", irq_nr);
 
 	if ( (irq_nr >= IT8172_LPC_IRQ_BASE) && (irq_nr <= IT8172_SERIRQ_15)) {
@@ -290,7 +288,6 @@
 		printk("Unhandled interrupt %d, cause %x, disabled\n", 
 				(unsigned)irq, (unsigned)regs->cp0_cause);
 		disable_it8172_irq(irq);
-		//disable_irq(1<<irq);
 	}
 	irq_exit(cpu, irq);
 }
@@ -325,7 +322,6 @@
                         cli();
                         *p = action->next;
 			disable_it8172_irq(irq);
-                        //disable_irq(1<<irq);
                         restore_flags(flags);
                         kfree(action);
                         return 0;
@@ -378,7 +374,11 @@
 
 void enable_cpu_timer(void)
 {
-	enable_irq(1<<EXT_IRQ5_TO_IP); /* timer interrupt */
+        unsigned long flags;
+
+        save_and_cli(flags);
+	unmask_irq(1<<EXT_IRQ5_TO_IP); /* timer interrupt */
+        restore_flags(flags);
 }
 
 unsigned long probe_irq_on (void)
@@ -395,6 +395,8 @@
 void __init init_IRQ(void)
 {
 	int i;
+        unsigned long flags;
+
 
         memset(irq_desc, 0, sizeof(irq_desc));
         set_except_vector(0, it8172_IRQ);
@@ -440,8 +442,9 @@
 	 * Enable external int line 2
 	 * All ITE interrupts are masked for now.
 	 */
-	enable_irq(1<<EXT_IRQ0_TO_IP);
-	//change_cp0_status(ST0_IM, IE_IRQ2);
+        save_and_cli(flags);
+	unmask_irq(1<<EXT_IRQ0_TO_IP);
+        restore_flags(flags);
 
 #ifdef CONFIG_REMOTE_DEBUG
 	/* If local serial I/O used for debug port, enter kgdb at once */
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ite-boards/generic/it8172_cir.c linux/arch/mips/ite-boards/generic/it8172_cir.c
--- v2.4.9/linux/arch/mips/ite-boards/generic/it8172_cir.c	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/ite-boards/generic/it8172_cir.c	Sun Sep  9 10:43:01 2001
@@ -5,7 +5,7 @@
  *
  * Copyright 2001 MontaVista Software Inc.
  * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or support@mvista.com
+ *         	ppopov@mvista.com or source@mvista.com
  *
  *  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
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ite-boards/generic/it8172_pci.c linux/arch/mips/ite-boards/generic/it8172_pci.c
--- v2.4.9/linux/arch/mips/ite-boards/generic/it8172_pci.c	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/ite-boards/generic/it8172_pci.c	Sun Sep  9 10:43:01 2001
@@ -1,11 +1,10 @@
 /*
- *
  * BRIEF MODULE DESCRIPTION
  *	IT8172 system controller specific pci support.
  *
  * Copyright 2000 MontaVista Software Inc.
  * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or support@mvista.com
+ *         	ppopov@mvista.com or source@mvista.com
  *
  *  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
@@ -271,6 +270,12 @@
 
 void __init pcibios_fixup_bus(struct pci_bus *b)
 {
-	printk("pcibios_fixup_bus\n");
+	//printk("pcibios_fixup_bus\n");
 }
+
+unsigned __init int pcibios_assign_all_busses(void)
+{
+	return 1;
+}
+
 #endif /* CONFIG_PCI */
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ite-boards/generic/it8172_rtc.c linux/arch/mips/ite-boards/generic/it8172_rtc.c
--- v2.4.9/linux/arch/mips/ite-boards/generic/it8172_rtc.c	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/ite-boards/generic/it8172_rtc.c	Sun Sep  9 10:43:01 2001
@@ -1,7 +1,7 @@
 /*
  * Copyright 2000 MontaVista Software Inc.
  * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or support@mvista.com
+ *         	ppopov@mvista.com or source@mvista.com
  *
  * Carsten Langgaard, carstenl@mips.com
  * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
@@ -26,7 +26,6 @@
  * RTC routines for ITE8172 MC146818-compatible rtc chip.
  *
  */
-#include <asm/spinlock.h>
 #include <linux/mc146818rtc.h>
 #include <asm/it8172/it8172.h>
 
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ite-boards/generic/it8172_setup.c linux/arch/mips/ite-boards/generic/it8172_setup.c
--- v2.4.9/linux/arch/mips/ite-boards/generic/it8172_setup.c	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/ite-boards/generic/it8172_setup.c	Sun Sep  9 10:43:01 2001
@@ -5,7 +5,7 @@
  *
  * Copyright 2000 MontaVista Software Inc.
  * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or support@mvista.com
+ *         	ppopov@mvista.com or source@mvista.com
  *
  *  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
@@ -66,7 +66,7 @@
 extern int SearchIT8712(void);
 extern void InitLPCInterface(void);
 extern char * __init prom_getcmdline(void);
-extern void it8172_restart(void);
+extern void it8172_restart(char *command);
 extern void it8172_halt(void);
 extern void it8172_power_off(void);
 
@@ -114,19 +114,18 @@
 
 void __init it8172_setup(void)
 {
-#ifdef CONFIG_BLK_DEV_IT8172
 	unsigned short dsr;
-#endif
 	char *argptr;
 
 	argptr = prom_getcmdline();
 #ifdef CONFIG_SERIAL_CONSOLE
-	if ((argptr = strstr(argptr, "console=ttyS0")) == NULL) {
-		strcpy(serial_console, "ttyS0,115200");
-		console_setup(serial_console, NULL);
+	if ((argptr = strstr(argptr, "console=")) == NULL) {
+		argptr = prom_getcmdline();
+		strcat(argptr, " console=ttyS0,115200");
 	}
 #endif	  
 
+	clear_cp0_status(ST0_FR);
 	rtc_ops = &it8172_rtc_ops;
 
 	_machine_restart = it8172_restart;
@@ -153,19 +152,25 @@
 	ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
 #endif
 
-#ifdef CONFIG_BLK_DEV_IT8172
 	/*
-	 * Pull IDE device out of standby mode.
+	 * Pull enabled devices out of standby
 	 */
 	IT_IO_READ16(IT_PM_DSR, dsr);
+#ifdef CONFIG_SOUND_IT8172
+	dsr &= ~IT_PM_DSR_ACSB;
+#else
+	dsr |= IT_PM_DSR_ACSB;
+#endif	
+#ifdef CONFIG_BLK_DEV_IT8172
 	dsr &= ~IT_PM_DSR_IDESB;
-	IT_IO_WRITE16(IT_PM_DSR, dsr);
-
 	ide_ops = &std_ide_ops;
+#else
+	dsr |= IT_PM_DSR_IDESB;
 #endif
+	IT_IO_WRITE16(IT_PM_DSR, dsr);
 
 #ifdef CONFIG_FB
-    conswitchp = &dummy_con;
+	conswitchp = &dummy_con;
 #endif
 
 	InitLPCInterface();
@@ -266,8 +271,6 @@
 	unsigned int data_port = 0x14000060;
 	unsigned char data;
 	int i;
-
-	printk("8712 keyboard init");
 
 	outb(0xaa, cmd_port); /* send self-test cmd */
 	i = 0;
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ite-boards/generic/lpc.c linux/arch/mips/ite-boards/generic/lpc.c
--- v2.4.9/linux/arch/mips/ite-boards/generic/lpc.c	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/ite-boards/generic/lpc.c	Sun Sep  9 10:43:01 2001
@@ -5,7 +5,7 @@
  *
  * Copyright 2001 MontaVista Software Inc.
  * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or support@mvista.com
+ *         	ppopov@mvista.com or source@mvista.com
  *
  *  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
@@ -41,7 +41,7 @@
 #define FALSE 0
 #endif
 
-void LPCEnterMBPnP()
+void LPCEnterMBPnP(void)
 {
 	int i;
 	unsigned char key[4] = {0x87, 0x01, 0x55, 0x55};
@@ -51,7 +51,7 @@
 
 }
 
-void LPCExitMBPnP()
+void LPCExitMBPnP(void)
 {
 	outb(0x02, LPC_KEY_ADDR);
 	outb(0x02, LPC_DATA_ADDR);
@@ -80,7 +80,7 @@
 	return rtn;
 }
 
-int SearchIT8712()
+int SearchIT8712(void)
 {
 	unsigned char Id1, Id2;
 	unsigned short Id;
@@ -98,7 +98,7 @@
 		return FALSE;
 }
 
-void InitLPCInterface()
+void InitLPCInterface(void)
 {
 	unsigned char bus, dev_fn;
 	unsigned long data;
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ite-boards/generic/pmon_prom.c linux/arch/mips/ite-boards/generic/pmon_prom.c
--- v2.4.9/linux/arch/mips/ite-boards/generic/pmon_prom.c	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/ite-boards/generic/pmon_prom.c	Sun Sep  9 10:43:01 2001
@@ -6,7 +6,7 @@
  *
  * Copyright 2000 MontaVista Software Inc.
  * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or support@mvista.com
+ *         	ppopov@mvista.com or source@mvista.com
  *
  * This file was derived from Carsten Langgaard's 
  * arch/mips/mips-boards/xx files.
@@ -35,6 +35,7 @@
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/string.h>
@@ -44,8 +45,8 @@
 /* #define DEBUG_CMDLINE */
 
 char arcs_cmdline[COMMAND_LINE_SIZE];
-int prom_argc;
-char **prom_argv, **prom_envp;
+extern int prom_argc;
+extern char **prom_argv, **prom_envp;
 
 typedef struct
 {
@@ -126,12 +127,16 @@
 
 	memsize_str = prom_getenv("memsize");
 	if (!memsize_str) {
-		printk("memsize unknown: setting to 32MB\n");
+#ifdef CONFIG_MIPS_ITE8172
 		memsize = 32; 
-	} else {
-#ifdef DEBUG
-		printk("prom_memsize: %s\n", memsize_str);
+#elif defined(CONFIG_MIPS_IVR)
+		memsize = 64; 
+#else
+		memsize = 8; 
 #endif
+		printk("memsize unknown: setting to %dMB\n", memsize);
+	} else {
+		printk("memsize: %s\n", memsize_str);
 		memsize = simple_strtol(memsize_str, NULL, 0);
 	}
 	return memsize;
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ite-boards/generic/puts.c linux/arch/mips/ite-boards/generic/puts.c
--- v2.4.9/linux/arch/mips/ite-boards/generic/puts.c	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/ite-boards/generic/puts.c	Sun Sep  9 10:43:01 2001
@@ -5,7 +5,7 @@
  *
  * Copyright 2000,2001 MontaVista Software Inc.
  * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or support@mvista.com
+ *         	ppopov@mvista.com or source@mvista.com
  *
  *  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
@@ -30,7 +30,7 @@
 
 #include <linux/types.h>
 
-#define SERIAL_BASE   0xB4011800 /* it8172 */
+#define SERIAL_BASE   0xB4011800	/* it8172 */
 #define SER_CMD       5
 #define SER_DATA      0x00
 #define TX_BUSY       0x20
@@ -39,106 +39,101 @@
 #undef SLOW_DOWN
 
 static const char digits[16] = "0123456789abcdef";
-static volatile unsigned char * const com1 = (unsigned char *)SERIAL_BASE;
+static volatile unsigned char *const com1 = (unsigned char *) SERIAL_BASE;
 
 
 #ifdef SLOW_DOWN
 static inline void slow_down()
 {
-    int k;
-    for (k=0; k<10000; k++);
+	int k;
+	for (k = 0; k < 10000; k++);
 }
 #else
 #define slow_down()
 #endif
 
-void
-putch(const unsigned char c)
+void putch(const unsigned char c)
 {
-    unsigned char ch;
-    int i = 0;
+	unsigned char ch;
+	int i = 0;
 
-    do {
-        ch = com1[SER_CMD];
-        slow_down();
-        i++;
-        if (i>TIMEOUT) {
-            break;
-        }
-    } while (0 == (ch & TX_BUSY));
-    com1[SER_DATA] = c;
+	do {
+		ch = com1[SER_CMD];
+		slow_down();
+		i++;
+		if (i > TIMEOUT) {
+			break;
+		}
+	} while (0 == (ch & TX_BUSY));
+	com1[SER_DATA] = c;
 }
 
-void
-puts(unsigned char *cp)
+void puts(unsigned char *cp)
 {
-    unsigned char ch;
-    int i = 0;
+	unsigned char ch;
+	int i = 0;
 
-    while (*cp) {
-        do {
-             ch = com1[SER_CMD];
-            slow_down();
-            i++;
-            if (i>TIMEOUT) {
-                break;
-            }
-        } while (0 == (ch & TX_BUSY));
-        com1[SER_DATA] = *cp++;
-    }
-    putch('\r');
-    putch('\n');
+	while (*cp) {
+		do {
+			ch = com1[SER_CMD];
+			slow_down();
+			i++;
+			if (i > TIMEOUT) {
+				break;
+			}
+		} while (0 == (ch & TX_BUSY));
+		com1[SER_DATA] = *cp++;
+	}
+	putch('\r');
+	putch('\n');
 }
 
-void
-fputs(unsigned char *cp)
+void fputs(unsigned char *cp)
 {
-    unsigned char ch;
-    int i = 0;
+	unsigned char ch;
+	int i = 0;
 
-    while (*cp) {
+	while (*cp) {
 
-        do {
-             ch = com1[SER_CMD];
-             slow_down();
-            i++;
-            if (i>TIMEOUT) {
-                break;
-            }
-        } while (0 == (ch & TX_BUSY));
-        com1[SER_DATA] = *cp++;
-    }
+		do {
+			ch = com1[SER_CMD];
+			slow_down();
+			i++;
+			if (i > TIMEOUT) {
+				break;
+			}
+		} while (0 == (ch & TX_BUSY));
+		com1[SER_DATA] = *cp++;
+	}
 }
 
 
-void
-put64(uint64_t ul)
+void put64(uint64_t ul)
 {
-    int cnt;
-    unsigned ch;
+	int cnt;
+	unsigned ch;
 
-    cnt = 16;            /* 16 nibbles in a 64 bit long */
-    putch('0');
-    putch('x');
-    do {
-        cnt--;
-        ch = (unsigned char)(ul >> cnt * 4) & 0x0F;
-                putch(digits[ch]);
-    } while (cnt > 0);
+	cnt = 16;		/* 16 nibbles in a 64 bit long */
+	putch('0');
+	putch('x');
+	do {
+		cnt--;
+		ch = (unsigned char) (ul >> cnt * 4) & 0x0F;
+		putch(digits[ch]);
+	} while (cnt > 0);
 }
 
-void
-put32(unsigned u)
+void put32(unsigned u)
 {
-    int cnt;
-    unsigned ch;
+	int cnt;
+	unsigned ch;
 
-    cnt = 8;            /* 8 nibbles in a 32 bit long */
-    putch('0');
-    putch('x');
-    do {
-        cnt--;
-        ch = (unsigned char)(u >> cnt * 4) & 0x0F;
-                putch(digits[ch]);
-    } while (cnt > 0);
+	cnt = 8;		/* 8 nibbles in a 32 bit long */
+	putch('0');
+	putch('x');
+	do {
+		cnt--;
+		ch = (unsigned char) (u >> cnt * 4) & 0x0F;
+		putch(digits[ch]);
+	} while (cnt > 0);
 }
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ite-boards/generic/reset.c linux/arch/mips/ite-boards/generic/reset.c
--- v2.4.9/linux/arch/mips/ite-boards/generic/reset.c	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/ite-boards/generic/reset.c	Sun Sep  9 10:43:01 2001
@@ -3,10 +3,9 @@
  * BRIEF MODULE DESCRIPTION
  *	ITE 8172 reset routines.
  *
- * Copyright (C) 1997, 2001 Ralf Baechle
  * Copyright 2001 MontaVista Software Inc.
  * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or support@mvista.com
+ *         	ppopov@mvista.com or source@mvista.com
  *
  *  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
@@ -37,7 +36,7 @@
 #include <asm/reboot.h>
 #include <asm/system.h>
 
-void it8172_restart(char *command)
+void it8172_restart()
 {
 	set_cp0_status(ST0_BEV | ST0_ERL);
 	change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ite-boards/generic/time.c linux/arch/mips/ite-boards/generic/time.c
--- v2.4.9/linux/arch/mips/ite-boards/generic/time.c	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/ite-boards/generic/time.c	Sun Sep  9 10:43:01 2001
@@ -23,6 +23,7 @@
  *
  */
 
+#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/kernel_stat.h>
 #include <linux/sched.h>
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ite-boards/ivr/Makefile linux/arch/mips/ite-boards/ivr/Makefile
--- v2.4.9/linux/arch/mips/ite-boards/ivr/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/ite-boards/ivr/Makefile	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,28 @@
+#
+#  Copyright 2000 MontaVista Software Inc.
+#  Author: MontaVista Software, Inc.
+#     	ppopov@mvista.com or source@mvista.com
+#
+# Makefile for the Globespan IVR board,
+# board-specific files.
+#
+# 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.s:
+	$(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+	$(CC) $(CFLAGS) -c $< -o $*.o
+
+all: ivr.o
+
+O_TARGET := ivr.o
+
+obj-y := init.o 
+
+obj-CONFIG_PCI += pci_fixup.o
+obj-CONFIG_BLK_DEV_INITRD += le_ramdisk.o
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ite-boards/ivr/README linux/arch/mips/ite-boards/ivr/README
--- v2.4.9/linux/arch/mips/ite-boards/ivr/README	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/ite-boards/ivr/README	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,3 @@
+This is not really a board made by ITE Semi, but it's very 
+similar to the ITE QED-4N-S01B board.  The IVR board is made
+by Globespan and it's a reference board for the PVR chip.
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ite-boards/ivr/init.c linux/arch/mips/ite-boards/ivr/init.c
--- v2.4.9/linux/arch/mips/ite-boards/ivr/init.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/ite-boards/ivr/init.c	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,87 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	IVR board setup.
+ *
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ *  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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <linux/config.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <asm/it8172/it8172.h>
+#include <asm/it8172/it8172_dbg.h>
+
+int prom_argc;
+char **prom_argv, **prom_envp;
+
+extern char _end;
+extern void  __init prom_init_cmdline(void);
+extern unsigned long __init prom_get_memsize(void);
+extern void __init it8172_init_ram_resource(unsigned long memsize);
+
+#define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
+#define PFN_ALIGN(x)	(((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK)
+
+
+int __init prom_init(int argc, char **argv, char **envp, int *prom_vec)
+{
+	unsigned long mem_size;
+	unsigned long pcicr;
+
+	prom_argc = argc;
+	prom_argv = argv;
+	prom_envp = envp;
+
+	puts("IVR board running...");
+
+	mips_machgroup = MACH_GROUP_GLOBESPAN;
+	mips_machtype = MACH_IVR;  /* Globespan's iTVC15 reference board */
+
+	prom_init_cmdline();
+
+	/* pmon does not set memsize */
+	mem_size = prom_get_memsize();
+	mem_size = mem_size << 20;
+
+	/*
+	 * make the entire physical memory visible to pci bus masters
+	 */
+	IT_READ(IT_MC_PCICR, pcicr);
+	pcicr &= ~0x1f; 
+	pcicr |= (mem_size - 1) >> 22;
+	IT_WRITE(IT_MC_PCICR, pcicr);
+
+	it8172_init_ram_resource(mem_size);
+	add_memory_region(0, mem_size, BOOT_MEM_RAM);
+	return 0;
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ite-boards/ivr/pci_fixup.c linux/arch/mips/ite-boards/ivr/pci_fixup.c
--- v2.4.9/linux/arch/mips/ite-boards/ivr/pci_fixup.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/ite-boards/ivr/pci_fixup.c	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,139 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Globespan IVR board-specific pci fixups.
+ *
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ *  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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+
+#ifdef CONFIG_PCI
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/it8172/it8172.h>
+#include <asm/it8172/it8172_pci.h>
+#include <asm/it8172/it8172_int.h>
+
+void __init board_int_line_fixup(struct pci_dev *dev)     
+{
+	unsigned int slot, func;
+	unsigned char pin;
+        const int internal_func_irqs[7] = {
+            IT8172_AC97_IRQ,
+            IT8172_DMA_IRQ,
+            IT8172_CDMA_IRQ,
+            IT8172_USB_IRQ,
+            IT8172_BRIDGE_MASTER_IRQ,
+            IT8172_IDE_IRQ,
+            IT8172_MC68K_IRQ
+        };
+
+#ifdef DEBUG
+	printk("board_int_line_fixup bus %d\n", dev->bus->number);
+#endif
+	if (dev->bus->number != 0)
+		return;
+
+	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+
+#ifdef DEBUG
+	pci_read_config_dword(dev, PCI_SUBSYSTEM_VENDOR_ID, &vendor);
+#endif
+
+	slot = PCI_SLOT(dev->devfn);
+        func = PCI_FUNC(dev->devfn);
+
+	switch (slot) {
+                case 0x01:
+                    /*
+                     * Internal device 1 is actually 7 different internal
+                     * devices on the IT8172G (a multi-function device).
+                     */
+                    if (func < 7)
+                        dev->irq = internal_func_irqs[func];
+                    break;
+		case 0x11:
+			switch (pin) {
+				case 0: /* pin A, hardware bug */
+				case 1: /* pin A */
+					dev->irq = IT8172_PCI_INTC_IRQ;
+					break;
+				case 2: /* pin B */
+					dev->irq = IT8172_PCI_INTD_IRQ;
+					break;
+				case 3: /* pin C */
+					dev->irq = IT8172_PCI_INTA_IRQ;
+					break;
+				case 4: /* pin D */
+					dev->irq = IT8172_PCI_INTB_IRQ;
+					break;
+				default:
+					dev->irq = 0xff; 
+					break;
+
+			}
+			break;
+		case 0x13:
+			switch (pin) {
+				case 0: /* pin A, hardware bug */
+				case 1: /* pin A */
+					dev->irq = IT8172_PCI_INTA_IRQ;
+					break;
+				case 2: /* pin B */
+					dev->irq = IT8172_PCI_INTB_IRQ;
+					break;
+				case 3: /* pin C */
+					dev->irq = IT8172_PCI_INTC_IRQ;
+					break;
+				case 4: /* pin D */
+					dev->irq = IT8172_PCI_INTD_IRQ;
+					break;
+				default:
+					dev->irq = 0xff; 
+					break;
+
+			}
+			break;
+		default:
+			return;
+	}
+
+#ifdef DEBUG
+	printk("irq fixup: slot %d, vendor %x, int line %d, int number %d\n",
+			slot, vendor, pin, dev->irq);
+#endif
+	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+
+}
+
+struct pci_fixup pcibios_fixups[] = {
+	{ PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, board_int_line_fixup },
+	{ 0 }
+};
+#endif
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ite-boards/qed-4n-s01b/Makefile linux/arch/mips/ite-boards/qed-4n-s01b/Makefile
--- v2.4.9/linux/arch/mips/ite-boards/qed-4n-s01b/Makefile	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/ite-boards/qed-4n-s01b/Makefile	Sun Sep  9 10:43:01 2001
@@ -1,7 +1,7 @@
 #
 #  Copyright 2000 MontaVista Software Inc.
 #  Author: MontaVista Software, Inc.
-#     	ppopov@mvista.com or support@mvista.com
+#     	ppopov@mvista.com or source@mvista.com
 #
 # Makefile for the ITE 8172 (qed-4n-s01b) board, board
 # specific files.
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ite-boards/qed-4n-s01b/init.c linux/arch/mips/ite-boards/qed-4n-s01b/init.c
--- v2.4.9/linux/arch/mips/ite-boards/qed-4n-s01b/init.c	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/ite-boards/qed-4n-s01b/init.c	Sun Sep  9 10:43:01 2001
@@ -5,7 +5,7 @@
  *
  * Copyright 2000 MontaVista Software Inc.
  * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or support@mvista.com
+ *         	ppopov@mvista.com or source@mvista.com
  *
  *  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
@@ -34,8 +34,10 @@
 #include <linux/bootmem.h>
 #include <asm/addrspace.h>
 #include <asm/bootinfo.h>
+#include <linux/config.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
+#include <linux/sched.h>
 #include <asm/it8172/it8172.h>
 #include <asm/it8172/it8172_dbg.h>
 
@@ -53,7 +55,7 @@
 
 int __init prom_init(int argc, char **argv, char **envp, int *prom_vec)
 {
-	unsigned long mem_size, free_start, free_end, bootmap_size;
+	unsigned long mem_size;
 	unsigned long pcicr;
 
 	prom_argc = argc;
@@ -81,7 +83,7 @@
 	IT_WRITE(IT_MC_PCICR, pcicr);
 
 	it8172_init_ram_resource(mem_size);
-	add_memory_region(0, 20 << 20, BOOT_MEM_RAM);
+	add_memory_region(0, mem_size, BOOT_MEM_RAM);
 
 	return 0;
 }
diff -u --recursive --new-file v2.4.9/linux/arch/mips/ite-boards/qed-4n-s01b/pci_fixup.c linux/arch/mips/ite-boards/qed-4n-s01b/pci_fixup.c
--- v2.4.9/linux/arch/mips/ite-boards/qed-4n-s01b/pci_fixup.c	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/ite-boards/qed-4n-s01b/pci_fixup.c	Sun Sep  9 10:43:01 2001
@@ -5,7 +5,7 @@
  *
  * Copyright 2000 MontaVista Software Inc.
  * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or support@mvista.com
+ *         	ppopov@mvista.com or source@mvista.com
  *
  *  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
diff -u --recursive --new-file v2.4.9/linux/arch/mips/jazz/irq.c linux/arch/mips/jazz/irq.c
--- v2.4.9/linux/arch/mips/jazz/irq.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/jazz/irq.c	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,45 @@
+/*
+ * This file 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 Linus Torvalds
+ * Copyright (C) 1994 - 2001 Ralf Baechle
+ */
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+
+#include <asm/io.h>
+#include <asm/jazz.h>
+
+extern asmlinkage void jazz_handle_int(void);
+
+/*
+ * On systems with i8259-style interrupt controllers we assume for
+ * driver compatibility reasons interrupts 0 - 15 to be the i8295
+ * interrupts even if the hardware uses a different interrupt numbering.
+ */
+void __init init_IRQ (void)
+{
+	int i;
+
+	set_except_vector(0, jazz_handle_int);
+
+	init_generic_irq();
+	init_i8259_irqs();			/* Integrated i8259  */
+#if 0
+	init_jazz_irq();
+
+	/* Actually we've got more interrupts to handle ...  */
+	for (i = PCIMT_IRQ_INT2; i <= PCIMT_IRQ_ETHERNET; i++) {
+		irq_desc[i].status     = IRQ_DISABLED;
+		irq_desc[i].action     = 0;
+		irq_desc[i].depth      = 1;
+		irq_desc[i].handler    = &pciasic_irq_type;
+	}
+#endif
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips/jazz/jazzdma.c linux/arch/mips/jazz/jazzdma.c
--- v2.4.9/linux/arch/mips/jazz/jazzdma.c	Thu Feb 24 22:52:30 2000
+++ linux/arch/mips/jazz/jazzdma.c	Sun Sep  9 10:43:01 2001
@@ -1,6 +1,4 @@
 /*
- * arch/mips/jazz/jazzdma.c
- *
  * Mips Jazz DMA controller support
  * Copyright (C) 1995, 1996 by Andreas Busse
  *
@@ -27,7 +25,7 @@
  */
 #define CONF_DEBUG_VDMA 0
 
-static unsigned long vdma_pagetable_start = 0;
+static unsigned long vdma_pagetable_start;
 
 /*
  * Debug stuff
@@ -44,16 +42,16 @@
  */
 static inline void vdma_pgtbl_init(void)
 {
-    int i;
-    unsigned long paddr = 0;
-    VDMA_PGTBL_ENTRY *pgtbl = (VDMA_PGTBL_ENTRY *)vdma_pagetable_start;
-  
-    for (i=0; i<VDMA_PGTBL_ENTRIES; i++)
-    {
-        pgtbl[i].frame = paddr;
-        pgtbl[i].owner = VDMA_PAGE_EMPTY;
-        paddr += VDMA_PAGESIZE;
-    }
+	int i;
+	unsigned long paddr = 0;
+	VDMA_PGTBL_ENTRY *pgtbl =
+	    (VDMA_PGTBL_ENTRY *) vdma_pagetable_start;
+
+	for (i = 0; i < VDMA_PGTBL_ENTRIES; i++) {
+		pgtbl[i].frame = paddr;
+		pgtbl[i].owner = VDMA_PAGE_EMPTY;
+		paddr += VDMA_PAGESIZE;
+	}
 }
 
 /*
@@ -77,13 +75,12 @@
 	 */
 	vdma_pgtbl_init();
 
-	r4030_write_reg32(JAZZ_R4030_TRSTBL_BASE,PHYSADDR(vdma_pagetable_start));
+	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");
-
-	return KSEG0ADDR(vdma_pagetable_end);
 }
 
 /*
@@ -91,92 +88,90 @@
  */
 unsigned long vdma_alloc(unsigned long paddr, unsigned long size)
 {
-    VDMA_PGTBL_ENTRY *entry = (VDMA_PGTBL_ENTRY *)vdma_pagetable_start;
-    int first;
-    int last;
-    int pages;
-    unsigned int frame;
-    unsigned long laddr;
-    int i;
-    unsigned long flags;
-
-    /* check arguments */
-  
-    if (paddr > 0x1fffffff)
-    {
-        if (vdma_debug)
-            printk("vdma_alloc: Invalid physical address: %08lx\n",paddr);
-        return VDMA_ERROR;	/* invalid physical address */
-    }
-    if (size > 0x400000 || size == 0)
-    {
-        if (vdma_debug)
-            printk("vdma_alloc: Invalid size: %08lx\n",size);
-        return VDMA_ERROR;	/* invalid physical address */
-    }
-  
-    save_and_cli (flags);
-    /*
-     * Find free chunk
-     */
-    pages = (size + 4095) >> 12; /* no. of pages to allocate */
-    first = 0;
-    while (1)
-    {
-        while (entry[first].owner != VDMA_PAGE_EMPTY &&
-               first < VDMA_PGTBL_ENTRIES)
-            first++;
-        if (first+pages > VDMA_PGTBL_ENTRIES) { /* nothing free */
-	    restore_flags (flags);
-            return VDMA_ERROR;
-	}
-
-        last = first+1;
-        while (entry[last].owner == VDMA_PAGE_EMPTY && last-first < pages)
-            last++;
-    
-        if (last-first == pages)
-            break;			/* found */
-    }
-  
-    /*
-     * Mark pages as allocated
-     */
-    laddr = (first << 12) + (paddr & (VDMA_PAGESIZE-1));
-    frame = paddr & ~(VDMA_PAGESIZE-1);
-  
-    for (i=first; i<last; i++)
-    {
-        entry[i].frame = frame;
-        entry[i].owner = laddr;
-        frame += VDMA_PAGESIZE;
-    }
-
-    /*
-     * Update translation table and return logical start address
-     */
-    r4030_write_reg32(JAZZ_R4030_TRSTBL_INV,0);
-
-    if (vdma_debug > 1)
-        printk("vdma_alloc: Allocated %d pages starting from %08lx\n",
-               pages,laddr);
-
-    if (vdma_debug > 2)
-    {
-        printk("LADDR: ");
-        for (i=first; i<last; i++)
-            printk("%08x ",i<<12);
-        printk("\nPADDR: ");
-        for (i=first; i<last; i++)
-            printk("%08x ",entry[i].frame);
-        printk("\nOWNER: ");
-        for (i=first; i<last; i++)
-            printk("%08x ",entry[i].owner);
-        printk("\n");
-    }
-  
-    restore_flags(flags);
-    return laddr;
+	VDMA_PGTBL_ENTRY *entry =
+	    (VDMA_PGTBL_ENTRY *) vdma_pagetable_start;
+	int first;
+	int last;
+	int pages;
+	unsigned int frame;
+	unsigned long laddr;
+	int i;
+	unsigned long flags;
+
+	/* check arguments */
+
+	if (paddr > 0x1fffffff) {
+		if (vdma_debug)
+			printk("vdma_alloc: Invalid physical address: %08lx\n",
+			       paddr);
+		return VDMA_ERROR;	/* invalid physical address */
+	}
+	if (size > 0x400000 || size == 0) {
+		if (vdma_debug)
+			printk("vdma_alloc: Invalid size: %08lx\n", size);
+		return VDMA_ERROR;	/* invalid physical address */
+	}
+
+	save_and_cli(flags);
+	/*
+	 * Find free chunk
+	 */
+	pages = (size + 4095) >> 12;	/* no. of pages to allocate */
+	first = 0;
+	while (1) {
+		while (entry[first].owner != VDMA_PAGE_EMPTY &&
+		       first < VDMA_PGTBL_ENTRIES) first++;
+		if (first + pages > VDMA_PGTBL_ENTRIES) {	/* nothing free */
+			restore_flags(flags);
+			return VDMA_ERROR;
+		}
+
+		last = first + 1;
+		while (entry[last].owner == VDMA_PAGE_EMPTY
+		       && last - first < pages)
+			last++;
+
+		if (last - first == pages)
+			break;	/* found */
+	}
+
+	/*
+	 * Mark pages as allocated
+	 */
+	laddr = (first << 12) + (paddr & (VDMA_PAGESIZE - 1));
+	frame = paddr & ~(VDMA_PAGESIZE - 1);
+
+	for (i = first; i < last; i++) {
+		entry[i].frame = frame;
+		entry[i].owner = laddr;
+		frame += VDMA_PAGESIZE;
+	}
+
+	/*
+	 * Update translation table and return logical start address
+	 */
+	r4030_write_reg32(JAZZ_R4030_TRSTBL_INV, 0);
+
+	if (vdma_debug > 1)
+		printk
+		    ("vdma_alloc: Allocated %d pages starting from %08lx\n",
+		     pages, laddr);
+
+	if (vdma_debug > 2) {
+		printk("LADDR: ");
+		for (i = first; i < last; i++)
+			printk("%08x ", i << 12);
+		printk("\nPADDR: ");
+		for (i = first; i < last; i++)
+			printk("%08x ", entry[i].frame);
+		printk("\nOWNER: ");
+		for (i = first; i < last; i++)
+			printk("%08x ", entry[i].owner);
+		printk("\n");
+	}
+
+	restore_flags(flags);
+	return laddr;
 }
 
 /*
@@ -186,102 +181,103 @@
  */
 int vdma_free(unsigned long laddr)
 {
-    VDMA_PGTBL_ENTRY *pgtbl = (VDMA_PGTBL_ENTRY *)vdma_pagetable_start;
-    int i;
+	VDMA_PGTBL_ENTRY *pgtbl =
+	    (VDMA_PGTBL_ENTRY *) vdma_pagetable_start;
+	int i;
+
+	i = laddr >> 12;
+
+	if (pgtbl[i].owner != laddr) {
+		printk
+		    ("vdma_free: trying to free other's dma pages, laddr=%8lx\n",
+		     laddr);
+		return -1;
+	}
+
+	while (pgtbl[i].owner == laddr && i < VDMA_PGTBL_ENTRIES) {
+		pgtbl[i].owner = VDMA_PAGE_EMPTY;
+		i++;
+	}
 
-    i = laddr >> 12;
+	if (vdma_debug > 1)
+		printk("vdma_free: freed %ld pages starting from %08lx\n",
+		       i - (laddr >> 12), laddr);
 
-    if (pgtbl[i].owner != laddr)
-    {
-        printk("vdma_free: trying to free other's dma pages, laddr=%8lx\n",
-               laddr);
-        return -1;
-    }
-  
-    while (pgtbl[i].owner == laddr && i < VDMA_PGTBL_ENTRIES)
-    {
-        pgtbl[i].owner = VDMA_PAGE_EMPTY;
-        i++;
-    }
-  
-    if (vdma_debug > 1)
-        printk("vdma_free: freed %ld pages starting from %08lx\n",
-               i-(laddr>>12),laddr);
-  
-    return 0;
+	return 0;
 }
 
 /*
  * Map certain page(s) to another physical address.
  * Caller must have allocated the page(s) before.
  */
-int vdma_remap(unsigned long laddr, unsigned long paddr, unsigned long size)
+int vdma_remap(unsigned long laddr, unsigned long paddr,
+	       unsigned long size)
 {
-    VDMA_PGTBL_ENTRY *pgtbl = (VDMA_PGTBL_ENTRY *)vdma_pagetable_start;
-    int first, pages, npages;
+	VDMA_PGTBL_ENTRY *pgtbl =
+	    (VDMA_PGTBL_ENTRY *) vdma_pagetable_start;
+	int first, pages, npages;
+
+	if (laddr > 0xffffff) {
+		if (vdma_debug)
+			printk
+			    ("vdma_map: Invalid logical address: %08lx\n",
+			     laddr);
+		return -EINVAL;	/* invalid logical address */
+	}
+	if (paddr > 0x1fffffff) {
+		if (vdma_debug)
+			printk
+			    ("vdma_map: Invalid physical address: %08lx\n",
+			     paddr);
+		return -EINVAL;	/* invalid physical address */
+	}
+
+	npages = pages =
+	    (((paddr & (VDMA_PAGESIZE - 1)) + size) >> 12) + 1;
+	first = laddr >> 12;
+	if (vdma_debug)
+		printk("vdma_remap: first=%x, pages=%x\n", first, pages);
+	if (first + pages > VDMA_PGTBL_ENTRIES) {
+		if (vdma_debug)
+			printk("vdma_alloc: Invalid size: %08lx\n", size);
+		return -EINVAL;
+	}
+
+	paddr &= ~(VDMA_PAGESIZE - 1);
+	while (pages > 0 && first < VDMA_PGTBL_ENTRIES) {
+		if (pgtbl[first].owner != laddr) {
+			if (vdma_debug)
+				printk("Trying to remap other's pages.\n");
+			return -EPERM;	/* not owner */
+		}
+		pgtbl[first].frame = paddr;
+		paddr += VDMA_PAGESIZE;
+		first++;
+		pages--;
+	}
+
+	/*
+	 * Update translation table
+	 */
+	r4030_write_reg32(JAZZ_R4030_TRSTBL_INV, 0);
+
+	if (vdma_debug > 2) {
+		int i;
+		pages = (((paddr & (VDMA_PAGESIZE - 1)) + size) >> 12) + 1;
+		first = laddr >> 12;
+		printk("LADDR: ");
+		for (i = first; i < first + pages; i++)
+			printk("%08x ", i << 12);
+		printk("\nPADDR: ");
+		for (i = first; i < first + pages; i++)
+			printk("%08x ", pgtbl[i].frame);
+		printk("\nOWNER: ");
+		for (i = first; i < first + pages; i++)
+			printk("%08x ", pgtbl[i].owner);
+		printk("\n");
+	}
 
-    if (laddr > 0xffffff)
-    {
-        if (vdma_debug)
-            printk("vdma_map: Invalid logical address: %08lx\n",laddr);
-        return -EINVAL;		/* invalid logical address */
-    }
-    if (paddr > 0x1fffffff)
-    {
-        if (vdma_debug)
-            printk("vdma_map: Invalid physical address: %08lx\n",paddr);
-        return -EINVAL;		/* invalid physical address */
-    }
-  
-    npages = pages = (((paddr & (VDMA_PAGESIZE-1)) + size) >> 12) + 1;
-    first = laddr >> 12;
-    if (vdma_debug)
-        printk("vdma_remap: first=%x, pages=%x\n",first,pages);
-    if (first+pages > VDMA_PGTBL_ENTRIES)
-    {
-        if (vdma_debug)
-            printk("vdma_alloc: Invalid size: %08lx\n",size);
-        return -EINVAL;
-    }
-
-    paddr &= ~(VDMA_PAGESIZE-1);
-    while (pages > 0 && first < VDMA_PGTBL_ENTRIES)
-    {
-        if (pgtbl[first].owner != laddr)
-        {
-            if (vdma_debug)
-                printk("Trying to remap other's pages.\n");
-            return -EPERM;		/* not owner */
-        }
-        pgtbl[first].frame = paddr;
-        paddr += VDMA_PAGESIZE;
-        first++;
-        pages--;
-    }
-
-    /*
-     * Update translation table
-     */
-    r4030_write_reg32(JAZZ_R4030_TRSTBL_INV,0);
-  
-    if (vdma_debug > 2)
-    {
-        int i;
-        pages = (((paddr & (VDMA_PAGESIZE-1)) + size) >> 12) + 1;
-        first = laddr >> 12;
-        printk("LADDR: ");
-        for (i=first; i<first+pages; i++)
-            printk("%08x ",i<<12);
-        printk("\nPADDR: ");
-        for (i=first; i<first+pages; i++)
-            printk("%08x ",pgtbl[i].frame);
-        printk("\nOWNER: ");
-        for (i=first; i<first+pages; i++)
-            printk("%08x ",pgtbl[i].owner);
-        printk("\n");
-    }
-      
-    return 0;
+	return 0;
 }
 
 /*
@@ -291,22 +287,22 @@
  */
 unsigned long vdma_phys2log(unsigned long paddr)
 {
-    int i;
-    int frame;
-    VDMA_PGTBL_ENTRY *pgtbl = (VDMA_PGTBL_ENTRY *)vdma_pagetable_start;
-
-    frame = paddr & ~(VDMA_PAGESIZE-1);
-
-    for (i=0; i<VDMA_PGTBL_ENTRIES; i++)
-    {
-        if (pgtbl[i].frame == frame)
-            break;
-    }
+	int i;
+	int frame;
+	VDMA_PGTBL_ENTRY *pgtbl =
+	    (VDMA_PGTBL_ENTRY *) vdma_pagetable_start;
+
+	frame = paddr & ~(VDMA_PAGESIZE - 1);
+
+	for (i = 0; i < VDMA_PGTBL_ENTRIES; i++) {
+		if (pgtbl[i].frame == frame)
+			break;
+	}
 
-    if (i == VDMA_PGTBL_ENTRIES)
-        return ~0UL;
+	if (i == VDMA_PGTBL_ENTRIES)
+		return ~0UL;
 
-    return (i<<12) + (paddr & (VDMA_PAGESIZE-1));
+	return (i << 12) + (paddr & (VDMA_PAGESIZE - 1));
 }
 
 /*
@@ -314,44 +310,47 @@
  */
 unsigned long vdma_log2phys(unsigned long laddr)
 {
-    VDMA_PGTBL_ENTRY *pgtbl = (VDMA_PGTBL_ENTRY *)vdma_pagetable_start;
+	VDMA_PGTBL_ENTRY *pgtbl =
+	    (VDMA_PGTBL_ENTRY *) vdma_pagetable_start;
 
-    return pgtbl[laddr >> 12].frame + (laddr & (VDMA_PAGESIZE-1));
+	return pgtbl[laddr >> 12].frame + (laddr & (VDMA_PAGESIZE - 1));
 }
-  
+
 /*
  * Print DMA statistics
  */
 void vdma_stats(void)
 {
-    int i;
-  
-    printk("vdma_stats: CONFIG: %08x\n",
-           r4030_read_reg32(JAZZ_R4030_CONFIG));
-    printk("R4030 translation table base: %08x\n",
-           r4030_read_reg32(JAZZ_R4030_TRSTBL_BASE));
-    printk("R4030 translation table limit: %08x\n",
-           r4030_read_reg32(JAZZ_R4030_TRSTBL_LIM));
-    printk("vdma_stats: INV_ADDR: %08x\n",
-           r4030_read_reg32(JAZZ_R4030_INV_ADDR));
-    printk("vdma_stats: R_FAIL_ADDR: %08x\n",
-           r4030_read_reg32(JAZZ_R4030_R_FAIL_ADDR));
-    printk("vdma_stats: M_FAIL_ADDR: %08x\n",
-           r4030_read_reg32(JAZZ_R4030_M_FAIL_ADDR));
-    printk("vdma_stats: IRQ_SOURCE: %08x\n",
-           r4030_read_reg32(JAZZ_R4030_IRQ_SOURCE));
-    printk("vdma_stats: I386_ERROR: %08x\n",
-           r4030_read_reg32(JAZZ_R4030_I386_ERROR));
-    printk("vdma_chnl_modes:   ");
-    for (i=0; i<8; i++)
-        printk("%04x ",
-               (unsigned)r4030_read_reg32(JAZZ_R4030_CHNL_MODE+(i<<5)));
-    printk("\n");
-    printk("vdma_chnl_enables: ");
-    for (i=0; i<8; i++)
-        printk("%04x ",
-               (unsigned)r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE+(i<<5)));
-    printk("\n");
+	int i;
+
+	printk("vdma_stats: CONFIG: %08x\n",
+	       r4030_read_reg32(JAZZ_R4030_CONFIG));
+	printk("R4030 translation table base: %08x\n",
+	       r4030_read_reg32(JAZZ_R4030_TRSTBL_BASE));
+	printk("R4030 translation table limit: %08x\n",
+	       r4030_read_reg32(JAZZ_R4030_TRSTBL_LIM));
+	printk("vdma_stats: INV_ADDR: %08x\n",
+	       r4030_read_reg32(JAZZ_R4030_INV_ADDR));
+	printk("vdma_stats: R_FAIL_ADDR: %08x\n",
+	       r4030_read_reg32(JAZZ_R4030_R_FAIL_ADDR));
+	printk("vdma_stats: M_FAIL_ADDR: %08x\n",
+	       r4030_read_reg32(JAZZ_R4030_M_FAIL_ADDR));
+	printk("vdma_stats: IRQ_SOURCE: %08x\n",
+	       r4030_read_reg32(JAZZ_R4030_IRQ_SOURCE));
+	printk("vdma_stats: I386_ERROR: %08x\n",
+	       r4030_read_reg32(JAZZ_R4030_I386_ERROR));
+	printk("vdma_chnl_modes:   ");
+	for (i = 0; i < 8; i++)
+		printk("%04x ",
+		       (unsigned) r4030_read_reg32(JAZZ_R4030_CHNL_MODE +
+						   (i << 5)));
+	printk("\n");
+	printk("vdma_chnl_enables: ");
+	for (i = 0; i < 8; i++)
+		printk("%04x ",
+		       (unsigned) r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE +
+						   (i << 5)));
+	printk("\n");
 }
 
 /*
@@ -363,33 +362,35 @@
  */
 void vdma_enable(int channel)
 {
-    int status;
-  
-    if (vdma_debug)
-        printk("vdma_enable: channel %d\n",channel);
-  
-    /*
-     * Check error conditions first
-     */
-    status = r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE+(channel<<5));
-    if (status & 0x400)
-        printk("VDMA: Channel %d: Address error!\n",channel);
-    if (status & 0x200)
-        printk("VDMA: Channel %d: Memory error!\n",channel);
-
-    /*
-     * Clear all interrupt flags
-     */
-    r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE+(channel<<5),
-		      r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE+(channel<<5)) |
-                      R4030_TC_INTR | R4030_MEM_INTR | R4030_ADDR_INTR);
-
-    /*
-     * Enable the desired channel
-     */
-    r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE+(channel<<5),
-                      r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE+(channel<<5)) |
-                      R4030_CHNL_ENABLE);
+	int status;
+
+	if (vdma_debug)
+		printk("vdma_enable: channel %d\n", channel);
+
+	/*
+	 * Check error conditions first
+	 */
+	status = r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5));
+	if (status & 0x400)
+		printk("VDMA: Channel %d: Address error!\n", channel);
+	if (status & 0x200)
+		printk("VDMA: Channel %d: Memory error!\n", channel);
+
+	/*
+	 * Clear all interrupt flags
+	 */
+	r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5),
+			  r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE +
+					   (channel << 5)) | R4030_TC_INTR
+			  | R4030_MEM_INTR | R4030_ADDR_INTR);
+
+	/*
+	 * Enable the desired channel
+	 */
+	r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5),
+			  r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE +
+					   (channel << 5)) |
+			  R4030_CHNL_ENABLE);
 }
 
 /*
@@ -397,28 +398,34 @@
  */
 void vdma_disable(int channel)
 {
-    if (vdma_debug)
-    {
-        int status = r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE+(channel<<5));
-
-        printk("vdma_disable: channel %d\n",channel);
-        printk("VDMA: channel %d status: %04x (%s) mode: "
-               "%02x addr: %06x count: %06x\n",
-               channel,status,((status & 0x600) ? "ERROR" : "OK"),
-               (unsigned)r4030_read_reg32(JAZZ_R4030_CHNL_MODE+(channel<<5)),
-               (unsigned)r4030_read_reg32(JAZZ_R4030_CHNL_ADDR+(channel<<5)),
-               (unsigned)r4030_read_reg32(JAZZ_R4030_CHNL_COUNT+(channel<<5)));
-    }
-  
-    r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE+(channel<<5),
-                      r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE+(channel<<5)) &
-                      ~R4030_CHNL_ENABLE);
-
-    /*
-     * After disabling a DMA channel a remote bus register should be
-     * read to ensure that the current DMA acknowledge cycle is completed.
-     */
-    *((volatile unsigned int *)JAZZ_DUMMY_DEVICE);
+	if (vdma_debug) {
+		int status =
+		    r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE +
+				     (channel << 5));
+
+		printk("vdma_disable: channel %d\n", channel);
+		printk("VDMA: channel %d status: %04x (%s) mode: "
+		       "%02x addr: %06x count: %06x\n",
+		       channel, status,
+		       ((status & 0x600) ? "ERROR" : "OK"),
+		       (unsigned) r4030_read_reg32(JAZZ_R4030_CHNL_MODE +
+						   (channel << 5)),
+		       (unsigned) r4030_read_reg32(JAZZ_R4030_CHNL_ADDR +
+						   (channel << 5)),
+		       (unsigned) r4030_read_reg32(JAZZ_R4030_CHNL_COUNT +
+						   (channel << 5)));
+	}
+
+	r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5),
+			  r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE +
+					   (channel << 5)) &
+			  ~R4030_CHNL_ENABLE);
+
+	/*
+	 * After disabling a DMA channel a remote bus register should be
+	 * read to ensure that the current DMA acknowledge cycle is completed.
+	 */
+	*((volatile unsigned int *) JAZZ_DUMMY_DEVICE);
 }
 
 /*
@@ -432,56 +439,60 @@
  */
 void vdma_set_mode(int channel, int mode)
 {
-    if (vdma_debug)
-        printk("vdma_set_mode: channel %d, mode 0x%x\n", channel, mode);
-
-    switch(channel)
-    {
-    case JAZZ_SCSI_DMA:			/* scsi */
-        r4030_write_reg32(JAZZ_R4030_CHNL_MODE+(channel<<5),
+	if (vdma_debug)
+		printk("vdma_set_mode: channel %d, mode 0x%x\n", channel,
+		       mode);
+
+	switch (channel) {
+	case JAZZ_SCSI_DMA:	/* scsi */
+		r4030_write_reg32(JAZZ_R4030_CHNL_MODE + (channel << 5),
 /*			  R4030_MODE_FAST | */
 /*			  R4030_MODE_BURST | */
-                          R4030_MODE_INTR_EN |
-                          R4030_MODE_WIDTH_16 |
-                          R4030_MODE_ATIME_80);
-        break;
-      
-    case JAZZ_FLOPPY_DMA:	/* floppy */
-        r4030_write_reg32(JAZZ_R4030_CHNL_MODE+(channel<<5),
+				  R4030_MODE_INTR_EN |
+				  R4030_MODE_WIDTH_16 |
+				  R4030_MODE_ATIME_80);
+		break;
+
+	case JAZZ_FLOPPY_DMA:	/* floppy */
+		r4030_write_reg32(JAZZ_R4030_CHNL_MODE + (channel << 5),
 /*			  R4030_MODE_FAST | */
 /*			  R4030_MODE_BURST | */
-                          R4030_MODE_INTR_EN |
-                          R4030_MODE_WIDTH_8 |
-                          R4030_MODE_ATIME_120);
-        break;
-
-    case JAZZ_AUDIOL_DMA:
-    case JAZZ_AUDIOR_DMA:
-        printk("VDMA: Audio DMA not supported yet.\n");
-        break;
-      
-    default:
-        printk("VDMA: vdma_set_mode() called with unsupported channel %d!\n",
-               channel);
-    }
-  
-    switch(mode)
-    {
-    case DMA_MODE_READ:
-        r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE+(channel<<5),
-                          r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE+(channel<<5)) &
-                          ~R4030_CHNL_WRITE);
-        break;
-      
-    case DMA_MODE_WRITE:
-        r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE+(channel<<5),
-                          r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE+(channel<<5)) |
-                          R4030_CHNL_WRITE);
-      break;
-      
-    default:
-        printk("VDMA: vdma_set_mode() called with unknown dma mode 0x%x\n",mode);
-    }
+				  R4030_MODE_INTR_EN |
+				  R4030_MODE_WIDTH_8 |
+				  R4030_MODE_ATIME_120);
+		break;
+
+	case JAZZ_AUDIOL_DMA:
+	case JAZZ_AUDIOR_DMA:
+		printk("VDMA: Audio DMA not supported yet.\n");
+		break;
+
+	default:
+		printk
+		    ("VDMA: vdma_set_mode() called with unsupported channel %d!\n",
+		     channel);
+	}
+
+	switch (mode) {
+	case DMA_MODE_READ:
+		r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5),
+				  r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE +
+						   (channel << 5)) &
+				  ~R4030_CHNL_WRITE);
+		break;
+
+	case DMA_MODE_WRITE:
+		r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5),
+				  r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE +
+						   (channel << 5)) |
+				  R4030_CHNL_WRITE);
+		break;
+
+	default:
+		printk
+		    ("VDMA: vdma_set_mode() called with unknown dma mode 0x%x\n",
+		     mode);
+	}
 }
 
 /*
@@ -489,10 +500,11 @@
  */
 void vdma_set_addr(int channel, long addr)
 {
-    if (vdma_debug)
-        printk("vdma_set_addr: channel %d, addr %lx\n",channel,addr);
+	if (vdma_debug)
+		printk("vdma_set_addr: channel %d, addr %lx\n", channel,
+		       addr);
 
-    r4030_write_reg32(JAZZ_R4030_CHNL_ADDR+(channel<<5),addr);
+	r4030_write_reg32(JAZZ_R4030_CHNL_ADDR + (channel << 5), addr);
 }
 
 /*
@@ -500,25 +512,28 @@
  */
 void vdma_set_count(int channel, int count)
 {
-    if (vdma_debug)
-        printk("vdma_set_count: channel %d, count %08x\n",channel,(unsigned)count);
-  
-    r4030_write_reg32(JAZZ_R4030_CHNL_COUNT+(channel<<5),count);
+	if (vdma_debug)
+		printk("vdma_set_count: channel %d, count %08x\n", channel,
+		       (unsigned) count);
+
+	r4030_write_reg32(JAZZ_R4030_CHNL_COUNT + (channel << 5), count);
 }
-     
+
 /*
  * Get Residual
  */
 int vdma_get_residue(int channel)
 {
-    int residual;
-  
-    residual = r4030_read_reg32(JAZZ_R4030_CHNL_COUNT+(channel<<5));
-
-    if (vdma_debug)
-        printk("vdma_get_residual: channel %d: residual=%d\n",channel,residual);
-  
-    return residual;
+	int residual;
+
+	residual =
+	    r4030_read_reg32(JAZZ_R4030_CHNL_COUNT + (channel << 5));
+
+	if (vdma_debug)
+		printk("vdma_get_residual: channel %d: residual=%d\n",
+		       channel, residual);
+
+	return residual;
 }
 
 /*
@@ -526,12 +541,13 @@
  */
 int vdma_get_enable(int channel)
 {
-    int enable;
-    
-    enable = r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE+(channel<<5));
-    
-    if (vdma_debug)
-	printk("vdma_get_enable: channel %d: enable=%d\n",channel,enable);
-    
-    return enable;
+	int enable;
+
+	enable = r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5));
+
+	if (vdma_debug)
+		printk("vdma_get_enable: channel %d: enable=%d\n", channel,
+		       enable);
+
+	return enable;
 }
diff -u --recursive --new-file v2.4.9/linux/arch/mips/jazz/rtc-jazz.c linux/arch/mips/jazz/rtc-jazz.c
--- v2.4.9/linux/arch/mips/jazz/rtc-jazz.c	Sat May 13 08:29:14 2000
+++ linux/arch/mips/jazz/rtc-jazz.c	Sun Sep  9 10:43:01 2001
@@ -1,12 +1,11 @@
-/* $Id: rtc-jazz.c,v 1.2 1998/06/25 20:19: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.
  *
  * RTC routines for Jazz style attached Dallas chip.
  *
- * Copyright (C) 1998 by Ralf Baechle
+ * Copyright (C) 1998, 2001 by Ralf Baechle
  */
 #include <linux/mc146818rtc.h>
 #include <asm/io.h>
diff -u --recursive --new-file v2.4.9/linux/arch/mips/jazz/setup.c linux/arch/mips/jazz/setup.c
--- v2.4.9/linux/arch/mips/jazz/setup.c	Sat May 13 08:29:14 2000
+++ linux/arch/mips/jazz/setup.c	Sun Sep  9 10:43:01 2001
@@ -1,12 +1,12 @@
-/* $Id: setup.c,v 1.24 1999/10/09 00:00:58 ralf Exp $
- *
+/*
  * Setup pointers to hardware-dependent routines.
  *
  * This file 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, 2001 by Ralf Baechle
+ * Copyright (C) 2001 MIPS Technologies, Inc.
  */
 #include <linux/config.h>
 #include <linux/hdreg.h>
@@ -72,7 +72,7 @@
 			  JAZZ_IE_FLOPPY);
 	r4030_read_reg16(JAZZ_IO_IRQ_SOURCE); /* clear pending IRQs */
 	r4030_read_reg32(JAZZ_R4030_INVAL_ADDR); /* clear error bits */
-	set_cp0_status(ST0_IM, IE_IRQ4 | IE_IRQ3 | IE_IRQ2 | IE_IRQ1);
+	change_cp0_status(ST0_IM, IE_IRQ4 | IE_IRQ3 | IE_IRQ2 | IE_IRQ1);
 	/* set the clock to 100 Hz */
 	r4030_write_reg32(JAZZ_TIMER_INTERVAL, 9);
 	request_region(0x20, 0x20, "pic1");
@@ -80,11 +80,6 @@
 	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);
@@ -93,6 +88,8 @@
 
 	irq_setup = jazz_irq_setup;
 	mips_io_port_base = JAZZ_PORT_BASE;
+	if (mips_machtype == MACH_MIPS_MAGNUM_4000)
+		EISA_bus = 1;
 	isa_slot_offset = 0xe3000000;
 	request_region(0x00,0x20,"dma1");
 	request_region(0x40,0x20,"timer");
diff -u --recursive --new-file v2.4.9/linux/arch/mips/kernel/Makefile linux/arch/mips/kernel/Makefile
--- v2.4.9/linux/arch/mips/kernel/Makefile	Tue Jul  3 17:08:18 2001
+++ linux/arch/mips/kernel/Makefile	Sun Sep  9 10:43:01 2001
@@ -35,15 +35,12 @@
 endif
 
 obj-$(CONFIG_SMP)		+= smp.o
-obj-$(CONFIG_MIPS_FPE_MODULE)	+= fpe.o
-ifndef CONFIG_MIPS_FPU_EMULATOR
-  obj-y				+= softfp.o
-endif
 
 # Old style irq support, going to die in 2.5.
 export-objs			+= old-irq.o
 obj-$(CONFIG_NEW_IRQ)		+= irq.o
 obj-$(CONFIG_ROTTEN_IRQ)	+= old-irq.o
+obj-$(CONFIG_I8259)		+= i8259.o
 
 # transition from old time.c to new time.c
 # some boards uses old-time.c, some use time.c, and some use their own ones
@@ -56,6 +53,11 @@
 obj-$(CONFIG_REMOTE_DEBUG)	+= gdb-low.o gdb-stub.o 
 obj-$(CONFIG_PCI)		+= pci-dma.o
 obj-$(CONFIG_PROC_FS)		+= proc.o
+
+ifdef CONFIG_PCI
+obj-$(CONFIG_NEW_PCI)          += pci.o
+obj-$(CONFIG_PCI_AUTO)         += pci_auto.o
+endif
 
 entry.o: entry.S
 head.o: head.S
diff -u --recursive --new-file v2.4.9/linux/arch/mips/kernel/branch.c linux/arch/mips/kernel/branch.c
--- v2.4.9/linux/arch/mips/kernel/branch.c	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/kernel/branch.c	Sun Sep  9 10:43:01 2001
@@ -5,9 +5,9 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996, 97, 2000 by Ralf Baechle
+ * Copyright (C) 1996, 97, 2000, 2001 by Ralf Baechle
+ * Copyright (C) 2001 MIPS Technologies, Inc.
  */
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/signal.h>
@@ -29,11 +29,8 @@
 	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;
-	}
+	if (epc & 3)
+		goto unaligned;
 
 	/*
 	 * Read the instruction
@@ -167,12 +164,10 @@
 	 * And now the FPA/cp1 branch instructions.
 	 */
 	case cop1_op:
-#ifdef CONFIG_MIPS_FPU_EMULATOR
 		if(!(mips_cpu.options & MIPS_CPU_FPU))
 			fcr31 = current->thread.fpu.soft.sr;
 		else
-#endif
-		asm ("cfc1\t%0,$31":"=r" (fcr31));
+			asm ("cfc1\t%0,$31":"=r" (fcr31));
 		bit = (insn.i_format.rt >> 2);
 		bit += (bit != 0);
 		bit += 23;
@@ -199,4 +194,9 @@
 	}
 
 	return 0;
+
+unaligned:
+	printk("%s: unaligned epc - sending SIGBUS.\n", current->comm);
+	force_sig(SIGBUS, current);
+	return -EFAULT;
 }
diff -u --recursive --new-file v2.4.9/linux/arch/mips/kernel/entry.S linux/arch/mips/kernel/entry.S
--- v2.4.9/linux/arch/mips/kernel/entry.S	Tue Jul  3 17:08:18 2001
+++ linux/arch/mips/kernel/entry.S	Sun Sep  9 10:43:01 2001
@@ -1,13 +1,12 @@
-/* $Id: entry.S,v 1.19 1999/12/08 22:05:10 harald 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 - 2000 by Ralf Baechle
+ * Copyright (C) 1994 - 2000, 2001 by Ralf Baechle
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2001 MIPS Technologies, Inc.
  */
 #include <linux/config.h>
 #include <linux/sys.h>
@@ -26,50 +25,64 @@
 #include <asm/unistd.h>
 #include <asm/isadep.h>
 
+/* This duplicates the definition from <linux/sched.h> */
+#define PT_TRACESYS	0x00000002		/* tracing system calls */
+
+
 		.text
 		.align 4
 		.set	push
 		.set	reorder
 EXPORT(ret_from_fork)
-		 move	a0, v0			# prev
+		move	a0, v0			# prev
 		jal	schedule_tail
+		lw	t0, TASK_PTRACE($28)	# syscall tracing enabled?
+		andi	t0, PT_TRACESYS
+		bnez	t0, tracesys_exit
 		j	ret_from_sys_call
 
-EXPORT(handle_softirq)
-		jal	do_softirq
-		b	9f
+tracesys_exit:	jal	syscall_trace
+		b	ret_from_sys_call
+
+EXPORT(ret_from_irq)
+EXPORT(ret_from_exception)
+		lw	t0, PT_STATUS(sp)	# returning to kernel mode?
+		andi	t0, t0, KU_USER
+		bnez	t0, ret_from_sys_call
+		j	restore_all
 
 reschedule:	jal	schedule 
 
 EXPORT(ret_from_sys_call)
-EXPORT(ret_from_irq)
 		.type	ret_from_irq,@function
-		la	t1, irq_stat		# softirq_active
-#ifdef CONFIG_SMP
-		lw	t0, TASK_PROCESSOR($28)
-		sll	t0, t0, 5
-		addu	t1, t0
-#endif
-		lw	t0, 0(t1)		# softirq_active
-		lw	t1, 4(t1)		# softirq_mask.  unused delay slot
-		and	t0, t1
-		bnez	t0, handle_softirq
-
-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
-		bnez	t2, reschedule
-		lw	v0, TASK_SIGPENDING($28)
-		 move	a0, zero
-		beqz	v0, return
-		 move	a1, sp
-		jal	do_signal
 
-EXPORT(return)	.set	noat
+		mfc0	t0, CP0_STATUS	# need_resched and signals atomic test
+		ori	t0, t0, 1
+		xori	t0, t0, 1
+		mtc0	t0, CP0_STATUS
+		nop; nop; nop
+
+		lw	v0, TASK_NEED_RESCHED($28)
+		lw	v1, TASK_SIGPENDING($28)
+		bnez	v0, reschedule
+		bnez	v1, signal_return
+restore_all:	.set	noat
 		RESTORE_ALL_AND_RET
 		.set	at
 
+/* Put this behind restore_all for the sake of the branch prediction.  */
+signal_return:
+		.type	signal_return, @function
+
+		mfc0	t0, CP0_STATUS
+		ori	t0, t0, 1
+		mtc0	t0, CP0_STATUS
+
+		move	a0, zero
+		move	a1, sp
+		jal	do_signal
+		b	restore_all
+
 /*
  * Common spurious interrupt handler.
  */
@@ -85,8 +98,8 @@
 		lw      t0,%lo(spurious_count)(t1)
 		.set	noreorder
 		addiu   t0,1
+		sw      t0,%lo(spurious_count)(t1)
 		j	ret_from_irq
-		 sw      t0,%lo(spurious_count)(t1)
 		END(spurious_interrupt)
 
 /*
@@ -106,7 +119,7 @@
 		ctc1	a2,fcr31;                                       \
 		STI
 #define __BUILD_clear_ade(exception)                                    \
-		.set	reorder;						\
+		.set	reorder;					\
 		MFC0	t0,CP0_BADVADDR;                                \
 		.set	noreorder;					\
 		REG_S	t0,PT_BVADDR(sp);                               \
@@ -139,8 +152,8 @@
 		.set	at;                                             \
 		__BUILD_##verbose(exception);                           \
 		jal	do_##handler;                                   \
-		 move	a0,sp;                                          \
-		j	ret_from_sys_call;                              \
+		 move	a0, sp;                                         \
+		j	ret_from_exception;                             \
 		 nop;                                                   \
 		END(handle_##exception)
 
diff -u --recursive --new-file v2.4.9/linux/arch/mips/kernel/fpe.c linux/arch/mips/kernel/fpe.c
--- v2.4.9/linux/arch/mips/kernel/fpe.c	Sun Jul  9 22:18:15 2000
+++ linux/arch/mips/kernel/fpe.c	Wed Dec 31 16:00:00 1969
@@ -1,51 +0,0 @@
-/*
- * The real floating point exception handler.  While it doesn't really
- * make sense to have this in a module, it makes debugging of this code
- * in the kernel space a lot easier.  So far this handler in the released
- * kernel source is just a dummy.
- *
- * Copyright (C) 1997, 2000 Ralf Baechle
- */
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/signal.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-
-#include <asm/branch.h>
-#include <asm/ptrace.h>
-
-MODULE_AUTHOR("Ralf Baechle <ralf@gnu.org>");
-MODULE_DESCRIPTION("Experimental floating point exception handler");
-MODULE_SUPPORTED_DEVICE("MIPS FPU");
-
-static void do_fpe(struct pt_regs *regs, unsigned int fcr31)
-{
-#ifdef CONF_DEBUG_EXCEPTIONS
-	show_regs(regs);
-#endif
-	printk("Caught floating exception at epc == %08lx, fcr31 == %08x\n",
-	       regs->cp0_epc, fcr31);
-	if (compute_return_epc(regs))
-		goto out;
-	force_sig(SIGFPE, current);
-out:
-}
-
-/*
- * For easier experimentation we never increment/decrement
- * the module usable counter.
- */
-int register_fpe(void (*handler)(struct pt_regs *regs, unsigned int fcr31));
-int unregister_fpe(void (*handler)(struct pt_regs *regs, unsigned int fcr31));
-
-int init_module(void)
-{
-	return register_fpe(do_fpe);
-}
-
-void cleanup_module(void)
-{
-	unregister_fpe(do_fpe);
-}
diff -u --recursive --new-file v2.4.9/linux/arch/mips/kernel/gdb-low.S linux/arch/mips/kernel/gdb-low.S
--- v2.4.9/linux/arch/mips/kernel/gdb-low.S	Sat May 13 08:29:14 2000
+++ linux/arch/mips/kernel/gdb-low.S	Sun Sep  9 10:43:01 2001
@@ -1,16 +1,13 @@
 /*
- * arch/mips/kernel/gdb-low.S
- *
  * gdb-low.S contains the low-level trap handler for the GDB stub.
  *
  * Copyright (C) 1995 Andreas Busse
- *
- * $Id: gdb-low.S,v 1.4 1997/12/01 17:57:26 ralf Exp $
  */
-
+#include <linux/config.h>
 #include <linux/sys.h>
 
 #include <asm/asm.h>
+#include <asm/errno.h>
 #include <asm/mipsregs.h>
 #include <asm/regdef.h>
 #include <asm/stackframe.h>
@@ -30,10 +27,15 @@
 		move	k1,sp
 
 		/*
-		 * Called from user mode, new stack
+		 * Called from user mode, go somewhere else.
 		 */
-		lui	k1,%hi(kernelsp)
-		lw	k1,%lo(kernelsp)(k1)
+		lui	k1,%hi(saved_vectors)
+		mfc0	k0,CP0_CAUSE
+		andi	k0,k0,0x7c
+		add	k1,k1,k0
+		lw	k0,%lo(saved_vectors)(k1)
+		jr	k0
+		nop
 1:
 		move	k0,sp
 		subu	sp,k1,GDB_FR_SIZE
@@ -302,11 +304,51 @@
 		lw	v1,GDB_FR_REG3(sp)
 		lw	v0,GDB_FR_REG2(sp)
 		lw	$1,GDB_FR_REG1(sp)
-		lw	sp,GDB_FR_REG29(sp)		/* Deallocate stack */
+#ifdef CONFIG_CPU_R3000
+		lw	k0, GDB_FR_EPC(sp)
+		lw	sp, GDB_FR_REG29(sp)		/* Deallocate stack */
+		jr	k0
+		rfe
+#else
+		lw	sp, GDB_FR_REG29(sp)		/* Deallocate stack */
 
 		.set	mips3
 		eret
 		.set	mips0
+#endif
 		.set	at
 		.set	reorder
 		END(trap_low)
+
+LEAF(kgdb_read_byte)
+		.set push
+		.set noreorder
+		.set nomacro
+4:		lb	t0, (a0)
+		.set pop
+		sb	t0, (a1)
+		li	v0, 0
+		jr	ra
+		.section __ex_table,"a"
+		PTR	4b, kgdbfault
+		.previous
+		END(kgdb_read_byte)
+
+LEAF(kgdb_write_byte)
+		.set push
+		.set noreorder
+		.set nomacro
+5:		sb	a0, (a1)
+		.set pop
+		li	v0, 0
+		jr	ra
+		.section __ex_table,"a"
+		PTR	5b, kgdbfault
+		.previous
+		END(kgdb_write_byte)
+
+		.type	kgdbfault@function
+		.ent	kgdbfault
+kgdbfault:	li	v0, -EFAULT
+		jr	ra
+		.end	kgdbfault
diff -u --recursive --new-file v2.4.9/linux/arch/mips/kernel/gdb-stub.c linux/arch/mips/kernel/gdb-stub.c
--- v2.4.9/linux/arch/mips/kernel/gdb-stub.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/mips/kernel/gdb-stub.c	Sun Sep  9 10:43:01 2001
@@ -142,7 +142,6 @@
 
 extern int putDebugChar(char c);    /* write a single character      */
 extern char getDebugChar(void);     /* read and return a single char */
-extern void fltr_set_mem_err(void);
 extern void trap_low(void);
 
 /*
@@ -175,6 +174,10 @@
 static int initialized;	/* !0 means we've been initialized */
 static const char hexchars[]="0123456789abcdef";
 
+/* Used to prevent crashes in memory access.  Note that they'll crash anyway if
+   we haven't set up fault handlers yet... */
+int kgdb_read_byte(unsigned *address, unsigned *dest);
+int kgdb_write_byte(unsigned val, unsigned *dest);
 
 /*
  * Convert ch from a hex digit to an int
@@ -294,42 +297,18 @@
 
 
 /*
- * Indicate to caller of mem2hex or hex2mem that there
- * has been an error.
- */
-static volatile int mem_err = 0;
-
-
-#if 0
-static void set_mem_fault_trap(int enable)
-{
-  mem_err = 0;
-
-#if 0
-  if (enable)
-    exceptionHandler(9, fltr_set_mem_err);
-  else
-    exceptionHandler(9, trap_low);
-#endif  
-}
-#endif /* dead code */
-
-/*
  * Convert the memory pointed to by mem into hex, placing result in buf.
  * Return a pointer to the last char put in buf (null), in case of mem fault,
  * return 0.
- * If MAY_FAULT is non-zero, then we will handle memory faults by returning
- * a 0, else treat a fault like any other fault in the stub.
+ * may_fault is non-zero if we are reading from arbitrary memory, but is currently
+ * not used.
  */
 static unsigned char *mem2hex(char *mem, char *buf, int count, int may_fault)
 {
 	unsigned char ch;
 
-/*	set_mem_fault_trap(may_fault); */
-
 	while (count-- > 0) {
-		ch = *(mem++);
-		if (mem_err)
+		if (kgdb_read_byte(mem++, &ch) != 0)
 			return 0;
 		*buf++ = hexchars[ch >> 4];
 		*buf++ = hexchars[ch & 0xf];
@@ -337,33 +316,28 @@
 
 	*buf = 0;
 
-/*	set_mem_fault_trap(0); */
-
 	return buf;
 }
 
 /*
  * convert the hex array pointed to by buf into binary to be placed in mem
  * return a pointer to the character AFTER the last byte written
+ * may_fault is non-zero if we are reading from arbitrary memory, but is currently
+ * not used.
  */
 static char *hex2mem(char *buf, char *mem, int count, int may_fault)
 {
 	int i;
 	unsigned char ch;
 
-/*	set_mem_fault_trap(may_fault); */
-
 	for (i=0; i<count; i++)
 	{
 		ch = hex(*buf++) << 4;
 		ch |= hex(*buf++);
-		*(mem++) = ch;
-		if (mem_err)
+		if (kgdb_write_byte(ch, mem++) != 0)
 			return 0;
 	}
 
-/*	set_mem_fault_trap(0); */
-
 	return mem;
 }
 
@@ -390,6 +364,8 @@
 	{ 0, 0}				/* Must be last */
 };
 
+/* Save the normal trap handlers for user-mode traps. */
+void *saved_vectors[32];
 
 /*
  * Set up exception handlers for tracing and breakpoints
@@ -402,7 +378,7 @@
 
 	save_and_cli(flags);
 	for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
-		set_except_vector(ht->tt, trap_low);
+		saved_vectors[ht->tt] = set_except_vector(ht->tt, trap_low);
   
 	putDebugChar('+'); /* 'hello world' */
 	/*
@@ -417,18 +393,6 @@
 
 	initialized = 1;
 	restore_flags(flags);
-}
-
-
-/*
- * Trap handler for memory errors.  This just sets mem_err to be non-zero.  It
- * assumes that %l1 is non-zero.  This should be safe, as it is doubtful that
- * 0 would ever contain code that could mem fault.  This routine will skip
- * past the faulting instruction after setting mem_err.
- */
-extern void fltr_set_mem_err(void)
-{
-	/* FIXME: Needs to be written... */
 }
 
 /*
diff -u --recursive --new-file v2.4.9/linux/arch/mips/kernel/head.S linux/arch/mips/kernel/head.S
--- v2.4.9/linux/arch/mips/kernel/head.S	Tue Jul  3 17:08:18 2001
+++ linux/arch/mips/kernel/head.S	Sun Sep  9 10:43:01 2001
@@ -76,7 +76,11 @@
 	addu	k1, k1, k0			# add in pgd offset
 	mfc0	k0, CP0_CONTEXT			# get context reg
 	lw	k1, (k1)
+#if defined(CONFIG_CPU_VR41XX)
+	srl	k0, k0, 3			# get pte offset
+#else
 	srl	k0, k0, 1			# get pte offset
+#endif
 	and	k0, k0, 0xff8
 	addu	k1, k1, k0			# add in offset
 	lw	k0, 0(k1)			# get even pte
@@ -275,7 +279,7 @@
 	END(except_vec0_r4k_MP250MHZhwbug)
 #endif
 
-	/* TLB refill, EXL == 0, R[23]00 version */
+	/* TLB refill, R[23]00 version */
 	LEAF(except_vec0_r2300)
 	.set	noat
 	.set	mips1
diff -u --recursive --new-file v2.4.9/linux/arch/mips/kernel/i8259.c linux/arch/mips/kernel/i8259.c
--- v2.4.9/linux/arch/mips/kernel/i8259.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/mips/kernel/i8259.c	Sun Sep  9 10:43:01 2001
@@ -295,7 +295,6 @@
 
 	request_resource(&ioport_resource, &pic1_io_resource);
 	request_resource(&ioport_resource, &pic2_io_resource);
-	setup_irq(2, &irq2);
 
 	init_8259A(0);
 
@@ -305,4 +304,6 @@
 		irq_desc[i].depth = 1;
 		irq_desc[i].handler = &i8259A_irq_type;
 	}
+
+	setup_irq(2, &irq2);
 }
diff -u --recursive --new-file v2.4.9/linux/arch/mips/kernel/irq.c linux/arch/mips/kernel/irq.c
--- v2.4.9/linux/arch/mips/kernel/irq.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/mips/kernel/irq.c	Sun Sep  9 10:43:01 2001
@@ -303,7 +303,7 @@
 	desc->handler->end(irq);
 	spin_unlock(&desc->lock);
 
-	if (softirq_active(cpu) & softirq_mask(cpu))
+	if (softirq_pending(cpu))
 		do_softirq();
 	return 1;
 }
diff -u --recursive --new-file v2.4.9/linux/arch/mips/kernel/mips_ksyms.c linux/arch/mips/kernel/mips_ksyms.c
--- v2.4.9/linux/arch/mips/kernel/mips_ksyms.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/mips/kernel/mips_ksyms.c	Sun Sep  9 10:43:01 2001
@@ -17,6 +17,7 @@
 #include <linux/pci.h>
 #include <linux/ide.h>
 
+#include <asm/bootinfo.h>
 #include <asm/checksum.h>
 #include <asm/dma.h>
 #include <asm/io.h>
@@ -40,6 +41,7 @@
 extern long __strnlen_user_nocheck_asm(const char *s);
 extern long __strnlen_user_asm(const char *s);
 
+EXPORT_SYMBOL(mips_machtype);
 EXPORT_SYMBOL(EISA_bus);
 
 /*
@@ -125,12 +127,6 @@
 
 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);
diff -u --recursive --new-file v2.4.9/linux/arch/mips/kernel/old-irq.c linux/arch/mips/kernel/old-irq.c
--- v2.4.9/linux/arch/mips/kernel/old-irq.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/mips/kernel/old-irq.c	Sun Sep  9 10:43:01 2001
@@ -232,7 +232,7 @@
 	}
 	irq_exit(cpu, irq);
 
-	if (softirq_active(cpu)&softirq_mask(cpu))
+	if (softirq_pending(cpu))
 		do_softirq();
 
 	/* unmasking and bottom half handling is done magically for us. */
diff -u --recursive --new-file v2.4.9/linux/arch/mips/kernel/old-time.c linux/arch/mips/kernel/old-time.c
--- v2.4.9/linux/arch/mips/kernel/old-time.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/mips/kernel/old-time.c	Sun Sep  9 10:43:01 2001
@@ -1,18 +1,11 @@
 /*
  * Copyright (C) 1991, 1992, 1995  Linus Torvalds
  * Copyright (C) 1996 - 2000  Ralf Baechle
+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
  *
- * This file contains the time handling details for PC-style clocks as
- * found in some MIPS systems.
+ * Don't use.  Deprecated.  Dead meat.
  */
-/**************************************************************************
- *  9 Nov, 2000.
- *  Changed init_cycle_counter() routine, use the mips_cpu structure.
- *
- *  Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips
- *  Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
- *************************************************************************/
-
 #include <linux/config.h>
 #include <linux/errno.h>
 #include <linux/init.h>
@@ -450,7 +443,12 @@
 void indy_r4k_timer_interrupt (struct pt_regs *regs)
 {
 	static const int INDY_R4K_TIMER_IRQ = 7;
+	int cpu = smp_processor_id();
+
 	r4k_timer_interrupt (INDY_R4K_TIMER_IRQ, NULL, regs);
+
+	if (softirq_pending(cpu))
+		do_softirq();
 }
 
 struct irqaction irq0  = { timer_interrupt, SA_INTERRUPT, 0,
diff -u --recursive --new-file v2.4.9/linux/arch/mips/kernel/pci-dma.c linux/arch/mips/kernel/pci-dma.c
--- v2.4.9/linux/arch/mips/kernel/pci-dma.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/mips/kernel/pci-dma.c	Sun Sep  9 10:43:01 2001
@@ -4,9 +4,10 @@
  * for more details.
  *
  * Copyright (C) 2000  Ani Joshi <ajoshi@unixbox.com>
- * Copyright (C) 2000  Ralf Baechle <ralf@gnu.org>
+ * Copyright (C) 2000, 2001  Ralf Baechle <ralf@gnu.org>
  * swiped from i386, and cloned for MIPS by Geert, polished by Ralf.
  */
+#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/mm.h>
 #include <linux/string.h>
@@ -26,9 +27,11 @@
 
 	if (ret != NULL) {
 		memset(ret, 0, size);
+#ifndef CONFIG_COHERENT_IO
 		dma_cache_wback_inv((unsigned long) ret, size);
-		*dma_handle = virt_to_bus(ret);
 		ret = KSEG1ADDR(ret);
+#endif
+		*dma_handle = virt_to_bus(ret);
 	}
 
 	return ret;
@@ -37,5 +40,10 @@
 void pci_free_consistent(struct pci_dev *hwdev, size_t size,
 			 void *vaddr, dma_addr_t dma_handle)
 {
-	free_pages((unsigned long) KSEG0ADDR(vaddr), get_order(size));
+	unsigned long addr = (unsigned long) vaddr;
+
+#ifndef CONFIG_COHERENT_IO
+	addr = KSEG0ADDR(addr);
+#endif
+	free_pages(addr, get_order(size));
 }
diff -u --recursive --new-file v2.4.9/linux/arch/mips/kernel/pci.c linux/arch/mips/kernel/pci.c
--- v2.4.9/linux/arch/mips/kernel/pci.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/kernel/pci.c	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * Modified to be mips generic, ppopov@mvista.com
+ * arch/mips/kernl/pci.c
+ *     Common MIPS PCI routines.
+ *
+ * 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 file contains common PCI routines meant to be shared for
+ * all MIPS machines.
+ *
+ * Strategies:
+ *
+ * . We rely on pci_auto.c file to assign PCI resources (MEM and IO)
+ *   TODO: this shold be optional for some machines where they do have
+ *   a real "pcibios" that does resource assignment.
+ *
+ * . We then use pci_scan_bus() to "discover" all the resources for
+ *   later use by Linux.
+ *
+ * . We finally reply on a board supplied function, pcibios_fixup_irq(), to
+ *   to assign the interrupts.  We may use setup-irq.c under drivers/pci
+ *   later.
+ *
+ * . Specifically, we will *NOT* use pci_assign_unassigned_resources(),
+ *   because we assume all PCI devices should have the resources correctly
+ *   assigned and recorded.
+ *
+ * Limitations:
+ *
+ * . We "collapse" all IO and MEM spaces in sub-buses under a top-level bus
+ *   into a contiguous range.
+ *
+ * . In the case of Memory space, the rnage is 1:1 mapping with CPU physical
+ *   address space.
+ *
+ * . In the case of IO space, it starts from 0, and the beginning address
+ *   is mapped to KSEG0ADDR(mips_io_port) in the CPU physical address.
+ *
+ * . These are the current MIPS limitations (by ioremap, etc).  In the
+ *   future, we may remove them.
+ *
+ * Credits:
+ *	Most of the code are derived from the pci routines from PPC and Alpha,
+ *	which were mostly writtne by
+ *		Cort Dougan, cort@fsmlabs.com
+ *		Matt Porter, mporter@mvista.com
+ *		Dave Rusling david.rusling@reo.mts.dec.com
+ *		David Mosberger davidm@cs.arizona.edu
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+
+#include <asm/pci_channel.h>
+
+extern void pcibios_fixup(void);
+extern void pcibios_fixup_irqs(void);
+
+struct pci_fixup pcibios_fixups[] = {
+	{ PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources },
+	{ 0 }
+};
+
+extern int pciauto_assign_resources(int busno, struct pci_channel * hose);
+
+void __init pcibios_init(void)
+{
+	struct pci_channel *p;
+	struct pci_bus *bus;
+	int busno;
+
+#ifdef CONFIG_PCI_AUTO
+	/* assign resources */
+	busno=0;
+	for (p= mips_pci_channels; p->pci_ops != NULL; p++) {
+		busno = pciauto_assign_resources(busno, p) + 1;
+	}
+#endif
+
+	/* scan the buses */
+	busno = 0;
+	for (p= mips_pci_channels; p->pci_ops != NULL; p++) {
+		bus = pci_scan_bus(busno, p->pci_ops, p);
+		busno = bus->subordinate+1;
+	}
+
+	/* machine dependent fixups */
+	pcibios_fixup();
+	/* fixup irqs (board specific routines) */
+	pcibios_fixup_irqs();
+}
+
+int pcibios_enable_device(struct pci_dev *dev)
+{
+	/* pciauto_assign_resources() will enable all devices found */
+	return 0;
+}
+
+unsigned long __init pci_bridge_check_io(struct pci_dev *bridge)
+{
+	u16 io;
+
+	pci_read_config_word(bridge, PCI_IO_BASE, &io);
+	if (!io) {
+		pci_write_config_word(bridge, PCI_IO_BASE, 0xf0f0);
+		pci_read_config_word(bridge, PCI_IO_BASE, &io);
+		pci_write_config_word(bridge, PCI_IO_BASE, 0x0);
+	}
+	if (io)
+		return IORESOURCE_IO;
+	printk(KERN_WARNING "PCI: bridge %s does not support I/O forwarding!\n",
+				bridge->name);
+	return 0;
+}
+
+void __init pcibios_fixup_bus(struct pci_bus *bus)
+{
+	/* Propogate hose info into the subordinate devices.  */
+
+	struct pci_channel *hose = bus->sysdata;
+	struct pci_dev *dev = bus->self;
+
+	if (!dev) {
+		/* Root bus */
+		bus->resource[0] = hose->io_resource;
+		bus->resource[1] = hose->mem_resource;
+	} else {
+		/* This is a bridge. Do not care how it's initialized,
+		   just link its resources to the bus ones */
+		int i;
+
+		for(i=0; i<3; i++) {
+			bus->resource[i] =
+				&dev->resource[PCI_BRIDGE_RESOURCES+i];
+			bus->resource[i]->name = bus->name;
+		}
+		bus->resource[0]->flags |= pci_bridge_check_io(dev);
+		bus->resource[1]->flags |= IORESOURCE_MEM;
+		/* For now, propogate hose limits to the bus;
+		   we'll adjust them later. */
+		bus->resource[0]->end = hose->io_resource->end;
+		bus->resource[1]->end = hose->mem_resource->end;
+		/* Turn off downstream PF memory address range by default */
+		bus->resource[2]->start = 1024*1024;
+		bus->resource[2]->end = bus->resource[2]->start - 1;
+	}
+}
+
+char *pcibios_setup(char *str)
+{
+	return str;
+}
+
+void
+pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+{
+	/* this should not be called */
+}
+
+void
+pcibios_update_resource(struct pci_dev *dev, struct resource *root,
+			struct resource *res, int resource)
+{
+	/* this should not be called */
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips/kernel/pci_auto.c linux/arch/mips/kernel/pci_auto.c
--- v2.4.9/linux/arch/mips/kernel/pci_auto.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/kernel/pci_auto.c	Sun Sep  9 10:43:01 2001
@@ -0,0 +1,323 @@
+/*
+ * PCI autoconfiguration library
+ *
+ * Author: Matt Porter <mporter@mvista.com>
+ *
+ * Copyright 2000, 2001 MontaVista Software Inc.
+ *
+ * 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.
+ */
+
+/*
+ * Modified for MIPS by Jun Sun, jsun@mvista.com
+ *
+ * . Simplify the interface between pci_auto and the rest: a single function.
+ * . Assign resources from low address to upper address.
+ * . change most int to u32.
+ *
+ * Further modified to include it as mips generic code, ppopov@mvista.com.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+
+#include <asm/pci_channel.h>
+
+#define	DEBUG
+#ifdef 	DEBUG
+#define	DBG(x...)	printk(x)
+#else
+#define	DBG(x...)	
+#endif
+
+/* These are used for config access before all the PCI probing has been done. */
+int early_read_config_byte(struct pci_channel *hose, int bus, int dev_fn, int where, u8 *val);
+int early_read_config_word(struct pci_channel *hose, int bus, int dev_fn, int where, u16 *val);
+int early_read_config_dword(struct pci_channel *hose, int bus, int dev_fn, int where, u32 *val);
+int early_write_config_byte(struct pci_channel *hose, int bus, int dev_fn, int where, u8 val);
+int early_write_config_word(struct pci_channel *hose, int bus, int dev_fn, int where, u16 val);
+int early_write_config_dword(struct pci_channel *hose, int bus, int dev_fn, int where, u32 val);
+
+static u32 pciauto_lower_iospc;
+static u32 pciauto_upper_iospc;
+
+static u32 pciauto_lower_memspc;
+static u32 pciauto_upper_memspc;
+
+void __init 
+pciauto_setup_bars(struct pci_channel *hose,
+		   int current_bus,
+		   int pci_devfn)
+{
+	u32 bar_response, bar_size, bar_value;
+	u32 bar, addr_mask, bar_nr = 0;
+	u32 * upper_limit;
+	u32 * lower_limit;
+	int found_mem64 = 0;
+
+	DBG("PCI Autoconfig: Found Bus %d, Device %d, Function %d\n",
+	    current_bus, PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn) );
+
+	for (bar = PCI_BASE_ADDRESS_0; bar <= PCI_BASE_ADDRESS_5; bar+=4) {
+		/* Tickle the BAR and get the response */
+		early_write_config_dword(hose,
+					 current_bus,
+					 pci_devfn,
+					 bar,
+					 0xffffffff);
+		early_read_config_dword(hose,
+					current_bus,
+					pci_devfn,
+					bar,
+					&bar_response);
+
+		/* If BAR is not implemented go to the next BAR */
+		if (!bar_response)
+			continue;
+
+		/* Check the BAR type and set our address mask */
+		if (bar_response & PCI_BASE_ADDRESS_SPACE) {
+			addr_mask = PCI_BASE_ADDRESS_IO_MASK;
+			upper_limit = &pciauto_upper_iospc;
+			lower_limit = &pciauto_lower_iospc;
+			DBG("PCI Autoconfig: BAR %d, I/O, ", bar_nr);
+		} else {
+			if ((bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
+			    PCI_BASE_ADDRESS_MEM_TYPE_64)
+				found_mem64 = 1;
+
+			addr_mask = PCI_BASE_ADDRESS_MEM_MASK;		
+			upper_limit = &pciauto_upper_memspc;
+			lower_limit = &pciauto_lower_memspc;
+			DBG("PCI Autoconfig: BAR %d, Mem, ", bar_nr);
+		}
+
+		/* Calculate requested size */
+		bar_size = ~(bar_response & addr_mask) + 1;
+
+		/* Allocate a base address */
+		bar_value = ((*lower_limit - 1) & ~(bar_size - 1)) + bar_size;
+
+		/* Write it out and update our limit */
+		early_write_config_dword(hose, current_bus, pci_devfn,
+					 bar, bar_value);
+
+		*lower_limit = bar_value + bar_size;
+
+		/*
+		 * If we are a 64-bit decoder then increment to the
+		 * upper 32 bits of the bar and force it to locate
+		 * in the lower 4GB of memory.
+		 */ 
+		if (found_mem64) {
+			bar += 4;
+			early_write_config_dword(hose,
+						 current_bus,
+						 pci_devfn,
+						 bar,
+						 0x00000000);
+		}
+
+		bar_nr++;
+
+		DBG("size=0x%x, address=0x%x\n",
+		    bar_size, bar_value);
+	}
+
+}
+
+void __init
+pciauto_prescan_setup_bridge(struct pci_channel *hose,
+			     int current_bus,
+			     int pci_devfn,
+			     int sub_bus)
+{
+	int cmdstat;
+
+	/* Configure bus number registers */
+	early_write_config_byte(hose, current_bus, pci_devfn,
+	                        PCI_PRIMARY_BUS, current_bus);
+	early_write_config_byte(hose, current_bus, pci_devfn,
+				PCI_SECONDARY_BUS, sub_bus + 1);
+	early_write_config_byte(hose, current_bus, pci_devfn,
+				PCI_SUBORDINATE_BUS, 0xff);
+
+	/* Round memory allocator to 1MB boundary */
+	pciauto_upper_memspc &= ~(0x100000 - 1);
+
+	/* Round I/O allocator to 4KB boundary */
+	pciauto_upper_iospc &= ~(0x1000 - 1);
+
+	/* Set up memory and I/O filter limits, assume 32-bit I/O space */
+	early_write_config_word(hose, current_bus, pci_devfn, PCI_MEMORY_LIMIT,
+				((pciauto_upper_memspc - 1) & 0xfff00000) >> 16);
+	early_write_config_byte(hose, current_bus, pci_devfn, PCI_IO_LIMIT,
+				((pciauto_upper_iospc - 1) & 0x0000f000) >> 8);
+	early_write_config_word(hose, current_bus, pci_devfn,
+				PCI_IO_LIMIT_UPPER16,
+				((pciauto_upper_iospc - 1) & 0xffff0000) >> 16);
+			
+	/* We don't support prefetchable memory for now, so disable */
+	early_write_config_word(hose, current_bus, pci_devfn,
+				PCI_PREF_MEMORY_BASE, 0x1000);
+	early_write_config_word(hose, current_bus, pci_devfn,
+				PCI_PREF_MEMORY_LIMIT, 0x1000);
+
+	/* Enable memory and I/O accesses, enable bus master */
+	early_read_config_dword(hose, current_bus, pci_devfn, PCI_COMMAND,
+				&cmdstat);
+	early_write_config_dword(hose, current_bus, pci_devfn, PCI_COMMAND,
+				 cmdstat | PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+				 PCI_COMMAND_MASTER);
+}
+
+void __init
+pciauto_postscan_setup_bridge(struct pci_channel *hose,
+			      int current_bus,
+			      int pci_devfn,
+			      int sub_bus)
+{
+	/* Configure bus number registers */
+	early_write_config_byte(hose, current_bus, pci_devfn,
+				PCI_SUBORDINATE_BUS, sub_bus);
+
+	/* Round memory allocator to 1MB boundary */
+	pciauto_upper_memspc &= ~(0x100000 - 1);
+	early_write_config_word(hose, current_bus, pci_devfn, PCI_MEMORY_BASE,
+				pciauto_upper_memspc >> 16);
+
+	/* Round I/O allocator to 4KB boundary */
+	pciauto_upper_iospc &= ~(0x1000 - 1);
+	early_write_config_byte(hose, current_bus, pci_devfn, PCI_IO_BASE,
+				(pciauto_upper_iospc & 0x0000f000) >> 8);
+	early_write_config_word(hose, current_bus, pci_devfn,
+				PCI_IO_BASE_UPPER16, pciauto_upper_iospc >> 16);
+}
+
+#define      PCIAUTO_IDE_MODE_MASK           0x05
+
+int __init
+pciauto_bus_scan(struct pci_channel *hose, int current_bus)
+{
+	int sub_bus;
+	u32 pci_devfn, pci_class, cmdstat, found_multi=0;
+	unsigned short vid;
+	unsigned char header_type;
+	int devfn_start = 0;
+	int devfn_stop = 0xff;
+
+	sub_bus = current_bus;
+	
+	if (hose->first_devfn)
+		devfn_start = hose->first_devfn;
+	if (hose->last_devfn)
+		devfn_stop = hose->last_devfn;
+	
+	for (pci_devfn=devfn_start; pci_devfn<devfn_stop; pci_devfn++) {
+
+		if (PCI_FUNC(pci_devfn) && !found_multi)
+			continue;
+
+		early_read_config_byte(hose, current_bus, pci_devfn,
+				       PCI_HEADER_TYPE, &header_type);
+
+		if (!PCI_FUNC(pci_devfn))
+			found_multi = header_type & 0x80;
+
+		early_read_config_word(hose, current_bus, pci_devfn,
+				       PCI_VENDOR_ID, &vid);
+
+		if (vid == 0xffff) continue;
+
+		early_read_config_dword(hose, current_bus, pci_devfn,
+					PCI_CLASS_REVISION, &pci_class);
+		if ((pci_class >> 16) == PCI_CLASS_BRIDGE_PCI) {
+			DBG("PCI Autoconfig: Found P2P bridge, device %d\n", PCI_SLOT(pci_devfn));
+			pciauto_prescan_setup_bridge(hose, current_bus,
+						     pci_devfn, sub_bus);
+			sub_bus = pciauto_bus_scan(hose, sub_bus+1);
+			pciauto_postscan_setup_bridge(hose, current_bus,
+						      pci_devfn, sub_bus);
+
+		} else if ((pci_class >> 16) == PCI_CLASS_STORAGE_IDE) {
+
+			unsigned char prg_iface;
+
+			early_read_config_byte(hose, current_bus, pci_devfn,
+					       PCI_CLASS_PROG, &prg_iface);
+			if (!(prg_iface & PCIAUTO_IDE_MODE_MASK)) {
+				DBG("PCI Autoconfig: Skipping legacy mode IDE controller\n");
+				continue;
+			}
+		}
+
+		/*
+		 * Found a peripheral, enable some standard
+		 * settings
+		 */
+		early_read_config_dword(hose, current_bus, pci_devfn,
+					PCI_COMMAND, &cmdstat);
+		early_write_config_dword(hose, current_bus, pci_devfn,
+					 PCI_COMMAND, cmdstat | PCI_COMMAND_IO |
+					 PCI_COMMAND_MEMORY |
+					 PCI_COMMAND_MASTER);
+		early_write_config_byte(hose, current_bus, pci_devfn,
+					PCI_LATENCY_TIMER, 0x80);
+
+		/* Allocate PCI I/O and/or memory space */
+		pciauto_setup_bars(hose, current_bus, pci_devfn);
+	}
+	return sub_bus;
+}
+
+int __init
+pciauto_assign_resources(int busno, struct pci_channel *hose)
+{
+	/* setup resource limits */
+	pciauto_lower_iospc = hose->io_resource->start;
+	pciauto_upper_iospc = hose->io_resource->end + 1;
+	pciauto_lower_memspc = hose->mem_resource->start;
+	pciauto_upper_memspc = hose->mem_resource->end + 1;
+
+	return pciauto_bus_scan(hose, busno);
+}
+
+
+/*
+ * These functions are used early on before PCI scanning is done
+ * and all of the pci_dev and pci_bus structures have been created.
+ */
+static struct pci_dev *fake_pci_dev(struct pci_channel *hose, int busnr,
+                                    int devfn)
+{
+	static struct pci_dev dev;
+	static struct pci_bus bus;
+
+	dev.bus = &bus;
+	dev.sysdata = hose;
+	dev.devfn = devfn;
+	bus.number = busnr;
+	bus.ops = hose->pci_ops;
+
+	return &dev;
+}
+
+#define EARLY_PCI_OP(rw, size, type)					\
+int early_##rw##_config_##size(struct pci_channel *hose, int bus,	\
+                               int devfn, int offset, type value)	\
+{									\
+	return pci_##rw##_config_##size(fake_pci_dev(hose, bus, devfn),	\
+	                                offset, value);			\
+}
+
+EARLY_PCI_OP(read, byte, u8 *)
+EARLY_PCI_OP(read, word, u16 *)
+EARLY_PCI_OP(read, dword, u32 *)
+EARLY_PCI_OP(write, byte, u8)
+EARLY_PCI_OP(write, word, u16)
+EARLY_PCI_OP(write, dword, u32)
diff -u --recursive --new-file v2.4.9/linux/arch/mips/kernel/proc.c linux/arch/mips/kernel/proc.c
--- v2.4.9/linux/arch/mips/kernel/proc.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/mips/kernel/proc.c	Sun Sep  9 10:43:01 2001
@@ -1,8 +1,10 @@
 /*
  *  linux/arch/mips/kernel/proc.c
  *
- *  Copyright (C) 1995, 1996  Ralf Baechle
+ *  Copyright (C) 1995, 1996, 2001  Ralf Baechle
+ *  Copyright (C) 2001  MIPS Technologies, Inc.
  */
+#include <linux/config.h>
 #include <linux/delay.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -12,9 +14,9 @@
 #include <asm/processor.h>
 #include <asm/watch.h>
 
-unsigned long unaligned_instructions;
+extern unsigned long unaligned_instructions;
 unsigned int vced_count, vcei_count;
-#if !defined(CONFIG_CPU_HAS_LLSC)
+#ifndef CONFIG_CPU_HAS_LLSC
 unsigned long ll_ops, sc_ops;
 #endif
 
@@ -83,7 +85,7 @@
 	len += sprintf(buffer + len, "microsecond timers\t: %s\n",
 	               (mips_cpu.options & MIPS_CPU_COUNTER) ? "yes" : "no");
 	len += sprintf(buffer + len, "extra interrupt vector\t: %s\n",
-	               dedicated_iv_available ? "yes" : "no");
+	               (mips_cpu.options & MIPS_CPU_DIVEC) ? "yes" : "no");
 	len += sprintf(buffer + len, "hardware watchpoint\t: %s\n",
 	               watch_available ? "yes" : "no");
 
@@ -92,7 +94,7 @@
 	len += sprintf(buffer + len, fmt, 'D', vced_count);
 	len += sprintf(buffer + len, fmt, 'I', vcei_count);
 
-#if !defined(CONFIG_CPU_HAS_LLSC)
+#ifndef CONFIG_CPU_HAS_LLSC
 	len += sprintf(buffer + len, "ll emulations\t\t: %lu\n",
 		       ll_ops);
 	len += sprintf(buffer + len, "sc emulations\t\t: %lu\n",
diff -u --recursive --new-file v2.4.9/linux/arch/mips/kernel/process.c linux/arch/mips/kernel/process.c
--- v2.4.9/linux/arch/mips/kernel/process.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/mips/kernel/process.c	Sun Sep  9 10:43:01 2001
@@ -83,13 +83,10 @@
 	childksp = (unsigned long)p + KERNEL_STACK_SIZE - 32;
 
 	if (last_task_used_math == current)
-#ifdef CONFIG_MIPS_FPU_EMULATOR
-		if (mips_cpu.options & MIPS_CPU_FPU)
-#endif
-	{
+		if (mips_cpu.options & MIPS_CPU_FPU) {
 			set_cp0_status(ST0_CU1);
 			save_fp(p);
-	}
+		}
 	/* set up new TSS. */
 	childregs = (struct pt_regs *) childksp - 1;
 	*childregs = *regs;
@@ -120,8 +117,8 @@
 	 * 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|KU_MASK);
-	childregs->cp0_status &= ~(ST0_CU3|ST0_CU2|ST0_CU1);
+                            ~(ST0_CU2|ST0_CU1|KU_MASK);
+	childregs->cp0_status &= ~(ST0_CU2|ST0_CU1);
 
 	return 0;
 }
diff -u --recursive --new-file v2.4.9/linux/arch/mips/kernel/ptrace.c linux/arch/mips/kernel/ptrace.c
--- v2.4.9/linux/arch/mips/kernel/ptrace.c	Wed Jul 25 17:10:18 2001
+++ linux/arch/mips/kernel/ptrace.c	Sun Sep  9 10:43:01 2001
@@ -33,7 +33,7 @@
 {
 	struct task_struct *child;
 	int res;
-	extern void save_fp(void*);
+	extern void save_fp(struct task_struct *);
 
 	lock_kernel();
 #if 0
@@ -111,19 +111,31 @@
 			        unsigned long long *fregs
 					= (unsigned long long *)
 					    &child->thread.fpu.hard.fp_regs[0];
-#ifdef CONFIG_MIPS_FPU_EMULATOR
-			    if(!(mips_cpu.options & MIPS_CPU_FPU)) {
-				    fregs = (unsigned long long *)
-					&child->thread.fpu.soft.regs[0];
-			    } else 
+			 	if(!(mips_cpu.options & MIPS_CPU_FPU)) {
+					fregs = (unsigned long long *)
+						child->thread.fpu.soft.regs;
+				} else 
+					if (last_task_used_math == child) {
+						enable_cp1();
+						save_fp(child);
+						disable_cp1();
+						last_task_used_math = NULL;
+						regs->cp0_status &= ~ST0_CU1;
+					}
+				/*
+				 * The odd registers are actually the high
+				 * order bits of the values stored in the even
+				 * registers - unless we're using r2k_switch.S.
+				 */
+#ifdef CONFIG_CPU_R3000
+				if (mips_cpu.options & MIPS_CPU_FPU)
+					tmp = *(unsigned long *)(fregs + addr);
+				else
 #endif
-				if (last_task_used_math == child) {
-					enable_cp1();
-					save_fp(child);
-					disable_cp1();
-					last_task_used_math = NULL;
-				}
-				tmp = (unsigned long) fregs[(addr - 32)];
+				if (addr & 1)
+					tmp = (unsigned long) (fregs[((addr & ~1) - 32)] >> 32);
+				else
+					tmp = (unsigned long) (fregs[(addr - 32)] & 0xffffffff);
 			} else {
 				tmp = -1;	/* FP not yet used  */
 			}
@@ -144,12 +156,10 @@
 			tmp = regs->lo;
 			break;
 		case FPC_CSR:
-#ifdef CONFIG_MIPS_FPU_EMULATOR
-			if(!(mips_cpu.options & MIPS_CPU_FPU))
+			if (!(mips_cpu.options & MIPS_CPU_FPU))
 				tmp = child->thread.fpu.soft.sr;
 			else
-#endif
-			tmp = child->thread.fpu.hard.control;
+				tmp = child->thread.fpu.hard.control;
 			break;
 		case FPC_EIR: {	/* implementation / version register */
 			unsigned int flags;
@@ -192,19 +202,17 @@
 			unsigned long long *fregs;
 			fregs = (unsigned long long *)&child->thread.fpu.hard.fp_regs[0];
 			if (child->used_math) {
-				if (last_task_used_math == child)
-#ifdef CONFIG_MIPS_FPU_EMULATOR
-				    if(!(mips_cpu.options & MIPS_CPU_FPU)) {
-					fregs = (unsigned long long *)
-					    &child->thread.fpu.soft.regs[0];
-				    } else
-#endif
-				{
-					enable_cp1();
-					save_fp(child);
-					disable_cp1();
-					last_task_used_math = NULL;
-					regs->cp0_status &= ~ST0_CU1;
+				if (last_task_used_math == child) {
+					if(!(mips_cpu.options & MIPS_CPU_FPU)) {
+						fregs = (unsigned long long *)
+						child->thread.fpu.soft.regs;
+					} else {
+						enable_cp1();
+						save_fp(child);
+						disable_cp1();
+						last_task_used_math = NULL;
+						regs->cp0_status &= ~ST0_CU1;
+					}
 				}
 			} else {
 				/* FP not yet used  */
@@ -212,7 +220,23 @@
 				       sizeof(child->thread.fpu.hard));
 				child->thread.fpu.hard.control = 0;
 			}
-			fregs[addr - FPR_BASE] = data;
+			/*
+			 * The odd registers are actually the high order bits
+			 * of the values stored in the even registers - unless
+			 * we're using r2k_switch.S.
+			 */
+#ifdef CONFIG_CPU_R3000
+			if (mips_cpu.options & MIPS_CPU_FPU)
+				*(unsigned long *)(fregs + addr) = data;
+			else
+#endif
+			if (addr & 1) {
+				fregs[(addr & ~1) - FPR_BASE] &= 0xffffffff;
+				fregs[(addr & ~1) - FPR_BASE] |= ((unsigned long long) data) << 32;
+			} else {
+				fregs[addr - FPR_BASE] &= ~0xffffffffLL;
+				fregs[addr - FPR_BASE] |= data;
+			}
 			break;
 		}
 		case PC:
@@ -225,12 +249,10 @@
 			regs->lo = data;
 			break;
 		case FPC_CSR:
-#ifdef CONFIG_MIPS_FPU_EMULATOR
-			if(!(mips_cpu.options & MIPS_CPU_FPU)) 
+			if (!(mips_cpu.options & MIPS_CPU_FPU)) 
 				child->thread.fpu.soft.sr = data;
 			else
-#endif
-			child->thread.fpu.hard.control = data;
+				child->thread.fpu.hard.control = data;
 			break;
 		default:
 			/* The rest are not allowed. */
diff -u --recursive --new-file v2.4.9/linux/arch/mips/kernel/r2300_switch.S linux/arch/mips/kernel/r2300_switch.S
--- v2.4.9/linux/arch/mips/kernel/r2300_switch.S	Tue Jul  3 17:08:18 2001
+++ linux/arch/mips/kernel/r2300_switch.S	Sun Sep  9 10:43:01 2001
@@ -1,5 +1,4 @@
-/* $Id: r2300_switch.S,v 1.8 1999/08/18 23:37:44 ralf Exp $
- *
+/*
  * r2300_switch.S: R2300 specific task switching code.
  *
  * Copyright (C) 1994, 1995, 1996, 1999 by Ralf Baechle
diff -u --recursive --new-file v2.4.9/linux/arch/mips/kernel/r4k_switch.S linux/arch/mips/kernel/r4k_switch.S
--- v2.4.9/linux/arch/mips/kernel/r4k_switch.S	Tue Jul  3 17:08:18 2001
+++ linux/arch/mips/kernel/r4k_switch.S	Sun Sep  9 10:43:01 2001
@@ -7,15 +7,10 @@
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  * Copyright (C) 1994, 1995, 1996, by Andreas Busse
  * Copyright (C) 1999 Silicon Graphics, Inc.
+ * Copyright (C) 2000 MIPS Technologies, Inc.
+ *    written by Carsten Langgaard, carstenl@mips.com
  */
-/**************************************************************************
- *  13 Nov, 2000.
- *  Made support for MIPS32 CPUs and restoring of fp registers.
- *
- *  Carsten Langgaard, carstenl@mips.com
- *  Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
- *************************************************************************/
-	
+#include <linux/config.h>
 #include <asm/asm.h>
 #include <asm/bootinfo.h>
 #include <asm/cachectl.h>
diff -u --recursive --new-file v2.4.9/linux/arch/mips/kernel/reset.c linux/arch/mips/kernel/reset.c
--- v2.4.9/linux/arch/mips/kernel/reset.c	Thu Jun 26 12:33:37 1997
+++ linux/arch/mips/kernel/reset.c	Sun Sep  9 10:43:01 2001
@@ -1,7 +1,10 @@
 /*
- *  linux/arch/mips/sni/process.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.
  *
- *  Reset the machine.
+ * Copyright (C) 2001 by Ralf Baechle
+ * Copyright (C) 2001 MIPS Technologies, Inc.
  */
 #include <linux/kernel.h>
 #include <linux/types.h>
@@ -13,6 +16,9 @@
  * So handle all using function pointers to machine specific
  * functions.
  */
+void (*_machine_restart)(char *command);
+void (*_machine_halt)(void);
+void (*_machine_power_off)(void);
 
 void machine_restart(char *command)
 {
diff -u --recursive --new-file v2.4.9/linux/arch/mips/kernel/scall_o32.S linux/arch/mips/kernel/scall_o32.S
--- v2.4.9/linux/arch/mips/kernel/scall_o32.S	Tue Jul  3 17:08:18 2001
+++ linux/arch/mips/kernel/scall_o32.S	Sun Sep  9 10:43:01 2001
@@ -65,36 +65,32 @@
 1:	sw	v0, PT_R2(sp)		# result
 
 EXPORT(o32_ret_from_sys_call)
-	la	t1, irq_stat		# softirq_active
-#ifdef CONFIG_SMP
-	lw	t0, TASK_PROCESSOR($28)
-        sll	t0, t0, 5
-	addu	t1, t0
-#endif
-	lw	t0, 0(t1)		# softirq_active
-	lw	t1, 4(t1)		# softirq_mask.  unused delay slot
-	and	t0, t1
-	bnez	t0, o32_handle_softirq
+	mfc0	t0, CP0_STATUS		# need_resched and signals atomic test
+	ori	t0, t0, 1
+	xori	t0, t0, 1
+	mtc0	t0, CP0_STATUS
 
-9:	lw	t0,PT_STATUS(sp)	# returning to kernel mode?
-	andi	t1, t0, KU_USER
 	lw	t2, TASK_NEED_RESCHED($28)
-	beqz	t1, o32_return		# -> yes
 	bnez	t2, o32_reschedule
 	lw	v0, TASK_SIGPENDING($28)
+	bnez	v0, signal_return
+restore_all:
+	RESTORE_SOME
+	RESTORE_SP_AND_RET
+
+/* Put this behind restore_all for the sake of the branch prediction.  */
+signal_return:
+	.type	signal_return, @function
+
+	mfc0	t0, CP0_STATUS
+	ori	t0, t0, 1
+	mtc0	t0, CP0_STATUS
+
 	move	a0, zero
-	beqz	v0, o32_return
 	move	a1, sp
-	SAVE_STATIC
 	jal	do_signal
+	b	restore_all
 
-o32_return:
-	RESTORE_SOME
-	RESTORE_SP_AND_RET
-
-o32_handle_softirq:
-	jal	do_softirq
-	b	9b
 o32_reschedule:
 	SAVE_STATIC
 	jal	schedule
diff -u --recursive --new-file v2.4.9/linux/arch/mips/kernel/setup.c linux/arch/mips/kernel/setup.c
--- v2.4.9/linux/arch/mips/kernel/setup.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/mips/kernel/setup.c	Sun Sep  9 10:43:01 2001
@@ -191,6 +191,12 @@
 				           MIPS_CPU_WATCH | MIPS_CPU_VCE;
 			mips_cpu.tlbsize = 48;
 			break;
+                case PRID_IMP_VR41XX:
+                        mips_cpu.cputype = CPU_VR41XX;
+                        mips_cpu.isa_level = MIPS_CPU_ISA_III;
+                        mips_cpu.options = R4K_OPTS;
+                        mips_cpu.tlbsize = 32;
+                        break;
 		case PRID_IMP_R4600:
 			mips_cpu.cputype = CPU_R4600;
 			mips_cpu.isa_level = MIPS_CPU_ISA_III;
@@ -282,7 +288,7 @@
 			break;
 		case PRID_IMP_R10000:
 			mips_cpu.cputype = CPU_R10000;
-			mips_cpu.cputype = MIPS_CPU_ISA_IV;
+			mips_cpu.isa_level = MIPS_CPU_ISA_IV;
 			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | 
 				           MIPS_CPU_FPU | MIPS_CPU_32FPR | 
 				           MIPS_CPU_COUNTER | MIPS_CPU_WATCH;
@@ -719,8 +725,10 @@
 #ifdef CONFIG_BLK_DEV_INITRD
 	/* Board specific code should have set up initrd_start and initrd_end */
 	ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
-	initrd_start = (unsigned long)&__rd_start;
-	initrd_end = (unsigned long)&__rd_end;
+	if( __rd_start != __rd_end ) {
+		initrd_start = (unsigned long)&__rd_start;
+		initrd_end = (unsigned long)&__rd_end;
+	}
 	initrd_below_start_ok = 1;
 	if (initrd_start) {
 		unsigned long initrd_size = ((unsigned char *)initrd_end) - ((unsigned char *)initrd_start); 
diff -u --recursive --new-file v2.4.9/linux/arch/mips/kernel/signal.c linux/arch/mips/kernel/signal.c
--- v2.4.9/linux/arch/mips/kernel/signal.c	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/kernel/signal.c	Sun Sep  9 10:43:01 2001
@@ -464,10 +464,10 @@
 		/*
 		 * Set up the return code ...
 		 *
-		 *         li      v0, __NR_sigreturn
+		 *         li      v0, __NR_rt_sigreturn
 		 *         syscall
 		 */
-		err |= __put_user(0x24020000 + __NR_sigreturn,
+		err |= __put_user(0x24020000 + __NR_rt_sigreturn,
 		                  frame->rs_code + 0);
 		err |= __put_user(0x0000000c                 ,
 		                  frame->rs_code + 1);
diff -u --recursive --new-file v2.4.9/linux/arch/mips/kernel/softfp.S linux/arch/mips/kernel/softfp.S
--- v2.4.9/linux/arch/mips/kernel/softfp.S	Sun Jul  9 22:18:15 2000
+++ linux/arch/mips/kernel/softfp.S	Wed Dec 31 16:00:00 1969
@@ -1,666 +0,0 @@
-/*
- * This file 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, 2000 by Ralf Baechle
- *
- * 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	a0, 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	t0, a0
-
-	/*
-	 * First table lookup using insn[5:0]
-	 */
-	la	t1, lowtab
-	andi	t2, t0, 0x3f
-	sll	t2, t2, 2
-	addu	t1, t2
-	lw	t1, (t1)
-	jr	t1
-	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,t0,t1,t2)
-
-/* Convert a single fp to a fixed point integer.  */
-cvt.w.s:
-	srl	t1, t0, fs_shift	# Get source register
-	andi	t1, 31
-	jal	s_get_fpreg
-
-	S_is_E_max(t1,t2,t3)
-	beqz	t2, 3f
-	/* Might be a NaN or Inf.  */
-	S_get_F(t1,t2)
-	beqz	t2, 2f
-
-	/* It's a NaN.  IEEE says undefined.  */
-	/* Is it a QNaN?  Then the result is a QNaN as well.  */
-	S_is_QNaN(t1,t2)
-	bltz	t2, 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	t2, W_QNaN
-	srl	t1, t0, fd_shift	# Put result register
-	andi	t1, 31
-	jal	s_put_fpreg
-	j	done
-2:
-
-	S_is_Inf(t1,t2)
-	bnez	t2, 2f
-
-	/* It's +/- Inf.  Set register to +/- max. integer.  */
-	/* XXX Send invalid operation exception instead, if enabled.  */
-	srl	t1, t1, 31		# Extract sign bit
-	li	t2, 0x7fffffff
-	addu	t2, t1
-
-	srl	t1, t0, fd_shift	# Put result register
-	andi	t1, 31
-	jal	s_put_fpreg
-	j	done
-2:
-3:	
-
-	/* But then it might be a denorm or zero?  */
-	S_is_E_min(t1,t2)
-	bnez	t2, 2f
-
-	/* Ok, it's a denorm or zero.  */
-	S_get_F(t1,t2)
-	beqz	t2, 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	t2, zero
-	srl	t1, t0, fd_shift	# Put result register
-	andi	t1, 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	t1, t0, fs_shift	# Get source register
-	andi	t1, 31
-	jal	d_get_fpreg
-
-	D_is_E_max(t1,t2,t3,t4)
-	beqz	t3, 3f
-
-	/* Might be a NaN or Inf.  */
-	D_get_F(t1,t2,t3)
-	or	t3, t2
-	beqz	t3, 2f
-
-	/* It's a NaN.  IEEE says undefined.  */
-	/* Is it a QNaN?  Then the result is a QNaN as well.  */
-	D_is_QNaN(t1,t2,t3)
-	bltz	t3, 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	t2, W_QNaN
-	srl	t1, t0, fd_shift	# Put result register
-	andi	t1, 31
-	jal	s_put_fpreg
-	j	done
-2:
-
-	D_is_Inf(t1,t2,t3)
-	bnez	t3, 2f
-
-	/* It's +/- Inf.  Set register to +/- max. integer.  */
-	/* XXX Send invalid operation exception instead, if enabled.  */
-	srl	t1, t1, 31		# Extract sign bit
-	li	t2, 0x7fffffff
-	addu	t2, t1
-
-	srl	t1, t0, fd_shift	# Put result register
-	andi	t1, 31
-	jal	s_put_fpreg
-	j	done
-2:
-3:	
-
-	/* But then it might be a denorm or zero?  */
-	D_is_E_min(t1,t2,t3)
-	bnez	t3, 2f
-
-	/* Ok, it's a denorm or zero.  */
-	D_get_F(t1,t2,t3)
-	or	t3, t2
-	beqz	t3, 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	t2, zero
-	srl	t1, t0, fd_shift	# Put result register
-	andi	t1, 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	t1, t1, 31		# Extract sign bit
-	li	t2, 0x7fffffff
-	addu	t2, t1
-
-	srl	t1, t0, fd_shift	# Put result register
-	andi	t1, 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 t1.  */
-s_get_fpreg:
-	.set	noat
-	sll	AT, t1, 2
-	sll	t1, 3
-	addu	t1, AT
-	la	AT, 1f
-	addu	AT, t1
-	jr	AT
-	.set	at
-
-1:	mfc1	t1, $0
-	jr	ra
-	mfc1	t1, $1
-	jr	ra
-	mfc1	t1, $2
-	jr	ra
-	mfc1	t1, $3
-	jr	ra
-	mfc1	t1, $4
-	jr	ra
-	mfc1	t1, $5
-	jr	ra
-	mfc1	t1, $6
-	jr	ra
-	mfc1	t1, $7
-	jr	ra
-	mfc1	t1, $8
-	jr	ra
-	mfc1	t1, $9
-	jr	ra
-	mfc1	t1, $10
-	jr	ra
-	mfc1	t1, $11
-	jr	ra
-	mfc1	t1, $12
-	jr	ra
-	mfc1	t1, $13
-	jr	ra
-	mfc1	t1, $14
-	jr	ra
-	mfc1	t1, $15
-	jr	ra
-	mfc1	t1, $16
-	jr	ra
-	mfc1	t1, $17
-	jr	ra
-	mfc1	t1, $18
-	jr	ra
-	mfc1	t1, $19
-	jr	ra
-	mfc1	t1, $20
-	jr	ra
-	mfc1	t1, $21
-	jr	ra
-	mfc1	t1, $22
-	jr	ra
-	mfc1	t1, $23
-	jr	ra
-	mfc1	t1, $24
-	jr	ra
-	mfc1	t1, $25
-	jr	ra
-	mfc1	t1, $26
-	jr	ra
-	mfc1	t1, $27
-	jr	ra
-	mfc1	t1, $28
-	jr	ra
-	mfc1	t1, $29
-	jr	ra
-	mfc1	t1, $30
-	jr	ra
-	mfc1	t1, $31
-	jr	ra
-
-/*
- * Put the value in t2 into the single precission register which's number
- * is in t1.
- */
-s_put_fpreg:
-	.set	noat
-	sll	AT, t1, 2
-	sll	t1, 3
-	addu	t1, AT
-	la	AT, 1f
-	addu	AT, t1
-	jr	AT
-	.set	at
-	
-1:	mtc1	t2, $0
-	jr	ra
-	mtc1	t2, $1
-	jr	ra
-	mtc1	t2, $2
-	jr	ra
-	mtc1	t2, $3
-	jr	ra
-	mtc1	t2, $4
-	jr	ra
-	mtc1	t2, $5
-	jr	ra
-	mtc1	t2, $6
-	jr	ra
-	mtc1	t2, $7
-	jr	ra
-	mtc1	t2, $8
-	jr	ra
-	mtc1	t2, $9
-	jr	ra
-	mtc1	t2, $10
-	jr	ra
-	mtc1	t2, $11
-	jr	ra
-	mtc1	t2, $12
-	jr	ra
-	mtc1	t2, $13
-	jr	ra
-	mtc1	t2, $14
-	jr	ra
-	mtc1	t2, $15
-	jr	ra
-	mtc1	t2, $16
-	jr	ra
-	mtc1	t2, $17
-	jr	ra
-	mtc1	t2, $18
-	jr	ra
-	mtc1	t2, $19
-	jr	ra
-	mtc1	t2, $20
-	jr	ra
-	mtc1	t2, $21
-	jr	ra
-	mtc1	t2, $22
-	jr	ra
-	mtc1	t2, $23
-	jr	ra
-	mtc1	t2, $24
-	jr	ra
-	mtc1	t2, $25
-	jr	ra
-	mtc1	t2, $26
-	jr	ra
-	mtc1	t2, $27
-	jr	ra
-	mtc1	t2, $28
-	jr	ra
-	mtc1	t2, $29
-	jr	ra
-	mtc1	t2, $30
-	jr	ra
-	mtc1	t2, $31
-	jr	ra
-
-/* Get the double precission register which's number is in t1 into t1/t2.  */
-d_get_fpreg:
-	.set	noat
-	sll	t1, 3
-	la	AT, 1f
-	addu	AT, t1
-	jr	AT
-	.set	at
-
-1:	mfc1	t1, $0
-	mfc1	t2, $1
-	jr	ra
-	mfc1	t1, $2
-	mfc1	t2, $3
-	jr	ra
-	mfc1	t1, $4
-	mfc1	t2, $5
-	jr	ra
-	mfc1	t1, $6
-	mfc1	t2, $7
-	jr	ra
-	mfc1	t1, $8
-	mfc1	t2, $9
-	jr	ra
-	mfc1	t1, $10
-	mfc1	t2, $11
-	jr	ra
-	mfc1	t1, $12
-	mfc1	t2, $13
-	jr	ra
-	mfc1	t1, $14
-	mfc1	t2, $15
-	jr	ra
-	mfc1	t1, $16
-	mfc1	t2, $17
-	jr	ra
-	mfc1	t1, $18
-	mfc1	t2, $19
-	jr	ra
-	mfc1	t1, $20
-	mfc1	t2, $21
-	jr	ra
-	mfc1	t1, $22
-	mfc1	t2, $23
-	jr	ra
-	mfc1	t1, $24
-	mfc1	t2, $25
-	jr	ra
-	mfc1	t1, $26
-	mfc1	t2, $27
-	jr	ra
-	mfc1	t1, $28
-	mfc1	t2, $29
-	jr	ra
-	mfc1	t1, $30
-	mfc1	t2, $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, t0
-	PRINT(KERN_DEBUG "FP support: unknown fp op %08lx, ")
-	PRINT("please mail to ralf@gnu.org.\n")
-
-	li	a0, SIGILL			# Die, sucker ...
-	move	a1, $28
-	jal	force_sig
-	UNLOCK_KERNEL
-
-	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.4.9/linux/arch/mips/kernel/time.c linux/arch/mips/kernel/time.c
--- v2.4.9/linux/arch/mips/kernel/time.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/mips/kernel/time.c	Sun Sep  9 10:43:01 2001
@@ -1,18 +1,15 @@
-/***********************************************************************
+/*
  * Copyright 2001 MontaVista Software Inc.
  * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
  *
- * arch/mips/kernel/time.c
- *     Common time service routines for MIPS machines.  See 
- *     Documents/MIPS/time.txt. 
+ * Common time service routines for MIPS machines. See 
+ * Documents/MIPS/README.txt. 
  *
  * 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/config.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
@@ -29,22 +26,11 @@
 #include <asm/cpu.h>
 #include <asm/time.h>
 #include <asm/hardirq.h>
-
-/* 
- * macro for catching spurious errors.  Eable to LL_DEBUG in kernel hacking
- * config menu.
- */
-#ifdef CONFIG_LL_DEBUG
-#define	MIPS_ASSERT(x)	if (!(x)) { panic("MIPS_ASSERT failed at %s:%d\n", __FILE__, __LINE__); }
-#define MIPS_DEBUG(x)  do { x; } while (0)
-#else
-#define MIPS_ASSERT(x)
-#define MIPS_DEBUG(x)
-#endif
+#include <asm/div64.h>
 
 /* This is for machines which generate the exact clock. */
 #define USECS_PER_JIFFY (1000000/HZ)
-#define USECS_PER_JIFFY_FRAC (0x100000000*1000000/HZ&0xffffffff)
+#define USECS_PER_JIFFY_FRAC ((1000000ULL << 32) / HZ & 0xffffffff)
 
 /*
  * forward reference
@@ -74,50 +60,50 @@
  */
 void do_gettimeofday(struct timeval *tv)
 {
-        unsigned long flags;
+	unsigned long flags;
+
+	read_lock_irqsave (&xtime_lock, flags);
+	*tv = xtime;
+	tv->tv_usec += do_gettimeoffset();
+
+	/*
+	 * xtime is atomically updated in timer_bh. jiffies - wall_jiffies
+	 * is nonzero if the timer bottom half hasnt executed yet.
+	 */
+	if (jiffies - wall_jiffies)
+		tv->tv_usec += USECS_PER_JIFFY;
 
-        read_lock_irqsave (&xtime_lock, flags);
-        *tv = xtime;
-        tv->tv_usec += do_gettimeoffset();
-
-        /*
-         * xtime is atomically updated in timer_bh. jiffies - wall_jiffies
-         * is nonzero if the timer bottom half hasnt executed yet.
-         */
-        if (jiffies - wall_jiffies)
-                tv->tv_usec += USECS_PER_JIFFY;
-
-        read_unlock_irqrestore (&xtime_lock, flags);
-
-        if (tv->tv_usec >= 1000000) {
-                tv->tv_usec -= 1000000;
-                tv->tv_sec++;
-        }
+	read_unlock_irqrestore (&xtime_lock, flags);
+
+	if (tv->tv_usec >= 1000000) {
+		tv->tv_usec -= 1000000;
+		tv->tv_sec++;
+	}
 }
 
 void do_settimeofday(struct timeval *tv)
 {
-        write_lock_irq (&xtime_lock);
+	write_lock_irq (&xtime_lock);
 
-        /* This is revolting. We need to set the xtime.tv_usec
-         * correctly. However, the value in this location is
-         * is value at the last tick.
-         * Discover what correction gettimeofday
-         * would have done, and then undo it!
-         */
-        tv->tv_usec -= do_gettimeoffset();
-
-        if (tv->tv_usec < 0) {
-                tv->tv_usec += 1000000;
-                tv->tv_sec--;
-        }
-        xtime = *tv;
-        time_adjust = 0;                /* stop active adjtime() */
-        time_status |= STA_UNSYNC;
-        time_maxerror = NTP_PHASE_LIMIT;
-        time_esterror = NTP_PHASE_LIMIT;
+	/* This is revolting. We need to set the xtime.tv_usec
+	 * correctly. However, the value in this location is
+	 * is value at the last tick.
+	 * Discover what correction gettimeofday
+	 * would have done, and then undo it!
+	 */
+	tv->tv_usec -= do_gettimeoffset();
 
-        write_unlock_irq (&xtime_lock);
+	if (tv->tv_usec < 0) {
+		tv->tv_usec += 1000000;
+		tv->tv_sec--;
+	}
+	xtime = *tv;
+	time_adjust = 0;			/* stop active adjtime() */
+	time_status |= STA_UNSYNC;
+	time_maxerror = NTP_PHASE_LIMIT;
+	time_esterror = NTP_PHASE_LIMIT;
+
+	write_unlock_irq (&xtime_lock);
 }
 
 
@@ -162,30 +148,26 @@
 	u32 count;
 	unsigned long res;
 
-	MIPS_ASSERT(mips_cpu.options & MIPS_CPU_COUNTER);
-	MIPS_ASSERT(mips_counter_frequency != 0);
-	MIPS_ASSERT(sll32_usecs_per_cycle != 0);
-
 	/* Get last timer tick in absolute kernel time */
-        count = read_32bit_cp0_register(CP0_COUNT);
+	count = read_32bit_cp0_register(CP0_COUNT);
 
-        /* .. relative to previous jiffy (32 bits is enough) */
-        count -= timerlo;
+	/* .. relative to previous jiffy (32 bits is enough) */
+	count -= timerlo;
 
-        __asm__("multu\t%1,%2\n\t"
-                "mfhi\t%0"
-                :"=r" (res)
-                :"r" (count),
-                 "r" (sll32_usecs_per_cycle));
-
-        /*
-         * Due to possible jiffies inconsistencies, we need to check
-         * the result so that we'll get a timer that is monotonic.
-         */
-        if (res >= USECS_PER_JIFFY)
-                res = USECS_PER_JIFFY-1;
+	__asm__("multu\t%1,%2\n\t"
+	        "mfhi\t%0"
+	        :"=r" (res)
+	        :"r" (count),
+	         "r" (sll32_usecs_per_cycle));
 
-        return res;
+	/*
+	 * Due to possible jiffies inconsistencies, we need to check
+	 * the result so that we'll get a timer that is monotonic.
+	 */
+	if (res >= USECS_PER_JIFFY)
+		res = USECS_PER_JIFFY-1;
+
+	return res;
 }
 
 /*
@@ -197,156 +179,107 @@
 /* Last jiffy when calibrate_divXX_gettimeoffset() was called. */
 static unsigned long last_jiffies = 0;
 
-/* 
- * copied from include/asm/div64.  
- * We do the copy instead of include the header file because we don't
- * want to reply on _MIPS_ISA value.
- */
-#define do_div64_32(res, high, low, base) ({ \
-        unsigned long __quot, __mod; \
-        unsigned long __cf, __tmp, __i; \
-        \
-        __asm__(".set   push\n\t" \
-                ".set   noat\n\t" \
-                ".set   noreorder\n\t" \
-                "b      1f\n\t" \
-                " li    %4,0x21\n" \
-                "0:\n\t" \
-                "sll    $1,%0,0x1\n\t" \
-                "srl    %3,%0,0x1f\n\t" \
-                "or     %0,$1,$2\n\t" \
-                "sll    %1,%1,0x1\n\t" \
-                "sll    %2,%2,0x1\n" \
-                "1:\n\t" \
-                "bnez   %3,2f\n\t" \
-                "sltu   $2,%0,%z5\n\t" \
-                "bnez   $2,3f\n\t" \
-                "2:\n\t" \
-                " addiu %4,%4,-1\n\t" \
-                "subu   %0,%0,%z5\n\t" \
-                "addiu  %2,%2,1\n" \
-                "3:\n\t" \
-                "bnez   %4,0b\n\t" \
-                " srl   $2,%1,0x1f\n\t" \
-                ".set   pop" \
-                : "=&r" (__mod), "=&r" (__tmp), "=&r" (__quot), "=&r" (__cf), \
-                  "=&r" (__i) \
-                : "Jr" (base), "0" (high), "1" (low), "2" (0), "3" (0) \
-                /* Aarrgh!  Ran out of gcc's limit on constraints... */ \
-                : "$1", "$2"); \
-        \
-        (res) = __quot; \
-        __mod; })
 
 /*
  * This is copied from dec/time.c:do_ioasic_gettimeoffset() by Mercij.
  */
 unsigned long calibrate_div32_gettimeoffset(void)
 {
-        u32 count;
-        unsigned long res, tmp;
-        unsigned long quotient;
-
-	MIPS_ASSERT(mips_cpu.options & MIPS_CPU_COUNTER);
-
-        tmp = jiffies;
-
-        quotient = cached_quotient;
-
-        if (last_jiffies != tmp) {
-                last_jiffies = tmp;
-                if (last_jiffies != 0) {
-                        unsigned long r0;
-                        do_div64_32(r0, timerhi, timerlo, tmp);
-                        do_div64_32(quotient, USECS_PER_JIFFY,
-                                    USECS_PER_JIFFY_FRAC, r0);
-                        cached_quotient = quotient;
-                }
-        }
-
-        /* Get last timer tick in absolute kernel time */
-        count = read_32bit_cp0_register(CP0_COUNT);
-
-        /* .. relative to previous jiffy (32 bits is enough) */
-        count -= timerlo;
-
-        __asm__("multu  %2,%3"
-                : "=l" (tmp), "=h" (res)
-                : "r" (count), "r" (quotient));
-
-        /*
-         * Due to possible jiffies inconsistencies, we need to check
-         * the result so that we'll get a timer that is monotonic.
-         */
-        if (res >= USECS_PER_JIFFY)
-                res = USECS_PER_JIFFY - 1;
+	u32 count;
+	unsigned long res, tmp;
+	unsigned long quotient;
+
+	tmp = jiffies;
+
+	quotient = cached_quotient;
+
+	if (last_jiffies != tmp) {
+		last_jiffies = tmp;
+		if (last_jiffies != 0) {
+			unsigned long r0;
+			do_div64_32(r0, timerhi, timerlo, tmp);
+			do_div64_32(quotient, USECS_PER_JIFFY,
+			            USECS_PER_JIFFY_FRAC, r0);
+			cached_quotient = quotient;
+		}
+	}
+
+	/* Get last timer tick in absolute kernel time */
+	count = read_32bit_cp0_register(CP0_COUNT);
+
+	/* .. relative to previous jiffy (32 bits is enough) */
+	count -= timerlo;
+
+	__asm__("multu  %2,%3"
+	        : "=l" (tmp), "=h" (res)
+	        : "r" (count), "r" (quotient));
+
+	/*
+	 * Due to possible jiffies inconsistencies, we need to check
+	 * the result so that we'll get a timer that is monotonic.
+	 */
+	if (res >= USECS_PER_JIFFY)
+		res = USECS_PER_JIFFY - 1;
 
-        return res;
+	return res;
 }
 
 unsigned long calibrate_div64_gettimeoffset(void)
 {
-        u32 count;
-        unsigned long res, tmp;
-        unsigned long quotient;
-
-
-	MIPS_ASSERT(mips_cpu.options & MIPS_CPU_COUNTER);
-	MIPS_ASSERT((mips_cpu.isa_level != MIPS_CPU_ISA_I) &&
-		    (mips_cpu.isa_level != MIPS_CPU_ISA_II) &&
-		    (mips_cpu.isa_level != MIPS_CPU_ISA_M32));
-
-
-        tmp = jiffies;
-
-        quotient = cached_quotient;
-
-        if (tmp && last_jiffies != tmp) {
-                last_jiffies = tmp;
-                __asm__(".set\tnoreorder\n\t"
-                        ".set\tnoat\n\t"
-                        ".set\tmips3\n\t"
-                        "lwu\t%0,%2\n\t"
-                        "dsll32\t$1,%1,0\n\t"
-                        "or\t$1,$1,%0\n\t"
-                        "ddivu\t$0,$1,%3\n\t"
-                        "mflo\t$1\n\t"
-                        "dsll32\t%0,%4,0\n\t"
-                        "nop\n\t"
-                        "ddivu\t$0,%0,$1\n\t"
-                        "mflo\t%0\n\t"
-                        ".set\tmips0\n\t"
-                        ".set\tat\n\t"
-                        ".set\treorder"
-                        :"=&r" (quotient)
-                        :"r" (timerhi),
-                         "m" (timerlo),
-                         "r" (tmp),
-                         "r" (USECS_PER_JIFFY)
-                        :"$1");
-                cached_quotient = quotient;
-        }
-
-        /* Get last timer tick in absolute kernel time */
-        count = read_32bit_cp0_register(CP0_COUNT);
-
-        /* .. relative to previous jiffy (32 bits is enough) */
-        count -= timerlo;
-
-        __asm__("multu\t%1,%2\n\t"
-                "mfhi\t%0"
-                :"=r" (res)
-                :"r" (count),
-                 "r" (quotient));
-
-        /*
-         * Due to possible jiffies inconsistencies, we need to check
-         * the result so that we'll get a timer that is monotonic.
-         */
-        if (res >= USECS_PER_JIFFY)
-                res = USECS_PER_JIFFY-1;
+	u32 count;
+	unsigned long res, tmp;
+	unsigned long quotient;
+
+	tmp = jiffies;
 
-        return res;
+	quotient = cached_quotient;
+
+	if (tmp && last_jiffies != tmp) {
+		last_jiffies = tmp;
+		__asm__(".set\tnoreorder\n\t"
+	        ".set\tnoat\n\t"
+	        ".set\tmips3\n\t"
+	        "lwu\t%0,%2\n\t"
+	        "dsll32\t$1,%1,0\n\t"
+	        "or\t$1,$1,%0\n\t"
+	        "ddivu\t$0,$1,%3\n\t"
+	        "mflo\t$1\n\t"
+	        "dsll32\t%0,%4,0\n\t"
+	        "nop\n\t"
+	        "ddivu\t$0,%0,$1\n\t"
+	        "mflo\t%0\n\t"
+	        ".set\tmips0\n\t"
+	        ".set\tat\n\t"
+	        ".set\treorder"
+	        :"=&r" (quotient)
+	        :"r" (timerhi),
+	         "m" (timerlo),
+	         "r" (tmp),
+	         "r" (USECS_PER_JIFFY)
+	        :"$1");
+	        cached_quotient = quotient;
+	}
+
+	/* Get last timer tick in absolute kernel time */
+	count = read_32bit_cp0_register(CP0_COUNT);
+
+	/* .. relative to previous jiffy (32 bits is enough) */
+	count -= timerlo;
+
+	__asm__("multu\t%1,%2\n\t"
+	        "mfhi\t%0"
+	        :"=r" (res)
+	        :"r" (count),
+	         "r" (quotient));
+
+	/*
+	 * Due to possible jiffies inconsistencies, we need to check
+	 * the result so that we'll get a timer that is monotonic.
+	 */
+	if (res >= USECS_PER_JIFFY)
+		res = USECS_PER_JIFFY-1;
+
+	return res;
 }
 
 
@@ -377,57 +310,56 @@
 
 	}
 
-        if(!user_mode(regs)) {
+	if(!user_mode(regs)) {
 		if (prof_buffer && current->pid) {
-                        extern int _stext;
-                        unsigned long pc = regs->cp0_epc;
+			extern int _stext;
+			unsigned long pc = regs->cp0_epc;
 
-                        pc -= (unsigned long) &_stext;
-                        pc >>= prof_shift;
-                        /*
-                         * Dont ignore out-of-bounds pc values silently,
-                         * put them into the last histogram slot, so if
-                         * present, they will show up as a sharp peak.
-                         */
-                        if (pc > prof_len-1)
-                                pc = prof_len-1;
-                        atomic_inc((atomic_t *)&prof_buffer[pc]);
-                }
-        }
+			pc -= (unsigned long) &_stext;
+			pc >>= prof_shift;
+			/*
+			 * Dont ignore out-of-bounds pc values silently,
+			 * put them into the last histogram slot, so if
+			 * present, they will show up as a sharp peak.
+			 */
+			if (pc > prof_len-1)
+			pc = prof_len-1;
+			atomic_inc((atomic_t *)&prof_buffer[pc]);
+		}
+	}
 
 	/*
 	 * call the generic timer interrupt handling
 	 */
-        do_timer(regs);
-
-        /*
-         * If we have an externally synchronized Linux clock, then update
-         * CMOS clock accordingly every ~11 minutes. rtc_set_time() has to be
-         * called as close as possible to 500 ms before the new second starts.
-         */
-        read_lock (&xtime_lock);
-        if ((time_status & STA_UNSYNC) == 0 &&
-            xtime.tv_sec > last_rtc_update + 660 &&
-            xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 &&
-            xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) {
+	do_timer(regs);
 
+	/*
+	 * If we have an externally synchronized Linux clock, then update
+	 * CMOS clock accordingly every ~11 minutes. rtc_set_time() has to be
+	 * called as close as possible to 500 ms before the new second starts.
+	 */
+	read_lock (&xtime_lock);
+	if ((time_status & STA_UNSYNC) == 0 &&
+	    xtime.tv_sec > last_rtc_update + 660 &&
+	    xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 &&
+	    xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) {
 		if (rtc_set_time(xtime.tv_sec) == 0) {
 			last_rtc_update = xtime.tv_sec;
 		} else {
 			last_rtc_update = xtime.tv_sec - 600; 
 			/* do it again in 60 s */
 		}
-        }
-        read_unlock (&xtime_lock);
+	}
+	read_unlock (&xtime_lock);
 
 	/*
 	 * If jiffies has overflowed in this timer_interrupt we must
 	 * update the timer[hi]/[lo] to make fast gettimeoffset funcs
 	 * quotient calc still valid. -arca
 	 */
-        if (!jiffies) {
-                timerhi = timerlo = 0;
-        }
+	if (!jiffies) {
+		timerhi = timerlo = 0;
+	}
 }
 
 asmlinkage void ll_timer_interrupt(int irq, struct pt_regs *regs)
@@ -442,9 +374,8 @@
 	
 	irq_exit(cpu, irq);
 
-	/* check for bottom half */
-        if (softirq_active(cpu)&softirq_mask(cpu))
-                do_softirq();
+	if (softirq_pending(cpu))
+		do_softirq();
 }
 
 
@@ -480,19 +411,14 @@
 
 void __init time_init(void)
 {
-	printk("New MIPS time_init() invoked.\n");
-
 	if (board_time_init)
 		board_time_init();
 
-	/* setup xtime */
-	write_lock_irq(&xtime_lock);
 	xtime.tv_sec = rtc_get_time();
 	xtime.tv_usec = 0;
-	write_unlock_irq(&xtime_lock);
 
 	/* choose appropriate gettimeoffset routine */
-	if ( ! (mips_cpu.options & MIPS_CPU_COUNTER) ) {
+	if (!(mips_cpu.options & MIPS_CPU_COUNTER)) {
 		/* no cpu counter - sorry */
 		do_gettimeoffset = null_gettimeoffset;
 	} else if (mips_counter_frequency != 0) {
@@ -519,11 +445,6 @@
 		sll32_usecs_per_cycle = mips_counter_frequency / 100000;
 		sll32_usecs_per_cycle = 0xffffffff / sll32_usecs_per_cycle;
 		sll32_usecs_per_cycle *= 10;
-
-		MIPS_DEBUG(printk("cycles_per_jiffy = %d\n", 
-				  cycles_per_jiffy));
-		MIPS_DEBUG(printk("sll32_usecs_per_cycle = %d \n",
-				  sll32_usecs_per_cycle));
 	}
 
 	/* 
@@ -537,6 +458,52 @@
 	 * to be NULL function so that we are sure the high-level code
 	 * is not invoked accidentally.
 	 */
-	MIPS_ASSERT(board_timer_setup != NULL);
 	board_timer_setup(&timer_irqaction);
+}
+
+#define FEBRUARY		2
+#define STARTOFTIME		1970
+#define SECDAY			86400L
+#define SECYR			(SECDAY * 365)
+#define leapyear(year)		((year) % 4 == 0)
+#define days_in_year(a)		(leapyear(a) ? 366 : 365)
+#define days_in_month(a)	(month_days[(a) - 1])
+
+static int month_days[12] = {
+	31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+};
+
+void to_tm(unsigned long tim, struct rtc_time * tm)
+{
+	long hms, day;
+	int i;
+
+	day = tim / SECDAY;
+	hms = tim % SECDAY;
+
+	/* Hours, minutes, seconds are easy */
+	tm->tm_hour = hms / 3600;
+	tm->tm_min = (hms % 3600) / 60;
+	tm->tm_sec = (hms % 3600) % 60;
+
+	/* Number of years in days */
+	for (i = STARTOFTIME; day >= days_in_year(i); i++)
+	day -= days_in_year(i);
+	tm->tm_year = i;
+
+	/* Number of months in days left */
+	if (leapyear(tm->tm_year))
+	days_in_month(FEBRUARY) = 29;
+	for (i = 1; day >= days_in_month(i); i++)
+	day -= days_in_month(i);
+	days_in_month(FEBRUARY) = 28;
+	tm->tm_mon = i;
+
+	/* Days are what is left over (+1) from all that. */
+	tm->tm_mday = day + 1;
+
+	/*
+	 * Determine the day of week
+	 */
+	tm->tm_wday = (day + 3) % 7;
 }
diff -u --recursive --new-file v2.4.9/linux/arch/mips/kernel/traps.c linux/arch/mips/kernel/traps.c
--- v2.4.9/linux/arch/mips/kernel/traps.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/mips/kernel/traps.c	Sun Sep  9 10:43:01 2001
@@ -3,17 +3,18 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1994 - 1999 by Ralf Baechle
+ * Copyright (C) 1994 - 1999, 2000, 01 Ralf Baechle
  * Modified for R3000 by Paul M. Antoine, 1995, 1996
  * Complete output from die() by Ulf Carlsson, 1998
  * Copyright (C) 1999 Silicon Graphics, Inc.
  *
  * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ * Copyright (C) 2000, 01 MIPS Technologies, Inc.
  */
 #include <linux/config.h>
 #include <linux/init.h>
 #include <linux/mm.h>
+#include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
@@ -25,6 +26,7 @@
 #include <asm/cachectl.h>
 #include <asm/inst.h>
 #include <asm/jazz.h>
+#include <asm/module.h>
 #include <asm/pgtable.h>
 #include <asm/io.h>
 #include <asm/siginfo.h>
@@ -32,9 +34,6 @@
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
-#ifndef CONFIG_MIPS_FPU_EMULATOR 
-#include <asm/inst.h>
-#endif
 
 /*
  * Machine specific interrupt handlers
@@ -63,12 +62,9 @@
 extern asmlinkage void handle_mcheck(void);
 extern asmlinkage void handle_reserved(void);
 
-extern int fpu_emulator_cop1Handler(int, struct pt_regs *);
-
-static char *cpu_names[] = CPU_NAMES;
+extern int fpu_emulator_cop1Handler(struct pt_regs *);
 
 char watch_available = 0;
-char dedicated_iv_available = 0;
 
 void (*ibe_board_handler)(struct pt_regs *regs);
 void (*dbe_board_handler)(struct pt_regs *regs);
@@ -81,7 +77,7 @@
  */
 #define MODULE_RANGE (8*1024*1024)
 
-#if !defined(CONFIG_CPU_HAS_LLSC)
+#ifndef CONFIG_CPU_HAS_LLSC
 /*
  * This stuff is needed for the userland ll-sc emulation for R2300
  */
@@ -94,8 +90,6 @@
 #define OFFSET 0x0000ffff
 #define LL     0xc0000000
 #define SC     0xe0000000
-
-#undef DEBUG_LLSC
 #endif
 
 /*
@@ -212,7 +206,6 @@
 	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);
 }
@@ -254,89 +247,101 @@
 	return (first == last && first->insn == value) ? first->nextinsn : 0;
 }
 
-#define search_dbe_table(addr)	\
-	search_one_table(__start___dbe_table, __stop___dbe_table - 1, (addr))
+extern spinlock_t modlist_lock;
+
+static inline unsigned long
+search_dbe_table(unsigned long addr)
+{
+	unsigned long ret = 0;
+
+#ifndef CONFIG_MODULES
+	/* There is only the kernel to search.  */
+	ret = search_one_table(__start___dbe_table, __stop___dbe_table-1, addr);
+	return ret;
+#else
+	unsigned long flags;
+
+	/* The kernel is the last "module" -- no need to treat it special.  */
+	struct module *mp;
+	struct archdata *ap;
+
+	spin_lock_irqsave(&modlist_lock, flags);
+	for (mp = module_list; mp != NULL; mp = mp->next) {
+		if (!mod_member_present(mp, archdata_end) ||
+        	    !mod_archdata_member_present(mp, struct archdata,
+						 dbe_table_end))
+			continue;
+		ap = (struct archdata *)(mp->archdata_start);
+
+		if (ap->dbe_table_start == NULL ||
+		    !(mp->flags & (MOD_RUNNING | MOD_INITIALIZING)))
+			continue;
+		ret = search_one_table(ap->dbe_table_start,
+				       ap->dbe_table_end - 1, addr);
+		if (ret)
+			break;
+	}
+	spin_unlock_irqrestore(&modlist_lock, flags);
+	return ret;
+#endif
+}
 
 static void default_be_board_handler(struct pt_regs *regs)
 {
 	unsigned long new_epc;
-	unsigned long fixup = search_dbe_table(regs->cp0_epc);
+	unsigned long fixup;
+	int data = regs->cp0_cause & 4;
 
-	if (fixup) {
-		new_epc = fixup_exception(dpf_reg, fixup, regs->cp0_epc);
-		regs->cp0_epc = new_epc;
-		return;
+	if (data && !user_mode(regs)) {
+		fixup = search_dbe_table(regs->cp0_epc);
+		if (fixup) {
+			new_epc = fixup_exception(dpf_reg, fixup,
+						  regs->cp0_epc);
+			regs->cp0_epc = new_epc;
+			return;
+		}
 	}
 
 	/*
 	 * Assume it would be too dangerous to continue ...
 	 */
+	printk(KERN_ALERT "%s bus error, epc == %08lx, ra == %08lx\n",
+	       data ? "Data" : "Instruction",
+	       regs->cp0_epc, regs->regs[31]);
+	die_if_kernel("Oops", regs);
 	force_sig(SIGBUS, current);
 }
 
-void do_ibe(struct pt_regs *regs)
+asmlinkage void do_ibe(struct pt_regs *regs)
 {
 	ibe_board_handler(regs);
 }
 
-void do_dbe(struct pt_regs *regs)
+asmlinkage void do_dbe(struct pt_regs *regs)
 {
 	dbe_board_handler(regs);
 }
 
-void do_ov(struct pt_regs *regs)
+asmlinkage 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;
+	force_sig(SIGFPE, current);
 }
-#endif
 
 /*
  * XXX Delayed fp exceptions when doing a lazy ctx switch XXX
  */
-void do_fpe(struct pt_regs *regs, unsigned long fcr31)
+asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
 {
-
-#ifdef CONFIG_MIPS_FPU_EMULATOR
-	if(!(mips_cpu.options & MIPS_CPU_FPU))
-		panic("Floating Point Exception with No FPU");
-#endif
-
-#ifdef CONFIG_MIPS_FPE_MODULE
-	if (fpe_handler != NULL) {
-		fpe_handler(regs, fcr31);
-		return;
-	}
-#endif
-
 	if (fcr31 & FPU_CSR_UNI_X) {
-#ifdef CONFIG_MIPS_FPU_EMULATOR
 		extern void save_fp(struct task_struct *);
 		extern void restore_fp(struct task_struct *);
 		int sig;
 		/*
 	 	 * Unimplemented operation exception.  If we've got the
-	 	 * Full software emulator on-board, let's use it...
+	 	 * full software emulator on-board, let's use it...
 		 *
 		 * Force FPU to dump state into task/thread context.
 		 * We're moving a lot of data here for what is probably
@@ -348,11 +353,11 @@
 		save_fp(current);
 	
 		/* Run the emulator */
-		sig = fpu_emulator_cop1Handler(0, regs);
+		sig = fpu_emulator_cop1Handler(regs);
 
 		/* 
 		 * We can't allow the emulated instruction to leave the
-		 * Unimplemented Operation bit set in the FCR31 fp-register.
+		 * Unimplemented Operation bit set in $fcr31.
 		 */
 		current->thread.fpu.soft.sr &= ~FPU_CSR_UNI_X;
 
@@ -362,37 +367,6 @@
 		/* If something went wrong, signal */
 		if (sig)
 			force_sig(sig, current);
-#else
-		/* Else use mini-emulator */
-
-		extern void simfp(int);
-		unsigned long pc;
-		unsigned int insn;
-
-		/* Retry instruction with flush to zero ...  */
-		if (!(fcr31 & (1<<24))) {
-			printk("Setting flush to zero for %s.\n",
-			       current->comm);
-			fcr31 &= ~FPU_CSR_UNI_X;
-			fcr31 |= (1<<24);
-			__asm__ __volatile__(
-				"ctc1\t%0,$31"
-				: /* No outputs */
-				: "r" (fcr31));
-			return;
-		}
-		pc = regs->cp0_epc + ((regs->cp0_cause & CAUSEF_BD) ? 4 : 0);
-		if(pc & 0x80000000) insn = *(unsigned int *)pc;
-		else 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(MIPSInst(insn));
-		compute_return_epc(regs);
-#endif /* CONFIG_MIPS_FPU_EMULATOR */
 
 		return;
 	}
@@ -408,31 +382,31 @@
 {
 	unsigned int *epc;
 
-	epc = (unsigned int *) (unsigned long) regs->cp0_epc;
-	if (regs->cp0_cause & CAUSEF_BD)
-		epc++;
-
-	if (verify_area(VERIFY_READ, epc, 4)) {
-		force_sig(SIGSEGV, current);
-		return 1;
-	}
-	*opcode = *epc;
+	epc = (unsigned int *) regs->cp0_epc +
+	      ((regs->cp0_cause & CAUSEF_BD) != 0);
+	if (!get_user(*opcode, epc))
+		return 0;
 
-	return 0;
+	force_sig(SIGSEGV, current);
+	return 1;
 }
 
-void do_bp(struct pt_regs *regs)
+asmlinkage void do_bp(struct pt_regs *regs)
 {
 	siginfo_t info;
 	unsigned int opcode, bcode;
+	unsigned int *epc;
+
+	epc = (unsigned int *) regs->cp0_epc +
+	      ((regs->cp0_cause & CAUSEF_BD) != 0);
+	if (get_user(opcode, epc))
+		goto sigsegv;
 
 	/*
 	 * 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));
 
 	/*
@@ -456,15 +430,23 @@
 	default:
 		force_sig(SIGTRAP, current);
 	}
+	return;
+
+sigsegv:
+	force_sig(SIGSEGV, current);
 }
 
-void do_tr(struct pt_regs *regs)
+asmlinkage void do_tr(struct pt_regs *regs)
 {
 	siginfo_t info;
 	unsigned int opcode, bcode;
+	unsigned *epc;
+
+	epc = (unsigned int *) regs->cp0_epc +
+	      ((regs->cp0_cause & CAUSEF_BD) != 0);
+	if (get_user(opcode, epc))
+		goto sigsegv;
 
-	if (get_insn_opcode(regs, &opcode))
-		return;
 	bcode = ((opcode >> 6) & ((1 << 20) - 1));
 
 	/*
@@ -488,9 +470,13 @@
 	default:
 		force_sig(SIGTRAP, current);
 	}
+	return;
+
+sigsegv:
+	force_sig(SIGSEGV, current);
 }
 
-#if !defined(CONFIG_CPU_HAS_LLSC)
+#ifndef CONFIG_CPU_HAS_LLSC
 
 #ifdef CONFIG_SMP
 #error "ll/sc emulation is not SMP safe"
@@ -503,7 +489,7 @@
  * this implementation can handle only sychronization between 2 or more
  * user contexts and is not SMP safe.
  */
-void do_ri(struct pt_regs *regs)
+asmlinkage void do_ri(struct pt_regs *regs)
 {
 	unsigned int opcode;
 
@@ -520,9 +506,7 @@
 			return;
 		}
 	}
-	printk("[%s:%d] Illegal instruction %08lx at %08lx, ra=%08lx, CP0_STATUS=%08lx\n",
-	       current->comm, current->pid, *((unsigned long*)regs->cp0_epc), regs->cp0_epc,
-		regs->regs[31], regs->cp0_status);
+
 	if (compute_return_epc(regs))
 		return;
 	force_sig(SIGILL, current);
@@ -558,10 +542,6 @@
 
 	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
-
 #ifdef CONFIG_PROC_FS
 	ll_ops++;
 #endif
@@ -604,10 +584,6 @@
 	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
-
 #ifdef CONFIG_PROC_FS
 	sc_ops++;
 #endif
@@ -628,52 +604,33 @@
 
 #else /* MIPS 2 or higher */
 
-void do_ri(struct pt_regs *regs)
+asmlinkage void do_ri(struct pt_regs *regs)
 {
 	unsigned int opcode;
 
-        get_insn_opcode(regs, &opcode);
-	printk("[%s:%ld] Illegal instruction %08x at %08lx ra=%08lx\n",
-	       current->comm, (unsigned long)current->pid, opcode,
-	       regs->cp0_epc, regs->regs[31]);
+	get_insn_opcode(regs, &opcode);
 	if (compute_return_epc(regs))
 		return;
+
 	force_sig(SIGILL, current);
 }
 
 #endif
 
-void do_cpu(struct pt_regs *regs)
+asmlinkage void do_cpu(struct pt_regs *regs)
 {
 	unsigned int cpid;
-	extern void lazy_fpu_switch(void*);
+	extern void lazy_fpu_switch(void *);
 	extern void init_fpu(void);
-#ifdef CONFIG_MIPS_FPU_EMULATOR
 	void fpu_emulator_init_fpu(void);
 	int sig;
-#endif
+
 	cpid = (regs->cp0_cause >> CAUSEB_CE) & 3;
 	if (cpid != 1)
 		goto bad_cid;
 
-#ifdef CONFIG_MIPS_FPU_EMULATOR
-	if(!(mips_cpu.options & MIPS_CPU_FPU)) {
-	    if (last_task_used_math != current) {
-		if(!current->used_math) {
-		    fpu_emulator_init_fpu();
-		    current->used_math = 1;
-		}
-	    }
-	    sig = fpu_emulator_cop1Handler(0, regs);
-	    last_task_used_math = current;
-	    if(sig) {
-		force_sig(sig, current);
-	    }
-	    return;
-	}
-#else
-	if(!(mips_cpu.options & MIPS_CPU_FPU)) goto bad_cid;
-#endif
+	if (!(mips_cpu.options & MIPS_CPU_FPU))
+		goto fp_emul;
 
 	regs->cp0_status |= ST0_CU1;
 	if (last_task_used_math == current)
@@ -682,18 +639,30 @@
 	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;
 
+fp_emul:
+	if (last_task_used_math != current) {
+		if (!current->used_math) {
+			fpu_emulator_init_fpu();
+			current->used_math = 1;
+		}
+	}
+	sig = fpu_emulator_cop1Handler(regs);
+	last_task_used_math = current;
+	if (sig)
+		force_sig(sig, current);
+	return;
+
 bad_cid:
 	force_sig(SIGILL, current);
 }
 
-void do_watch(struct pt_regs *regs)
+asmlinkage void do_watch(struct pt_regs *regs)
 {
 	/*
 	 * We use the watch exception where available to detect stack
@@ -703,14 +672,14 @@
 	panic("Caught WATCH exception - probably caused by stack overflow.");
 }
 
-void do_mcheck(struct pt_regs *regs)
+asmlinkage void do_mcheck(struct pt_regs *regs)
 {
 	show_regs(regs);
 	panic("Caught Machine Check exception - probably caused by multiple "
 	      "matching entries in the TLB.");
 }
 
-void do_reserved(struct pt_regs *regs)
+asmlinkage void do_reserved(struct pt_regs *regs)
 {
 	/*
 	 * Game over - no way to handle this if it ever occurs.  Most probably
@@ -723,34 +692,19 @@
 
 static inline void watch_init(void)
 {
-        if(mips_cpu.options & MIPS_CPU_WATCH ) {
-		(void)set_except_vector(23, handle_watch);
+	if (mips_cpu.options & MIPS_CPU_WATCH ) {
+		set_except_vector(23, handle_watch);
  		watch_available = 1;
  	}
 }
 
 /*
- * Some MIPS CPUs have a dedicated interrupt vector which reduces the
- * interrupt processing overhead.  Use it where available.
- */
-static inline void setup_dedicated_int(void)
-{
-	extern void except_vec4(void);
-
-	if(mips_cpu.options & MIPS_CPU_DIVEC) {
-		memcpy((void *)(KSEG0 + 0x200), except_vec4, 8);
-		set_cp0_cause(CAUSEF_IV);
-		dedicated_iv_available = 1;
-	}
-}
-
-/*
- * Some MIPS CPUs can enable/disable for cache parity detection, but does
+ * Some MIPS CPUs can enable/disable for cache parity detection, but do
  * it different ways.
  */
 static inline void parity_protection_init(void)
 {
-	switch(mips_cpu.cputype) {
+	switch (mips_cpu.cputype) {
 	case CPU_5KC:
 		/* Set the PE bit (bit 31) in the CP0_ECC register. */
 		printk(KERN_INFO "Enable the cache parity protection for "
@@ -764,38 +718,39 @@
 	}
 }
 
-void cache_parity_error(void)
+asmlinkage void cache_parity_error(void)
 {
-        unsigned int reg_val;
+	unsigned int reg_val;
 
-        /* For the moment, report the problem and hang. */
-        reg_val = read_32bit_cp0_register(CP0_ERROREPC);
+	/* For the moment, report the problem and hang. */
+	reg_val = read_32bit_cp0_register(CP0_ERROREPC);
 	printk("Cache error exception:\n");
 	printk("cp0_errorepc == %08x\n", reg_val);
 	reg_val = read_32bit_cp0_register(CP0_CACHEERR);
 	printk("cp0_cacheerr == %08x\n", reg_val);
 
 	printk("Decoded CP0_CACHEERR: %s cache fault in %s reference.\n",
-	       reg_val&(1<<30)?"secondary":"primary",
-	       reg_val&(1<<31)?"data":"insn");
+	       reg_val & (1<<30) ? "secondary" : "primary",
+	       reg_val & (1<<31) ? "data" : "insn");
 	printk("Error bits: %s%s%s%s%s%s%s\n",
-	       reg_val&(1<<29)?"ED ":"",
-	       reg_val&(1<<28)?"ET ":"",
-	       reg_val&(1<<26)?"EE ":"",
-	       reg_val&(1<<25)?"EB ":"",
-	       reg_val&(1<<24)?"EI ":"",
-	       reg_val&(1<<23)?"E1 ":"",
-	       reg_val&(1<<22)?"E0 ":"");
-	printk("IDX: 0x%08x\n", reg_val&((1<<22)-1));
+	       reg_val & (1<<29) ? "ED " : "",
+	       reg_val & (1<<28) ? "ET " : "",
+	       reg_val & (1<<26) ? "EE " : "",
+	       reg_val & (1<<25) ? "EB " : "",
+	       reg_val & (1<<24) ? "EI " : "",
+	       reg_val & (1<<23) ? "E1 " : "",
+	       reg_val & (1<<22) ? "E0 " : "");
+	printk("IDX: 0x%08x\n", reg_val & ((1<<22)-1));
 
 	if (reg_val&(1<<22))
-		printk("DErrAddr0: 0x%08x\n", read_32bit_cp0_set1_register(CP0_S1_DERRADDR0));
+		printk("DErrAddr0: 0x%08x\n",
+		       read_32bit_cp0_set1_register(CP0_S1_DERRADDR0));
 
 	if (reg_val&(1<<23))
-		printk("DErrAddr1: 0x%08x\n", read_32bit_cp0_set1_register(CP0_S1_DERRADDR1));
+		printk("DErrAddr1: 0x%08x\n",
+		       read_32bit_cp0_set1_register(CP0_S1_DERRADDR1));
 
-
-	panic("Can't handle the cache error - panic!");
+	panic("Can't handle the cache error!");
 }
 
 unsigned long exception_handlers[32];
@@ -810,7 +765,8 @@
 	unsigned handler = (unsigned long) addr;
 	unsigned old_handler = exception_handlers[n];
 	exception_handlers[n] = handler;
-	if (n == 0 && dedicated_iv_available) {
+
+	if (n == 0 && mips_cpu.options & MIPS_CPU_DIVEC) {
 		*(volatile u32 *)(KSEG0+0x200) = 0x08000000 |
 		                                 (0x03ffffff & (handler >> 2));
 		flush_icache_range(KSEG0+0x200, KSEG0 + 0x204);
@@ -823,10 +779,8 @@
 extern asmlinkage int _save_fp_context(struct sigcontext *sc);
 extern asmlinkage int _restore_fp_context(struct sigcontext *sc);
 
-#ifdef CONFIG_MIPS_FPU_EMULATOR
 extern asmlinkage int fpu_emulator_save_context(struct sigcontext *sc);
 extern asmlinkage int fpu_emulator_restore_context(struct sigcontext *sc);
-#endif
 
 void __init trap_init(void)
 {
@@ -834,13 +788,10 @@
 	extern char except_vec0_r4600, except_vec0_r2300;
 	extern char except_vec1_generic, except_vec2_generic;
 	extern char except_vec3_generic, except_vec3_r4000;
+	extern char except_vec4;
 	extern char except_vec_ejtag_debug;
 	unsigned long i;
 
-	if(mips_machtype == MACH_MIPS_MAGNUM_4000 ||
-	   mips_machtype == MACH_SNI_RM200_PCI)
-		EISA_bus = 1;
-
 	/* Some firmware leaves the BEV flag set, clear it.  */
 	clear_cp0_status(ST0_BEV);
 
@@ -852,8 +803,8 @@
 	/*
 	 * Setup default vectors
 	 */
-	for(i = 0; i <= 31; i++)
-		(void)set_except_vector(i, handle_reserved);
+	for (i = 0; i <= 31; i++)
+		set_except_vector(i, handle_reserved);
 
 	/* 
 	 * Copy the EJTAG debug exception vector handler code to it's final 
@@ -866,7 +817,15 @@
 	 * interrupt vector.
 	 */
 	watch_init();
-	setup_dedicated_int();
+
+	/*
+	 * Some MIPS CPUs have a dedicated interrupt vector which reduces the
+	 * interrupt processing overhead.  Use it where available.
+	 */
+	if (mips_cpu.options & MIPS_CPU_DIVEC) {
+		memcpy((void *)(KSEG0 + 0x200), &except_vec4, 8);
+		set_cp0_cause(CAUSEF_IV);
+	}
 
 	/*
 	 * Some CPUs can enable/disable for cache parity detection, but does
@@ -874,35 +833,38 @@
 	 */
 	parity_protection_init();
 
-	(void)set_except_vector(1, handle_mod);
-	(void)set_except_vector(2, handle_tlbl);
-	(void)set_except_vector(3, handle_tlbs);
-	(void)set_except_vector(4, handle_adel);
-	(void)set_except_vector(5, handle_ades);
+	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.
 	 */
-	(void)set_except_vector(6, handle_ibe);
-	(void)set_except_vector(7, handle_dbe);
+	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;
 
-	(void)set_except_vector(8, handle_sys);
-	(void)set_except_vector(9, handle_bp);
-	(void)set_except_vector(10, handle_ri);
-	(void)set_except_vector(11, handle_cpu);
-	(void)set_except_vector(12, handle_ov);
-	(void)set_except_vector(13, handle_tr);
-	(void)set_except_vector(15, handle_fpe);
-	
+	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);
+
+	if (mips_cpu.options & MIPS_CPU_FPU)
+		set_except_vector(15, handle_fpe);
+
 	/*
 	 * Handling the following exceptions depends mostly of the cpu type
 	 */
 	if ((mips_cpu.options & MIPS_CPU_4KEX)
 	    && (mips_cpu.options & MIPS_CPU_4KTLB)) {
-		if(mips_cpu.cputype == CPU_NEVADA) {
+		if (mips_cpu.cputype == CPU_NEVADA) {
 			memcpy((void *)KSEG0, &except_vec0_nevada, 0x80);
 		} else if (mips_cpu.cputype == CPU_R4600)
 			memcpy((void *)KSEG0, &except_vec0_r4600, 0x80);
@@ -919,36 +881,25 @@
 			       0x80);
 		}
 
-		if(mips_cpu.options & MIPS_CPU_FPU) {
+		if (mips_cpu.options & MIPS_CPU_FPU) {
 		        save_fp_context = _save_fp_context;
 			restore_fp_context = _restore_fp_context;
-#ifdef CONFIG_MIPS_FPU_EMULATOR
 		} else {
 		        save_fp_context = fpu_emulator_save_context;
 			restore_fp_context = fpu_emulator_restore_context;
-#endif
 		}
-	} else switch(mips_cpu.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);
+	} else switch (mips_cpu.cputype) {
+	case CPU_SB1:
 		/*
-		 * The R10k might even work for Linux/MIPS - but we're paranoid
-		 * and refuse to run until this is tested on real silicon
+		 * XXX - This should be folded in to the "cleaner" handling,
+		 * above
 		 */
-		panic("CPU too expensive - making holiday in the ANDES!");
-		break;
-	case CPU_SB1:
-		/* XXX - This should be folded in to the "cleaner" handling, above */
 		memcpy((void *)KSEG0, &except_vec0_r4000, 0x80);
 		memcpy((void *)(KSEG0 + 0x180), &except_vec3_r4000, 0x80);
 		save_fp_context = _save_fp_context;
 		restore_fp_context = _restore_fp_context;
-		/* Enable timer interrupt and scd mapped interrupt in status register */
+
+		/* Enable timer interrupt and scd mapped interrupt */
 		clear_cp0_status(0xf000);
 		set_cp0_status(0xc00);
 		break;
@@ -983,17 +934,15 @@
 		memcpy((void *)KSEG0, &except_vec0_r2300, 0x80);
 		memcpy((void *)(KSEG0 + 0x80), &except_vec3_generic, 0x80);
 		break;
-	case CPU_R8000:
-		printk("Detected unsupported CPU type %s.\n",
-			cpu_names[mips_cpu.cputype]);
-		panic("Can't handle CPU");
-		break;
 
 	case CPU_UNKNOWN:
 	default:
 		panic("Unknown CPU type");
 	}
 	flush_icache_range(KSEG0, KSEG0 + 0x200);
+
+	if (mips_cpu.isa_level == MIPS_CPU_ISA_IV)
+		set_cp0_status(ST0_XX);
 
 	atomic_inc(&init_mm.mm_count);	/* XXX  UP?  */
 	current->active_mm = &init_mm;
diff -u --recursive --new-file v2.4.9/linux/arch/mips/kernel/unaligned.c linux/arch/mips/kernel/unaligned.c
--- v2.4.9/linux/arch/mips/kernel/unaligned.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/mips/kernel/unaligned.c	Sun Sep  9 10:43:01 2001
@@ -72,6 +72,7 @@
  *       A store crossing a page boundary might be executed only partially.
  *       Undo the partial store in this case.
  */
+#include <linux/config.h>
 #include <linux/mm.h>
 #include <linux/signal.h>
 #include <linux/smp.h>
@@ -378,26 +379,26 @@
 	return;
 }
 
+#ifdef CONFIG_PROC_FS
 unsigned long unaligned_instructions;
+#endif
 
 asmlinkage void do_ade(struct pt_regs *regs)
 {
 	unsigned long pc;
-#ifdef CONFIG_MIPS_FPU_EMULATOR
-        extern int do_dsemulret(struct pt_regs *);
+	extern int do_dsemulret(struct pt_regs *);
+
+	/* 
+	 * Address errors may be deliberately induced
+	 * by the FPU emulator to take retake control
+	 * of the CPU after executing the instruction
+	 * in the delay slot of an emulated branch.
+	 */
 
-        /* 
-         * Address errors may be deliberately induced
-         * by the FPU emulator to take retake control
-         * of the CPU after executing the instruction
-         * in the delay slot of an emulated branch.
-         */
-
-        if((unsigned long)regs->cp0_epc == current->thread.dsemul_aerpc) {
-                (void)do_dsemulret(regs);
-                return;
-        }
-#endif /* CONFIG_MIPS_FPU_EMULATOR */
+	if ((unsigned long)regs->cp0_epc == current->thread.dsemul_aerpc) {
+		do_dsemulret(regs);
+		return;
+	}
 
 	/*
 	 * Did we catch a fault trying to load an instruction?
@@ -414,7 +415,9 @@
 		goto sigbus;
 
 	emulate_load_store_insn(regs, regs->cp0_badvaddr, pc);
+#ifdef CONFIG_PROC_FS
 	unaligned_instructions++;
+#endif
 
 	return;
 
diff -u --recursive --new-file v2.4.9/linux/arch/mips/lib/ide-std.c linux/arch/mips/lib/ide-std.c
--- v2.4.9/linux/arch/mips/lib/ide-std.c	Sat May 13 08:29:14 2000
+++ linux/arch/mips/lib/ide-std.c	Sun Sep  9 10:43:01 2001
@@ -1,12 +1,11 @@
-/* $Id: ide-std.c,v 1.4 1999/06/11 14:29:45 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
+ * Copyright (C) 1998, 1999, 2001 by Ralf Baechle
  */
 #include <linux/sched.h>
 #include <linux/ide.h>
@@ -60,6 +59,7 @@
 	}
 	if (irq != NULL)
 		*irq = 0;
+	hw->io_ports[IDE_IRQ_OFFSET] = 0;
 }
 
 static int std_ide_request_irq(unsigned int irq,
diff -u --recursive --new-file v2.4.9/linux/arch/mips/lib/memcpy.S linux/arch/mips/lib/memcpy.S
--- v2.4.9/linux/arch/mips/lib/memcpy.S	Tue Dec  5 23:15:12 2000
+++ linux/arch/mips/lib/memcpy.S	Sun Sep  9 10:43:01 2001
@@ -402,16 +402,20 @@
 
 	.align	5
 LEAF(memmove)
-	sltu	t0, a0, a1			# dst < src -> memcpy
-	bnez	t0, memcpy
-	 addu	v0, a0, a2
-	sltu	t0, v0, a1			# dst + len < src -> non-
-	bnez	t0, __memcpy			# overlapping, can use memcpy
+	addu	t0, a0, a2
+	sltu	t0, a1, t0			# dst + len <= src -> memcpy
+	addu	t1, a1, a2
+	sltu	t1, a0, t1			# dst >= src + len -> memcpy
+	and	t0, t1
+	beqz	t0, __memcpy
 	 move	v0, a0				/* return value */
 	beqz	a2, r_out
 	END(memmove)
 
 LEAF(__rmemcpy)					/* a0=dst a1=src a2=len */
+	sltu	t0, a1, a0
+	beqz	t0, r_end_bytes_up		# src >= dst
+	 nop
 	addu	a0, a2				# dst = dst + len
 	addu	a1, a2				# src = src + len
 
@@ -563,6 +567,17 @@
 	 subu	a0, a0, 0x1
 
 r_out:
+	jr	ra
+	 move	a2, zero
+
+r_end_bytes_up:
+	lb	t0, (a1)
+	subu	a2, a2, 0x1
+	sb	t0, (a0)
+	addu	a1, a1, 0x1
+	bnez	a2, r_end_bytes_up
+	 addu	a0, a0, 0x1
+
 	jr	ra
 	 move	a2, zero
 
diff -u --recursive --new-file v2.4.9/linux/arch/mips/math-emu/cp1emu.c linux/arch/mips/math-emu/cp1emu.c
--- v2.4.9/linux/arch/mips/math-emu/cp1emu.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/mips/math-emu/cp1emu.c	Sun Sep  9 10:43:01 2001
@@ -5,7 +5,8 @@
  * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
  * http://www.algor.co.uk
  *
- * ########################################################################
+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000  MIPS Technologies, Inc.
  *
  *  This program is free software; you can distribute it and/or modify it
  *  under the terms of the GNU General Public License (Version 2) as
@@ -20,8 +21,6 @@
  *  with this program; if not, write to the Free Software Foundation, Inc.,
  *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  *
- * ########################################################################
- *
  * A complete emulator for MIPS coprocessor 1 instructions.  This is
  * required for #float(switch) or #float(trap), where it catches all
  * COP1 instructions via the "CoProcessor Unusable" exception.  
@@ -32,24 +31,9 @@
  * quite nasty because emulation of some non-COP1 instructions is
  * required, e.g. in branch delay slots.
  * 
- * Notes: 
- *  1) the IEEE754 library (-le) performs the actual arithmetic;
- *  2) if you know that you won't have an fpu, then you'll get much 
- *     better performance by compiling with -msoft-float!  */
-
-/**************************************************************************
- *  Nov 7, 2000
- *  Massive changes to integrate with Linux kernel.
- *
- *  Replace use of kernel data area with use of user stack 
- *  for execution of instructions in branch delay slots.
- *
- *  Replace use of static kernel variables with thread_struct elements.
- *
- *  Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
- *  Copyright (C) 2000  MIPS Technologies, Inc.  All rights reserved.
- *************************************************************************/
-#include <linux/config.h>
+ * Note if you know that you won't have an fpu, then you'll get much 
+ * better performance by compiling with -msoft-float!
+ */
 #include <linux/mm.h>
 #include <linux/signal.h>
 #include <linux/smp.h>
@@ -57,7 +41,9 @@
 
 #include <asm/asm.h>
 #include <asm/branch.h>
+#include <asm/bootinfo.h>
 #include <asm/byteorder.h>
+#include <asm/cpu.h>
 #include <asm/inst.h>
 #include <asm/uaccess.h>
 #include <asm/processor.h>
@@ -181,19 +167,17 @@
 #define REG_TO_VA (vaddr_t)
 #define VA_TO_REG (unsigned long)
 
-static unsigned long
-mips_get_word(struct pt_regs *xcp, void *va, int *perr)
+static unsigned long mips_get_word(struct pt_regs *xcp, void *va, int *perr)
 {
 	unsigned long temp;
 
 	if (!user_mode(xcp)) {
 		*perr = 0;
 		return (*(unsigned long *) va);
-	} else {
-		/* Use kernel get_user() macro */
-		*perr = (int) get_user(temp, (unsigned long *) va);
-		return temp;
 	}
+
+	*perr = (int) get_user(temp, (unsigned long *) va);
+	return temp;
 }
 
 static unsigned long long
@@ -204,11 +188,10 @@
 	if (!user_mode(xcp)) {
 		*perr = 0;
 		return (*(unsigned long long *) va);
-	} else {
-		/* Use kernel get_user() macro */
-		*perr = (int) get_user(temp, (unsigned long long *) va);
-		return temp;
 	}
+
+	*perr = (int) get_user(temp, (unsigned long long *) va);
+	return temp;
 }
 
 static int mips_put_word(struct pt_regs *xcp, void *va, unsigned long val)
@@ -216,10 +199,9 @@
 	if (!user_mode(xcp)) {
 		*(unsigned long *) va = val;
 		return 0;
-	} else {
-		/* Use kernel get_user() macro */
-		return (int) put_user(val, (unsigned long *) va);
 	}
+
+	return put_user(val, (unsigned long *) va);
 }
 
 static int mips_put_dword(struct pt_regs *xcp, void *va, long long val)
@@ -227,10 +209,9 @@
 	if (!user_mode(xcp)) {
 		*(unsigned long long *) va = val;
 		return 0;
-	} else {
-		/* Use kernel get_user() macro */
-		return (int) put_user(val, (unsigned long long *) va);
 	}
+
+	return put_user(val, (unsigned long long *) va);
 }
 
 
@@ -249,9 +230,7 @@
  * Two instructions if the instruction is in a branch delay slot.
  */
 
-static int
-cop1Emulate(int xcptno, struct pt_regs *xcp,
-	    struct mips_fpu_soft_struct *ctx)
+static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
 {
 	mips_instruction ir;
 	vaddr_t emulpc;
@@ -259,7 +238,6 @@
 	unsigned int cond;
 	int err = 0;
 
-
 	ir = mips_get_word(xcp, REG_TO_VA xcp->cp0_epc, &err);
 	if (err) {
 		fpuemuprivate.stats.errors++;
@@ -303,7 +281,7 @@
 		contpc = REG_TO_VA xcp->cp0_epc + 4;
 	}
 
-      emul:
+emul:
 	fpuemuprivate.stats.emulated++;
 	switch (MIPSInst_OPCODE(ir)) {
 #ifdef CP0_STATUS_FR_SUPPORT
@@ -491,9 +469,8 @@
 			}
 			break;
 
-		case dmtc_op:
+		case dmtc_op: {
 			/* copregister fs <- rt */
-			{
 				fpureg_t value;
 				int fs = MIPSInst_RD(ir);
 				if (!(xcp->cp0_status & ST0_FR))
@@ -502,8 +479,8 @@
 				    (MIPSInst_RT(ir) ==
 				     0) ? 0 : xcp->regs[MIPSInst_RT(ir)];
 				ctx->regs[fs] = value;
-			}
 			break;
+		}
 #endif
 
 		case mfc_op:
@@ -638,95 +615,92 @@
 			}
 			break;
 
-		case bc_op:
-			if (xcp->cp0_cause & CAUSEF_BD) {
+		case bc_op: {
+			int likely = 0;
+
+			if (xcp->cp0_cause & CAUSEF_BD)
 				return SIGILL;
-			}
-			{
-				int likely = 0;
 
 #if __mips >= 4
-				cond =
-				    ctx->
-				    sr & fpucondbit[MIPSInst_RT(ir) >> 2];
+			cond = ctx-> sr & fpucondbit[MIPSInst_RT(ir) >> 2];
 #else
-				cond = ctx->sr & FPU_CSR_COND;
+			cond = ctx->sr & FPU_CSR_COND;
 #endif
-				switch (MIPSInst_RT(ir) & 3) {
-				case bcfl_op:
-					likely = 1;
-				case bcf_op:
-					cond = !cond;
-					break;
-				case bctl_op:
-					likely = 1;
-				case bct_op:
-					break;
-				default:
-					/* thats an illegal instruction */
-					return SIGILL;
-				}
+			switch (MIPSInst_RT(ir) & 3) {
+			case bcfl_op:
+				likely = 1;
+			case bcf_op:
+				cond = !cond;
+				break;
+			case bctl_op:
+				likely = 1;
+			case bct_op:
+				break;
+			default:
+				/* thats an illegal instruction */
+				return SIGILL;
+			}
 
-				xcp->cp0_cause |= CAUSEF_BD;
-				if (cond) {
-					/* branch taken: emulate dslot instruction */
-					xcp->cp0_epc += 4;
-					contpc =
-					    REG_TO_VA xcp->cp0_epc +
-					    (MIPSInst_SIMM(ir) << 2);
-
-					ir =
-					    mips_get_word(xcp,
-							  REG_TO_VA(xcp->
-								    cp0_epc),
-							  &err);
-					if (err) {
-						fpuemuprivate.stats.
-						    errors++;
-						return SIGBUS;
-					}
+			xcp->cp0_cause |= CAUSEF_BD;
+			if (cond) {
+				/* branch taken: emulate dslot instruction */
+				xcp->cp0_epc += 4;
+				contpc = REG_TO_VA xcp->cp0_epc +
+				         (MIPSInst_SIMM(ir) << 2);
+
+				ir = mips_get_word(xcp, REG_TO_VA(xcp->cp0_epc),
+				      &err);
+				if (err) {
+					fpuemuprivate.stats.errors++;
+					return SIGBUS;
+				}
 
-					switch (MIPSInst_OPCODE(ir)) {
-					case lwc1_op:
-					case swc1_op:
+				switch (MIPSInst_OPCODE(ir)) {
+				case lwc1_op:
+				case swc1_op:
 #if (__mips >= 2 || __mips64) && !defined(SINGLE_ONLY_FPU)
-					case ldc1_op:
-					case sdc1_op:
+				case ldc1_op:
+				case sdc1_op:
 #endif
-					case cop1_op:
+				case cop1_op:
 #if __mips >= 4 && __mips != 32
-					case cop1x_op:
+				case cop1x_op:
 #endif
-						/* its one of ours */
-						goto emul;
+					/* its one of ours */
+					goto emul;
 #if __mips >= 4
-					case spec_op:
-						if (MIPSInst_FUNC(ir) ==
-						    movc_op) goto emul;
-						break;
+				case spec_op:
+					if (MIPSInst_FUNC(ir) == movc_op)
+						goto emul;
+					break;
 #endif
-					}
+				}
 
-					/* single step the non-cp1 instruction in the dslot */
-					return mips_dsemul(xcp, ir,
-							   contpc);
-				} else {
-					/* branch not taken */
-					if (likely)
-						/* branch likely nullifies dslot if not taken */
-						xcp->cp0_epc += 4;
+				/*
+				 * Single step the non-cp1 instruction in the
+				 * dslot
+				 */
+				return mips_dsemul(xcp, ir, contpc);
+			} else {
+				/* branch not taken */
+				if (likely)
+					/*
+					 * branch likely nullifies dslot if not
+					 * taken
+					 */
+					xcp->cp0_epc += 4;
 					/* else continue & execute dslot as normal insn */
-				}
 			}
 			break;
+		}
 
-		default:
-			if (!(MIPSInst_RS(ir) & 0x10)) {
+		default: {
+			int sig;
+
+			if (!(MIPSInst_RS(ir) & 0x10))
 				return SIGILL;
-			}
+
 			/* a real fpu computation instruction */
-			{
-				int sig;
 				if ((sig = fpu_emu(xcp, ctx, ir)))
 					return sig;
 			}
@@ -822,14 +796,15 @@
 	 */
 	dsemul_insns = (mips_instruction *) (xcp->regs[29] & ~3);
 	dsemul_insns -= 3;	/* Two instructions, plus one for luck ;-) */
+
 	/* Verify that the stack pointer is not competely insane */
-	if (verify_area
-	    (VERIFY_WRITE, dsemul_insns, sizeof(mips_instruction) * 2))
+	if (verify_area(VERIFY_WRITE, dsemul_insns,
+	                sizeof(mips_instruction) * 2))
 		return SIGBUS;
 
 	if (mips_put_word(xcp, &dsemul_insns[0], ir)) {
 		fpuemuprivate.stats.errors++;
-		return (SIGBUS);
+		return SIGBUS;
 	}
 
 	/* 
@@ -856,11 +831,8 @@
 	current->thread.dsemul_epc = (unsigned long) cpc;
 	current->thread.dsemul_aerpc = (unsigned long) &dsemul_insns[1];
 	xcp->cp0_epc = VA_TO_REG & dsemul_insns[0];
+	flush_cache_sigtramp((unsigned long) dsemul_insns);
 
-	/* What we'd really like to do is just flush the line(s) of the */
-	/* icache containing the dsemulret instructions, but there's no */
-	/* mechanism to do this yet...  */
-	flush_cache_all();
 	return SIGILL;		/* force out of emulation loop */
 }
 
@@ -971,9 +943,8 @@
 	return ieee754sp_neg(ieee754sp_sub(ieee754sp_mul(s, t), r));
 }
 
-static int
-fpux_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
-	 mips_instruction ir)
+static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
+                    mips_instruction ir)
 {
 	unsigned rcsr = 0;	/* resulting csr */
 
@@ -1226,9 +1197,8 @@
 /*
  * Emulate a single COP1 arithmetic instruction.
  */
-static int
-fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
-	mips_instruction ir)
+static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
+                   mips_instruction ir)
 {
 	int rfmt;		/* resulting format */
 	unsigned rcsr = 0;	/* resulting csr */
@@ -1244,8 +1214,7 @@
 
 	fpuemuprivate.stats.cp1ops++;
 	switch (rfmt = (MIPSInst_FFMT(ir) & 0xf)) {
-
-	case s_fmt:{		/* 0 */
+	case s_fmt: {		/* 0 */
 		ieee754sp(*handler) ();
 
 		switch (MIPSInst_FUNC(ir)) {
@@ -1342,73 +1311,68 @@
 				/* unary conv ops */
 		case fcvts_op:
 			return SIGILL;	/* not defined */
-		case fcvtd_op:
-#if defined(SINGLE_ONLY_FPU)
+		case fcvtd_op: {
+#ifdef SINGLE_ONLY_FPU
 			return SIGILL;	/* not defined */
 #else
-			{
-				ieee754sp fs;
+			ieee754sp fs;
 
-				SPFROMREG(fs, MIPSInst_FS(ir));
-				rv.d = ieee754dp_fsp(fs);
-				rfmt = d_fmt;
-				goto copcsr;
-			}
+			SPFROMREG(fs, MIPSInst_FS(ir));
+			rv.d = ieee754dp_fsp(fs);
+			rfmt = d_fmt;
+			goto copcsr;
+		}
 #endif
-		case fcvtw_op:
-			{
-				ieee754sp fs;
+		case fcvtw_op: {
+			ieee754sp fs;
 
-				SPFROMREG(fs, MIPSInst_FS(ir));
-				rv.w = ieee754sp_tint(fs);
-				rfmt = w_fmt;
-				goto copcsr;
-			}
+			SPFROMREG(fs, MIPSInst_FS(ir));
+			rv.w = ieee754sp_tint(fs);
+			rfmt = w_fmt;
+			goto copcsr;
+		}
 
 #if __mips >= 2 || __mips64
 		case fround_op:
 		case ftrunc_op:
 		case fceil_op:
-		case ffloor_op:
-			{
-				unsigned int oldrm = ieee754_csr.rm;
-				ieee754sp fs;
-
-				SPFROMREG(fs, MIPSInst_FS(ir));
-				ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3];
-				rv.w = ieee754sp_tint(fs);
-				ieee754_csr.rm = oldrm;
-				rfmt = w_fmt;
-				goto copcsr;
-			}
-#endif			/* __mips >= 2 */
+		case ffloor_op: {
+			unsigned int oldrm = ieee754_csr.rm;
+			ieee754sp fs;
+
+			SPFROMREG(fs, MIPSInst_FS(ir));
+			ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3];
+			rv.w = ieee754sp_tint(fs);
+			ieee754_csr.rm = oldrm;
+			rfmt = w_fmt;
+			goto copcsr;
+		}
+#endif /* __mips >= 2 */
 
 #if __mips64 && !defined(SINGLE_ONLY_FPU)
-		case fcvtl_op:
-			{
-				ieee754sp fs;
+		case fcvtl_op: {
+			ieee754sp fs;
 
-				SPFROMREG(fs, MIPSInst_FS(ir));
-				rv.l = ieee754sp_tlong(fs);
-				rfmt = l_fmt;
-				goto copcsr;
-			}
+			SPFROMREG(fs, MIPSInst_FS(ir));
+			rv.l = ieee754sp_tlong(fs);
+			rfmt = l_fmt;
+			goto copcsr;
+		}
 
 		case froundl_op:
 		case ftruncl_op:
 		case fceill_op:
-		case ffloorl_op:
-			{
-				unsigned int oldrm = ieee754_csr.rm;
-				ieee754sp fs;
-
-				SPFROMREG(fs, MIPSInst_FS(ir));
-				ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3];
-				rv.l = ieee754sp_tlong(fs);
-				ieee754_csr.rm = oldrm;
-				rfmt = l_fmt;
-				goto copcsr;
-			}
+		case ffloorl_op: {
+			unsigned int oldrm = ieee754_csr.rm;
+			ieee754sp fs;
+
+			SPFROMREG(fs, MIPSInst_FS(ir));
+			ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3];
+			rv.l = ieee754sp_tlong(fs);
+			ieee754_csr.rm = oldrm;
+			rfmt = l_fmt;
+			goto copcsr;
+		}
 #endif /* __mips64 && !fpu(single) */
 
 		default:
@@ -1484,9 +1448,11 @@
 		case fabs_op:
 			handler = ieee754dp_abs;
 			goto dcopuop;
+
 		case fneg_op:
 			handler = ieee754dp_neg;
 			goto dcopuop;
+
 		case fmov_op:
 			/* an easy one */
 			DPFROMREG(rv.d, MIPSInst_FS(ir));
@@ -1513,71 +1479,67 @@
 			}
 
 		/* unary conv ops */
-		case fcvts_op:
-			{
-				ieee754dp fs;
+		case fcvts_op: {
+			ieee754dp fs;
 
-				DPFROMREG(fs, MIPSInst_FS(ir));
-				rv.s = ieee754sp_fdp(fs);
-				rfmt = s_fmt;
-				goto copcsr;
-			}
+			DPFROMREG(fs, MIPSInst_FS(ir));
+			rv.s = ieee754sp_fdp(fs);
+			rfmt = s_fmt;
+			goto copcsr;
+		}
 		case fcvtd_op:
 			return SIGILL;	/* not defined */
-		case fcvtw_op:
-			{
-				ieee754dp fs;
 
-				DPFROMREG(fs, MIPSInst_FS(ir));
-				rv.w = ieee754dp_tint(fs);	/* wrong */
-				rfmt = w_fmt;
-				goto copcsr;
-			}
+		case fcvtw_op: {
+			ieee754dp fs;
+
+			DPFROMREG(fs, MIPSInst_FS(ir));
+			rv.w = ieee754dp_tint(fs);	/* wrong */
+			rfmt = w_fmt;
+			goto copcsr;
+		}
 
 #if __mips >= 2 || __mips64
 		case fround_op:
 		case ftrunc_op:
 		case fceil_op:
-		case ffloor_op:
-			{
-				unsigned int oldrm = ieee754_csr.rm;
-				ieee754dp fs;
-
-				DPFROMREG(fs, MIPSInst_FS(ir));
-				ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3];
-				rv.w = ieee754dp_tint(fs);
-				ieee754_csr.rm = oldrm;
-				rfmt = w_fmt;
-				goto copcsr;
-			}
+		case ffloor_op: {
+			unsigned int oldrm = ieee754_csr.rm;
+			ieee754dp fs;
+
+			DPFROMREG(fs, MIPSInst_FS(ir));
+			ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3];
+			rv.w = ieee754dp_tint(fs);
+			ieee754_csr.rm = oldrm;
+			rfmt = w_fmt;
+			goto copcsr;
+		}
 #endif
 
 #if __mips64 && !defined(SINGLE_ONLY_FPU)
-		case fcvtl_op:
-			{
-				ieee754dp fs;
+		case fcvtl_op: {
+			ieee754dp fs;
 
-				DPFROMREG(fs, MIPSInst_FS(ir));
-				rv.l = ieee754dp_tlong(fs);
-				rfmt = l_fmt;
-				goto copcsr;
-			}
+			DPFROMREG(fs, MIPSInst_FS(ir));
+			rv.l = ieee754dp_tlong(fs);
+			rfmt = l_fmt;
+			goto copcsr;
+		}
 
 		case froundl_op:
 		case ftruncl_op:
 		case fceill_op:
-		case ffloorl_op:
-			{
-				unsigned int oldrm = ieee754_csr.rm;
-				ieee754dp fs;
-
-				DPFROMREG(fs, MIPSInst_FS(ir));
-				ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3];
-				rv.l = ieee754dp_tlong(fs);
-				ieee754_csr.rm = oldrm;
-				rfmt = l_fmt;
-				goto copcsr;
-			}
+		case ffloorl_op: {
+			unsigned int oldrm = ieee754_csr.rm;
+			ieee754dp fs;
+
+			DPFROMREG(fs, MIPSInst_FS(ir));
+			ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3];
+			rv.l = ieee754dp_tlong(fs);
+			ieee754_csr.rm = oldrm;
+			rfmt = l_fmt;
+			goto copcsr;
+		}
 #endif /* __mips >= 3 && !fpu(single) */
 
 		default:
@@ -1598,7 +1560,7 @@
 		}
 		break;
 	}
-#endif				/* !defined(SINGLE_ONLY_FPU) */
+#endif /* !defined(SINGLE_ONLY_FPU) */
 
 	case w_fmt: {
 		switch (MIPSInst_FUNC(ir)) {
@@ -1698,12 +1660,11 @@
 
 
 /*
- * Emulate the floating point instruction at EPC, and continue
- * to run until we hit a non-fp instruction, or a backward
- * branch.  This cuts down dramatically on the per instruction 
- * exception overhead.
+ * Emulate the floating point instruction at EPC, and continue to run until we
+ * hit a non-fp instruction, or a backward branch.  This cuts down dramatically
+ * on the per instruction exception overhead.
  */
-int fpu_emulator_cop1Handler(int xcptno, struct pt_regs *xcp)
+int fpu_emulator_cop1Handler(struct pt_regs *xcp)
 {
 	struct mips_fpu_soft_struct *ctx = &current->thread.fpu.soft;
 	unsigned long oldepc, prevepc;
@@ -1713,6 +1674,9 @@
 
 	oldepc = xcp->cp0_epc;
 	do {
+		if (current->need_resched)
+			schedule();
+
 		prevepc = xcp->cp0_epc;
 		insn = mips_get_word(xcp, REG_TO_VA(xcp->cp0_epc), &err);
 		if (err) {
@@ -1720,9 +1684,12 @@
 			return SIGBUS;
 		}
 		if (insn != 0)
-			sig = cop1Emulate(xcptno, xcp, ctx);
+			sig = cop1Emulate(xcp, ctx);
 		else
 			xcp->cp0_epc += 4;	/* skip nops */
+
+		if (mips_cpu.options & MIPS_CPU_FPU)
+			break;
 	} while (xcp->cp0_epc > prevepc && sig == 0);
 
 	/* SIGILL indicates a non-fpu instruction */
@@ -1753,7 +1720,7 @@
 
 	/* get current rounding mode for IEEE library, and emulate insn */
 	ieee754_csr.rm = ieee_rm[ctx->sr & 0x3];
-	sig = cop1Emulate(xcptno, xcp, ctx);
+	sig = cop1Emulate(xcp, ctx);
 
 	/* don't return with f.p. exceptions pending */
 	ctx->sr &= ~FPU_CSR_ALL_X;
@@ -1809,4 +1776,3 @@
 	}
 }
 #endif
-
diff -u --recursive --new-file v2.4.9/linux/arch/mips/mips-boards/atlas/atlas_int.c linux/arch/mips/mips-boards/atlas/atlas_int.c
--- v2.4.9/linux/arch/mips/mips-boards/atlas/atlas_int.c	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/mips-boards/atlas/atlas_int.c	Sun Sep  9 10:43:02 2001
@@ -51,6 +51,11 @@
 #define DEBUG_INT(x...)
 #endif
 
+void inline disable_irq_nosync(unsigned int irq_nr)
+{
+	disable_atlas_irq(irq_nr);
+}
+
 void disable_atlas_irq(unsigned int irq_nr)
 {
 	atlas_hw0_icregs->intrsten = (1 << irq_nr);
diff -u --recursive --new-file v2.4.9/linux/arch/mips/mips-boards/atlas/atlas_rtc.c linux/arch/mips/mips-boards/atlas/atlas_rtc.c
--- v2.4.9/linux/arch/mips/mips-boards/atlas/atlas_rtc.c	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/mips-boards/atlas/atlas_rtc.c	Sun Sep  9 10:43:02 2001
@@ -22,7 +22,6 @@
  * RTC routines for Atlas style attached Dallas chip.
  *
  */
-#include <linux/spinlock.h>
 #include <linux/mc146818rtc.h>
 #include <asm/mips-boards/atlas.h>
 
diff -u --recursive --new-file v2.4.9/linux/arch/mips/mips-boards/atlas/atlas_setup.c linux/arch/mips/mips-boards/atlas/atlas_setup.c
--- v2.4.9/linux/arch/mips/mips-boards/atlas/atlas_setup.c	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/mips-boards/atlas/atlas_setup.c	Sun Sep  9 10:43:02 2001
@@ -54,8 +54,8 @@
 	char rs_getDebugChar(void);
 	int saa9730_putDebugChar(char);
 	char saa9730_getDebugChar(void);
-	extern int (*putDebugChar)(char);
-	extern char (*getDebugChar)(void);
+	extern int (*generic_putDebugChar)(char);
+	extern char (*generic_getDebugChar)(void);
 #endif
 	char *argptr;
 
@@ -89,12 +89,12 @@
 
 		if(line == 0) {
 			rs_kgdb_hook(line);
-			putDebugChar = rs_putDebugChar;
-			getDebugChar = rs_getDebugChar;
+			generic_putDebugChar = rs_putDebugChar;
+			generic_getDebugChar = rs_getDebugChar;
 		} else {
 			saa9730_kgdb_hook();
-			putDebugChar = saa9730_putDebugChar;
-			getDebugChar = saa9730_getDebugChar;
+			generic_putDebugChar = saa9730_putDebugChar;
+			generic_getDebugChar = saa9730_getDebugChar;
 		}
 
 		prom_printf("KGDB: Using serial line /dev/ttyS%d for session, "
diff -u --recursive --new-file v2.4.9/linux/arch/mips/mips-boards/generic/cmdline.c linux/arch/mips/mips-boards/generic/cmdline.c
--- v2.4.9/linux/arch/mips/mips-boards/generic/cmdline.c	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/mips-boards/generic/cmdline.c	Sun Sep  9 10:43:02 2001
@@ -17,6 +17,7 @@
  *
  * Kernel command line creation using the prom monitor (YAMON) argc/argv.
  */
+#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/string.h>
 
diff -u --recursive --new-file v2.4.9/linux/arch/mips/mips-boards/generic/gdb_hook.c linux/arch/mips/mips-boards/generic/gdb_hook.c
--- v2.4.9/linux/arch/mips/mips-boards/generic/gdb_hook.c	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/mips-boards/generic/gdb_hook.c	Sun Sep  9 10:43:02 2001
@@ -23,7 +23,6 @@
  *
  */
 
-#include <linux/config.h>
 #include <linux/serialP.h>
 #include <linux/serial_reg.h>
 
@@ -36,8 +35,8 @@
 
 static struct async_struct kdb_port_info = {0};
 
-int (*putDebugChar)(char);
-char (*getDebugChar)(void);
+int (*generic_putDebugChar)(char);
+char (*generic_getDebugChar)(void);
 
 static __inline__ unsigned int serial_in(struct async_struct *info, int offset)
 {
@@ -96,6 +95,16 @@
 	serial_out(&kdb_port_info, UART_DLM, t >> 8);  /* MS of divisor */
 	/* reset DLAB */
 	serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8);
+}
+
+int putDebugChar(char c)
+{
+	return generic_putDebugChar(c);
+}
+
+char getDebugChar(void) 
+{
+	return generic_getDebugChar();
 }
 
 int rs_putDebugChar(char c)
diff -u --recursive --new-file v2.4.9/linux/arch/mips/mips-boards/generic/memory.c linux/arch/mips/mips-boards/generic/memory.c
--- v2.4.9/linux/arch/mips/mips-boards/generic/memory.c	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/mips-boards/generic/memory.c	Sun Sep  9 10:43:02 2001
@@ -50,6 +50,11 @@
 };
 #endif
 
+/* References to section boundaries */
+extern char _end;
+
+#define PFN_ALIGN(x)    (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK)
+
 
 struct prom_pmemblock * __init prom_getmdesc(void)
 {
@@ -94,9 +99,13 @@
 	mdesc[2].size = 0x00010000;
 #endif
 
-	mdesc[3].type = yamon_free;
+	mdesc[3].type = yamon_dontuse;
 	mdesc[3].base = 0x00100000;
-	mdesc[3].size = memsize - mdesc[3].base;
+	mdesc[3].size = PHYSADDR(PFN_ALIGN(&_end)) - mdesc[3].base;
+
+	mdesc[4].type = yamon_free;
+	mdesc[4].base = PHYSADDR(PFN_ALIGN(&_end));
+	mdesc[4].size = memsize - mdesc[4].base;
 
 	return &mdesc[0];
 }
@@ -118,11 +127,10 @@
 	struct prom_pmemblock *p;
 
 #ifdef DEBUG
-	int i = 0;
-
 	prom_printf("YAMON MEMORY DESCRIPTOR dump:\n");
 	p = prom_getmdesc();
 	while (p->size) {
+		int i = 0;
 		prom_printf("[%d,%p]: base<%08lx> size<%08lx> type<%s>\n",
 			    i, p, p->base, p->size, mtypes[p->type]);
 		p++;
@@ -130,24 +138,24 @@
 	}
 #endif
 	p = prom_getmdesc();
+
 	while (p->size) {
-		unsigned long base, size;
 		long type;
+		unsigned long base, size;
 
 		type = prom_memtype_classify (p->type);
 		base = p->base;
 		size = p->size;
 
 		add_memory_region(base, size, type);
-
-		p++;
+                p++; 
 	}
 }
 
-void prom_free_prom_memory (void)
+void __init
+prom_free_prom_memory (void)
 {
 	int i;
-	struct prom_pmemblock *p;
 	unsigned long freed = 0;
 	unsigned long addr;
 
@@ -158,9 +166,9 @@
 		addr = boot_mem_map.map[i].addr;
 		while (addr < boot_mem_map.map[i].addr
 			      + boot_mem_map.map[i].size) {
-		        ClearPageReserved(virt_to_page(phys_to_virt(addr)));
-			set_page_count(virt_to_page(phys_to_virt(addr)), 1);
-			free_page(phys_to_virt(addr));
+			ClearPageReserved(virt_to_page(__va(addr)));
+			set_page_count(virt_to_page(__va(addr)), 1);
+			free_page(__va(addr));
 			addr += PAGE_SIZE;
 			freed += PAGE_SIZE;
 		}
diff -u --recursive --new-file v2.4.9/linux/arch/mips/mips-boards/generic/pci.c linux/arch/mips/mips-boards/generic/pci.c
--- v2.4.9/linux/arch/mips/mips-boards/generic/pci.c	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/mips-boards/generic/pci.c	Sun Sep  9 10:43:02 2001
@@ -325,4 +325,9 @@
 	pci_read_bridge_bases(b);
 }
 
+unsigned __init int pcibios_assign_all_busses(void)
+{
+	return 1;
+}
+
 #endif /* CONFIG_PCI */
diff -u --recursive --new-file v2.4.9/linux/arch/mips/mips-boards/generic/time.c linux/arch/mips/mips-boards/generic/time.c
--- v2.4.9/linux/arch/mips/mips-boards/generic/time.c	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/mips-boards/generic/time.c	Sun Sep  9 10:43:02 2001
@@ -275,7 +275,7 @@
 
 /* This is for machines which generate the exact clock. */
 #define USECS_PER_JIFFY (1000000/HZ)
-#define USECS_PER_JIFFY_FRAC (0x100000000*1000000/HZ&0xffffffff)
+#define USECS_PER_JIFFY_FRAC ((1000000 << 32) / HZ & 0xffffffff)
 
 /* Cycle counter value at the previous timer interrupt.. */
 
diff -u --recursive --new-file v2.4.9/linux/arch/mips/mips-boards/malta/malta_int.c linux/arch/mips/mips-boards/malta/malta_int.c
--- v2.4.9/linux/arch/mips/mips-boards/malta/malta_int.c	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/mips-boards/malta/malta_int.c	Sun Sep  9 10:43:02 2001
@@ -1,6 +1,7 @@
 /*
  * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ * Copyright (C) 2000, 2001 MIPS Technologies, Inc.
+ * Copyright (C) 2001 Ralf Baechle
  *
  *  This program is free software; you can distribute it and/or modify it
  *  under the terms of the GNU General Public License (Version 2) as
@@ -20,6 +21,7 @@
  * The interrupt controller is located in the South Bridge a PIIX4 device 
  * with two internal 82C95 interrupt controllers.
  */
+#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
@@ -37,342 +39,42 @@
 
 extern asmlinkage void mipsIRQ(void);
 
-unsigned int local_bh_count[NR_CPUS];
-unsigned int local_irq_count[NR_CPUS];
-unsigned long spurious_count = 0;
-
-static struct irqaction *hw0_irq_action[MALTAINT_END] = {
-	NULL, NULL, NULL, NULL,
-	NULL, NULL, NULL, NULL,
-	NULL, NULL, NULL, NULL,
-	NULL, NULL, NULL, NULL
-};
-
-static struct irqaction r4ktimer_action = {
-	NULL, 0, 0, "R4000 timer/counter", NULL, NULL,
-};
-
-static struct irqaction *irq_action[8] = {
-	NULL, NULL, NULL, NULL,
-	NULL, NULL, NULL, &r4ktimer_action
-};
-
-#if 0
-#define DEBUG_INT(x...) printk(x)
-#else
-#define DEBUG_INT(x...)
-#endif
-
-/*
- * This contains the interrupt mask for both 82C59 interrupt controllers.
- */
-static unsigned int cached_int_mask = 0xffff;
-
-
-void disable_irq(unsigned int irq_nr)
-{
-        unsigned long flags;
-
-	if(irq_nr >= MALTAINT_END) {
-		printk("whee, invalid irq_nr %d\n", irq_nr);
-		panic("IRQ, you lose...");
-	}
-
-	save_and_cli(flags);
-	cached_int_mask |= (1 << irq_nr);
-	if (irq_nr & 8) {
-	        outb((cached_int_mask >> 8) & 0xff, PIIX4_ICTLR2_OCW1);
-	} else {
-		outb(cached_int_mask & 0xff, PIIX4_ICTLR1_OCW1);
-	}
-	restore_flags(flags);
-}
-
-
-void enable_irq(unsigned int irq_nr)
-{
-        unsigned long flags;
-
-	if(irq_nr >= MALTAINT_END) {
-		printk("whee, invalid irq_nr %d\n", irq_nr);
-		panic("IRQ, you lose...");
-	}
-
-	save_and_cli(flags);
-	cached_int_mask &= ~(1 << irq_nr);
-	if (irq_nr & 8) {
-		outb((cached_int_mask >> 8) & 0xff, PIIX4_ICTLR2_OCW1);
-
-		/* Enable irq 2 (cascade interrupt). */
-	        cached_int_mask &= ~(1 << 2); 
-		outb(cached_int_mask & 0xff, PIIX4_ICTLR1_OCW1);
-	} else {
-		outb(cached_int_mask & 0xff, PIIX4_ICTLR1_OCW1);
-	}	
-	restore_flags(flags);
-}
-
-
-int get_irq_list(char *buf)
-{
-	int i, len = 0;
-	int num = 0;
-	struct irqaction *action;
-
-	for (i = 0; i < 8; 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 < MALTAINT_END; i++, num++) {
-		action = hw0_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, " [hw0]\n");
-	}
-	return len;
-}
-
-
-static int setup_irq(unsigned int irq, struct irqaction * new)
-{
-	int shared = 0;
-	struct irqaction *old, **p;
-
-	p = &hw0_irq_action[irq];
-	if ((old = *p) != NULL) {
-		/* Can't share interrupts unless both agree to */
-		if (!(old->flags & new->flags & SA_SHIRQ))
-			return -EBUSY;
-
-		/* Can't share interrupts unless both are same type */
-		if ((old->flags ^ new->flags) & SA_INTERRUPT)
-			return -EBUSY;
-
-		/* add new interrupt at end of irq queue */
-		do {
-			p = &old->next;
-			old = *p;
-		} while (old);
-		shared = 1;
-	}
-
-	if (new->flags & SA_SAMPLE_RANDOM)
-		rand_initialize_irq(irq);
-
-	*p = new;
-	if (!shared)
-		enable_irq(irq);
-
-	return 0;
-}
-
-int request_irq(unsigned int irq, 
-		void (*handler)(int, void *, struct pt_regs *),
-		unsigned long irqflags, 
-		const char * devname,
-		void *dev_id)
-{  
-        struct irqaction *action;
-	int retval;
-
-	DEBUG_INT("request_irq: irq=%d, devname = %s\n", irq, devname);
-
-        if (irq >= MALTAINT_END)
-	        return -EINVAL;
-	if (!handler)
-	        return -EINVAL;
-
-	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->dev_id = dev_id;
-	action->next = 0;
-
-	retval = setup_irq(irq, action);
-	if (retval)
-		kfree(action);
-
-	return retval;	
-}
-
-
-void free_irq(unsigned int irq, void *dev_id)
-{
-	struct irqaction *action, **p;
-
-	if (irq >= MALTAINT_END) {
-		printk("Trying to free IRQ%d\n",irq);
-		return;
-	}
-	
-	for (p = &hw0_irq_action[irq]; (action = *p) != NULL; 
-	     p = &action->next) 
-	{
-		if (action->dev_id != dev_id)
-			continue;
-
-		/* Found it - now free it */
-		*p = action->next;
-		kfree(action);
-		if (!hw0_irq_action[irq])
-			disable_irq(irq);
-		return;
-	}
-	printk("Trying to free IRQ%d\n",irq);
-}
-
-void __init init_IRQ(void)
+void malta_hw0_irqdispatch(struct pt_regs *regs)
 {
-	irq_setup();
-}
+	int irq;
 
-static inline int get_int(int *irq)
-{
 	/*  
-	 * Determine highest priority pending interrupt by performing
-         * a PCI Interrupt Acknowledge cycle.
+	 * Determine highest priority pending interrupt by performing a PCI
+	 * Interrupt Acknowledge cycle.
 	 */
-	GT_READ(GT_PCI0_IACK_OFS, *irq);
-	*irq &= 0xFF;
+	GT_READ(GT_PCI0_IACK_OFS, irq);
+	irq &= 0xFF;
 
 	/*  
-	 * IRQ7 is used to detect spurious interrupts.
-	 * The interrupt acknowledge cycle returns IRQ7, if no 
-	 * interrupts is requested.
-	 * We can differentiate between this situation and a
-	 * "Normal" IRQ7 by reading the ISR.
+	 * IRQ7 is used to detect spurious interrupts.  The interrupt
+	 * acknowledge cycle returns IRQ7, if no interrupts is requested.  We
+	 * can differentiate between this situation and a "normal" IRQ7 by
+	 * reading the ISR.
 	 */
-	if (*irq == 7) 
-	{
+	if (irq == 7) {
 		outb(PIIX4_OCW3_SEL | PIIX4_OCW3_ISR, PIIX4_ICTLR1_OCW3);
 		if (!(inb(PIIX4_ICTLR1_OCW3) & (1 << 7)))
-		        return -1;    /* Spurious interrupt. */
-	}
-
-	return 0;
-}
-
-static inline void ack_int(int irq)
-{
-	if (irq & 8) {
-	        /* Specific EOI to cascade */
-		outb(PIIX4_OCW2_SEL | PIIX4_OCW2_NSEOI | PIIX4_OCW2_ILS_2, 
-		     PIIX4_ICTLR1_OCW2);
-
-	        /* Non specific EOI to cascade */
-		outb(PIIX4_OCW2_SEL | PIIX4_OCW2_NSEOI, PIIX4_ICTLR2_OCW2);
-	} else {
-	        /* Non specific EOI to cascade */
-		outb(PIIX4_OCW2_SEL | PIIX4_OCW2_NSEOI, PIIX4_ICTLR1_OCW2);
+		        return;    /* Spurious interrupt. */
 	}
-}
-
-void malta_hw0_irqdispatch(struct pt_regs *regs)
-{
-        struct irqaction *action;
-	int irq=0, cpu = smp_processor_id();
-
-	DEBUG_INT("malta_hw0_irqdispatch\n");
-	
-	if (get_int(&irq))
-	        return;  /* interrupt has already been cleared */
 
-	disable_irq(irq);
-	ack_int(irq);
-
-	DEBUG_INT("malta_hw0_irqdispatch: irq=%d\n", irq);
-	action = hw0_irq_action[irq];
-
-	/* 
-	 * if action == NULL, then we don't have a handler 
-	 * for the irq 
-	 */
-	if ( action == NULL )
-		return;
-
-	irq_enter(cpu, irq);
-	kstat.irqs[0][irq + 8]++;
-	do {
-	        action->handler(irq, action->dev_id, regs);
-		action = action->next;
-	} while (action);
-
-	enable_irq(irq);
-	irq_exit(cpu, irq);
+	do_IRQ(irq, regs);
 }
 
-
-unsigned long probe_irq_on (void)
+void __init init_IRQ(void)
 {
-	unsigned int i, irqs = 0;
-	unsigned long delay;
+	set_except_vector(0, mipsIRQ);
+	init_generic_irq();
+	init_i8259_irqs();
 
-	/* first, enable any unassigned irqs */
-	for (i = MALTAINT_END-1; i > 0; i--) {
-		if (!hw0_irq_action[i]) {
-			enable_irq(i);
-			irqs |= (1 << i);
-		}
+#ifdef CONFIG_REMOTE_DEBUG
+	if (remote_debug) {
+		set_debug_traps();
+		breakpoint();
 	}
-
-	/* wait for spurious interrupts to mask themselves out again */
-	for (delay = jiffies + HZ/10; time_before(jiffies, delay); )
-		/* about 100ms delay */;
-
-	/* now filter out any obviously spurious interrupts */
-	return irqs & ~cached_int_mask;
-}
-
-
-int probe_irq_off (unsigned long irqs)
-{
-	unsigned int i;
-
-	irqs &= cached_int_mask;
-	if (!irqs)
-		return 0;
-	i = ffz(~irqs);
-	if (irqs != (irqs & (1 << i)))
-		i = -i;
-
-	return i;
-}
-
-
-void __init maltaint_init(void)
-{
-        /* 
-	 * Mask out all interrupt by writing "1" to all bit position in 
-	 * the IMR register. 
-	 */
-	outb(cached_int_mask & 0xff, PIIX4_ICTLR1_OCW1);
-	outb((cached_int_mask >> 8) & 0xff, PIIX4_ICTLR2_OCW1);
-
-	/* Now safe to set the exception vector. */
-	set_except_vector(0, mipsIRQ);
+#endif
 }
diff -u --recursive --new-file v2.4.9/linux/arch/mips/mips-boards/malta/malta_rtc.c linux/arch/mips/mips-boards/malta/malta_rtc.c
--- v2.4.9/linux/arch/mips/mips-boards/malta/malta_rtc.c	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/mips-boards/malta/malta_rtc.c	Sun Sep  9 10:43:02 2001
@@ -23,7 +23,6 @@
  * Motorola MC146818A-compatible Real Time Clock.
  *
  */
-#include <linux/spinlock.h>
 #include <linux/mc146818rtc.h>
 #include <asm/mips-boards/malta.h>
 
diff -u --recursive --new-file v2.4.9/linux/arch/mips/mips-boards/malta/malta_setup.c linux/arch/mips/mips-boards/malta/malta_setup.c
--- v2.4.9/linux/arch/mips/mips-boards/malta/malta_setup.c	Fri Apr 13 20:26:07 2001
+++ linux/arch/mips/mips-boards/malta/malta_setup.c	Sun Sep  9 10:43:02 2001
@@ -2,8 +2,6 @@
  * Carsten Langgaard, carstenl@mips.com
  * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
  *
- * ########################################################################
- *
  *  This program is free software; you can distribute it and/or modify it
  *  under the terms of the GNU General Public License (Version 2) as
  *  published by the Free Software Foundation.
@@ -16,11 +14,6 @@
  *  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.
- *
- * ########################################################################
- *
- * Malta specific setup, including init of the feature struct.
- *
  */
 #include <linux/config.h>
 #include <linux/init.h>
@@ -56,53 +49,33 @@
 static int remote_debug = 0;
 #endif
 
-#ifdef CONFIG_BLK_DEV_IDE
 extern struct ide_ops std_ide_ops;
-#endif
-#ifdef CONFIG_BLK_DEV_FD
 extern struct fd_ops std_fd_ops;
-#endif
 extern struct rtc_ops malta_rtc_ops;
+extern struct kbd_ops std_kbd_ops;
 
 extern void mips_reboot_setup(void);
 
 struct resource standard_io_resources[] = {
 	{ "dma1", 0x00, 0x1f, IORESOURCE_BUSY },
-	{ "pic1", 0x20, 0x3f, IORESOURCE_BUSY },
 	{ "timer", 0x40, 0x5f, IORESOURCE_BUSY },
 	{ "dma page reg", 0x80, 0x8f, IORESOURCE_BUSY },
-	{ "pic2", 0xa0, 0xbf, IORESOURCE_BUSY },
 	{ "dma2", 0xc0, 0xdf, IORESOURCE_BUSY },
 };
 
 #define STANDARD_IO_RESOURCES (sizeof(standard_io_resources)/sizeof(struct resource))
 
-static void __init malta_irq_setup(void)
-{
-  	maltaint_init();
-
-#ifdef CONFIG_REMOTE_DEBUG
-	if (remote_debug) {
-		set_debug_traps();
-		breakpoint(); 
-	}
-#endif
-}
-
-
 void __init malta_setup(void)
 {
 #ifdef CONFIG_REMOTE_DEBUG
 	int rs_putDebugChar(char);
 	char rs_getDebugChar(void);
-	extern int (*putDebugChar)(char);
-	extern char (*getDebugChar)(void);
+	extern int (*generic_putDebugChar)(char);
+	extern char (*generic_getDebugChar)(void);
 #endif
 	char *argptr;
 	int i;
 
-	irq_setup = malta_irq_setup;
-
 	/* Request I/O space for devices used on the Malta board. */
 	for (i = 0; i < STANDARD_IO_RESOURCES; i++)
 		request_resource(&ioport_resource, standard_io_resources+i);
@@ -133,14 +106,14 @@
 		       line ? 1 : 0);
 
 		rs_kgdb_hook(line);
-		putDebugChar = rs_putDebugChar;
-		getDebugChar = rs_getDebugChar;
+		generic_putDebugChar = rs_putDebugChar;
+		generic_getDebugChar = rs_getDebugChar;
 
 		prom_printf("KGDB: Using serial line /dev/ttyS%d for session, "
 			    "please connect your debugger\n", line ? 1 : 0);
 
 		remote_debug = 1;
-		/* Breakpoints and stuff are in malta_irq_setup() */
+		/* Breakpoints are in init_IRQ() */
 	}
 #endif
 
@@ -154,6 +127,9 @@
 #endif
 #ifdef CONFIG_BLK_DEV_FD
         fd_ops = &std_fd_ops;
+#endif
+#ifdef CONFIG_PC_KEYB
+	kbd_ops = &std_kbd_ops;
 #endif
 	mips_reboot_setup();
 }
diff -u --recursive --new-file v2.4.9/linux/arch/mips/mm/Makefile linux/arch/mips/mm/Makefile
--- v2.4.9/linux/arch/mips/mm/Makefile	Tue Jul  3 17:08:18 2001
+++ linux/arch/mips/mm/Makefile	Sun Sep  9 10:43:02 2001
@@ -15,11 +15,13 @@
 obj-$(CONFIG_CPU_R3000)		+= r2300.o
 obj-$(CONFIG_CPU_R4300)		+= r4xx0.o
 obj-$(CONFIG_CPU_R4X00)		+= r4xx0.o
+obj-$(CONFIG_CPU_VR41XX)	+= r4xx0.o
 obj-$(CONFIG_CPU_R5000)		+= r4xx0.o
 obj-$(CONFIG_CPU_NEVADA)	+= r4xx0.o
 obj-$(CONFIG_CPU_R5432)		+= r5432.o
 obj-$(CONFIG_CPU_RM7000)	+= rm7k.o
 obj-$(CONFIG_CPU_MIPS32)	+= mips32.o
+obj-$(CONFIG_CPU_MIPS64)	+= mips32.o
 obj-$(CONFIG_SGI_IP22)		+= umap.o
 obj-$(CONFIG_BAGET_MIPS)	+= umap.o
 
diff -u --recursive --new-file v2.4.9/linux/arch/mips/mm/andes.c linux/arch/mips/mm/andes.c
--- v2.4.9/linux/arch/mips/mm/andes.c	Wed Jul 25 17:10:18 2001
+++ linux/arch/mips/mm/andes.c	Sun Sep  9 10:43:02 2001
@@ -132,7 +132,8 @@
 
 static void andes_flush_cache_sigtramp(unsigned long page)
 {
-	/* XXX */
+	protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
+	protected_flush_icache_line(addr & ~(ic_lsize - 1));
 }
 
 /* TLB operations. XXX Write these dave... */
@@ -182,6 +183,14 @@
 	_flush_icache_page = andes_flush_icache_page;
 	_flush_icache_range = andes_flush_icache_range;
 
+	write_32bit_cp0_register(CP0_FRAMEMASK, 0);
+
 	flush_cache_all();
 	flush_tlb_all();
+
+	/*
+	 * The R10k might even work for Linux/MIPS - but we're paranoid
+	 * and refuse to run until this is tested on real silicon
+	 */
+	panic("CPU too expensive - making holiday in the ANDES!");
 }
diff -u --recursive --new-file v2.4.9/linux/arch/mips/mm/loadmmu.c linux/arch/mips/mm/loadmmu.c
--- v2.4.9/linux/arch/mips/mm/loadmmu.c	Wed Jul 25 17:10:18 2001
+++ linux/arch/mips/mm/loadmmu.c	Sun Sep  9 10:43:02 2001
@@ -52,8 +52,9 @@
 {
 
 	if (mips_cpu.options & MIPS_CPU_4KTLB) {
-#if defined(CONFIG_CPU_R4X00) || defined(CONFIG_CPU_R4300) || \
-    defined(CONFIG_CPU_R5000) || defined(CONFIG_CPU_NEVADA)
+#if defined(CONFIG_CPU_R4X00) || defined(CONFIG_CPU_VR41XX) || \
+    defined(CONFIG_CPU_R4300) || defined(CONFIG_CPU_R5000) || \
+    defined(CONFIG_CPU_NEVADA)
 		printk("Loading R4000 MMU routines.\n");
 		ld_mmu_r4xx0();
 #endif
@@ -66,7 +67,7 @@
 		ld_mmu_r5432();
 #endif
 
-#if defined(CONFIG_CPU_MIPS32)
+#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
 		printk("Loading MIPS32 MMU routines.\n");
 		ld_mmu_mips32();
 #endif
diff -u --recursive --new-file v2.4.9/linux/arch/mips/mm/mips32.c linux/arch/mips/mm/mips32.c
--- v2.4.9/linux/arch/mips/mm/mips32.c	Wed Jul 25 17:10:18 2001
+++ linux/arch/mips/mm/mips32.c	Sun Sep  9 10:43:02 2001
@@ -69,10 +69,8 @@
 {
 	unsigned long i;
 
-        if (mips_cpu.options & MIPS_CPU_CACHE_CDEX)
-	{
-	        for (i=page; i<page+PAGE_SIZE; i+=dc_lsize)
-		{
+        if (mips_cpu.options & MIPS_CPU_CACHE_CDEX) {
+	        for (i=page; i<page+PAGE_SIZE; i+=dc_lsize) {
 		        __asm__ __volatile__(
 			        ".set\tnoreorder\n\t"
 				".set\tnoat\n\t"
@@ -94,10 +92,8 @@
 {
 	unsigned long i;
 
-        if (mips_cpu.options & MIPS_CPU_CACHE_CDEX)
-	{
-	        for (i=page; i<page+PAGE_SIZE; i+=sc_lsize)
-		{
+        if (mips_cpu.options & MIPS_CPU_CACHE_CDEX) {
+	        for (i=page; i<page+PAGE_SIZE; i+=sc_lsize) {
 		        __asm__ __volatile__(
 				".set\tnoreorder\n\t"
 				".set\tnoat\n\t"
@@ -119,10 +115,8 @@
 {
 	unsigned long i;
 
-        if (mips_cpu.options & MIPS_CPU_CACHE_CDEX)
-	{
-	        for (i=to; i<to+PAGE_SIZE; i+=dc_lsize)
-		{
+        if (mips_cpu.options & MIPS_CPU_CACHE_CDEX) {
+	        for (i=to; i<to+PAGE_SIZE; i+=dc_lsize) {
 		        __asm__ __volatile__(
 			        ".set\tnoreorder\n\t"
 				".set\tnoat\n\t"
@@ -144,10 +138,8 @@
 {
 	unsigned long i;
 
-        if (mips_cpu.options & MIPS_CPU_CACHE_CDEX)
-	{
-	        for (i=to; i<to+PAGE_SIZE; i+=sc_lsize)
-		{
+        if (mips_cpu.options & MIPS_CPU_CACHE_CDEX) {
+	        for (i=to; i<to+PAGE_SIZE; i+=sc_lsize) {
 		        __asm__ __volatile__(
 				".set\tnoreorder\n\t"
 				".set\tnoat\n\t"
@@ -514,14 +506,8 @@
  */
 static void mips32_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);
+	protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
+	protected_flush_icache_line(addr & ~(ic_lsize - 1));
 }
 
 #undef DEBUG_TLB
diff -u --recursive --new-file v2.4.9/linux/arch/mips/mm/r2300.c linux/arch/mips/mm/r2300.c
--- v2.4.9/linux/arch/mips/mm/r2300.c	Wed Jul 25 17:10:18 2001
+++ linux/arch/mips/mm/r2300.c	Sun Sep  9 10:43:02 2001
@@ -33,7 +33,7 @@
 /* For R3000 cores with R4000 style caches */
 static unsigned long icache_size, dcache_size;		/* Size in bytes */
 static unsigned long icache_lsize, dcache_lsize;	/* Size in bytes */
-static unsigned long scache_size = 0;
+static unsigned long scache_size;
 
 #include <asm/cacheops.h>
 #include <asm/r4kcache.h>
@@ -134,31 +134,64 @@
 	dummy = *p;
 	status = read_32bit_cp0_register(CP0_STATUS);
 
-	if (dummy != 0xa5a55a5a || (status & (1<<19))) {
+	if (dummy != 0xa5a55a5a || (status & ST0_CM)) {
 		size = 0;
 	} else {
-		for (size = 512; size <= 0x40000; size <<= 1)
+		for (size = 128; size <= 0x40000; size <<= 1)
 			*(p + size) = 0;
 		*p = -1;
-		for (size = 512; 
+		for (size = 128; 
 		     (size <= 0x40000) && (*(p + size) == 0); 
 		     size <<= 1)
 			;
 		if (size > 0x40000)
 			size = 0;
 	}
+
 	write_32bit_cp0_register(CP0_STATUS, flags);
 
 	return size * sizeof(*p);
 }
 
+unsigned long __init r3k_cache_lsize(unsigned long ca_flags)
+{
+	unsigned long flags, status, lsize, i, j;
+	volatile unsigned long *p;
+
+	p = (volatile unsigned long *) KSEG0;
+
+	flags = read_32bit_cp0_register(CP0_STATUS);
+
+	/* isolate cache space */
+	write_32bit_cp0_register(CP0_STATUS, (ca_flags|flags)&~ST0_IEC);
+
+	for (i = 0; i < 128; i++)
+		*(p + i) = 0;
+	*(volatile unsigned char *)p = 0;
+	for (lsize = 1; lsize < 128; lsize <<= 1) {
+		*(p + lsize);
+		status = read_32bit_cp0_register(CP0_STATUS);
+		if (!(status & ST0_CM))
+			break;
+	}
+	for (i = 0; i < 128; i += lsize)
+		*(volatile unsigned char *)(p + i) = 0;
+
+	write_32bit_cp0_register(CP0_STATUS, flags);
+
+	return lsize * sizeof(*p);
+}
+
 static void __init r3k_probe_cache(void)
 {
 	dcache_size = r3k_cache_size(ST0_ISC);
-	dcache_lsize = 4;
+	if (dcache_size)
+		dcache_lsize = r3k_cache_lsize(ST0_ISC);
+	
 
 	icache_size = r3k_cache_size(ST0_ISC|ST0_SWC);
-	icache_lsize = 4;
+	if (icache_size)
+		icache_lsize = r3k_cache_lsize(ST0_ISC|ST0_SWC);
 }
 
 static void r3k_flush_icache_range(unsigned long start, unsigned long end)
@@ -391,11 +424,17 @@
 
 	flags = read_32bit_cp0_register(CP0_STATUS);
 
+	write_32bit_cp0_register(CP0_STATUS, flags&~ST0_IEC);
+
+	/* Fill the TLB to avoid an exception with caches isolated. */
+	asm ( 	"lw\t$0,0x000(%0)\n\t"
+		"lw\t$0,0x004(%0)\n\t"
+		: : "r" (addr) );
+
 	write_32bit_cp0_register(CP0_STATUS, (ST0_ISC|ST0_SWC|flags)&~ST0_IEC);
 
 	asm ( 	"sb\t$0,0x000(%0)\n\t"
 		"sb\t$0,0x004(%0)\n\t"
-		"sb\t$0,0x008(%0)\n\t"
 		: : "r" (addr) );
 
 	write_32bit_cp0_register(CP0_STATUS, flags);
diff -u --recursive --new-file v2.4.9/linux/arch/mips/mm/r4xx0.c linux/arch/mips/mm/r4xx0.c
--- v2.4.9/linux/arch/mips/mm/r4xx0.c	Wed Jul 25 17:10:18 2001
+++ linux/arch/mips/mm/r4xx0.c	Sun Sep  9 10:43:02 2001
@@ -2088,43 +2088,29 @@
  */
 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);
+	protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
+	protected_flush_icache_line(addr & ~(ic_lsize - 1));
 }
 
 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);
+	protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
+	protected_flush_icache_line(addr & ~(ic_lsize - 1));
+
 	__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... */
-
 void flush_tlb_all(void)
 {
 	unsigned long flags;
@@ -2146,7 +2132,7 @@
 	entry = get_wired();
 
 	/* Blast 'em all away. */
-	while(entry < NTLB_ENTRIES) {
+	while(entry < mips_cpu.tlbsize) {
 		set_index(entry);
 		BARRIER;
 		tlb_write_indexed();
@@ -2188,7 +2174,7 @@
 		__save_and_cli(flags);
 		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
 		size = (size + 1) >> 1;
-		if(size <= NTLB_ENTRIES_HALF) {
+		if(size <= mips_cpu.tlbsize/2) {
 			int oldpid = (get_entryhi() & 0xff);
 			int newpid = (mm->context & 0xff);
 
@@ -2416,7 +2402,14 @@
 /* Detect and size the various r4k caches. */
 static void __init probe_icache(unsigned long config)
 {
-	icache_size = 1 << (12 + ((config >> 9) & 7));
+        switch (mips_cpu.cputype) {
+        case CPU_VR41XX:
+                icache_size = 1 << (10 + ((config >> 9) & 7));
+                break;
+        default:
+                icache_size = 1 << (12 + ((config >> 9) & 7));
+                break;
+        }
 	ic_lsize = 16 << ((config >> 5) & 1);
 
 	printk("Primary instruction cache %dkb, linesize %d bytes.\n",
@@ -2425,7 +2418,14 @@
 
 static void __init probe_dcache(unsigned long config)
 {
-	dcache_size = 1 << (12 + ((config >> 6) & 7));
+        switch (mips_cpu.cputype) {
+        case CPU_VR41XX:
+                dcache_size = 1 << (10 + ((config >> 6) & 7));
+                break;
+        default:
+                dcache_size = 1 << (12 + ((config >> 6) & 7));
+                break;
+        }
 	dc_lsize = 16 << ((config >> 4) & 1);
 
 	printk("Primary data cache %dkb, linesize %d bytes.\n",
@@ -2708,6 +2708,6 @@
 	 *   - The entire mm handling assumes the c0_pagemask register to
 	 *     be set for 4kb pages.
 	 */
-	write_32bit_cp0_register(CP0_PAGEMASK, PM_4K);
+	set_pagemask(PM_4K);
 	flush_tlb_all();
 }
diff -u --recursive --new-file v2.4.9/linux/arch/mips/mm/r5432.c linux/arch/mips/mm/r5432.c
--- v2.4.9/linux/arch/mips/mm/r5432.c	Wed Jul 25 17:10:18 2001
+++ linux/arch/mips/mm/r5432.c	Sun Sep  9 10:43:02 2001
@@ -531,14 +531,8 @@
  */
 static void r5432_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);
+	protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
+	protected_flush_icache_line(addr & ~(ic_lsize - 1));
 }
 
 #undef DEBUG_TLB
diff -u --recursive --new-file v2.4.9/linux/arch/mips/philips/nino/Makefile linux/arch/mips/philips/nino/Makefile
--- v2.4.9/linux/arch/mips/philips/nino/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/philips/nino/Makefile	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,33 @@
+#
+# Makefile for the Philips Nino specific parts of the 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.s:
+	$(CPP) $(AFLAGS) $< -o $@
+.S.o:
+	$(CC) $(AFLAGS) -c $< -o $@
+
+O_TARGET := nino.o
+
+all: nino.o
+
+obj-y	 := int-handler.o setup.o irq.o time.o reset.o rtc.o prom.o power.o
+
+int-handler.o: int-handler.S
+
+obj-$(CONFIG_REMOTE_DEBUG)	+= kgdb.o
+
+obj-$(CONFIG_BLK_DEV_INITRD)	+= ramdisk.o
+
+ramdisk.o:
+		$(MAKE) -C ramdisk
+		mv ramdisk/ramdisk.o ramdisk.o
+
+clean:
+		rm -f *.o
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.9/linux/arch/mips/philips/nino/int-handler.S linux/arch/mips/philips/nino/int-handler.S
--- v2.4.9/linux/arch/mips/philips/nino/int-handler.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/philips/nino/int-handler.S	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,137 @@
+/*
+ *  linux/arch/mips/philips/nino/int-handler.S
+ *
+ *  Copyright (C) 1999 Harald Koerfgen
+ *  Copyright (C) 2000 Jim Pick (jim@jimpick.com)
+ *  Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Interrupt handler for Philips Nino.
+ */
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+#include <asm/tx3912.h>
+
+		.data
+	        .globl  HighPriVect
+
+HighPriVect:	.word   spurious        # Reserved
+	        .word   io_posnegint0   # IOPOSINT(0) or IONEGINT(0)
+	        .word   spurious        # CHIDMACNTINT
+	        .word   spurious        # TELDMACNTINT
+	        .word   spurious        # SNDDMACNTINT
+	        .word   spurious        # Reserved
+	        .word   io_negint56     # IONEGINT(6) or IONEGINT(5)
+	        .word   spurious        # Reserved
+	        .word   io_posint56     # IOPOSINT(6) or IOPOSINT(5)
+	        .word   spurious        # Reserved
+	        .word   spurious        # UARTBRXINT
+	        .word   uarta_rx        # UARTARXINT
+	        .word   spurious        # Reserved
+	        .word   periodic_timer  # PERINT
+	        .word   spurious        # ALARMINT
+	        .word   spurious        # POSPWROKINT or NEGPWROKINT
+
+/*
+ *  Here is the entry point to handle all interrupts.
+ */
+		.text
+		.set	noreorder
+		.align	5
+		NESTED(nino_handle_int, PT_SIZE, ra)
+		.set	noat
+		SAVE_ALL
+		CLI
+		.set	at
+	
+		/*
+		 * Get pending Interrupts
+		 */
+		mfc0	t0, CP0_CAUSE		# Get pending interrupts
+		andi	t2, t0, IE_IRQ4		# IRQ4 (high priority)
+		bne	t2, IE_IRQ4, low_priority
+		nop
+
+/*
+ *  Ok, we've got a high priority interrupt (a.k.a. an external interrupt).
+ *  Read Interrupt Status Register 6 to get vector.
+ */
+high_priority:
+		lui	t0, %hi(IntStatus6)
+		lw	t1, %lo(IntStatus6)(t0)
+		andi	t1, INT6_INTVECT
+		la	t2, HighPriVect
+		addu	t1, t1, t2
+		lw	t2, 0(t1)
+		jr	t2
+		nop
+
+/*
+ * Ok, we've got one of over a hundred other interupts.
+ */
+low_priority:
+		lui	t0, %hi(IntStatus1)
+		lw	t1, %lo(IntStatus1)(t0)
+		j	handle_it
+		li	a0, 20
+
+/*
+ * We don't currently handle spurious interrupts.
+ */
+spurious:	
+		j	spurious_interrupt
+		nop
+
+/*
+ * We have the IRQ number, dispatch to the real handler.
+ */
+handle_it:	jal	do_IRQ
+		move	a1,sp
+		j	ret_from_irq
+		nop
+
+/************************************
+ * High priority interrupt mappings *
+ ************************************/
+		
+/* 
+ *  Periodic timer - IRQ 0
+ */
+periodic_timer:
+		j	handle_it
+		li	a0, 0
+
+/* 
+ *  UARTA RX - IRQ 3
+ */
+uarta_rx:
+		j	handle_it
+		li	a0, 3
+
+/* 
+ *  GPIO Pin 0 transition - IRQ 10
+ */
+io_posnegint0:
+		j	handle_it
+		li	a0, 10
+
+/* 
+ *  GPIO Pin 5 or 6 transition (0-to-1) - IRQ 11
+ */
+io_posint56:
+		j	handle_it
+		li	a0, 11
+
+/*
+ *  GPIO Pin 5 or 6 transition (1-to-0) - IRQ 12
+ */
+io_negint56:
+		j	handle_it
+		li	a0, 12
+
+		END(nino_handle_int)
diff -u --recursive --new-file v2.4.9/linux/arch/mips/philips/nino/irq.c linux/arch/mips/philips/nino/irq.c
--- v2.4.9/linux/arch/mips/philips/nino/irq.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/philips/nino/irq.c	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,314 @@
+/*
+ *  linux/arch/mips/philips/nino/irq.c
+ *
+ *  Copyright (C) 1992 Linus Torvalds
+ *  Copyright (C) 1999 Harald Koerfgen
+ *  Copyright (C) 2000 Pavel Machek (pavel@suse.cz)
+ *  Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com)
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *  
+ *  Generic interrupt handler for Philips Nino.
+ */
+#include <linux/errno.h>
+#include <linux/init.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/slab.h>
+#include <linux/random.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/tx3912.h>
+
+unsigned long spurious_count = 0;
+
+irq_cpustat_t irq_stat [NR_CPUS];
+
+static inline void mask_irq(unsigned int irq_nr)
+{
+	switch (irq_nr) {
+	case 0:  /* Periodic Timer Interrupt */ 
+		IntClear5 = INT5_PERIODICINT;
+		IntClear6 = INT6_PERIODICINT;
+		IntEnable6 &= ~INT6_PERIODICINT;
+		break;
+
+	case 3:
+		/* Serial port receive interrupt */
+		break;
+
+	case 2:
+		/* Serial port transmit interrupt */
+		break;
+
+	default:
+		printk( "Attempt to mask unknown IRQ %d?\n", irq_nr );
+	}
+}
+
+static inline void unmask_irq(unsigned int irq_nr)
+{
+	switch (irq_nr) {
+	case 0:
+		IntEnable6 |= INT6_PERIODICINT;
+		break;
+
+	case 3:
+		/* Serial port receive interrupt */
+		break;
+
+	case 2:
+		/* Serial port transmit interrupt */
+		break;
+
+	default:
+		printk( "Attempt to unmask unknown IRQ %d?\n", irq_nr );
+	}
+}
+
+void disable_irq(unsigned int irq_nr)
+{
+    unsigned long flags;
+
+    save_and_cli(flags);
+    mask_irq(irq_nr);
+    restore_flags(flags);
+}
+
+void enable_irq(unsigned int irq_nr)
+{
+    unsigned long flags;
+
+    save_and_cli(flags);
+    unmask_irq(irq_nr);
+    restore_flags(flags);
+}
+
+/*
+ * Pointers to the low-level handlers: first the general ones, then the
+ * fast ones, then the bad ones.
+ */
+extern void interrupt(void);
+
+static struct irqaction *irq_action[NR_IRQS] =
+{
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    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 get_irq_list(char *buf)
+{
+    int i, len = 0;
+    struct irqaction *action;
+
+    for (i = 0; i < NR_IRQS; 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;
+}
+
+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
+ * 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;
+
+    if (irq == 20) {
+        if (IntStatus2 & 0xfffff00) {
+		if (IntStatus2 & 0x0f000000)
+		return do_IRQ(2, regs);
+	}
+    }
+
+    cpu = smp_processor_id();
+    irq_enter(cpu, irq);
+    kstat.irqs[cpu][irq]++;
+
+    if (irq == 20) {
+            printk("20 %08lx %08lx\n   %08lx %08lx\n   %08lx\n",
+                   IntStatus1, IntStatus2, IntStatus3,
+                   IntStatus4, IntStatus5 );
+            printk("20 %08lx %08lx\n   %08lx %08lx\n   %08lx\n",
+                   IntEnable1, IntEnable2, IntEnable3,
+                   IntEnable4, IntEnable5 );
+
+    }
+
+    mask_irq(irq);
+    action = *(irq + irq_action);
+    if (action) {
+	if (!(action->flags & SA_INTERRUPT))
+	    __sti();
+	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);
+	unmask_irq(irq);
+	__cli();
+    } else {
+            IntClear1 = ~0;
+            IntClear3 = ~0;
+	    IntClear4 = ~0;
+	    IntClear5 = ~0;
+	    unmask_irq(irq);
+    }
+    irq_exit(cpu, irq);
+
+    /* unmasking and bottom half handling is done magically for us. */
+}
+
+/*
+ * Idea is to put all interrupts
+ * in a single table and differenciate them just by number.
+ */
+int setup_nino_irq(int irq, struct irqaction *new)
+{
+    int shared = 0;
+    struct irqaction *old, **p;
+    unsigned long flags;
+
+    p = irq_action + irq;
+    if ((old = *p) != NULL) {
+	/* Can't share interrupts unless both agree to */
+	if (!(old->flags & new->flags & SA_SHIRQ))
+	    return -EBUSY;
+
+	/* Can't share interrupts unless both are same type */
+	if ((old->flags ^ new->flags) & SA_INTERRUPT)
+	    return -EBUSY;
+
+	/* add new interrupt at end of irq queue */
+	do {
+	    p = &old->next;
+	    old = *p;
+	} while (old);
+	shared = 1;
+    }
+    if (new->flags & SA_SAMPLE_RANDOM)
+	rand_initialize_irq(irq);
+
+    save_and_cli(flags);
+    *p = new;
+
+    if (!shared) {
+	unmask_irq(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 >= NR_IRQS)
+	return -EINVAL;
+    if (!handler)
+	return -EINVAL;
+
+    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_nino_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 >= NR_IRQS) {
+	printk(KERN_CRIT __FUNCTION__ ": 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])
+	    mask_irq(irq);
+	restore_flags(flags);
+	kfree(action);
+	return;
+    }
+    printk(KERN_CRIT __FUNCTION__ ": trying to free free IRQ%d\n", irq);
+}
+
+unsigned long probe_irq_on(void)
+{
+    /* TODO */
+    return 0;
+}
+
+int probe_irq_off(unsigned long irqs)
+{
+    /* TODO */
+    return 0;
+}
+
+void __init init_IRQ(void)
+{
+    irq_setup();
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips/philips/nino/kgdb.c linux/arch/mips/philips/nino/kgdb.c
--- v2.4.9/linux/arch/mips/philips/nino/kgdb.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/philips/nino/kgdb.c	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,83 @@
+/*
+ *  linux/arch/mips/philips/nino/kgdb.c
+ *
+ *  Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Kernel debugging on the Philips Nino.
+ */
+#include <asm/system.h>
+#include <asm/tx3912.h>
+
+static int remoteDebugInitialized = 0;
+
+void debugInit(void)
+{
+/*
+ * If low-level debugging (before GDB or console operational) is
+ * configured, then we do not need to re-initialize the UART.
+ */
+#ifndef CONFIG_DEBUG_LL
+	earlyInitUartPR31700();
+#endif
+}
+
+char getDebugChar(void)
+{
+	char buf;
+	unsigned long int2, flags;
+
+	if (!remoteDebugInitialized) {
+		debugInit();
+		remoteDebugInitialized = 1;
+	}
+
+	save_and_cli(flags);
+
+	int2 = IntEnable2;
+
+	IntEnable2 = 0;
+
+	while(!(UartA_Ctrl1 & UART_RX_HOLD_FULL));
+
+	buf = UartA_Data;
+
+	IntEnable2 = int2;
+
+	restore_flags(flags);
+
+	return buf;	
+}
+
+int putDebugChar(char c)
+{
+	int i;
+	unsigned long int2;
+
+	if (!remoteDebugInitialized) {
+		debugInit();
+		remoteDebugInitialized = 1;
+	}
+
+	int2 = IntEnable2;
+
+	IntEnable2 &=
+		~(INT2_UARTATXINT | INT2_UARTATXOVERRUN | INT2_UARTAEMPTY);
+
+	for (i = 0; !(IntStatus2 & INT2_UARTATXINT) && (i < 10000); i++);
+
+	IntClear2 = INT2_UARTATXINT | INT2_UARTATXOVERRUN | INT2_UARTAEMPTY;
+
+	UartA_Data = c;
+
+	for (i = 0; !(IntStatus2 & INT2_UARTATXINT) && (i < 10000); i++);
+
+	IntClear2 = INT2_UARTATXINT | INT2_UARTATXOVERRUN | INT2_UARTAEMPTY;
+
+	IntEnable2 = int2;
+
+	return 1;
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips/philips/nino/power.c linux/arch/mips/philips/nino/power.c
--- v2.4.9/linux/arch/mips/philips/nino/power.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/philips/nino/power.c	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,36 @@
+/*
+ *  linux/arch/mips/philips/nino/power.c
+ *
+ *  Copyright (C) 2000 Jim Pick <jim@jimpick.com>
+ *  Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Power management routines on the Philips Nino.
+ */
+#include <asm/tx3912.h>
+
+void nino_wait(void)
+{
+	/* We stop the CPU to conserve power */
+	PowerControl |= PWR_STOPCPU;
+
+	/* 
+	 * We wait until an interrupt happens...
+	 */
+
+	/* We resume here */
+	PowerControl &= ~PWR_STOPCPU;
+
+	/* Give ourselves a little delay */
+	__asm__ __volatile__(
+		"nop\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		"nop\n\t");
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips/philips/nino/prom.c linux/arch/mips/philips/nino/prom.c
--- v2.4.9/linux/arch/mips/philips/nino/prom.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/philips/nino/prom.c	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,80 @@
+/*
+ *  linux/arch/mips/philips/nino/prom.c
+ *
+ *  Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *  
+ *  Early initialization code for the Philips Nino.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <asm/bootinfo.h>
+#include <asm/addrspace.h>
+#include <asm/page.h>
+
+char arcs_cmdline[COMMAND_LINE_SIZE];
+
+#ifdef CONFIG_FB_TX3912
+extern u_long tx3912fb_paddr;
+extern u_long tx3912fb_vaddr;
+extern u_long tx3912fb_size;
+#endif
+
+/* Do basic initialization */
+void __init prom_init(int argc, char **argv,
+		unsigned long magic, int *prom_vec)
+{
+	u_long free_end, mem_size;
+	u_int i;
+
+	/*
+	 * collect args and prepare cmd_line
+	 */
+	for (i = 1; i < argc; i++) {
+		strcat(arcs_cmdline, argv[i]);
+		if (i < (argc - 1))
+			strcat(arcs_cmdline, " ");
+	}
+
+	mips_machgroup = MACH_GROUP_PHILIPS;
+	mips_machtype = MACH_PHILIPS_NINO;
+
+#ifdef CONFIG_NINO_4MB
+	mem_size = 4 << 20;
+#elif CONFIG_NINO_8MB
+	mem_size = 8 << 20;
+#elif CONFIG_NINO_16MB
+	mem_size = 16 << 20;
+#endif
+
+#ifdef CONFIG_FB_TX3912
+	/*
+	 * The LCD controller requires that the framebuffer
+	 * start address fall within a 1MB segment and is
+	 * aligned on a 16 byte boundary. The way to assure
+	 * this is to place the framebuffer at the end of
+	 * memory and mark it as reserved.
+	 */
+	free_end = (mem_size - tx3912fb_size) & PAGE_MASK;
+	add_memory_region(0, free_end, BOOT_MEM_RAM); 
+	add_memory_region(free_end, (mem_size - free_end), BOOT_MEM_RESERVED); 
+
+	/*
+	 * Calculate physical and virtual addresses for
+	 * the beginning of the framebuffer.
+	 */
+	tx3912fb_paddr = PHYSADDR(free_end);
+	tx3912fb_vaddr = KSEG1ADDR(free_end);
+#else
+	add_memory_region(0, mem_size, BOOT_MEM_RAM); 
+#endif
+}
+
+void __init prom_free_prom_memory (void)
+{
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips/philips/nino/ramdisk/Makefile linux/arch/mips/philips/nino/ramdisk/Makefile
--- v2.4.9/linux/arch/mips/philips/nino/ramdisk/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/philips/nino/ramdisk/Makefile	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,12 @@
+#
+# Makefile for the Philips Nino ramdisk
+#
+# 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).
+#
+
+ramdisk.o: ramdisk.gz ld.script
+	$(LD) -T ld.script -b binary -o $@ ramdisk.gz
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.9/linux/arch/mips/philips/nino/ramdisk/ld.script linux/arch/mips/philips/nino/ramdisk/ld.script
--- v2.4.9/linux/arch/mips/philips/nino/ramdisk/ld.script	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/philips/nino/ramdisk/ld.script	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,9 @@
+OUTPUT_FORMAT("ecoff-littlemips")
+OUTPUT_ARCH(mips)
+SECTIONS
+{
+  .initrd :
+  {
+        *(.data)
+  }
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips/philips/nino/reset.c linux/arch/mips/philips/nino/reset.c
--- v2.4.9/linux/arch/mips/philips/nino/reset.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/philips/nino/reset.c	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,37 @@
+/*
+ *  linux/arch/mips/philips/nino/reset.c
+ *
+ *  Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Generic restart, halt and power off functions for Philips Nino.
+ */
+#include <linux/init.h>
+#include <asm/reboot.h>
+
+void (*reset_vector)(void) = (void (*)(void)) 0xBFC00000;
+
+void nino_machine_restart(char *command)
+{
+	reset_vector();
+}
+
+void nino_machine_halt(void)
+{
+	reset_vector();
+}
+
+void nino_machine_power_off(void)
+{
+	reset_vector();
+}
+
+void __init setup_nino_reset_vectors(void)
+{
+	_machine_restart = nino_machine_restart;
+	_machine_halt = nino_machine_halt;
+	_machine_power_off = nino_machine_power_off;
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips/philips/nino/rtc.c linux/arch/mips/philips/nino/rtc.c
--- v2.4.9/linux/arch/mips/philips/nino/rtc.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/philips/nino/rtc.c	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,34 @@
+/*
+ *  linux/arch/mips/philips/nino/rtc.c
+ *
+ *  Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Functions to access RTC on the Philips Nino.
+ */
+#include <linux/spinlock.h>
+#include <linux/mc146818rtc.h>
+
+static unsigned char nino_rtc_read_data(unsigned long addr)
+{
+	return 0;
+}
+
+static void nino_rtc_write_data(unsigned char data, unsigned long addr)
+{
+}
+
+static int nino_rtc_bcd_mode(void)
+{
+	return 0;
+}
+
+struct rtc_ops nino_rtc_ops =
+{
+	&nino_rtc_read_data,
+	&nino_rtc_write_data,
+	&nino_rtc_bcd_mode
+};
diff -u --recursive --new-file v2.4.9/linux/arch/mips/philips/nino/setup.c linux/arch/mips/philips/nino/setup.c
--- v2.4.9/linux/arch/mips/philips/nino/setup.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/philips/nino/setup.c	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,120 @@
+/*
+ *  linux/arch/mips/philips/nino/setup.c
+ *
+ *  Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Interrupt and exception initialization for Philips Nino.
+ */
+#include <linux/console.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/mc146818rtc.h>
+#include <linux/sched.h>
+#include <asm/addrspace.h>
+#include <asm/gdb-stub.h>
+#include <asm/irq.h>
+#include <asm/wbflush.h>
+#include <asm/tx3912.h>
+
+extern struct rtc_ops nino_rtc_ops;
+
+extern void nino_wait(void);
+extern void setup_nino_reset_vectors(void);
+extern asmlinkage void nino_handle_int(void);
+extern int setup_nino_irq(int, struct irqaction *);
+void (*board_time_init) (struct irqaction * irq);
+
+#ifdef CONFIG_REMOTE_DEBUG
+extern void set_debug_traps(void);
+extern void breakpoint(void);
+static int remote_debug = 0;
+#endif
+
+static void __init nino_irq_setup(void)
+{
+	unsigned int tmp;
+
+	/* Turn all interrupts off */
+	IntEnable1 = 0;
+	IntEnable2 = 0;
+	IntEnable3 = 0;
+	IntEnable4 = 0;
+	IntEnable5 = 0;
+	IntEnable6 = 0;
+
+	/* Clear all interrupts */
+	IntClear1 = 0xffffffff;
+	IntClear2 = 0xffffffff;
+	IntClear3 = 0xffffffff;
+	IntClear4 = 0xffffffff;
+	IntClear5 = 0xffffffff;
+	IntClear6 = 0xffffffff;
+
+	/*
+	 * Enable only the interrupts for the UART and negative
+	 * edge (1-to-0) triggered multi-function I/O pins.
+	 */
+    	change_cp0_status(ST0_BEV, 0);
+	tmp = read_32bit_cp0_register(CP0_STATUS);
+    	change_cp0_status(ST0_IM, tmp | IE_IRQ2 | IE_IRQ4);
+
+	/* Register the global interrupt handler */
+	set_except_vector(0, nino_handle_int);
+
+#ifdef CONFIG_REMOTE_DEBUG
+	if (remote_debug) {
+		set_debug_traps();
+		breakpoint();
+	}
+#endif
+}
+
+static __init void nino_time_init(struct irqaction *irq)
+{
+	unsigned int scratch = 0;
+
+	/*
+	 * Enable periodic interrupts
+	 */
+	setup_nino_irq(0, irq);
+
+	RTCperiodTimer = PER_TIMER_COUNT;
+	RTCtimerControl = TIM_ENPERTIMER;
+	IntEnable5 |= INT5_PERIODICINT;
+
+	scratch = inl(TX3912_CLK_CTRL_BASE);
+	scratch |= TX3912_CLK_CTRL_ENTIMERCLK;
+	outl(scratch, TX3912_CLK_CTRL_BASE);
+
+	/* Enable all interrupts */
+	IntEnable6 |= INT6_GLOBALEN | INT6_PERIODICINT;
+}
+
+void __init nino_setup(void)
+{
+	irq_setup = nino_irq_setup;
+
+	board_time_init = nino_time_init;
+
+	/* Base address to use for PC type I/O accesses */
+	mips_io_port_base = KSEG1ADDR(0xB0C00000);
+
+	setup_nino_reset_vectors();
+
+	/* Function called during process idle (cpu_idle) */
+	cpu_wait = nino_wait;
+
+#ifdef CONFIG_FB
+	conswitchp = &dummy_con;
+#endif
+
+#ifdef CONFIG_REMOTE_DEBUG
+	remote_debug = 1;
+#endif
+
+	rtc_ops = &nino_rtc_ops;
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips/philips/nino/time.c linux/arch/mips/philips/nino/time.c
--- v2.4.9/linux/arch/mips/philips/nino/time.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/philips/nino/time.c	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,216 @@
+/*
+ *  linux/arch/mips/philips/nino/time.c
+ *
+ *  Copyright (C) 1999 Harald Koerfgen
+ *  Copyright (C) 2000 Pavel Machek (pavel@suse.cz)
+ *  Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Time handling functinos for Philips Nino.
+ */
+#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/delay.h>
+#include <asm/tx3912.h>
+
+extern volatile unsigned long wall_jiffies;
+extern rwlock_t xtime_lock;
+
+static struct timeval xbase;
+
+#define USECS_PER_JIFFY (1000000/HZ)
+
+/*
+ * Poll the Interrupt Status Registers
+ */
+#undef POLL_STATUS
+
+static unsigned long do_gettimeoffset(void)
+{
+    /*
+     * This is a kludge
+     */
+    return 0;
+}
+
+static
+void inline readRTC(unsigned long *high, unsigned long *low)
+{
+	/* read twice, and keep reading till we find two
+	 * the same pairs. This is needed in case the RTC
+	 * was updating its registers and we read a old
+	 * High but a new Low. */
+	do {
+		*high = RTChigh & RTC_HIGHMASK;
+		*low = RTClow;
+	} while (*high != (RTChigh & RTC_HIGHMASK) || RTClow!=*low);
+}
+
+/*
+ * This version of gettimeofday has near millisecond resolution.
+ */
+void do_gettimeofday(struct timeval *tv)
+{
+    unsigned long flags;
+    unsigned long high, low;
+
+    read_lock_irqsave(&xtime_lock, flags);
+    // 40 bit RTC, driven by 32khz source:
+    // +-----------+-----------------------------------------+
+    // | HHHH.HHHH | LLLL.LLLL.LLLL.LLLL.LMMM.MMMM.MMMM.MMMM |
+    // +-----------+-----------------------------------------+
+    readRTC(&high,&low);
+    tv->tv_sec  = (high << 17) | (low >> 15);
+    tv->tv_usec = (low % 32768) * 1953 / 64;
+    tv->tv_sec += xbase.tv_sec;
+    tv->tv_usec += xbase.tv_usec;
+
+    tv->tv_usec += do_gettimeoffset();
+
+    /*
+     * xtime is atomically updated in timer_bh. lost_ticks is
+     * nonzero if the timer bottom half hasnt executed yet.
+     */
+    if (jiffies - wall_jiffies)
+	tv->tv_usec += USECS_PER_JIFFY;
+
+    read_unlock_irqrestore(&xtime_lock, flags);
+
+    if (tv->tv_usec >= 1000000) {
+	tv->tv_usec -= 1000000;
+	tv->tv_sec++;
+    }
+}
+
+void do_settimeofday(struct timeval *tv)
+{
+    write_lock_irq(&xtime_lock);
+    /* This is revolting. We need to set the xtime.tv_usec
+     * correctly. However, the value in this location is
+     * is value at the last tick.
+     * Discover what correction gettimeofday
+     * would have done, and then undo it!
+     */
+    tv->tv_usec -= do_gettimeoffset();
+
+    if (tv->tv_usec < 0) {
+	tv->tv_usec += 1000000;
+	tv->tv_sec--;
+    }
+
+    /* reset RTC to 0 (real time is xbase + RTC) */
+    xbase = *tv;
+    RTCtimerControl |=  TIM_RTCCLEAR;
+    RTCtimerControl &= ~TIM_RTCCLEAR;
+    RTCalarmHigh = RTCalarmLow = ~0UL;
+
+    xtime = *tv;
+    time_state = TIME_BAD;
+    time_maxerror = MAXPHASE;
+    time_esterror = MAXPHASE;
+    write_unlock_irq(&xtime_lock);
+}
+
+static int set_rtc_mmss(unsigned long nowtime)
+{
+    int retval = 0;
+
+    return retval;
+}
+
+/* last time the cmos clock got updated */
+static long last_rtc_update = 0;
+
+/*
+ * timer_interrupt() needs to keep up the real-time clock,
+ * as well as call the "do_timer()" routine every clocktick
+ */
+
+int do_write = 1;
+
+static void
+timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+#ifdef POLL_STATUS
+    static unsigned long old_IntStatus1 = 0;
+    static unsigned long old_IntStatus3 = 0;
+    static unsigned long old_IntStatus4 = 0;
+    static unsigned long old_IntStatus5 = 0;
+    static int counter = 0;
+    int i;
+
+    new_spircv = SPIData & 0xff;
+    if ((old_spircv != new_spircv) && (new_spircv != 0xff)) {
+	    printk( "SPIData changed: %x\n", new_spircv );
+    }
+    old_spircv = new_spircv;
+    if (do_write)
+	    SPIData = 0;
+#endif
+
+    if (!user_mode(regs)) {
+	if (prof_buffer && current->pid) {
+	    extern int _stext;
+	    unsigned long pc = regs->cp0_epc;
+
+	    pc -= (unsigned long) &_stext;
+	    pc >>= prof_shift;
+	    /*
+	     * Dont ignore out-of-bounds pc values silently,
+	     * put them into the last histogram slot, so if
+	     * present, they will show up as a sharp peak.
+	     */
+	    if (pc > prof_len - 1)
+		pc = prof_len - 1;
+		atomic_inc((atomic_t *) & prof_buffer[pc]);
+	    }
+    }
+
+    /*
+     * aaaand... action!
+     */
+    do_timer(regs);
+
+    /*
+     * If we have an externally syncronized Linux clock, then update
+     * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
+     * called as close as possible to 500 ms before the new second starts.
+     */
+    if (time_state != TIME_BAD && 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 */
+    }
+}
+
+static struct irqaction irq0 = {timer_interrupt, SA_INTERRUPT, 0,
+ 			 "timer", NULL, NULL};
+
+void (*board_time_init) (struct irqaction * irq);
+
+int __init time_init(void)
+{
+    struct timeval starttime;
+
+    starttime.tv_sec = mktime(2000, 1, 1, 0, 0, 0);
+    starttime.tv_usec = 0;
+    do_settimeofday(&starttime);
+
+    board_time_init(&irq0);
+
+    return 0;
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips/sgi/kernel/indy_hpc.c linux/arch/mips/sgi/kernel/indy_hpc.c
--- v2.4.9/linux/arch/mips/sgi/kernel/indy_hpc.c	Sat May 13 08:29:14 2000
+++ linux/arch/mips/sgi/kernel/indy_hpc.c	Sun Sep  9 10:43:02 2001
@@ -12,6 +12,7 @@
 #include <asm/sgi/sgihpc.h>
 #include <asm/sgi/sgint23.h>
 #include <asm/sgialib.h>
+#include <asm/bootinfo.h>
 
 /* #define DEBUG_SGIHPC */
 
@@ -50,10 +51,12 @@
 		prom_printf("GUINESS ");
 #endif
 		sgi_guiness = 1;
+		mips_machtype = MACH_SGI_INDY;
 	} else {
 #ifdef DEBUG_SGIHPC
 		prom_printf("FULLHOUSE ");
 #endif
+                mips_machtype = MACH_SGI_INDIGO2;
 		sgi_guiness = 0;
 	}
 	sgi_boardid = brev;
diff -u --recursive --new-file v2.4.9/linux/arch/mips/sgi/kernel/indy_int.c linux/arch/mips/sgi/kernel/indy_int.c
--- v2.4.9/linux/arch/mips/sgi/kernel/indy_int.c	Fri Feb  9 11:29:44 2001
+++ linux/arch/mips/sgi/kernel/indy_int.c	Sun Sep  9 10:43:02 2001
@@ -1,5 +1,4 @@
-/* $Id: indy_int.c,v 1.18 2000/03/02 02:36:50 ralf Exp $
- *
+/*
  * indy_int.c: Routines for generic manipulation of the INT[23] ASIC
  *             found on INDY workstations..
  *
@@ -70,8 +69,6 @@
 
 extern asmlinkage void indyIRQ(void);
 
-unsigned long spurious_count = 0;
-
 /* Local IRQ's are layed out logically like this:
  *
  * 0  --> 7   ==   local 0 interrupts
@@ -79,433 +76,333 @@
  * 16 --> 23  ==   vectored level 2 interrupts
  * 24 --> 31  ==   vectored level 3 interrupts (not used)
  */
-void disable_local_irq(unsigned int irq_nr)
+static void enable_local0_irq(unsigned int irq)
 {
 	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!");
-	};
+	ioc_icontrol->imask0 |= (1 << (irq - SGINT_LOCAL0));
 	restore_flags(flags);
 }
 
-void enable_local_irq(unsigned int irq_nr)
+static unsigned int startup_local0_irq(unsigned int irq)
+{
+	enable_local0_irq(irq);
+
+	return 0;		/* Never anything pending  */
+}
+
+static void disable_local0_irq(unsigned int irq)
 {
 	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!");
-	};
+	ioc_icontrol->imask0 &= ~(1 << (irq - SGINT_LOCAL0));
 	restore_flags(flags);
 }
 
-void disable_gio_irq(unsigned int irq_nr)
+#define shutdown_local0_irq	disable_local0_irq
+#define mask_and_ack_local0_irq	disable_local0_irq
+
+static void end_local0_irq (unsigned int irq)
 {
-	/* XXX TODO XXX */
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_local0_irq(irq);
 }
 
-void enable_gio_irq(unsigned int irq_nr)
+static struct hw_interrupt_type ip22_local0_irq_type = {
+	"IP22 local 0",
+	startup_local0_irq,
+	shutdown_local0_irq,
+	enable_local0_irq,
+	disable_local0_irq,
+	mask_and_ack_local0_irq,
+	end_local0_irq,
+	NULL
+};
+
+static void enable_local1_irq(unsigned int irq)
 {
-	/* XXX TODO XXX */
+	unsigned long flags;
+
+	save_and_cli(flags);
+	ioc_icontrol->imask1 |= (1 << (irq - SGINT_LOCAL1));
+	restore_flags(flags);
 }
 
-void disable_hpcdma_irq(unsigned int irq_nr)
+static unsigned int startup_local1_irq(unsigned int irq)
 {
-	/* XXX TODO XXX */
+	enable_local1_irq(irq);
+
+	return 0;		/* Never anything pending  */
 }
 
-void enable_hpcdma_irq(unsigned int irq_nr)
+void disable_local1_irq(unsigned int irq)
 {
-	/* XXX TODO XXX */
+	unsigned long flags;
+
+	save_and_cli(flags);
+	ioc_icontrol->imask1 &= ~(1 << (irq- SGINT_LOCAL1));
+	restore_flags(flags);
 }
 
-void disable_irq(unsigned int irq_nr)
+#define shutdown_local1_irq	disable_local1_irq
+#define mask_and_ack_local1_irq	disable_local1_irq
+
+static void end_local1_irq (unsigned int irq)
 {
-	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?");
-	}
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_local1_irq(irq);
 }
 
-void enable_irq(unsigned int irq_nr)
+static struct hw_interrupt_type ip22_local1_irq_type = {
+	"IP22 local 1",
+	startup_local1_irq,
+	shutdown_local1_irq,
+	enable_local1_irq,
+	disable_local1_irq,
+	mask_and_ack_local1_irq,
+	end_local1_irq,
+	NULL
+};
+
+static void enable_local2_irq(unsigned int irq)
 {
-	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?");
-	}
+	unsigned long flags;
+
+	save_and_cli(flags);
+	enable_local0_irq(7);
+	ioc_icontrol->cmeimask0 |= (1 << (irq - SGINT_LOCAL2));
+	restore_flags(flags);
 }
 
-#if 0
-/*
- * Currently unused.
- */
-static void local_unex(int irq, void *data, struct pt_regs *regs)
+static unsigned int startup_local2_irq(unsigned int irq)
 {
-	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
+	enable_local2_irq(irq);
 
-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
-};
+	return 0;		/* Never anything pending  */
+}
 
-int setup_indy_irq(int irq, struct irqaction * new)
+void disable_local2_irq(unsigned int irq)
 {
-	printk("setup_indy_irq: Yeee, don't know how to setup irq<%d> for %s  %p\n",
-	       irq, new->name, new->handler);
-	return 0;
+	unsigned long flags;
+
+	save_and_cli(flags);
+	ioc_icontrol->cmeimask0 &= ~(1 << (irq - SGINT_LOCAL2));
+	restore_flags(flags);
 }
 
-static struct irqaction r4ktimer_action = {
-	NULL, 0, 0, "R4000 timer/counter", NULL, NULL,
-};
+#define shutdown_local2_irq disable_local2_irq
+#define mask_and_ack_local2_irq	disable_local2_irq
 
-static struct irqaction indy_berr_action = {
-	NULL, 0, 0, "IP22 Bus Error", NULL, NULL,
-};
+static void end_local2_irq (unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_local2_irq(irq);
+}
 
-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
+static struct hw_interrupt_type ip22_local2_irq_type = {
+	"IP22 local 2",
+	startup_local2_irq,
+	shutdown_local2_irq,
+	enable_local2_irq,
+	disable_local2_irq,
+	mask_and_ack_local2_irq,
+	end_local2_irq,
+	NULL
 };
 
-int get_irq_list(char *buf)
+static void enable_local3_irq(unsigned int irq)
 {
-	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;
+	unsigned long flags;
+
+	save_and_cli(flags);
+	printk("Yeeee, got passed irq_nr %d at enable_local3_irq\n", irq);
+	panic("INVALID IRQ level!");
+	restore_flags(flags);
 }
 
-/*
- * 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)
+static unsigned int startup_local3_irq(unsigned int irq)
 {
-	struct irqaction *action;
-	int do_random, cpu;
+	enable_local3_irq(irq);
 
-	cpu = smp_processor_id();
-	irq_enter(cpu);
-	kstat.irqs[0][irq]++;
+	return 0;		/* Never anything pending  */
+}
 
-	printk("Got irq %d, press a key.", irq);
-	prom_getchar();
-	romvec->imode();
+void disable_local3_irq(unsigned int irq)
+{
+	unsigned long flags;
 
+	save_and_cli(flags);
 	/*
-	 * 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 ...
+	 * This way we'll see if anyone would ever want vectored level 3
+	 * interrupts.  Highly unlikely.
 	 */
-        /* mask_and_ack_irq(irq); */
+	printk("Yeeee, got passed irq_nr %d at disable_local3_irq\n", irq);
+	panic("INVALID IRQ level!");
+	restore_flags(flags);
+}
 
-	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);
+#define shutdown_local3_irq disable_local3_irq
+#define mask_and_ack_local3_irq	disable_local3_irq
 
-	/* unmasking and bottom half handling is done magically for us. */
+static void end_local3_irq (unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_local3_irq(irq);
 }
 
-int request_local_irq(unsigned int lirq, void (*func)(int, void *, struct pt_regs *),
-		      unsigned long iflags, const char *dname, void *devid)
+static struct hw_interrupt_type ip22_local3_irq_type = {
+	"IP22 local 3",
+	startup_local3_irq,
+	shutdown_local3_irq,
+	enable_local3_irq,
+	disable_local3_irq,
+	mask_and_ack_local3_irq,
+	end_local3_irq,
+	NULL
+};
+
+void enable_gio_irq(unsigned int irq)
 {
-	struct irqaction *action;
+	/* XXX TODO XXX */
+}
 
-	lirq -= SGINT_LOCAL0;
-	if(lirq >= 24 || !func)
-		return -EINVAL;
+static unsigned int startup_gio_irq(unsigned int irq)
+{
+	enable_gio_irq(irq);
 
-	action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
-	if(!action)
-		return -ENOMEM;
+	return 0;		/* Never anything pending  */
+}
 
-	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 disable_gio_irq(unsigned int irq)
+{
+	/* XXX TODO XXX */
 }
 
-void free_local_irq(unsigned int lirq, void *dev_id)
+#define shutdown_gio_irq	disable_gio_irq
+#define mask_and_ack_gio_irq	disable_gio_irq
+
+static void end_gio_irq (unsigned int irq)
 {
-	struct irqaction *action;
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_gio_irq(irq);
+}
 
-	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;
+static struct hw_interrupt_type ip22_gio_irq_type = {
+	"IP22 GIO",
+	startup_gio_irq,
+	shutdown_gio_irq,
+	enable_gio_irq,
+	disable_gio_irq,
+	mask_and_ack_gio_irq,
+	end_gio_irq,
+	NULL
+};
+
+void enable_hpcdma_irq(unsigned int irq)
+{
+	/* XXX TODO XXX */
 }
-		
-void free_irq(unsigned int irq, void *dev_id)
+
+static unsigned int startup_hpcdma_irq(unsigned int irq)
 {
-	struct irqaction * action, **p;
-	unsigned long flags;
+	enable_hpcdma_irq(irq);
 
-	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);
+	return 0;		/* Never anything pending  */
 }
 
-int (*irq_cannonicalize)(int irq);
-
-static int indy_irq_cannonicalize(int irq)
+void disable_hpcdma_irq(unsigned int irq)
 {
-	return irq;	/* Sane hardware, sane code ... */
+	/* XXX TODO XXX */
 }
 
-void __init init_IRQ(void)
+#define shutdown_hpcdma_irq	disable_hpcdma_irq
+#define mask_and_ack_hpcdma_irq	disable_hpcdma_irq
+
+static void end_hpcdma_irq (unsigned int irq)
 {
-	irq_cannonicalize = indy_irq_cannonicalize;
-	irq_setup();
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_hpcdma_irq(irq);
 }
 
+static struct hw_interrupt_type ip22_hpcdma_irq_type = {
+	"IP22 HPC DMA",
+	startup_hpcdma_irq,
+	shutdown_hpcdma_irq,
+	enable_hpcdma_irq,
+	disable_hpcdma_irq,
+	mask_and_ack_hpcdma_irq,
+	end_hpcdma_irq,
+	NULL
+};
+
+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
+};
+
 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();;
+	int irq;
 
 	mask &= ioc_icontrol->imask0;
-	if(mask & ISTAT0_LIO2) {
+	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];
 	}
 
 	/* if irq == 0, then the interrupt has already been cleared */
-	if ( irq == 0 ) { goto end; }
-	/* if action == NULL, then we do have a handler for the irq */
-	if ( action == NULL ) { goto no_handler; }
-	
-	irq_enter(cpu);
-	kstat.irqs[0][irq + 16]++;
-	action->handler(irq, action->dev_id, regs);
-	irq_exit(cpu);
+	if (irq == 0)
+		goto end;
+
+	do_IRQ(irq, regs);
 	goto end;
 
 no_handler:
 	printk("No handler for local0 irq: %i\n", irq);
 
 end:	
-	return;	
-	
+	return;
 }
 
 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();;
+	int irq;
 
 	mask &= ioc_icontrol->imask1;
-	if(mask & ISTAT1_LIO3) {
+	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];
 	}
+
 	/* if irq == 0, then the interrupt has already been cleared */
 	/* not sure if it is needed here, but it is needed for local0 */
-	if ( irq == 0 ) { goto end; }
-	/* if action == NULL, then we do have a handler for the irq */
-	if ( action == NULL ) { goto no_handler; }
-	
-	irq_enter(cpu);
-	kstat.irqs[0][irq + 24]++;
-	action->handler(irq, action->dev_id, regs);
-	irq_exit(cpu);
+	if (irq == 0)
+		goto end;
+
+	do_IRQ(irq, regs);
 	goto end;
 	
 no_handler:
@@ -520,27 +417,16 @@
 	int cpu = smp_processor_id();
 	int irq = 6;
 
-	irq_enter(cpu);
+	irq_enter(cpu, irq);
 	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;
+	irq_exit(cpu, irq);
 }
 
-int probe_irq_off (unsigned long irqs)
-{
-	return 0;
-}
-
-void __init sgint_init(void)
+void __init init_IRQ(void)
 {
 	int i;
 
@@ -548,43 +434,43 @@
 	sgi_i3regs = (struct sgi_int3_regs *) (KSEG1 + SGI_INT3_BASE);
 
 	/* Init local mask --> irq tables. */
-	for(i = 0; i < 256; i++) {
-		if(i & 0x80) {
+	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) {
+		} 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) {
+		} 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) {
+		} 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) {
+		} 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) {
+		} 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) {
+		} 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) {
+		} else if (i & 0x01) {
 			lc0msk_to_irqnr[i] = 0;
 			lc1msk_to_irqnr[i] = 8;
 			lc2msk_to_irqnr[i] = 16;
@@ -614,6 +500,29 @@
 	ioc_icontrol->cmeimask0 = 0;
 	ioc_icontrol->cmeimask1 = 0;
 
-	/* Now safe to set the exception vector. */
 	set_except_vector(0, indyIRQ);
+
+	init_generic_irq();
+
+	for (i = SGINT_LOCAL0; i < SGINT_END; i++) {
+		hw_irq_controller *handler;
+
+		if (i < SGINT_LOCAL1)
+			handler		= &ip22_local0_irq_type;
+		else if (i < SGINT_LOCAL2)
+			handler		= &ip22_local1_irq_type;
+		else if (i < SGINT_LOCAL3)
+			handler		= &ip22_local2_irq_type;
+		else if (i < SGINT_GIO)
+			handler		= &ip22_local3_irq_type;
+		else if (i < SGINT_HPCDMA)
+			handler		= &ip22_gio_irq_type;
+		else if (i < SGINT_END)
+			handler		= &ip22_hpcdma_irq_type;
+
+		irq_desc[i].status	= IRQ_DISABLED;
+		irq_desc[i].action	= 0;
+		irq_desc[i].depth	= 1;
+		irq_desc[i].handler	= handler;
+	}
 }
diff -u --recursive --new-file v2.4.9/linux/arch/mips/sgi/kernel/indy_rtc.c linux/arch/mips/sgi/kernel/indy_rtc.c
--- v2.4.9/linux/arch/mips/sgi/kernel/indy_rtc.c	Sat May 13 08:29:14 2000
+++ linux/arch/mips/sgi/kernel/indy_rtc.c	Sun Sep  9 10:43:02 2001
@@ -1,12 +1,11 @@
-/* $Id: indy_rtc.c,v 1.1 1998/06/30 00:21: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
  * for more details.
  *
  * RTC routines for Indy style attached Dallas chip.
  *
- * Copyright (C) 1998 by Ralf Baechle
+ * Copyright (C) 1998, 2001 by Ralf Baechle
  */
 #include <linux/mc146818rtc.h>
 #include <asm/sgi/sgihpc.h>
diff -u --recursive --new-file v2.4.9/linux/arch/mips/sgi/kernel/indy_sc.c linux/arch/mips/sgi/kernel/indy_sc.c
--- v2.4.9/linux/arch/mips/sgi/kernel/indy_sc.c	Tue Mar  6 19:44:36 2001
+++ linux/arch/mips/sgi/kernel/indy_sc.c	Sun Sep  9 10:43:02 2001
@@ -1,8 +1,7 @@
-/* $Id: indy_sc.c,v 1.14 2000/03/25 22:35:07 ralf Exp $
- *
+/*
  * indy_sc.c: Indy cache management functions.
  *
- * Copyright (C) 1997 Ralf Baechle (ralf@gnu.org),
+ * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org),
  * derived from r4xx0.c by David S. Miller (dm@engr.sgi.com).
  */
 #include <linux/init.h>
@@ -34,30 +33,30 @@
 {
 	unsigned long tmp;
 
-	__asm__ __volatile__("
-		.set	noreorder
-		.set	mips3
-		.set	noat
-		mfc0	%2, $12
-		li	$1, 0x80	# Go 64 bit
-		mtc0	$1, $12
-
-		dli	$1, 0x9000000080000000
-		or	%0, $1		# first line to flush
-		or	%1, $1		# last line to flush
-		.set	at
-
-1:		sw	$0, 0(%0)
-		bne	%0, %1, 1b
-		daddu	%0, 32
-
-		mtc0	%2, $12		# Back to 32 bit
-		nop; nop; nop; nop;
-		.set mips0
-		.set reorder"
-		: "=r" (first), "=r" (last), "=&r" (tmp)
-		: "0" (first), "1" (last)
-		: "$1");
+	__asm__ __volatile__(
+	".set\tnoreorder\t\t\t# indy_sc_wipe\n\t"
+	".set\tmips3\n\t"
+	".set\tnoat\n\t"
+	"mfc0\t%2, $12\n\t"
+	"li\t$1, 0x80\t\t\t# Go 64 bit\n\t"
+	"mtc0\t$1, $12\n\t"
+
+	"dli\t$1, 0x9000000080000000\n\t"
+	"or\t%0, $1\t\t\t# first line to flush\n\t"
+	"or\t%1, $1\t\t\t# last line to flush\n\t"
+	".set\tat\n\t"
+
+	"1:\tsw\t$0, 0(%0)\n\t"
+	"bne\t%0, %1, 1b\n\t"
+	"daddu\t%0, 32\n\t"
+
+	"mtc0\t%2, $12\t\t\t# Back to 32 bit\n\t"
+	"nop; nop; nop; nop;\n\t"
+	".set\tmips0\n\t"
+	".set\treorder"
+	: "=r" (first), "=r" (last), "=&r" (tmp)
+	: "0" (first), "1" (last)
+	: "$1");
 }
 
 static void indy_sc_wback_invalidate(unsigned long addr, unsigned long size)
@@ -96,27 +95,27 @@
 #ifdef DEBUG_CACHE
 	printk("Enabling R4600 SCACHE\n");
 #endif
-	__asm__ __volatile__("
-		.set	push
-		.set	noreorder
-		.set	mips3
-		mfc0	%2, $12
-		nop; nop; nop; nop;
-		li	%1, 0x80
-		mtc0	%1, $12
-		nop; nop; nop; nop;
-		li	%0, 0x1
-		dsll	%0, 31
-		lui	%1, 0x9000
-		dsll32	%1, 0
-		or	%0, %1, %0
-		sb	$0, 0(%0)
-		mtc0	$0, $12
-		nop; nop; nop; nop;
-		mtc0	%2, $12
-		nop; nop; nop; nop;
-		.set	pop"
-		: "=r" (tmp1), "=r" (tmp2), "=r" (addr));
+	__asm__ __volatile__(
+	".set\tpush\n\t"
+	".set\tnoreorder\n\t"
+	".set\tmips3\n\t"
+	"mfc0\t%2, $12\n\t"
+	"nop; nop; nop; nop;\n\t"
+	"li\t%1, 0x80\n\t"
+	"mtc0\t%1, $12\n\t"
+	"nop; nop; nop; nop;\n\t"
+	"li\t%0, 0x1\n\t"
+	"dsll\t%0, 31\n\t"
+	"lui\t%1, 0x9000\n\t"
+	"dsll32\t%1, 0\n\t"
+	"or\t%0, %1, %0\n\t"
+	"sb\t$0, 0(%0)\n\t"
+	"mtc0\t$0, $12\n\t"
+	"nop; nop; nop; nop;\n\t"
+	"mtc0\t%2, $12\n\t"
+	"nop; nop; nop; nop;\n\t"
+	".set\tpop"
+	: "=r" (tmp1), "=r" (tmp2), "=r" (addr));
 }
 
 static void indy_sc_disable(void)
@@ -126,27 +125,27 @@
 #ifdef DEBUG_CACHE
 	printk("Disabling R4600 SCACHE\n");
 #endif
-	__asm__ __volatile__("
-		.set	push
-		.set	noreorder
-		.set	mips3
-		li	%0, 0x1
-		dsll	%0, 31
-		lui	%1, 0x9000
-		dsll32	%1, 0
-		or	%0, %1, %0
-		mfc0	%2, $12
-		nop; nop; nop; nop;
-		li	%1, 0x80
-		mtc0	%1, $12
-		nop; nop; nop; nop;
-		sh	$0, 0(%0)
-		mtc0	$0, $12
-		nop; nop; nop; nop;
-		mtc0	%2, $12
-		nop; nop; nop; nop;
-		.set	pop"
-		: "=r" (tmp1), "=r" (tmp2), "=r" (tmp3));
+	__asm__ __volatile__(
+	".set\tpush\n\t"
+	".set\tnoreorder\n\t"
+	".set\tmips3\n\t"
+	"li\t%0, 0x1\n\t"
+	"dsll\t%0, 31\n\t"
+	"lui\t%1, 0x9000\n\t"
+	"dsll32\t%1, 0\n\t"
+	"or\t%0, %1, %0\n\t"
+	"mfc0\t%2, $12\n\t"
+	"nop; nop; nop; nop\n\t"
+	"li\t%1, 0x80\n\t"
+	"mtc0\t%1, $12\n\t"
+	"nop; nop; nop; nop\n\t"
+	"sh\t$0, 0(%0)\n\t"
+	"mtc0\t$0, $12\n\t"
+	"nop; nop; nop; nop\n\t"
+	"mtc0\t%2, $12\n\t"
+	"nop; nop; nop; nop\n\t"
+	".set\tpop"
+	: "=r" (tmp1), "=r" (tmp2), "=r" (tmp3));
 }
 
 static inline int __init indy_sc_probe(void)
diff -u --recursive --new-file v2.4.9/linux/arch/mips/sgi/kernel/indy_timer.c linux/arch/mips/sgi/kernel/indy_timer.c
--- v2.4.9/linux/arch/mips/sgi/kernel/indy_timer.c	Mon Oct 16 12:58:51 2000
+++ linux/arch/mips/sgi/kernel/indy_timer.c	Wed Dec 31 16:00:00 1969
@@ -1,266 +0,0 @@
-/* $Id: indy_timer.c,v 1.17 2000/01/21 22:34:03 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/sgialib.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
- * 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;
-unsigned long missed_heart_beats;
-
-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 60 s */
-			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;
-}
-
-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();
-	prom_imode();
-	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.4.9/linux/arch/mips/sgi/kernel/promcon.c linux/arch/mips/sgi/kernel/promcon.c
--- v2.4.9/linux/arch/mips/sgi/kernel/promcon.c	Thu Oct 12 14:20:48 2000
+++ linux/arch/mips/sgi/kernel/promcon.c	Wed Dec 31 16:00:00 1969
@@ -1,68 +0,0 @@
-/*
- * Wrap-around code for a console using the
- * SGI PROM io-routines.
- *
- * Copyright (c) 1999 Ulf Carlsson
- *
- * Derived from DECstation promcon.c
- * Copyright (c) 1998 Harald Koerfgen 
- */
-
-#include <linux/tty.h>
-#include <linux/major.h>
-#include <linux/ptrace.h>
-#include <linux/init.h>
-#include <linux/console.h>
-#include <linux/fs.h>
-
-#include <asm/sgialib.h>
-
-static void prom_console_write(struct console *co, const char *s,
-			       unsigned count)
-{
-    unsigned i;
-
-    /*
-     *    Now, do each character
-     */
-    for (i = 0; i < count; i++) {
-	if (*s == 10)
-	    prom_printf("%c", 13);
-	prom_printf("%c", *s++);
-    }
-}
-
-static int prom_console_wait_key(struct console *co)
-{
-    return prom_getchar();
-}
-
-static int __init prom_console_setup(struct console *co, char *options)
-{
-    return 0;
-}
-
-static kdev_t prom_console_device(struct console *c)
-{
-    return MKDEV(TTY_MAJOR, 64 + c->index);
-}
-
-static struct console sercons =
-{
-    name:	"ttyS",
-    write:	prom_console_write,
-    device:	prom_console_device,
-    wait_key:	prom_console_wait_key,
-    setup:	prom_console_setup,
-    flags:	CON_PRINTBUFFER,
-    index:	-1,
-};
-
-/*
- *    Register console.
- */
-
-void __init sgi_prom_console_init(void )
-{
-    register_console(&sercons);
-}
diff -u --recursive --new-file v2.4.9/linux/arch/mips/sgi/kernel/reset.c linux/arch/mips/sgi/kernel/reset.c
--- v2.4.9/linux/arch/mips/sgi/kernel/reset.c	Sat May 13 08:29:14 2000
+++ linux/arch/mips/sgi/kernel/reset.c	Sun Sep  9 10:43:02 2001
@@ -1,12 +1,9 @@
-/* $Id: reset.c,v 1.7 1999/08/11 20:26:51 andrewb Exp $
- *
- * Reset a SGI.
- *
+/*
  * This file 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, 2001 by Ralf Baechle
  */
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -54,7 +51,7 @@
 {
 	if (shuting_down)
 		sgi_machine_power_off();
-	prom_imode();
+	ArcEnterInteractiveMode();
 }
 
 static void sgi_machine_power_off(void)
diff -u --recursive --new-file v2.4.9/linux/arch/mips/sgi/kernel/setup.c linux/arch/mips/sgi/kernel/setup.c
--- v2.4.9/linux/arch/mips/sgi/kernel/setup.c	Tue Mar  6 19:44:36 2001
+++ linux/arch/mips/sgi/kernel/setup.c	Sun Sep  9 10:43:02 2001
@@ -24,6 +24,7 @@
 #include <asm/sgi/sgimc.h>
 #include <asm/sgi/sgihpc.h>
 #include <asm/sgi/sgint23.h>
+#include <asm/time.h>
 #include <asm/gdb-stub.h>
 
 #ifdef CONFIG_REMOTE_DEBUG
@@ -32,7 +33,7 @@
 static int remote_debug = 0;
 #endif
 
-#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_SGI_PROM_CONSOLE)
+#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_ARC_CONSOLE)
 extern void console_setup(char *);
 #endif
 
@@ -117,28 +118,6 @@
 	sgi_read_status
 };
 
-static void __init sgi_irq_setup(void)
-{
-	sgint_init();
-
-#ifdef CONFIG_REMOTE_DEBUG
-	if (remote_debug)
-		set_debug_traps();
-	breakpoint(); /* you may move this line to whereever you want :-) */
-#endif
-}
-
-int __init page_is_ram(unsigned long pagenr)
-{
-	if ((pagenr<<PAGE_SHIFT) < 0x2000UL)
-		return 1;
-	if ((pagenr<<PAGE_SHIFT) > 0x08002000)
-		return 1;
-	return 0;
-}
-
-void (*board_time_init)(struct irqaction *irq);
-
 static unsigned long dosample(volatile unsigned char *tcwp,
                               volatile unsigned char *tc2p)
 {
@@ -161,14 +140,16 @@
                 ct1 = read_32bit_cp0_register(CP0_COUNT);
         } while(msb);
 
-        /* Stop the counter. */
-        *tcwp = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL | SGINT_TCWORD_MSWST);
+	/* 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 1/HZ seconds. We round off the nearest 1 MHz of
-	 * master clock (= 1000000 / 100 / 2 = 5000 count).
-         */
-        return ((ct1 - ct0) / 5000) * 5000;
+	/*
+	 * Return the difference, this is how far the r4k counter increments
+	 * for every 1/HZ seconds. We round off the nearest 1 MHz of master
+	 * clock (= 1000000 / 100 / 2 = 5000 count).
+	 */
+
+	return ((ct1 - ct0) / 5000) * 5000;
 }
 
 #define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
@@ -180,7 +161,7 @@
 	 */
         struct sgi_ioc_timers *p;
         volatile unsigned char *tcwp, *tc2p;
-	unsigned long r4k_ticks[3] = { 0, 0, 0 };
+	unsigned long r4k_ticks[3];
 	unsigned long r4k_next;
 
         /* Figure out the r4k offset, the algorithm is very simple
@@ -201,10 +182,12 @@
         dosample(tcwp, tc2p);                   /* Prime cache. */
         dosample(tcwp, tc2p);                   /* Prime cache. */
 	/* Zero is NOT an option. */
-	while (!r4k_ticks[0])
+	do {
 		r4k_ticks[0] = dosample (tcwp, tc2p);
-	while (!r4k_ticks[1])
+	} while (!r4k_ticks[0]);
+	do {
 		r4k_ticks[1] = dosample (tcwp, tc2p);
+	} while (!r4k_ticks[1]);
 
 	if (r4k_ticks[0] != r4k_ticks[1]) {
 		printk ("warning: timer counts differ, retrying...");
@@ -226,7 +209,7 @@
 	/* Set ourselves up for future interrupts */
         r4k_next = (read_32bit_cp0_register(CP0_COUNT) + r4k_interval);
         write_32bit_cp0_register(CP0_COMPARE, r4k_next);
-        set_cp0_status(ST0_IM, ALLINTS);
+        change_cp0_status(ST0_IM, ALLINTS);
 	sti ();
 }
 
@@ -239,8 +222,6 @@
 	char *kgdb_ttyd;
 #endif
 
-
-	irq_setup = sgi_irq_setup;
 	board_time_init = sgi_time_init;
 
 	/* Init the INDY HPC I/O controller.  Need to call this before
@@ -282,7 +263,7 @@
 		       line ? 1 : 2);
 		rs_kgdb_hook(line);
 
-		prom_printf("KGDB: Using serial line /dev/ttyd%d for session, "
+		printk("KGDB: Using serial line /dev/ttyd%d for session, "
 			    "please connect your debugger\n", line ? 1 : 2);
 
 		remote_debug = 1;
@@ -290,7 +271,7 @@
 	}
 #endif
 
-#ifdef CONFIG_SGI_PROM_CONSOLE
+#ifdef CONFIG_ARC_CONSOLE
 	console_setup("ttyS0");
 #endif
  
@@ -324,5 +305,4 @@
 #ifdef CONFIG_VIDEO_VINO
 	init_vino();
 #endif
-
 }
diff -u --recursive --new-file v2.4.9/linux/arch/mips/sgi/kernel/time.c linux/arch/mips/sgi/kernel/time.c
--- v2.4.9/linux/arch/mips/sgi/kernel/time.c	Sun Jul  9 22:18:15 2000
+++ linux/arch/mips/sgi/kernel/time.c	Sun Sep  9 10:43:02 2001
@@ -9,13 +9,13 @@
 
 void indy_8254timer_irq(void)
 {
-        int cpu = smp_processor_id();
-        int irq = 4;
+	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();
-        prom_imode();
-        irq_exit(cpu);
+	irq_enter(cpu, irq);
+	kstat.irqs[0][irq]++;
+	printk("indy_8254timer_irq: Whoops, should not have gotten this IRQ\n");
+	prom_getchar();
+	ArcEnterInteractiveMode();
+	irq_exit(cpu, irq);
 }
diff -u --recursive --new-file v2.4.9/linux/arch/mips/sni/dma.c linux/arch/mips/sni/dma.c
--- v2.4.9/linux/arch/mips/sni/dma.c	Sat May 13 08:29:14 2000
+++ linux/arch/mips/sni/dma.c	Wed Dec 31 16:00:00 1969
@@ -1,42 +0,0 @@
-/* $Id: dma.c,v 1.1 2000/02/18 00:24:30 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.4.9/linux/arch/mips/sni/int-handler.S linux/arch/mips/sni/int-handler.S
--- v2.4.9/linux/arch/mips/sni/int-handler.S	Sat May 13 08:29:14 2000
+++ linux/arch/mips/sni/int-handler.S	Sun Sep  9 10:43:02 2001
@@ -1,8 +1,7 @@
-/* $Id: int-handler.S,v 1.4 1999/01/04 16:03:58 ralf Exp $
- *
+/*
  * SNI RM200 PCI specific interrupt handler code.
  *
- * Copyright (C) 1994 - 1997 by Ralf Baechle
+ * Copyright (C) 1994, 95, 96, 97, 98, 1999, 2000 by Ralf Baechle
  */
 #include <asm/asm.h>
 #include <asm/mipsregs.h>
@@ -37,22 +36,14 @@
 		mfc0	t1, CP0_CAUSE
 		and	t0, t1
 
-		/* The following interrupt dispatch tests for hwint 1 /
-		   EISA bridge first such that the timer interrupt get the
-		   highest priority.  */
-		 andi	t1, t0, 0x0800			# hardware interrupt 1
-		bnez	t1, hwint1
-		 andi	t1, t0, 0x4000			# hardware interrupt 4
-		bnez	t1, hwint4
-
+		 andi	t1, t0, 0x4a00			# hardware interrupt 1
+		bnez	t1, _hwint134
 		 andi	t1, t0, 0x1000			# hardware interrupt 2
-		bnez	t1, hwint2
-		 andi	t1, t0, 0x2000			# hardware interrupt 3
-		bnez	t1, hwint3
+		bnez	t1, _hwint2
 		 andi	t1, t0, 0x8000			# hardware interrupt 5
-		bnez	t1, hwint5
+		bnez	t1, _hwint5
 		 andi	t1, t0, 0x0400			# hardware interrupt 0
-		bnez	t1, hwint0
+		bnez	t1, _hwint0
 		 nop
 
 		j	return				# spurious interrupt
@@ -60,66 +51,23 @@
 
  ##############################################################################
 
-swint0:		PANIC("swint0")
-swint1:		PANIC("swint1")
-
- /* ------------------------------------------------------------------------ */
-
-/* hwint1 deals with EISA and SCSI interrupts.  */
-hwint1:		lbu	s0, PCIMT_CSITPEND
-
-		andi	t1, s0, 0x20
-		beqz	t1, 1f
-		 andi	s1, s0, 0x40
-		lbu	a0, PCIMT_INT_ACKNOWLEDGE	# IACK cycle
-		xori	t0, a0, 0xff
-		beqz	t0, 1f				# spurious interrupt?
-		 nop
-		jal	i8259_do_irq			# call real handler
-		 move	a1, sp
-
-1:		bnez	s1, 1f
-		 li	a0, PCIMT_IRQ_SCSI
-		jal	do_IRQ
-		 move	a1, sp
-
-1:		lui	t0, %hi(PCIMT_CSITPEND)
-		j	ret_from_irq
-		 lbu	zero, %lo(PCIMT_CSITPEND)(t0)
-
- /* ------------------------------------------------------------------------ */
-
 /* hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug
    button interrupts.  */
-hwint0:		PANIC("Received int0 but no handler yet ...\n")
-1:		j	1b
-		 nop
-
-go_spurious:	j	spurious_interrupt		# we got fooled
-		 nop
-
-/* hwint4 is used for only the onboard PCnet 32.  */
-hwint4:		mfc0	s0, CP0_STATUS
-		ori	t0, s0, 0x4000
-		xori	t0, 0x4000
-		mtc0	t0, CP0_STATUS
-
-		li	a0, PCIMT_IRQ_ETHERNET
-		jal	do_IRQ
+_hwint0:	jal	pciasic_hwint0
 		 move	a1, sp
 
-		mtc0	s0, CP0_STATUS
+/*
+ * hwint 1 deals with EISA and SCSI interrupts,
+ * hwint 3 should deal with the PCI A - D interrupts,
+ * hwint 4 is used for only the onboard PCnet 32.
+ */
+_hwint134:	jal	pciasic_hwint134
 
-		j	ret_from_irq
-		 nop
 
 /* This interrupt was used for the com1 console on the first prototypes.  */
-hwint2:		PANIC("hwint2 and no handler yet")
-
-/* hwint3 should deal with the PCI A - D interrupts.  */
-hwint3:		PANIC("hwint3 and no handler yet")
+_hwint2:	jal	pciasic_hwint2
 
 /* hwint5 is the r4k count / compare interrupt  */
-hwint5:		PANIC("hwint5 and no handler yet")
+_hwint5:	jal	pciasic_hwint5
 
 		END(sni_rm200_pci_handle_int)
diff -u --recursive --new-file v2.4.9/linux/arch/mips/sni/irq.c linux/arch/mips/sni/irq.c
--- v2.4.9/linux/arch/mips/sni/irq.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/sni/irq.c	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,159 @@
+/*
+ * This file 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 Linus Torvalds
+ * Copyright (C) 1994 - 2000 Ralf Baechle
+ */
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+
+#include <asm/io.h>
+#include <asm/sni.h>
+
+spinlock_t pciasic_lock = SPIN_LOCK_UNLOCKED;
+
+extern asmlinkage void sni_rm200_pci_handle_int(void);
+extern void do_IRQ(int irq, struct pt_regs *regs);
+
+static void enable_pciasic_irq(unsigned int irq);
+
+static unsigned int startup_pciasic_irq(unsigned int irq)
+{
+	enable_pciasic_irq(irq);
+	return 0; /* never anything pending */
+}
+
+#define shutdown_pciasic_irq	disable_pciasic_irq
+
+void disable_pciasic_irq(unsigned int irq)
+{
+	unsigned int mask = ~(1 << (irq - PCIMT_IRQ_INT2));
+	unsigned long flags;
+
+	spin_lock_irqsave(&pciasic_lock, flags);
+	*(volatile u8 *) PCIMT_IRQSEL &= mask;
+	spin_unlock_irqrestore(&pciasic_lock, flags);
+}
+
+static void enable_pciasic_irq(unsigned int irq)
+{
+	unsigned int mask = 1 << (irq - PCIMT_IRQ_INT2);
+	unsigned long flags;
+
+	spin_lock_irqsave(&pciasic_lock, flags);
+	*(volatile u8 *) PCIMT_IRQSEL |= mask;
+	spin_unlock_irqrestore(&pciasic_lock, flags);
+}
+
+#define mask_and_ack_pciasic_irq disable_pciasic_irq
+
+static void end_pciasic_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_pciasic_irq(irq);
+}
+
+static struct hw_interrupt_type pciasic_irq_type = {
+	"PCIASIC",
+	startup_pciasic_irq,
+	shutdown_pciasic_irq,
+	enable_pciasic_irq,
+	disable_pciasic_irq,
+	mask_and_ack_pciasic_irq,
+	end_pciasic_irq,
+	NULL
+};
+
+/*
+ * hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug
+ * button interrupts.  Later ...
+ */
+void pciasic_hwint0(struct pt_regs *regs)
+{
+	panic("Received int0 but no handler yet ...");
+}
+
+/* This interrupt was used for the com1 console on the first prototypes.  */
+void pciasic_hwint2(struct pt_regs *regs)
+{
+	/* I think this shouldn't happen on production machines.  */
+	panic("hwint2 and no handler yet");
+}
+
+/* hwint5 is the r4k count / compare interrupt  */
+void pciasic_hwint5(struct pt_regs *regs)
+{
+	panic("hwint5 and no handler yet");
+}
+
+static inline int ls1bit8(unsigned int x)
+{
+	int b = 8, s;
+
+	x <<= 24;
+	s = 4; if ((x & 0x0f) == 0) s = 0; b -= s; x <<= s;
+	s = 2; if ((x & 0x03) == 0) s = 0; b -= s; x <<= s;
+	s = 1; if ((x & 0x01) == 0) s = 0; b -= s;
+
+	return b;
+}
+
+/*
+ * hwint 1 deals with EISA and SCSI interrupts,
+ * hwint 3 should deal with the PCI A - D interrupts,
+ * hwint 4 is used for only the onboard PCnet 32.
+ */
+void pciasic_hwint134(struct pt_regs *regs)
+{
+	u8 pend = *(volatile char *)PCIMT_CSITPEND;
+	int irq;
+
+	irq = PCIMT_IRQ_INT2 + ls1bit8(pend);
+	if (irq == PCIMT_IRQ_EISA) {
+		pend = *(volatile char *)PCIMT_INT_ACKNOWLEDGE;
+		if (!(pend ^ 0xff))
+			return;
+	}
+	do_IRQ(irq, regs);
+	return;
+}
+
+void __init init_pciasic(void)
+{
+	unsigned int flags;
+
+	spin_lock_irqsave(&pciasic_lock, flags);
+	* (volatile u8 *) PCIMT_IRQSEL =
+		IT_EISA | IT_INTA | IT_INTB | IT_INTC | IT_INTD;
+	spin_unlock_irqrestore(&pciasic_lock, flags);
+}
+
+/*
+ * On systems with i8259-style interrupt controllers we assume for
+ * driver compatibility reasons interrupts 0 - 15 to be the i8295
+ * interrupts even if the hardware uses a different interrupt numbering.
+ */
+void __init init_IRQ (void)
+{
+	int i;
+
+	set_except_vector(0, sni_rm200_pci_handle_int);
+
+	init_generic_irq();
+	init_i8259_irqs();			/* Integrated i8259  */
+	init_pciasic();
+
+	/* Actually we've got more interrupts to handle ...  */
+	for (i = PCIMT_IRQ_INT2; i <= PCIMT_IRQ_ETHERNET; i++) {
+		irq_desc[i].status     = IRQ_DISABLED;
+		irq_desc[i].action     = 0;
+		irq_desc[i].depth      = 1;
+		irq_desc[i].handler    = &pciasic_irq_type;
+	}
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips/sni/pci.c linux/arch/mips/sni/pci.c
--- v2.4.9/linux/arch/mips/sni/pci.c	Mon Aug  7 14:31:40 2000
+++ linux/arch/mips/sni/pci.c	Sun Sep  9 10:43:02 2001
@@ -203,6 +203,11 @@
 {
 }
 
+unsigned __init int pcibios_assign_all_busses(void)
+{
+	return 0;
+}
+
 char * __init
 pcibios_setup(char *str)
 {
diff -u --recursive --new-file v2.4.9/linux/arch/mips/sni/setup.c linux/arch/mips/sni/setup.c
--- v2.4.9/linux/arch/mips/sni/setup.c	Sun Jul  9 22:18:15 2000
+++ linux/arch/mips/sni/setup.c	Sun Sep  9 10:43:02 2001
@@ -31,18 +31,6 @@
 #include <asm/reboot.h>
 #include <asm/sni.h>
 
-/*
- * Initial irq handlers.
- */
-static void no_action(int cpl, void *dev_id, struct pt_regs *regs) { }
-
-/*
- * IRQ2 is cascade interrupt to second interrupt controller
- */
-static struct irqaction irq2  = { no_action, 0, 0, "cascade", NULL, NULL};
-
-extern asmlinkage void sni_rm200_pci_handle_int(void);
-
 extern void sni_machine_restart(char *command);
 extern void sni_machine_halt(void);
 extern void sni_machine_power_off(void);
@@ -51,20 +39,6 @@
 extern struct rtc_ops std_rtc_ops;
 extern struct kbd_ops std_kbd_ops;
 
-static void __init sni_irq_setup(void)
-{
-	set_except_vector(0, sni_rm200_pci_handle_int);
-	request_region(0x20,0x20, "pic1");
-	request_region(0xa0,0x20, "pic2");	
-	i8259_setup_irq(2, &irq2);
-	/*
-	 * IRQ0 seems to be the irq for PC style stuff.
-	 * I don't know how to handle the debug button interrupt, so
-	 * don't use this button yet or bad things happen ...
-	 */
-	set_cp0_status(ST0_IM, IE_IRQ1 | IE_IRQ3 | IE_IRQ4);
-}
-
 void (*board_time_init)(struct irqaction *irq);
 
 static void __init sni_rm200_pci_time_init(struct irqaction *irq)
@@ -73,7 +47,7 @@
 	outb_p(0x34,0x43);		/* binary, mode 2, LSB/MSB, ch 0 */
 	outb_p(LATCH & 0xff , 0x40);	/* LSB */
 	outb(LATCH >> 8 , 0x40);	/* MSB */
-	i8259_setup_irq(0, irq);
+	setup_irq(0, irq);
 }
 
 unsigned char aux_device_present;
@@ -101,45 +75,11 @@
 	printk("%s.\n", boardtype);
 }
 
-int __init page_is_ram(unsigned long pagenr)
-{
-	return 1;
-}
-
 void __init sni_rm200_pci_setup(void)
 {
-#if 0 /* XXX Tag me deeper  */
-	tag *atag;
-
-	/*
-	 * We just check if a tag_screen_info can be gathered
-	 * in setup_arch(), if yes we don't proceed futher...
-	 */
-	atag = bi_TagFind(tag_screen_info);
-	if (!atag) {
-		/*
-		 * If no, we try to find the tag_arc_displayinfo which is
-		 * always created by Milo for an ARC box (for now Milo only
-		 * works on ARC boxes :) -Stoned.
-		 */
-		atag = bi_TagFind(tag_arcdisplayinfo);
-		if (atag) {
-			screen_info.orig_x = 
-				((mips_arc_DisplayInfo*)TAGVALPTR(atag))->cursor_x;
-			screen_info.orig_y = 
-				((mips_arc_DisplayInfo*)TAGVALPTR(atag))->cursor_y;
-			screen_info.orig_video_cols  = 
-				((mips_arc_DisplayInfo*)TAGVALPTR(atag))->columns;
-			screen_info.orig_video_lines  = 
-				((mips_arc_DisplayInfo*)TAGVALPTR(atag))->lines;
-		}
-	}
-#endif
-
 	sni_pcimt_detect();
 	sni_pcimt_sc_init();
 
-	irq_setup = sni_irq_setup;
 	mips_io_port_base = SNI_PORT_BASE;
 
 	/*
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/Makefile linux/arch/mips64/Makefile
--- v2.4.9/linux/arch/mips64/Makefile	Wed Jul 25 17:10:18 2001
+++ linux/arch/mips64/Makefile	Sun Sep  9 10:43:02 2001
@@ -84,7 +84,8 @@
 endif
 
 ifdef CONFIG_SGI_IP27
-LIBS          += arch/mips64/sgi-ip27/ip27.a arch/mips64/arc/arclib.a
+CORE_FILES    += arch/mips64/sgi-ip27/ip27.o
+LIBS          += arch/mips64/arc/arclib.a
 SUBDIRS       += arch/mips64/sgi-ip27 arch/mips64/arc
 #
 # Set LOADADDR to >= 0xc000000000300000 if you want to leave space for
@@ -97,6 +98,17 @@
 else
 LOADADDR      += 0x8001c000
 endif
+endif
+
+ifdef CONFIG_SGI_IP32
+LIBS		+= arch/mips64/sgi-ip32/ip32-kern.a arch/mips64/arc/arclib.a
+SUBDIRS		+= arch/mips64/sgi-ip32 arch/mips64/arc
+#
+# Set LOADADDR to >= 0x????????? if you want to leave space for symmon,
+# 0x80002000 for production kernels.  Note that the value must be
+# 16kb aligned or the handling of the current variable will break.
+#
+LOADADDR	+= 0x80002000
 endif
 
 #
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/arc/env.c linux/arch/mips64/arc/env.c
--- v2.4.9/linux/arch/mips64/arc/env.c	Sat May 13 08:30:17 2000
+++ linux/arch/mips64/arc/env.c	Sun Sep  9 10:43:02 2001
@@ -1,5 +1,4 @@
-/* $Id: env.c,v 1.4 1999/10/19 20:51: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
  * for more details.
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/arc/file.c linux/arch/mips64/arc/file.c
--- v2.4.9/linux/arch/mips64/arc/file.c	Sat May 13 08:30:17 2000
+++ linux/arch/mips64/arc/file.c	Sun Sep  9 10:43:02 2001
@@ -1,5 +1,4 @@
-/* $Id: file.c,v 1.3 1999/10/19 20:51: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
  * for more details.
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/arc/init.c linux/arch/mips64/arc/init.c
--- v2.4.9/linux/arch/mips64/arc/init.c	Mon Feb 28 07:18:20 2000
+++ linux/arch/mips64/arc/init.c	Sun Sep  9 10:43:02 2001
@@ -1,5 +1,4 @@
-/* $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.
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/arc/memory.c linux/arch/mips64/arc/memory.c
--- v2.4.9/linux/arch/mips64/arc/memory.c	Wed Jul 25 17:10:18 2001
+++ linux/arch/mips64/arc/memory.c	Sun Sep  9 10:43:02 2001
@@ -54,7 +54,8 @@
 	"FirmwarePermanent",
 	"FreeContiguous"
 };
-#define mtypes(a) (prom_flags & PROM_FLAG_ARCS) ? arcs_mtypes[a.arcs] : arc_mtypes[a.arc]
+#define mtypes(a) (prom_flags & PROM_FLAG_ARCS) ? arcs_mtypes[a.arcs] \
+						: arc_mtypes[a.arc]
 #endif
 
 static inline int memtype_classify_arcs (union linux_memtypes type)
@@ -138,10 +139,8 @@
 	}
 }
 
-void __init
-prom_free_prom_memory (void)
+void __init prom_free_prom_memory (void)
 {
-	struct prom_pmemblock *p;
 	unsigned long freed = 0;
 	unsigned long addr;
 	int i;
@@ -160,5 +159,5 @@
 			freed += PAGE_SIZE;
 		}
 	}
-	printk("Freeing prom memory: %ldkb freed\n", freed >> 10);
+	printk(KERN_INFO "Freeing prom memory: %ldkb freed\n", freed >> 10);
 }
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/arc/misc.c linux/arch/mips64/arc/misc.c
--- v2.4.9/linux/arch/mips64/arc/misc.c	Sat May 13 08:30:17 2000
+++ linux/arch/mips64/arc/misc.c	Sun Sep  9 10:43:02 2001
@@ -1,5 +1,4 @@
-/* $Id: misc.c,v 1.2 1999/08/21 21:42: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.
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/arc/salone.c linux/arch/mips64/arc/salone.c
--- v2.4.9/linux/arch/mips64/arc/salone.c	Sat May 13 08:30:17 2000
+++ linux/arch/mips64/arc/salone.c	Sun Sep  9 10:43:02 2001
@@ -1,5 +1,4 @@
-/* $Id: salone.c,v 1.2 1999/08/21 21:42:59 ralf Exp $
- *
+/*
  * Routines to load into memory and execute stand-along program images using
  * ARCS PROM firmware.
  *
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/arc/time.c linux/arch/mips64/arc/time.c
--- v2.4.9/linux/arch/mips64/arc/time.c	Sat May 13 08:30:17 2000
+++ linux/arch/mips64/arc/time.c	Sun Sep  9 10:43:02 2001
@@ -1,5 +1,4 @@
-/* $Id: time.c,v 1.2 1999/08/21 21:42: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.
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/arc/tree.c linux/arch/mips64/arc/tree.c
--- v2.4.9/linux/arch/mips64/arc/tree.c	Wed Jul 25 17:10:18 2001
+++ linux/arch/mips64/arc/tree.c	Sun Sep  9 10:43:02 2001
@@ -1,5 +1,4 @@
-/* $Id: tree.c,v 1.3 1999/09/27 16:01: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
  * for more details.
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/config.in linux/arch/mips64/config.in
--- v2.4.9/linux/arch/mips64/config.in	Wed Jul 25 17:10:18 2001
+++ linux/arch/mips64/config.in	Sun Sep  9 10:43:02 2001
@@ -41,6 +41,7 @@
 unset CONFIG_BOOT_ELF64
 unset CONFIG_COHERENT_IO
 unset CONFIG_ISA
+unset CONFIG_MAPPED_PCI_IO
 unset CONFIG_PCI
 
 if [ "$CONFIG_SGI_IP22" = "y" ]; then
@@ -56,6 +57,7 @@
    define_bool CONFIG_BOOT_ELF64 y
    define_bool CONFIG_ARC64 y
    define_bool CONFIG_COHERENT_IO y
+   define_bool CONFIG_MAPPED_PCI_IO y
    define_bool CONFIG_PCI y
    define_bool CONFIG_QL_ISP_A64 y
    define_int CONFIG_L1_CACHE_SHIFT 7
@@ -177,7 +179,7 @@
 fi
 endmenu
 
-source drivers/message/i2o/Config.in
+#source drivers/message/i2o/Config.in
 
 if [ "$CONFIG_NET" = "y" ]; then
    mainmenu_option next_comment
@@ -270,7 +272,7 @@
 fi
 bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG
 bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
-if [ "$CONFIG_SMP" != "n" ]; then
+if [ "$CONFIG_SMP" != "y" ]; then
    bool 'Run uncached' CONFIG_MIPS_UNCACHED
 fi
 endmenu
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/defconfig linux/arch/mips64/defconfig
--- v2.4.9/linux/arch/mips64/defconfig	Wed Jul 25 17:10:18 2001
+++ linux/arch/mips64/defconfig	Sun Sep  9 10:43:02 2001
@@ -24,6 +24,7 @@
 CONFIG_BOOT_ELF64=y
 CONFIG_ARC64=y
 CONFIG_COHERENT_IO=y
+CONFIG_MAPPED_PCI_IO=y
 CONFIG_PCI=y
 CONFIG_QL_ISP_A64=y
 CONFIG_L1_CACHE_SHIFT=7
@@ -142,6 +143,7 @@
 #
 # CONFIG_PHONE is not set
 # CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA is not set
 
 #
 # ATA/IDE/MFM/RLL support
@@ -184,6 +186,7 @@
 # CONFIG_SCSI_AHA1740 is not set
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
 # CONFIG_SCSI_AM53C974 is not set
@@ -201,6 +204,7 @@
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_NCR_D700 is not set
 # CONFIG_SCSI_NCR53C7xx is not set
 # CONFIG_SCSI_NCR53C8XX is not set
 # CONFIG_SCSI_SYM53C8XX is not set
@@ -219,16 +223,6 @@
 # CONFIG_SCSI_U14_34F 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
@@ -241,18 +235,22 @@
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
-# CONFIG_NET_SB1000 is not set
 
 #
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
 CONFIG_SGI_IOC3_ETH=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNGEM is not set
 # 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_HP100 is not set
 # CONFIG_NET_ISA is not set
 # CONFIG_NET_PCI is not set
@@ -262,9 +260,14 @@
 # Ethernet (1000 Mbit)
 #
 # CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN 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
 
@@ -329,7 +332,11 @@
 #
 # Joysticks
 #
-# CONFIG_JOYSTICK is not set
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
 
 #
 # Input core support is needed for joysticks
@@ -367,24 +374,30 @@
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_BFS_FS is not set
+# CONFIG_CMS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG 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_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_TMPFS is not set
 # CONFIG_RAMFS is not set
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
 # CONFIG_MINIX_FS is not set
-# CONFIG_VXFS_FS is not set
+# CONFIG_FREEVXFS_FS is not set
 # CONFIG_NTFS_FS is not set
 # CONFIG_NTFS_RW is not set
 # CONFIG_HPFS_FS is not set
@@ -398,7 +411,6 @@
 # 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
@@ -408,6 +420,7 @@
 # Network File Systems
 #
 # CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 CONFIG_ROOT_NFS=y
@@ -441,6 +454,7 @@
 # CONFIG_MINIX_SUBPARTITION is not set
 # CONFIG_SOLARIS_X86_PARTITION is not set
 # CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
 CONFIG_SGI_PARTITION=y
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
@@ -459,9 +473,107 @@
 # CONFIG_USB is not set
 
 #
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# USB Network adaptors
+#
+# CONFIG_USB_PLUSB is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# Miscellaneous USB drivers
+#
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_ID75 is not set
+
+#
 # Input core support
 #
 # CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
 
 #
 # Kernel hacking
@@ -469,4 +581,3 @@
 CONFIG_CROSSCOMPILE=y
 # CONFIG_REMOTE_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_MIPS_UNCACHED is not set
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/defconfig-ip22 linux/arch/mips64/defconfig-ip22
--- v2.4.9/linux/arch/mips64/defconfig-ip22	Wed Jul 25 17:10:18 2001
+++ linux/arch/mips64/defconfig-ip22	Sun Sep  9 10:43:02 2001
@@ -149,6 +149,7 @@
 #
 # CONFIG_PHONE is not set
 # CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA is not set
 
 #
 # ATA/IDE/MFM/RLL support
@@ -193,6 +194,7 @@
 # CONFIG_SCSI_AHA1740 is not set
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
 # CONFIG_SCSI_AM53C974 is not set
@@ -209,6 +211,7 @@
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_NCR_D700 is not set
 # CONFIG_SCSI_NCR53C7xx is not set
 # CONFIG_SCSI_PAS16 is not set
 # CONFIG_SCSI_PCI2000 is not set
@@ -222,15 +225,6 @@
 # CONFIG_SCSI_DEBUG is not set
 
 #
-# I2O device support
-#
-# CONFIG_I2O 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
@@ -244,18 +238,20 @@
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
 # CONFIG_ETHERTAP is not set
-# CONFIG_NET_SB1000 is not set
 
 #
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNGEM is not set
 # 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_AT1700 is not set
-# CONFIG_DEPCA is not set
 # CONFIG_NET_ISA is not set
 # CONFIG_NET_PCI is not set
 # CONFIG_NET_POCKET is not set
@@ -265,11 +261,15 @@
 # Ethernet (1000 Mbit)
 #
 # CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
 
@@ -336,7 +336,11 @@
 #
 # Joysticks
 #
-# CONFIG_JOYSTICK is not set
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
 
 #
 # Input core support is needed for joysticks
@@ -353,6 +357,7 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
+# CONFIG_SONYPI is not set
 
 #
 # Ftape, the floppy tape device driver
@@ -374,24 +379,30 @@
 CONFIG_AUTOFS4_FS=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_BFS_FS is not set
+# CONFIG_CMS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG 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_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_TMPFS is not set
 # CONFIG_RAMFS is not set
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
 # CONFIG_MINIX_FS is not set
-# CONFIG_VXFS_FS is not set
+# CONFIG_FREEVXFS_FS is not set
 # CONFIG_NTFS_FS is not set
 # CONFIG_NTFS_RW is not set
 # CONFIG_HPFS_FS is not set
@@ -405,7 +416,6 @@
 # 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
@@ -415,6 +425,7 @@
 # Network File Systems
 #
 # CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 is not set
 CONFIG_ROOT_NFS=y
@@ -447,6 +458,7 @@
 # CONFIG_MINIX_SUBPARTITION is not set
 # CONFIG_SOLARIS_X86_PARTITION is not set
 # CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
 CONFIG_SGI_PARTITION=y
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
@@ -484,9 +496,107 @@
 # CONFIG_USB is not set
 
 #
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# USB Network adaptors
+#
+# CONFIG_USB_PLUSB is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# Miscellaneous USB drivers
+#
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_ID75 is not set
+
+#
 # Input core support
 #
 # CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
 
 #
 # Kernel hacking
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/defconfig-ip27 linux/arch/mips64/defconfig-ip27
--- v2.4.9/linux/arch/mips64/defconfig-ip27	Wed Jul 25 17:10:18 2001
+++ linux/arch/mips64/defconfig-ip27	Sun Sep  9 10:43:02 2001
@@ -24,6 +24,7 @@
 CONFIG_BOOT_ELF64=y
 CONFIG_ARC64=y
 CONFIG_COHERENT_IO=y
+CONFIG_MAPPED_PCI_IO=y
 CONFIG_PCI=y
 CONFIG_QL_ISP_A64=y
 CONFIG_L1_CACHE_SHIFT=7
@@ -142,6 +143,7 @@
 #
 # CONFIG_PHONE is not set
 # CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA is not set
 
 #
 # ATA/IDE/MFM/RLL support
@@ -184,6 +186,7 @@
 # CONFIG_SCSI_AHA1740 is not set
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
 # CONFIG_SCSI_AM53C974 is not set
@@ -201,6 +204,7 @@
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_NCR_D700 is not set
 # CONFIG_SCSI_NCR53C7xx is not set
 # CONFIG_SCSI_NCR53C8XX is not set
 # CONFIG_SCSI_SYM53C8XX is not set
@@ -219,16 +223,6 @@
 # CONFIG_SCSI_U14_34F 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
@@ -241,18 +235,22 @@
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
-# CONFIG_NET_SB1000 is not set
 
 #
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
 CONFIG_SGI_IOC3_ETH=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNGEM is not set
 # 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_HP100 is not set
 # CONFIG_NET_ISA is not set
 # CONFIG_NET_PCI is not set
@@ -262,9 +260,14 @@
 # Ethernet (1000 Mbit)
 #
 # CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN 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
 
@@ -329,7 +332,11 @@
 #
 # Joysticks
 #
-# CONFIG_JOYSTICK is not set
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
 
 #
 # Input core support is needed for joysticks
@@ -367,24 +374,30 @@
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_BFS_FS is not set
+# CONFIG_CMS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG 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_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_TMPFS is not set
 # CONFIG_RAMFS is not set
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
 # CONFIG_MINIX_FS is not set
-# CONFIG_VXFS_FS is not set
+# CONFIG_FREEVXFS_FS is not set
 # CONFIG_NTFS_FS is not set
 # CONFIG_NTFS_RW is not set
 # CONFIG_HPFS_FS is not set
@@ -398,7 +411,6 @@
 # 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
@@ -408,6 +420,7 @@
 # Network File Systems
 #
 # CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 CONFIG_ROOT_NFS=y
@@ -441,6 +454,7 @@
 # CONFIG_MINIX_SUBPARTITION is not set
 # CONFIG_SOLARIS_X86_PARTITION is not set
 # CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
 CONFIG_SGI_PARTITION=y
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
@@ -459,9 +473,107 @@
 # CONFIG_USB is not set
 
 #
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# USB Network adaptors
+#
+# CONFIG_USB_PLUSB is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# Miscellaneous USB drivers
+#
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_ID75 is not set
+
+#
 # Input core support
 #
 # CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
 
 #
 # Kernel hacking
@@ -469,4 +581,3 @@
 CONFIG_CROSSCOMPILE=y
 # CONFIG_REMOTE_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_MIPS_UNCACHED is not set
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/defconfig-ip32 linux/arch/mips64/defconfig-ip32
--- v2.4.9/linux/arch/mips64/defconfig-ip32	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/defconfig-ip32	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,511 @@
+#
+# Automatically generated make config: don't edit
+#
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Machine selection
+#
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+CONFIG_SGI_IP32=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_BOOT_ELF32=y
+CONFIG_ARC32=y
+CONFIG_PC_KEYB=y
+CONFIG_PCI=y
+CONFIG_ARC_MEMORY=y
+CONFIG_L1_CACHE_SHIFT=5
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+
+#
+# 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_MIPS_FPU_EMULATOR is not set
+CONFIG_NET=y
+CONFIG_PCI_NAMES=y
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_SYSCTL=y
+# CONFIG_PROM_CONSOLE is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_MIPS32_COMPAT=y
+CONFIG_BINFMT_ELF32=y
+CONFIG_BINFMT_MISC=y
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+CONFIG_PCI_NAMES=y
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+# 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_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES 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_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT 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
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD 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_CHR_DEV_OSST=y
+CONFIG_BLK_DEV_SR=y
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_SR_EXTRA_DEVS=2
+CONFIG_CHR_DEV_SG=y
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_DEBUG_QUEUES=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# 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=y
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=8
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_BUILD_FIRMWARE 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_CPQFCTS is not set
+# CONFIG_SCSI_DMX3191D 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_NCR53C406A 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 is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_DEBUG 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_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+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_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+CONFIG_TULIP=y
+# CONFIG_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+CONFIG_EEPRO100=y
+# CONFIG_EEPRO100_PM is not set
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_LAN_SAA9730 is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI 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 devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER 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=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# 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
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC 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_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW 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_JFFS_FS is not set
+# CONFIG_CRAMFS is not set
+CONFIG_TMPFS=y
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_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_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# 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_NFS_V3=y
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+# CONFIG_MSDOS_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+CONFIG_KCORE_ELF=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+
+#
+# Kernel hacking
+#
+CONFIG_CROSSCOMPILE=y
+# CONFIG_REMOTE_DEBUG is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_MIPS_UNCACHED=y
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/kernel/binfmt_elf32.c linux/arch/mips64/kernel/binfmt_elf32.c
--- v2.4.9/linux/arch/mips64/kernel/binfmt_elf32.c	Wed Jul 25 17:10:18 2001
+++ linux/arch/mips64/kernel/binfmt_elf32.c	Sun Sep  9 10:43:01 2001
@@ -32,7 +32,7 @@
 
 #define TASK32_SIZE		0x80000000UL
 #undef ELF_ET_DYN_BASE
-#define ELF_ET_DYN_BASE         (2 * TASK32_SIZE / 3)
+#define ELF_ET_DYN_BASE         (TASK32_SIZE / 3 * 2)
 
 #include <asm/processor.h>
 #include <linux/module.h>
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/kernel/entry.S linux/arch/mips64/kernel/entry.S
--- v2.4.9/linux/arch/mips64/kernel/entry.S	Wed Jul 25 17:10:18 2001
+++ linux/arch/mips64/kernel/entry.S	Sun Sep  9 10:43:01 2001
@@ -5,8 +5,9 @@
  *
  * Low level exception handling
  *
- * Copyright (C) 1994 - 2000 by Ralf Baechle
+ * Copyright (C) 1994 - 2000, 2001 Ralf Baechle
  * Copyright (C) 1999, 2000 Silicon Graphics
+ * Copyright (C) 2001 MIPS Technologies, Inc.
  */
 #include <linux/config.h>
 
@@ -15,53 +16,61 @@
 #include <asm/mipsregs.h>
 #include <asm/stackframe.h>
 
+/* This duplicates the definition from <linux/sched.h> */
+#define PT_TRACESYS	0x00000002		/* tracing system calls */
+
+#define KU_USER 0x10
+
 		.text
-		.set	noreorder
 		.align 4
 FEXPORT(ret_from_fork)
+		move	a0, v0			# prev
 		jal	schedule_tail
-		 move	a0, v0					# prev
+		lw	t0, TASK_PTRACE($28)	# syscall tracing enabled?
+		andi	t0, PT_TRACESYS
+		bnez	t0, tracesys_exit
 		j	ret_from_sys_call
-		 nop
-FEXPORT(handle_softirq)
-		jal	do_softirq
-		 nop
-		b	9f
-		 nop
+
+tracesys_exit:
+		jal	syscall_trace
+		b	ret_from_sys_call
+
+EXPORT(ret_from_irq)
+EXPORT(ret_from_exception)
+		lw	t0, PT_STATUS(sp)	# returning to kernel mode?
+		andi	t0, t0, KU_USER
+		bnez	t0, ret_from_sys_call
+		j	restore_all
 
 reschedule:	jal	schedule 
-		 nop
 
 FEXPORT(ret_from_sys_call)
-FEXPORT(ret_from_irq)
-		la	t1, irq_stat		# softirq_active
-#ifdef CONFIG_SMP
-		lwu	t0, TASK_PROCESSOR($28)
-		dsll	t0, t0, 5
-		daddu	t1, t0
-#endif
-		lw	t0, 0 (t1)		# softirq_active
-		lw	t1, 4 (t1)		# softirq_mask.  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
+		mfc0	t0, CP0_STATUS	# need_resched and signals atomic test
+		ori	t0, t0, 1
+		xori	t0, t0, 1
+		mtc0	t0, CP0_STATUS
+
+		ld	v0, TASK_NEED_RESCHED($28)
+		lw	v1, TASK_SIGPENDING($28)
+		bnez	v0, reschedule
+		bnez	v1, signal_return
 
-FEXPORT(return)	.set	noat
+restore_all:	.set	noat
 		RESTORE_ALL
 		eret
 		.set	at
 
+signal_return:	.type	signal_return, @function
+
+		mfc0	t0, CP0_STATUS
+		ori	t0, t0, 1
+		mtc0	t0, CP0_STATUS
+
+		move	a0, zero
+		move	a1, sp
+		jal	do_signal
+		b	restore_all
+
 /*
  * Common spurious interrupt handler.
  */
@@ -75,6 +84,6 @@
 		lui     t1,%hi(spurious_count)
 		lw      t0,%lo(spurious_count)(t1)
 		addiu   t0,1
+		sw      t0,%lo(spurious_count)(t1)
 		j	ret_from_irq
-		 sw      t0,%lo(spurious_count)(t1)
 		END(spurious_interrupt)
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/kernel/ioctl32.c linux/arch/mips64/kernel/ioctl32.c
--- v2.4.9/linux/arch/mips64/kernel/ioctl32.c	Wed Jul 25 17:10:18 2001
+++ linux/arch/mips64/kernel/ioctl32.c	Sat Sep  1 11:01:28 2001
@@ -770,6 +770,8 @@
 	IOCTL32_HANDLER(BLKPG, blkpg_ioctl_trans),
 	IOCTL32_DEFAULT(BLKELVGET),
 	IOCTL32_DEFAULT(BLKELVSET),
+	IOCTL32_DEFAULT(BLKBSZGET),
+	IOCTL32_DEFAULT(BLKBSZSET),
 
 #ifdef CONFIG_MD
 	/* status */
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/kernel/linux32.c linux/arch/mips64/kernel/linux32.c
--- v2.4.9/linux/arch/mips64/kernel/linux32.c	Wed Jul 25 17:10:18 2001
+++ linux/arch/mips64/kernel/linux32.c	Sun Sep  9 10:43:01 2001
@@ -1538,11 +1538,11 @@
 	err = -EFAULT;
 	if (get_user (pad, (u32 *)uptr))
 		return err;
-	if(third == SETVAL)
+	if ((third & ~IPC_64) == SETVAL)
 		fourth.val = (int)pad;
 	else
 		fourth.__pad = (void *)A(pad);
-	switch (third) {
+	switch (third & ~IPC_64) {
 
 	case IPC_INFO:
 	case IPC_RMID:
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/kernel/mips64_ksyms.c linux/arch/mips64/kernel/mips64_ksyms.c
--- v2.4.9/linux/arch/mips64/kernel/mips64_ksyms.c	Wed Jul 25 17:10:18 2001
+++ linux/arch/mips64/kernel/mips64_ksyms.c	Sun Sep  9 10:43:01 2001
@@ -17,6 +17,7 @@
 #include <linux/in6.h>
 #include <linux/pci.h>
 
+#include <asm/bootinfo.h>
 #include <asm/dma.h>
 #include <asm/floppy.h>
 #include <asm/io.h>
@@ -37,6 +38,7 @@
 extern long __strnlen_user_nocheck_asm(const char *s);
 extern long __strnlen_user_asm(const char *s);
 
+EXPORT_SYMBOL(mips_machtype);
 EXPORT_SYMBOL(EISA_bus);
 
 /*
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/kernel/proc.c linux/arch/mips64/kernel/proc.c
--- v2.4.9/linux/arch/mips64/kernel/proc.c	Wed Jul 25 17:10:18 2001
+++ linux/arch/mips64/kernel/proc.c	Sun Sep  9 10:43:01 2001
@@ -1,12 +1,10 @@
-/* $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.
+ * Copyright (C) 1995, 1996, 1999, 2001 Ralf Baechle
+ * Copyright (C) 2001 MIPS Technologies, Inc.
  */
 #include <linux/delay.h>
 #include <linux/kernel.h>
@@ -17,7 +15,7 @@
 #include <asm/processor.h>
 #include <asm/watch.h>
 
-unsigned long unaligned_instructions;
+extern unsigned long unaligned_instructions;
 unsigned int vced_count, vcei_count;
 
 /*
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/kernel/ptrace.c linux/arch/mips64/kernel/ptrace.c
--- v2.4.9/linux/arch/mips64/kernel/ptrace.c	Wed Jul 25 17:10:18 2001
+++ linux/arch/mips64/kernel/ptrace.c	Sun Sep  9 10:43:01 2001
@@ -104,6 +104,9 @@
 			break;
 		case FPR_BASE ... FPR_BASE + 31:
 			if (child->used_math) {
+				unsigned long *fregs =
+					(void *) child->thread.fpu.hard.fp_regs;
+
 #ifndef CONFIG_SMP
 				if (last_task_used_math == child) {
 					set_cp0_status(ST0_CU1, ST0_CU1);
@@ -112,7 +115,15 @@
 					last_task_used_math = NULL;
 				}
 #endif
-				tmp = child->thread.fpu.hard.fp_regs[addr - 32];
+				/*
+				 * The odd registers are actually the high
+				 * order bits of the values stored in the even
+				 * registers.
+				 */
+				if (addr & 1)
+					tmp = (unsigned long) (fregs[((addr & ~1) - 32)] >> 32);
+				else
+					tmp = (unsigned long) (fregs[(addr - 32)] & 0xffffffff);
 			} else {
 				tmp = -EIO;
 			}
@@ -171,7 +182,8 @@
 			regs->regs[addr] = data;
 			break;
 		case FPR_BASE ... FPR_BASE + 31: {
-			unsigned long *fregs;
+			unsigned long *fregs =
+				(void *) child->thread.fpu.hard.fp_regs;
 			if (child->used_math) {
 #ifndef CONFIG_SMP
 				if (last_task_used_math == child) {
@@ -188,8 +200,18 @@
 				       sizeof(child->thread.fpu.hard));
 				child->thread.fpu.hard.control = 0;
 			}
-			fregs = child->thread.fpu.hard.fp_regs;
-			fregs[addr - FPR_BASE] = data;
+			/*
+			 * The odd registers are actually the high order bits
+			 * of the values stored in the even registers - unless
+			 * we're using r2k_switch.S.
+			 */
+			if (addr & 1) {
+				fregs[(addr & ~1) - FPR_BASE] &= 0xffffffff;
+				fregs[(addr & ~1) - FPR_BASE] |= ((unsigned long) data) << 32;
+			} else {
+				fregs[addr - FPR_BASE] &= ~0xffffffffLL;
+				fregs[addr - FPR_BASE] |= data;
+			}
 			break;
 		}
 		case PC:
@@ -354,6 +376,9 @@
 			break;
 		case FPR_BASE ... FPR_BASE + 31:
 			if (child->used_math) {
+				unsigned long long *fregs
+					= (unsigned long long *)
+					&child->thread.fpu.hard.fp_regs[0];
 #ifndef CONFIG_SMP
 				if (last_task_used_math == child) {
 					set_cp0_status(ST0_CU1, ST0_CU1);
@@ -362,7 +387,15 @@
 					last_task_used_math = NULL;
 				}
 #endif
-				tmp = child->thread.fpu.hard.fp_regs[addr - 32];
+				/*
+				 * The odd registers are actually the high
+				 * order bits of the values stored in the even
+				 * registers.
+				 */
+				if (addr & 1)
+					tmp = (unsigned long) (fregs[((addr & ~1) - 32)] >> 32);
+				else
+					tmp = (unsigned long) (fregs[(addr - 32)] & 0xffffffff);
 			} else {
 				tmp = -EIO;
 			}
@@ -421,7 +454,8 @@
 			regs->regs[addr] = data;
 			break;
 		case FPR_BASE ... FPR_BASE + 31: {
-			unsigned long *fregs;
+			unsigned long *fregs =
+				(void *) child->thread.fpu.hard.fp_regs;
 			if (child->used_math) {
 #ifndef CONFIG_SMP
 				if (last_task_used_math == child) {
@@ -438,8 +472,18 @@
 				       sizeof(child->thread.fpu.hard));
 				child->thread.fpu.hard.control = 0;
 			}
-			fregs = child->thread.fpu.hard.fp_regs;
-			fregs[addr - FPR_BASE] = data;
+			/*
+			 * The odd registers are actually the high order bits
+			 * of the values stored in the even registers - unless
+			 * we're using r2k_switch.S.
+			 */
+			if (addr & 1) {
+				fregs[(addr & ~1) - FPR_BASE] &= 0xffffffff;
+				fregs[(addr & ~1) - FPR_BASE] |= ((unsigned long) data) << 32;
+			} else {
+				fregs[addr - FPR_BASE] &= ~0xffffffffLL;
+				fregs[addr - FPR_BASE] |= data;
+			}
 			break;
 		}
 		case PC:
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/kernel/r4k_cache.S linux/arch/mips64/kernel/r4k_cache.S
--- v2.4.9/linux/arch/mips64/kernel/r4k_cache.S	Sat May 13 08:30:17 2000
+++ linux/arch/mips64/kernel/r4k_cache.S	Sun Sep  9 10:43:01 2001
@@ -1,5 +1,4 @@
-/* $Id: r4k_cache.S,v 1.1 1999/10/10 18:49: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.
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/kernel/r4k_genex.S linux/arch/mips64/kernel/r4k_genex.S
--- v2.4.9/linux/arch/mips64/kernel/r4k_genex.S	Sat May 13 08:30:17 2000
+++ linux/arch/mips64/kernel/r4k_genex.S	Sun Sep  9 10:43:01 2001
@@ -1,5 +1,4 @@
-/* $Id: r4k_genex.S,v 1.3 1999/11/23 17:12: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.
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/kernel/r4k_switch.S linux/arch/mips64/kernel/r4k_switch.S
--- v2.4.9/linux/arch/mips64/kernel/r4k_switch.S	Sat May 13 08:30:17 2000
+++ linux/arch/mips64/kernel/r4k_switch.S	Sun Sep  9 10:43:01 2001
@@ -1,5 +1,4 @@
-/* $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.
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/kernel/r4k_tlb_debug.c linux/arch/mips64/kernel/r4k_tlb_debug.c
--- v2.4.9/linux/arch/mips64/kernel/r4k_tlb_debug.c	Sat May 13 08:30:17 2000
+++ linux/arch/mips64/kernel/r4k_tlb_debug.c	Sun Sep  9 10:43:01 2001
@@ -1,5 +1,4 @@
-/* $Id: r4k_tlb_debug.c,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.
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/kernel/r4k_tlb_glue.S linux/arch/mips64/kernel/r4k_tlb_glue.S
--- v2.4.9/linux/arch/mips64/kernel/r4k_tlb_glue.S	Tue Jul 11 11:14:48 2000
+++ linux/arch/mips64/kernel/r4k_tlb_glue.S	Sun Sep  9 10:43:01 2001
@@ -1,5 +1,4 @@
-/* $Id: r4k_tlb_glue.S,v 1.5 1999/11/23 17:12: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.
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/kernel/scall_64.S linux/arch/mips64/kernel/scall_64.S
--- v2.4.9/linux/arch/mips64/kernel/scall_64.S	Wed Jul 25 17:10:18 2001
+++ linux/arch/mips64/kernel/scall_64.S	Sun Sep  9 10:43:01 2001
@@ -3,8 +3,9 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000 by Ralf Baechle
+ * Copyright (C) 1995, 96, 97, 98, 99, 2000, 01 by Ralf Baechle
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2001 MIPS Technologies, Inc.
  */
 #include <linux/config.h>
 #include <asm/asm.h>
@@ -62,44 +63,39 @@
 	sd	v0, PT_R0(sp)		# set flag for syscall restarting
 1:	sd	v0, PT_R2(sp)		# result
 
-FEXPORT(ret_from_sys_call_64)
-	la	t1, irq_stat		# softirq_active
-#ifdef CONFIG_SMP
-	lwu	t0, TASK_PROCESSOR($28)
-	dsll	t0, t0, 5
-	daddu	t1, t0
-#endif
-	lw	t0, 0(t1)		# softirq_active
-	lw	t1, 4(t1)		# softirq_mask.  unused delay slot
-	and	t0, t1
-	bnez	t0, handle_softirq_64
+ret_from_sys_call:
+	mfc0	t0, CP0_STATUS
+	xori	t0, t0, 1
+	ori	t0, t0, 1
+	mtc0	t0, CP0_STATUS
 
-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
+	bnez	t2, reschedule
 	lw	v0, TASK_SIGPENDING($28)
-	move	a0, zero
-	beqz	v0, return_64
-	move	a1, sp
-	SAVE_STATIC
-	jal	do_signal
+	bnez	v0, signal_return
 
-return_64:
+restore_all:
 	RESTORE_SOME
 	RESTORE_SP
-	.set	mips3
 	eret
-	.set	mips0
 
-handle_softirq_64:
-	jal	do_softirq
-	b	9b
-reschedule_64:
+/* Put this behind restore_all for the sake of the branch prediction.  */
+signal_return:
+	.type	signal_return, @function
+
+	mfc0	t0, CP0_STATUS
+	ori	t0, t0, 1
+	mtc0	t0, CP0_STATUS
+
+	move	a0, zero
+	move	a1, sp
+	jal	do_signal
+	b	restore_all
+
+reschedule:
 	SAVE_STATIC
 	jal	schedule
-	b	ret_from_sys_call_64
+	b	ret_from_sys_call
 
 /* ------------------------------------------------------------------------ */
 
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/kernel/scall_o32.S linux/arch/mips64/kernel/scall_o32.S
--- v2.4.9/linux/arch/mips64/kernel/scall_o32.S	Wed Jul 25 17:10:18 2001
+++ linux/arch/mips64/kernel/scall_o32.S	Sun Sep  9 10:43:01 2001
@@ -3,8 +3,9 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1995 - 2000 by Ralf Baechle
+ * Copyright (C) 1995 - 2000, 2001 by Ralf Baechle
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2001 MIPS Technologies, Inc.
  *
  * Hairy, the userspace application uses a different argument passing
  * convention than the kernel, so we have to translate things from o32
@@ -18,6 +19,7 @@
 #include <asm/regdef.h>
 #include <asm/stackframe.h>
 #include <asm/unistd.h>
+#include <asm/sysmips.h>
 
 /* This duplicates the definition from <linux/sched.h> */
 #define PT_TRACESYS	0x00000002	/* tracing system calls */
@@ -34,14 +36,6 @@
 	SAVE_SOME
 	STI
 	.set	at
-#if DEBUG_MIPS64
- jal dodebug
- ld $4, PT_R4(sp)
- ld $5, PT_R5(sp)
- ld $6, PT_R6(sp)
- ld $7, PT_R7(sp)
- ld $2, PT_R2(sp)
-#endif
 	ld	t1, PT_EPC(sp)		# skip syscall on return
 
 	subu	t0, v0, __NR_Linux32	# check syscall number
@@ -60,59 +54,50 @@
 	bgez	t0, stackargs
 
 stack_done:
-	ld	t0, TASK_PTRACE($28)	# syscall tracing enabled?
-	andi	t0, PT_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
+		ld	t0, TASK_PTRACE($28)	# syscall tracing enabled?
+		andi	t0, PT_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)		# flag for syscall restarting
+1:		sd	v0, PT_R2(sp)		# result
 
-	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)
-	la	t1, irq_stat		# softirq_active
-#ifdef CONFIG_SMP
-	lwu	t0, TASK_PROCESSOR($28)
-	dsll	t0, t0, 5
-	daddu	t1, t0
-#endif
-	lw	t0, 0(t1)		# softirq_active
-	lw	t1, 4(t1)		# softirq_mask.  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
+		mfc0	t0, CP0_STATUS	# need_resched and signals atomic test
+		ori	t0, t0, 1
+		xori	t0, t0, 1
+		mtc0	t0, CP0_STATUS
+
+		ld	t2, TASK_NEED_RESCHED($28)
+		bnez	t2, o32_reschedule
+		lw	v0, TASK_SIGPENDING($28)
+		bnez	v0, signal_return
+
+restore_all:	RESTORE_SOME
+		RESTORE_SP
+		.set	mips3
+		eret
+		.set	mips0
+
+signal_return:	mfc0	t0, CP0_STATUS	# need_resched and signals atomic test
+		ori	t0, t0, 1
+		mtc0	t0, CP0_STATUS
+		move	a0, zero
+		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
+		SAVE_STATIC
+		jal	schedule
+		b	o32_ret_from_sys_call
 
 /* ------------------------------------------------------------------------ */
 
@@ -205,6 +190,47 @@
 	sd	t0, PT_R7(sp)
 	j	ret_from_sys_call
 	END(handle_sys)
+
+	LEAF(mips_atomic_set)
+	ld	v1, THREAD_CURDS($28)
+	daddiu	a0, a1, 4
+	or	a0, a0, a1
+	li	v0, -EFAULT
+	and	a0, a0, v1
+	bltz	a0, 9f
+
+	/* Ok, this is the ll/sc case.  World is sane :-)  */
+1:	ll	v0, (a1)
+	move	a0, a2
+2:	sc	a0, (a1)
+	beqz	a0, 1b
+
+	.section __ex_table,"a"
+	PTR	1b, bad_stack
+	PTR	2b, bad_stack
+	.previous
+
+1:	sd	v0, PT_R2(sp)		# result
+
+	/* Success, so skip usual error handling garbage.  */
+	ld	t0, TASK_PTRACE($28)	# syscall tracing enabled?
+	andi	t0, PT_TRACESYS
+	bnez	t0, 1f
+	b	o32_ret_from_sys_call
+
+1:	SAVE_STATIC
+	jal	syscall_trace
+	li	a3, 0			# success
+	j	ret_from_sys_call
+
+9:	li	v0, -EFAULT
+	jr	ra
+	END(mips_atomic_set)
+
+	LEAF(sys_sysmips)
+	beq	a0, MIPS_ATOMIC_SET, mips_atomic_set
+	j	_sys_sysmips
+	END(sys_sysmips)
 
 	.macro	syscalltable
 	sys	sys_syscall	0			/* 4000 */
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/kernel/setup.c linux/arch/mips64/kernel/setup.c
--- v2.4.9/linux/arch/mips64/kernel/setup.c	Wed Jul 25 17:10:18 2001
+++ linux/arch/mips64/kernel/setup.c	Sun Sep  9 10:43:01 2001
@@ -81,7 +81,6 @@
  *
  * 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;
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/kernel/signal.c linux/arch/mips64/kernel/signal.c
--- v2.4.9/linux/arch/mips64/kernel/signal.c	Wed Jan 24 15:22:55 2001
+++ linux/arch/mips64/kernel/signal.c	Sun Sep  9 10:43:01 2001
@@ -267,8 +267,7 @@
 	struct ucontext rs_uc;
 };
 
-asmlinkage void
-sys_sigreturn(abi64_no_regargs, struct pt_regs regs)
+asmlinkage void sys_sigreturn(abi64_no_regargs, struct pt_regs regs)
 {
 	struct sigframe *frame;
 	sigset_t blocked;
@@ -304,8 +303,7 @@
 	force_sig(SIGSEGV, current);
 }
 
-asmlinkage void
-sys_rt_sigreturn(abi64_no_regargs, struct pt_regs regs)
+asmlinkage void sys_rt_sigreturn(abi64_no_regargs, struct pt_regs regs)
 {
 	struct rt_sigframe *frame;
 	sigset_t set;
@@ -346,8 +344,8 @@
 	force_sig(SIGSEGV, current);
 }
 
-static int inline
-setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
+static int inline setup_sigcontext(struct pt_regs *regs,
+				   struct sigcontext *sc)
 {
 	int err = 0;
 
@@ -392,8 +390,8 @@
 /*
  * Determine which stack to use..
  */
-static inline void *
-get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
+static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
+				 size_t frame_size)
 {
 	unsigned long sp;
 
@@ -407,9 +405,8 @@
 	return (void *)((sp - frame_size) & ALMASK);
 }
 
-static void inline
-setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
-            int signr, sigset_t *set)
+static void inline setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
+			       int signr, sigset_t *set)
 {
 	struct sigframe *frame;
 	int err = 0;
@@ -470,9 +467,9 @@
 	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)
+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;
@@ -489,10 +486,10 @@
 		/*
 		 * Set up the return code ...
 		 *
-		 *         li      v0, __NR_sigreturn
+		 *         li      v0, __NR_rt_sigreturn
 		 *         syscall
 		 */
-		err |= __put_user(0x24020000 + __NR_sigreturn,
+		err |= __put_user(0x24020000 + __NR_rt_sigreturn,
 		                  frame->rs_code + 0);
 		err |= __put_user(0x0000000c                 ,
 		                  frame->rs_code + 1);
@@ -546,9 +543,9 @@
 	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)
+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);
@@ -566,8 +563,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:
@@ -599,11 +596,6 @@
 	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)
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/kernel/signal32.c linux/arch/mips64/kernel/signal32.c
--- v2.4.9/linux/arch/mips64/kernel/signal32.c	Wed Jan 24 15:22:55 2001
+++ linux/arch/mips64/kernel/signal32.c	Sun Sep  9 10:43:01 2001
@@ -152,10 +152,6 @@
 	sigset32_t *uset;
 	sigset_t newset, saveset;
 
-#if DEBUG_MIPS64
-printk("%s called.\n", __FUNCTION__);
-#endif
-
 	save_static(&regs);
 	uset = (sigset32_t *) regs.regs[4];
 	if (get_sigset(&newset, uset))
@@ -185,10 +181,6 @@
 	sigset_t newset, saveset;
         size_t sigsetsize;
 
-#if DEBUG_MIPS64
-printk("%s called.\n", __FUNCTION__);
-#endif
-
 	save_static(&regs);
 	/* XXX Don't preclude handling different sized sigset_t's.  */
 	sigsetsize = regs.regs[5];
@@ -359,10 +351,6 @@
 	struct sigframe *frame;
 	sigset_t blocked;
 
-#if DEBUG_MIPS64
-printk("%s called.\n", __FUNCTION__);
-#endif
-
 	frame = (struct sigframe *) regs.regs[29];
 	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
 		goto badframe;
@@ -400,7 +388,6 @@
 	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)))
@@ -580,10 +567,10 @@
 		/*
 		 * Set up the return code ...
 		 *
-		 *         li      v0, __NR_Linux32_sigreturn
+		 *         li      v0, __NR_Linux32_rt_sigreturn
 		 *         syscall
 		 */
-		err |= __put_user(0x24020000 + __NR_Linux32_sigreturn,
+		err |= __put_user(0x24020000 + __NR_Linux32_rt_sigreturn,
 		                  frame->rs_code + 0);
 		err |= __put_user(0x0000000c                 ,
 		                  frame->rs_code + 1);
@@ -683,10 +670,6 @@
 	struct k_sigaction *ka;
 	siginfo_t info;
 
-#if DEBUG_MIPS64
-printk("%s: delivering signal.\n", current->comm);
-#endif
-
 	if (!oldset)
 		oldset = &current->blocked;
 
@@ -785,9 +768,6 @@
 		if (regs->regs[0])
 			syscall_restart(regs, ka);
 		/* Whee!  Actually deliver the signal.  */
-#if DEBUG_MIPS64
-printk("%s: delivering signal.\n", __FUNCTION__);
-#endif
 		handle_signal(signr, ka, &info, oldset, regs);
 		return 1;
 	}
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/kernel/syscall.c linux/arch/mips64/kernel/syscall.c
--- v2.4.9/linux/arch/mips64/kernel/syscall.c	Mon Mar 19 12:35:10 2001
+++ linux/arch/mips64/kernel/syscall.c	Sun Sep  9 10:43:01 2001
@@ -3,8 +3,9 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1995 - 2000 by Ralf Baechle
+ * Copyright (C) 1995 - 2000, 2001 by Ralf Baechle
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2001 MIPS Technologies, Inc.
  */
 #include <linux/errno.h>
 #include <linux/linkage.h>
@@ -129,7 +130,7 @@
 }
 
 asmlinkage int
-sys_sysmips(int cmd, long arg1, int arg2, int arg3)
+_sys_sysmips(int cmd, long arg1, int arg2, int arg3)
 {
 	int	*p;
 	char	*name;
@@ -155,50 +156,9 @@
 		return 0;
 	}
 
-	case MIPS_ATOMIC_SET: {
-		unsigned int tmp;
-
-		p = (int *) arg1;
-		errno = verify_area(VERIFY_WRITE, p, sizeof(*p));
-		if (errno)
-			return errno;
-		errno = 0;
-
-		__asm__(".set\tpush\t\t\t# sysmips(MIPS_ATOMIC, ...)\n\t"
-			".set\tnoreorder\n\t"
-			".set\tnoat\n\t"
-			"1:\tll\t%0, %4\n\t"
-			"2:\tmove\t$1, %3\n\t"
-			"3:\tsc\t$1, %1\n\t"
-			"beqzl\t$1, 2b\n\t"
-			"4:\t ll\t%0, %4\n\t"
-			".set\tpop\n\t"
-			".section\t.fixup,\"ax\"\n"
-			"5:\tli\t%2, 1\t\t\t# error\n\t"
-			".previous\n\t"
-			".section\t__ex_table,\"a\"\n\t"
-			".dword\t1b, 5b\n\t"
-			".dword\t3b, 5b\n\t"
-			".dword\t4b, 5b\n\t"
-			".previous\n\t"
-			: "=&r" (tmp), "=o" (* (u32 *) p), "=r" (errno)
-			: "r" (arg2), "o" (* (u32 *) p), "2" (errno)
-			: "$1");
-
-		if (errno)
-			return -EFAULT;
-
-		/* We're skipping error handling etc.  */
-		if (current->ptrace & PT_TRACESYS)
-			syscall_trace();
-
-		__asm__ __volatile__(
-			"move\t$29, %0\n\t"
-			"j\tret_from_sys_call"
-			: /* No outputs */
-			: "r" (&cmd));
-		/* Unreached */
-	}
+	case MIPS_ATOMIC_SET:
+		printk(KERN_CRIT "How did I get here?\n");
+		return -EINVAL;
 
 	case MIPS_FIXADE:
 		tmp = current->thread.mflags & ~3;
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/kernel/traps.c linux/arch/mips64/kernel/traps.c
--- v2.4.9/linux/arch/mips64/kernel/traps.c	Wed Jul 25 17:10:18 2001
+++ linux/arch/mips64/kernel/traps.c	Sun Sep  9 10:43:01 2001
@@ -258,58 +258,91 @@
 	printk(KERN_DEBUG "Should send SIGFPE to %s\n", current->comm);
 }
 
-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++;
-
-	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;
+	unsigned int *epc;
+	siginfo_t info;
+
+	epc = (unsigned int *) regs->cp0_epc +
+	      ((regs->cp0_cause & CAUSEF_BD) != 0);
+	if (get_user(opcode, epc))
+		goto sigsegv;
 
 	/*
 	 * 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 ...)
+	 * But should we continue the brokenness???  --macro
 	 */
+	switch (bcode) {
+	case 6:
+	case 7:
+		if (bcode == 7)
+			info.si_code = FPE_INTDIV;
+		else
+			info.si_code = FPE_INTOVF;
+		info.si_signo = SIGFPE;
+		info.si_errno = 0;
+		info.si_addr = (void *)compute_return_epc(regs);
+		force_sig_info(SIGFPE, &info, current);
+		break;
+	default:
+		force_sig(SIGTRAP, current);
+	}
+
 	force_sig(SIGTRAP, current);
+	return;
+
+sigsegv:
+	force_sig(SIGSEGV, current);
 }
 
 void do_tr(struct pt_regs *regs)
 {
 	unsigned int opcode, bcode;
+	unsigned int *epc;
+	siginfo_t info;
+
+	epc = (unsigned int *) regs->cp0_epc +
+	      ((regs->cp0_cause & CAUSEF_BD) != 0);
+	if (get_user(opcode, epc))
+		goto sigsegv;
 
-	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 ...)
+	 * But should we continue the brokenness???  --macro
 	 */
-	force_sig(SIGTRAP, current);
+	switch (bcode) {
+	case 6:
+	case 7:
+		if (bcode == 7)
+			info.si_code = FPE_INTDIV;
+		else
+			info.si_code = FPE_INTOVF;
+		info.si_signo = SIGFPE;
+		info.si_errno = 0;
+		info.si_addr = (void *)compute_return_epc(regs);
+		force_sig_info(SIGFPE, &info, current);
+		break;
+	default:
+		force_sig(SIGTRAP, current);
+	}
+	return;
+
+sigsegv:
+	force_sig(SIGSEGV, current);
 }
 
 void do_ri(struct pt_regs *regs)
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/kernel/unaligned.c linux/arch/mips64/kernel/unaligned.c
--- v2.4.9/linux/arch/mips64/kernel/unaligned.c	Wed Jul 25 17:10:18 2001
+++ linux/arch/mips64/kernel/unaligned.c	Sun Sep  9 10:43:01 2001
@@ -72,6 +72,7 @@
  *       A store crossing a page boundary might be executed only partially.
  *       Undo the partial store in this case.
  */
+#include <linux/config.h>
 #include <linux/mm.h>
 #include <linux/signal.h>
 #include <linux/smp.h>
@@ -378,7 +379,9 @@
 	return;
 }
 
+#ifdef CONFIG_PROC_FS
 unsigned long unaligned_instructions;
+#endif
 
 asmlinkage void do_ade(struct pt_regs *regs)
 {
@@ -399,7 +402,9 @@
 		goto sigbus;
 
 	emulate_load_store_insn(regs, regs->cp0_badvaddr, pc);
+#ifdef CONFIG_PROC_FS
 	unaligned_instructions++;
+#endif
 
 	return;
 
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/lib/csum_partial.S linux/arch/mips64/lib/csum_partial.S
--- v2.4.9/linux/arch/mips64/lib/csum_partial.S	Sat May 13 08:30:17 2000
+++ linux/arch/mips64/lib/csum_partial.S	Sun Sep  9 10:43:01 2001
@@ -1,5 +1,4 @@
-/* $Id: csum_partial.S,v 1.1 1999/08/21 21:43: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.
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/lib/csum_partial_copy.c linux/arch/mips64/lib/csum_partial_copy.c
--- v2.4.9/linux/arch/mips64/lib/csum_partial_copy.c	Sat May 13 08:30:17 2000
+++ linux/arch/mips64/lib/csum_partial_copy.c	Sun Sep  9 10:43:01 2001
@@ -1,5 +1,4 @@
-/* $Id: csum_partial_copy.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.
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/lib/dump_tlb.c linux/arch/mips64/lib/dump_tlb.c
--- v2.4.9/linux/arch/mips64/lib/dump_tlb.c	Sun Jul  9 22:18:16 2000
+++ linux/arch/mips64/lib/dump_tlb.c	Sun Sep  9 10:43:01 2001
@@ -168,14 +168,12 @@
 	printk("\n");
 }
 
-void
-dump_list_current(void *address)
+void dump_list_current(void *address)
 {
 	dump_list_process(current, address);
 }
 
-unsigned int
-vtop(void *address)
+unsigned int vtop(void *address)
 {
 	pgd_t	*pgd;
 	pmd_t	*pmd;
@@ -192,16 +190,17 @@
 	return paddr;
 }
 
-void
-dump16(unsigned long *p)
+void dump16(unsigned long *p)
 {
 	int i;
 
 	for(i=0;i<8;i++)
 	{
 		printk("*%08lx == %08lx, ",
-		       (unsigned long)p, (unsigned long)*p++);
+		       (unsigned long)p, (unsigned long)*p);
+		p++;
 		printk("*%08lx == %08lx\n",
-		       (unsigned long)p, (unsigned long)*p++);
+		       (unsigned long)p, (unsigned long)*p);
+		p++;
 	}
 }
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/lib/floppy-no.c linux/arch/mips64/lib/floppy-no.c
--- v2.4.9/linux/arch/mips64/lib/floppy-no.c	Sat May 13 08:30:17 2000
+++ linux/arch/mips64/lib/floppy-no.c	Sun Sep  9 10:43:01 2001
@@ -1,5 +1,4 @@
-/* $Id: floppy-no.c,v 1.1 1999/08/21 21:43: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.
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/lib/ide-no.c linux/arch/mips64/lib/ide-no.c
--- v2.4.9/linux/arch/mips64/lib/ide-no.c	Sat May 13 08:30:17 2000
+++ linux/arch/mips64/lib/ide-no.c	Sun Sep  9 10:43:01 2001
@@ -1,5 +1,4 @@
-/* $Id: ide-no.c,v 1.1 1999/08/21 21:43: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.
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/lib/ide-std.c linux/arch/mips64/lib/ide-std.c
--- v2.4.9/linux/arch/mips64/lib/ide-std.c	Sat May 13 08:30:17 2000
+++ linux/arch/mips64/lib/ide-std.c	Sun Sep  9 10:43:01 2001
@@ -1,12 +1,11 @@
-/* $Id: ide-std.c,v 1.1 1999/08/21 21:43: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
+ * Copyright (C) 1998, 1999, 2001 by Ralf Baechle
  */
 #include <linux/sched.h>
 #include <linux/ide.h>
@@ -60,6 +59,7 @@
 	}
 	if (irq != NULL)
 		*irq = 0;
+	hw->io_ports[IDE_IRQ_OFFSET] = 0;
 }
 
 static int std_ide_request_irq(unsigned int irq,
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/lib/kbd-no.c linux/arch/mips64/lib/kbd-no.c
--- v2.4.9/linux/arch/mips64/lib/kbd-no.c	Sat May 13 08:30:17 2000
+++ linux/arch/mips64/lib/kbd-no.c	Sun Sep  9 10:43:01 2001
@@ -1,5 +1,4 @@
-/* $Id: kbd-no.c,v 1.1 1999/08/21 21:43: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.
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/lib/kbd-std.c linux/arch/mips64/lib/kbd-std.c
--- v2.4.9/linux/arch/mips64/lib/kbd-std.c	Sat May 13 08:30:17 2000
+++ linux/arch/mips64/lib/kbd-std.c	Sun Sep  9 10:43:01 2001
@@ -1,5 +1,4 @@
-/* $Id: kbd-std.c,v 1.1 1999/08/21 21:43: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.
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/lib/memcpy.S linux/arch/mips64/lib/memcpy.S
--- v2.4.9/linux/arch/mips64/lib/memcpy.S	Wed Jul 25 17:10:18 2001
+++ linux/arch/mips64/lib/memcpy.S	Sun Sep  9 10:43:02 2001
@@ -5,7 +5,7 @@
  *
  * Unified implementation of memcpy, memmove and the __copy_user backend.
  *
- * Copyright (C) 1998, 1999, 2000 Ralf Baechle
+ * Copyright (C) 1998, 1999, 2000, 2001 Ralf Baechle
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  *
  * For __rmemcpy and memmove an exception is always a kernel bug, therefore
@@ -238,10 +238,8 @@
 	 andi	ta2, a2, 0x40
 
 move_128bytes:
-#if (_MIPS_ISA == _MIPS_ISA_MIPS4)
-	pref	0, 2*128(a0)
-	pref	1, 2*128(a1)
-#endif
+	PREF	(0, 2*128(a0))
+	PREF	(1, 2*128(a1))
 	MOVE_BIGGERCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0)
 	MOVE_BIGGERCHUNK(a1, a0, 0x40, ta0, ta1, ta3, t0)
 	dsubu	t8, t8, 0x01
@@ -454,16 +452,21 @@
 
 	.align	5
 LEAF(memmove)
-	sltu	ta0, a0, a1			# dst < src -> memcpy
-	bnez	ta0, memcpy
-	 daddu	v0, a0, a2
-	sltu	ta0, v0, a1			# dst + len < src -> non-
-	bnez	ta0, __memcpy			# overlapping, can use memcpy
+	daddu	t0, a0, a2
+	sltu	t0, a1, t0			# dst + len <= src -> memcpy
+	daddu	t1, a1, a2
+	sltu	t1, a0, t1			# dst >= src + len -> memcpy
+	and	t0, t1
+	beqz	t0, __memcpy
+
 	 move	v0, a0				/* return value */
 	beqz	a2, r_out
 	END(memmove)
 
 LEAF(__rmemcpy)					/* a0=dst a1=src a2=len */
+	sltu	t0, a1, a0
+	beqz	t0, r_end_bytes_up		# src >= dst
+	 nop
 	daddu	a0, a2				# dst = dst + len
 	daddu	a1, a2				# src = src + len
 
@@ -615,6 +618,17 @@
 	 dsubu	a0, a0, 0x1
 
 r_out:
+	jr      ra
+	 move   a2, zero
+
+r_end_bytes_up:
+	lb	t0, (a1)
+	dsubu	a2, a2, 0x1
+	sb	t0, (a0)
+	daddu	a1, a1, 0x1
+	bnez	a2, r_end_bytes_up
+	 daddu	a0, a0, 0x1
+
 	jr	ra
 	 move	a2, zero
 
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/lib/strlen_user.S linux/arch/mips64/lib/strlen_user.S
--- v2.4.9/linux/arch/mips64/lib/strlen_user.S	Sat May 13 08:30:17 2000
+++ linux/arch/mips64/lib/strlen_user.S	Sun Sep  9 10:43:02 2001
@@ -1,5 +1,4 @@
-/* $Id: strlen_user.S,v 1.2 1999/11/19 20:35:22 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.
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/lib/strncpy_user.S linux/arch/mips64/lib/strncpy_user.S
--- v2.4.9/linux/arch/mips64/lib/strncpy_user.S	Sat May 13 08:30:17 2000
+++ linux/arch/mips64/lib/strncpy_user.S	Sun Sep  9 10:43:02 2001
@@ -1,5 +1,4 @@
-/* $Id: strncpy_user.S,v 1.2 1999/11/19 20:35: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
  * for more details.
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/lib/strnlen_user.S linux/arch/mips64/lib/strnlen_user.S
--- v2.4.9/linux/arch/mips64/lib/strnlen_user.S	Sat May 13 08:30:17 2000
+++ linux/arch/mips64/lib/strnlen_user.S	Sun Sep  9 10:43:02 2001
@@ -1,5 +1,4 @@
-/* $Id: strnlen_user.S,v 1.1 1999/11/19 20:35: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
  * for more details.
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/math-emu/cp1emu.c linux/arch/mips64/math-emu/cp1emu.c
--- v2.4.9/linux/arch/mips64/math-emu/cp1emu.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/mips64/math-emu/cp1emu.c	Sun Sep  9 10:43:02 2001
@@ -53,7 +53,9 @@
 
 #include <asm/asm.h>
 #include <asm/branch.h>
+#include <asm/bootinfo.h>
 #include <asm/byteorder.h>
+#include <asm/cpu.h>
 #include <asm/inst.h>
 #include <asm/uaccess.h>
 #include <asm/processor.h>
@@ -851,11 +853,8 @@
 	current->thread.dsemul_epc = (unsigned long) cpc;
 	current->thread.dsemul_aerpc = (unsigned long) &dsemul_insns[1];
 	xcp->cp0_epc = VA_TO_REG & dsemul_insns[0];
+	flush_cache_sigtramp((unsigned long) dsemul_insns);
 
-	/* What we'd really like to do is just flush the line(s) of the */
-	/* icache containing the dsemulret instructions, but there's no */
-	/* mechanism to do this yet...  */
-	flush_cache_all();
 	return SIGILL;		/* force out of emulation loop */
 }
 
@@ -1708,6 +1707,9 @@
 
 	oldepc = xcp->cp0_epc;
 	do {
+		if (current->need_resched)
+			schedule();
+
 		prevepc = xcp->cp0_epc;
 		insn = mips_get_word(xcp, REG_TO_VA(xcp->cp0_epc), &err);
 		if (err) {
@@ -1718,6 +1720,9 @@
 			sig = cop1Emulate(xcptno, xcp, ctx);
 		else
 			xcp->cp0_epc += 4;	/* skip nops */
+
+		if (mips_cpu.options & MIPS_CPU_FPU)
+			break;
 	} while (xcp->cp0_epc > prevepc && sig == 0);
 
 	/* SIGILL indicates a non-fpu instruction */
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/mips-boards/atlas/Makefile linux/arch/mips64/mips-boards/atlas/Makefile
--- v2.4.9/linux/arch/mips64/mips-boards/atlas/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/mips-boards/atlas/Makefile	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,42 @@
+#
+# Carsten Langgaard, carstenl@mips.com
+# Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+#
+# ########################################################################
+#
+# This program is free software; you can distribute it and/or modify it
+# under the terms of the GNU General Public License (Version 2) as
+# published by the Free Software Foundation.
+# 
+# This program is distributed in the hope 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.
+#
+# #######################################################################
+#
+# Makefile for the MIPS Atlas 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...
+
+.S.s:
+	$(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+	$(CC) $(CFLAGS) -c $< -o $*.o
+
+all: atlas.o
+
+O_TARGET := atlas.o
+
+obj-y   := atlas_int.o atlas_rtc.o atlas_setup.o
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/mips-boards/atlas/atlas_int.c linux/arch/mips64/mips-boards/atlas/atlas_int.c
--- v2.4.9/linux/arch/mips64/mips-boards/atlas/atlas_int.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/mips-boards/atlas/atlas_int.c	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,249 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope 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.
+ *
+ * ########################################################################
+ *
+ * Routines for generic manipulation of the interrupts found on the MIPS 
+ * Atlas board.
+ *
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+
+#include <asm/irq.h>
+#include <asm/mips-boards/atlas.h>
+#include <asm/mips-boards/atlasint.h>
+#ifdef CONFIG_REMOTE_DEBUG
+#include <asm/gdb-stub.h>
+#endif
+
+struct atlas_ictrl_regs *atlas_hw0_icregs
+	= (struct atlas_ictrl_regs *)ATLAS_ICTRL_REGS_BASE;
+
+extern asmlinkage void mipsIRQ(void);
+extern void do_IRQ(int irq, struct pt_regs *regs);
+
+unsigned long spurious_count = 0;
+irq_desc_t irq_desc[NR_IRQS];
+
+#if 0
+#define DEBUG_INT(x...) printk(x)
+#else
+#define DEBUG_INT(x...)
+#endif
+
+void disable_atlas_irq(unsigned int irq_nr)
+{
+	atlas_hw0_icregs->intrsten = (1 << irq_nr);
+}
+
+void enable_atlas_irq(unsigned int irq_nr)
+{
+	atlas_hw0_icregs->intseten = (1 << irq_nr);
+}
+
+static unsigned int startup_atlas_irq(unsigned int irq)
+{
+	enable_atlas_irq(irq);
+	return 0; /* never anything pending */
+}
+
+#define shutdown_atlas_irq	disable_atlas_irq
+
+#define mask_and_ack_atlas_irq disable_atlas_irq
+
+static void end_atlas_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_atlas_irq(irq);
+}
+
+static struct hw_interrupt_type atlas_irq_type = {
+	"Atlas",
+	startup_atlas_irq,
+	shutdown_atlas_irq,
+	enable_atlas_irq,
+	disable_atlas_irq,
+	mask_and_ack_atlas_irq,
+	end_atlas_irq,
+	NULL
+};
+
+int get_irq_list(char *buf)
+{
+	int i, len = 0;
+	int num = 0;
+	struct irqaction *action;
+
+	for (i = 0; i < ATLASINT_END; i++, num++) {
+		action = irq_desc[i].action;
+		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, " [hw0]\n");
+	}
+	return len;
+}
+
+int request_irq(unsigned int irq, 
+		void (*handler)(int, void *, struct pt_regs *),
+		unsigned long irqflags, 
+		const char * devname,
+		void *dev_id)
+{  
+        struct irqaction *action;
+
+	DEBUG_INT("request_irq: irq=%d, devname = %s\n", irq, devname);
+
+        if (irq >= ATLASINT_END)
+	        return -EINVAL;
+	if (!handler)
+	        return -EINVAL;
+
+	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->dev_id = dev_id;
+	action->next = 0;
+	irq_desc[irq].action = action;
+	enable_atlas_irq(irq);
+
+	return 0;
+}
+
+void free_irq(unsigned int irq, void *dev_id)
+{
+	struct irqaction *action;
+
+	if (irq >= ATLASINT_END) {
+		printk("Trying to free IRQ%d\n",irq);
+		return;
+	}
+
+	action = irq_desc[irq].action;
+	irq_desc[irq].action = NULL;
+	disable_atlas_irq(irq);
+	kfree(action);
+}
+
+static inline int ls1bit32(unsigned int x)
+{
+	int b = 31, s;
+
+	s = 16; if (x << 16 == 0) s = 0; b -= s; x <<= s;
+	s =  8; if (x <<  8 == 0) s = 0; b -= s; x <<= s;
+	s =  4; if (x <<  4 == 0) s = 0; b -= s; x <<= s;
+	s =  2; if (x <<  2 == 0) s = 0; b -= s; x <<= s;
+	s =  1; if (x <<  1 == 0) s = 0; b -= s;
+
+	return b;
+}
+
+void atlas_hw0_irqdispatch(struct pt_regs *regs)
+{
+	struct irqaction *action;
+	unsigned long int_status;
+	int irq, cpu = smp_processor_id();
+
+	int_status = atlas_hw0_icregs->intstatus; 
+
+	/* if int_status == 0, then the interrupt has already been cleared */
+	if (int_status == 0)
+		return;
+
+	irq = ls1bit32(int_status);
+	action = irq_desc[irq].action;
+
+	DEBUG_INT("atlas_hw0_irqdispatch: irq=%d\n", irq);
+
+	/* if action == NULL, then we don't have a handler for the irq */
+	if ( action == NULL ) {
+	        printk("No handler for hw0 irq: %i\n", irq);
+		spurious_count++;
+		return;
+	}
+
+	irq_enter(cpu, irq);
+	kstat.irqs[0][irq]++;
+	action->handler(irq, action->dev_id, regs);
+	irq_exit(cpu, irq);
+
+	return;		
+}
+
+unsigned long probe_irq_on (void)
+{
+	return 0;
+}
+
+
+int probe_irq_off (unsigned long irqs)
+{
+	return 0;
+}
+
+#ifdef CONFIG_REMOTE_DEBUG
+extern void breakpoint(void);
+extern int remote_debug;
+#endif
+
+void __init init_IRQ(void)
+{
+	int i;
+
+	/* 
+	 * Mask out all interrupt by writing "1" to all bit position in 
+	 * the interrupt reset reg. 
+	 */
+	atlas_hw0_icregs->intrsten = 0xffffffff;    
+
+	/* Now safe to set the exception vector. */
+	set_except_vector(0, mipsIRQ);
+
+	for (i = 0; i <= ATLASINT_END; i++) {
+		irq_desc[i].status	= IRQ_DISABLED;
+		irq_desc[i].action	= 0;
+		irq_desc[i].depth	= 1;
+		irq_desc[i].handler	= &atlas_irq_type;
+	}
+
+#ifdef CONFIG_REMOTE_DEBUG
+	if (remote_debug) {
+		set_debug_traps();
+		breakpoint();
+	}
+#endif
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/mips-boards/atlas/atlas_rtc.c linux/arch/mips64/mips-boards/atlas/atlas_rtc.c
--- v2.4.9/linux/arch/mips64/mips-boards/atlas/atlas_rtc.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/mips-boards/atlas/atlas_rtc.c	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,58 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope 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.
+ *
+ * ########################################################################
+ *
+ * RTC routines for Atlas style attached Dallas chip.
+ *
+ */
+#include <asm/mc146818rtc.h>
+#include <asm/mips-boards/atlas.h>
+
+
+static unsigned char atlas_rtc_read_data(unsigned long addr)
+{
+	volatile unsigned int *rtc_adr_reg = (void *)ATLAS_RTC_ADR_REG;
+	volatile unsigned int *rtc_dat_reg = (void *)ATLAS_RTC_DAT_REG;
+
+	*rtc_adr_reg = addr;
+
+	return *rtc_dat_reg;
+}
+
+static void atlas_rtc_write_data(unsigned char data, unsigned long addr)
+{
+	volatile unsigned int *rtc_adr_reg = (void *)ATLAS_RTC_ADR_REG;
+	volatile unsigned int *rtc_dat_reg = (void *)ATLAS_RTC_DAT_REG;
+
+	*rtc_adr_reg = addr;
+	*rtc_dat_reg = data;
+}
+
+static int atlas_rtc_bcd_mode(void)
+{
+	return 0;
+}
+
+struct rtc_ops atlas_rtc_ops = {
+	&atlas_rtc_read_data,
+	&atlas_rtc_write_data,
+	&atlas_rtc_bcd_mode
+};
+
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/mips-boards/atlas/atlas_setup.c linux/arch/mips64/mips-boards/atlas/atlas_setup.c
--- v2.4.9/linux/arch/mips64/mips-boards/atlas/atlas_setup.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/mips-boards/atlas/atlas_setup.c	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,123 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope 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.
+ *
+ * ########################################################################
+ *
+ * Atlas specific setup, including init of the feature struct.
+ *
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/mc146818rtc.h>
+#include <linux/ioport.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/mips-boards/generic.h>
+#include <asm/mips-boards/prom.h>
+#include <asm/mips-boards/gt64120.h>
+#include <asm/mips-boards/atlasint.h>
+
+#include <asm/mmu_context.h>
+
+#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_PROM_CONSOLE)
+extern void console_setup(char *, int *);
+char serial_console[20];
+#endif
+
+#ifdef CONFIG_REMOTE_DEBUG
+extern void rs_kgdb_hook(int);
+extern void saa9730_kgdb_hook(void);
+extern void breakpoint(void);
+int remote_debug = 0;
+#endif
+
+extern struct rtc_ops atlas_rtc_ops;
+
+extern void mips_reboot_setup(void);
+
+void __init atlas_setup(void)
+{
+#ifdef CONFIG_REMOTE_DEBUG
+	int rs_putDebugChar(char);
+	char rs_getDebugChar(void);
+	int saa9730_putDebugChar(char);
+	char saa9730_getDebugChar(void);
+	extern int (*putDebugChar)(char);
+	extern char (*getDebugChar)(void);
+#endif
+	char *argptr;
+
+	current_cpu_data.asid_cache = ASID_FIRST_VERSION;
+	TLBMISS_HANDLER_SETUP();
+
+	ioport_resource.end = 0x7fffffff;
+
+#ifdef CONFIG_SERIAL_CONSOLE
+	argptr = prom_getcmdline();
+	if ((argptr = strstr(argptr, "console=ttyS0")) == NULL) {
+		int i = 0;
+		char *s = prom_getenv("modetty0");
+		while(s[i] >= '0' && s[i] <= '9')
+			i++;
+		strcpy(serial_console, "ttyS0,");
+		strncpy(serial_console + 6, s, i);
+		prom_printf("Config serial console: %s\n", serial_console);
+		console_setup(serial_console, NULL);
+	}
+#endif	  
+
+#ifdef CONFIG_REMOTE_DEBUG
+	argptr = prom_getcmdline();
+	if ((argptr = strstr(argptr, "kgdb=ttyS")) != NULL) {
+		int line;
+		argptr += strlen("kgdb=ttyS");
+		if (*argptr != '0' && *argptr != '1')
+			printk("KGDB: Uknown serial line /dev/ttyS%c, "
+			       "falling back to /dev/ttyS1\n", *argptr);
+		line = *argptr == '0' ? 0 : 1;
+		printk("KGDB: Using serial line /dev/ttyS%d for session\n",
+		       line ? 1 : 0);
+
+		if(line == 0) {
+			rs_kgdb_hook(line);
+			putDebugChar = rs_putDebugChar;
+			getDebugChar = rs_getDebugChar;
+		} else {
+			saa9730_kgdb_hook();
+			putDebugChar = saa9730_putDebugChar;
+			getDebugChar = saa9730_getDebugChar;
+		}
+
+		prom_printf("KGDB: Using serial line /dev/ttyS%d for session, "
+			    "please connect your debugger\n", line ? 1 : 0);
+
+		remote_debug = 1;
+		/* Breakpoints and stuff are in atlas_irq_setup() */
+	}
+#endif
+	argptr = prom_getcmdline();
+
+	if ((argptr = strstr(argptr, "nofpu")) != NULL)
+		mips_cpu.options &= ~MIPS_CPU_FPU;
+
+	rtc_ops = &atlas_rtc_ops;
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/mips-boards/generic/Makefile linux/arch/mips64/mips-boards/generic/Makefile
--- v2.4.9/linux/arch/mips64/mips-boards/generic/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/mips-boards/generic/Makefile	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,43 @@
+#
+# Carsten Langgaard, carstenl@mips.com
+# Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+#
+# ########################################################################
+#
+# This program is free software; you can distribute it and/or modify it
+# under the terms of the GNU General Public License (Version 2) as
+# published by the Free Software Foundation.
+# 
+# This program is distributed in the hope 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.
+#
+# #######################################################################
+#
+# Makefile for the MIPS boards generic 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...
+
+.S.s:
+	$(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+	$(CC) $(CFLAGS) -c $< -o $*.o
+
+all: mipsboards.o
+
+O_TARGET := mipsboards.o
+
+obj-y                           := mipsIRQ.o pci.o reset.o display.o init.o \
+                                   memory.o printf.o cmdline.o time.o
+obj-$(CONFIG_REMOTE_DEBUG)      += gdb_hook.o
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/mips-boards/generic/cmdline.c linux/arch/mips64/mips-boards/generic/cmdline.c
--- v2.4.9/linux/arch/mips64/mips-boards/generic/cmdline.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/mips-boards/generic/cmdline.c	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,71 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope 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.
+ *
+ * ########################################################################
+ * 
+ * Kernel command line creation using the prom monitor (YAMON) argc/argv.
+ *
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+
+/*#define DEBUG_CMDLINE*/
+
+extern int prom_argc;
+extern int *_prom_argv;
+
+/*
+ * A 32-bit PROM pass arguments and environment as 32-bit pointer.
+ * This macro take care of sign extension.
+ */
+#define prom_argv(index) ((char *)(((int *)(int)_prom_argv)[(index)]))
+
+char arcs_cmdline[CL_SIZE];
+
+char * __init prom_getcmdline(void)
+{
+	return &(arcs_cmdline[0]);
+}
+
+
+void  __init prom_init_cmdline(void)
+{
+	char *cp;
+	int actr;
+
+	actr = 1; /* Always ignore argv[0] */
+
+	cp = &(arcs_cmdline[0]);
+	while(actr < prom_argc) {
+	        strcpy(cp, prom_argv(actr));
+		cp += strlen(prom_argv(actr));
+		*cp++ = ' ';
+		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.4.9/linux/arch/mips64/mips-boards/generic/display.c linux/arch/mips64/mips-boards/generic/display.c
--- v2.4.9/linux/arch/mips64/mips-boards/generic/display.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/mips-boards/generic/display.c	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,47 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope 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.
+ *
+ * ########################################################################
+ * 
+ * Display routines for display messages in MIPS boards ascii display.
+ *
+ */
+
+#include <asm/mips-boards/generic.h>
+
+
+void mips_display_message(const char *str)
+{
+        volatile unsigned int *display = (void *)ASCII_DISPLAY_POS_BASE;
+	int i;
+
+	for (i = 0; i <= 14; i=i+2) {
+	         if (*str)
+		         display[i] = *str++;
+		 else
+		         display[i] = ' ';
+	}
+}
+
+void mips_display_word(unsigned int num)
+{
+        volatile unsigned int *display = (void *)ASCII_DISPLAY_WORD_BASE;
+	
+	*display = num;
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/mips-boards/generic/gdb_hook.c linux/arch/mips64/mips-boards/generic/gdb_hook.c
--- v2.4.9/linux/arch/mips64/mips-boards/generic/gdb_hook.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/mips-boards/generic/gdb_hook.c	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,202 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope 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.
+ *
+ * ########################################################################
+ *
+ * This is the interface to the remote debugger stub.
+ *
+ */
+
+#include <linux/serialP.h>
+#include <linux/serial_reg.h>
+
+#include <asm/serial.h>
+#include <asm/io.h>
+
+static struct serial_state rs_table[RS_TABLE_SIZE] = {
+	SERIAL_PORT_DFNS	/* Defined in serial.h */
+};
+
+static struct async_struct kdb_port_info = {0};
+
+
+static __inline__ unsigned int serial_in(struct async_struct *info, int offset)
+{
+	return inb(info->port + offset);
+}
+
+static __inline__ void serial_out(struct async_struct *info, int offset,
+				int value)
+{
+	outb(value, info->port+offset);
+}
+
+void rs_kgdb_hook(int tty_no) {
+	int t;
+	struct serial_state *ser = &rs_table[tty_no];
+
+	kdb_port_info.state = ser;
+	kdb_port_info.magic = SERIAL_MAGIC;
+	kdb_port_info.port = ser->port;
+	kdb_port_info.flags = ser->flags;
+
+	/*
+	 * Clear all interrupts
+	 */
+	serial_in(&kdb_port_info, UART_LSR);
+	serial_in(&kdb_port_info, UART_RX);
+	serial_in(&kdb_port_info, UART_IIR);
+	serial_in(&kdb_port_info, UART_MSR);
+
+	/*
+	 * Now, initialize the UART 
+	 */
+	serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8);	/* reset DLAB */
+	if (kdb_port_info.flags & ASYNC_FOURPORT) {
+		kdb_port_info.MCR = UART_MCR_DTR | UART_MCR_RTS;
+		t = UART_MCR_DTR | UART_MCR_OUT1;
+	} else {
+		kdb_port_info.MCR 
+			= UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2;
+		t = UART_MCR_DTR | UART_MCR_RTS;
+	}
+
+	kdb_port_info.MCR = t;		/* no interrupts, please */
+	serial_out(&kdb_port_info, UART_MCR, kdb_port_info.MCR);
+	
+	/*
+	 * and set the speed of the serial port
+	 * (currently hardwired to 9600 8N1
+	 */
+
+	/* baud rate is fixed to 9600 (is this sufficient?)*/
+	t = kdb_port_info.state->baud_base / 9600;	
+	/* set DLAB */
+	serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8 | UART_LCR_DLAB);
+	serial_out(&kdb_port_info, UART_DLL, t & 0xff);/* LS of divisor */
+	serial_out(&kdb_port_info, UART_DLM, t >> 8);  /* MS of divisor */
+	/* reset DLAB */
+	serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8);
+}
+
+int rs_putDebugChar(char c)
+{
+
+	if (!kdb_port_info.state) { 	/* need to init device first */
+		return 0;
+	}
+
+	while ((serial_in(&kdb_port_info, UART_LSR) & UART_LSR_THRE) == 0)
+		;
+
+	serial_out(&kdb_port_info, UART_TX, c);
+
+	return 1;
+}
+
+char rs_getDebugChar(void)
+{
+	if (!kdb_port_info.state) { 	/* need to init device first */
+		return 0;
+	}
+
+	while (!(serial_in(&kdb_port_info, UART_LSR) & 1))
+		;
+
+	return(serial_in(&kdb_port_info, UART_RX));
+}
+
+
+#ifdef CONFIG_MIPS_ATLAS
+
+#include <asm/mips-boards/atlas.h>
+#include <asm/mips-boards/saa9730_uart.h>
+
+#define INB(a)     inb((unsigned long)a)
+#define OUTB(x,a)  outb(x,(unsigned long)a)
+
+/*
+ * This is the interface to the remote debugger stub
+ * if the Philips part is used for the debug port,
+ * called from the platform setup code.
+ *
+ * PCI init will not have been done yet, we make a
+ * universal assumption about the way the bootloader (YAMON)
+ * have located and set up the chip.
+ */
+static t_uart_saa9730_regmap *kgdb_uart = (void *)(ATLAS_SAA9730_REG + SAA9730_UART_REGS_ADDR);
+
+static int saa9730_kgdb_active = 0;
+
+void saa9730_kgdb_hook(void) 
+{
+        volatile unsigned char t;
+
+        /*
+         * Clear all interrupts
+         */
+	t = INB(&kgdb_uart->Lsr);
+	t += INB(&kgdb_uart->Msr);
+	t += INB(&kgdb_uart->Thr_Rbr);
+	t += INB(&kgdb_uart->Iir_Fcr);
+
+        /*
+         * Now, initialize the UART
+         */
+	/* 8 data bits, one stop bit, no parity */
+	OUTB(SAA9730_LCR_DATA8, &kgdb_uart->Lcr);
+
+        /* baud rate is fixed to 9600 (is this sufficient?)*/
+	OUTB(0, &kgdb_uart->BaudDivMsb); /* HACK - Assumes standard crystal */
+	OUTB(23, &kgdb_uart->BaudDivLsb); /* HACK - known for MIPS Atlas */
+
+	/* Set RTS/DTR active */
+	OUTB(SAA9730_MCR_DTR | SAA9730_MCR_RTS, &kgdb_uart->Mcr);
+	saa9730_kgdb_active = 1;
+}
+
+int saa9730_putDebugChar(char c)
+{
+
+        if (!saa9730_kgdb_active) {     /* need to init device first */
+                return 0;
+        }
+
+        while (!(INB(&kgdb_uart->Lsr) & SAA9730_LSR_THRE))
+                ;
+	OUTB(c, &kgdb_uart->Thr_Rbr);
+
+        return 1;
+}
+
+char saa9730_getDebugChar(void)
+{
+	char c;
+
+        if (!saa9730_kgdb_active) {     /* need to init device first */
+                return 0;
+        }
+        while (!(INB(&kgdb_uart->Lsr) & SAA9730_LSR_DR))
+                ;
+
+	c = INB(&kgdb_uart->Thr_Rbr);
+        return(c);
+}
+
+#endif
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/mips-boards/generic/init.c linux/arch/mips64/mips-boards/generic/init.c
--- v2.4.9/linux/arch/mips64/mips-boards/generic/init.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/mips-boards/generic/init.c	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,152 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope 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.
+ *
+ * ########################################################################
+ *
+ * PROM library initialisation code.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+
+#include <asm/io.h>
+#include <asm/mips-boards/prom.h>
+#include <asm/mips-boards/generic.h>
+#include <asm/mips-boards/gt64120.h>
+#include <asm/mips-boards/malta.h>
+
+/* Environment variable */
+typedef struct
+{
+    char *name;
+    char *val;
+}t_env_var;
+
+int prom_argc;
+int *_prom_argv, *_prom_envp;
+
+/*
+ * A 32-bit PROM pass arguments and environment as 32-bit pointer.
+ * This macro take care of sign extension.
+ */
+#define prom_envp(index) ((char *)(((int *)(int)_prom_envp)[(index)]))
+
+int init_debug = 0;
+
+char *prom_getenv(char *envname)
+{
+        /*
+	 * Return a pointer to the given environment variable.
+	 * We're using 64-bit pointers, but all pointers in the PROM 
+	 * structures are only 32-bit, so we need some workarounds.
+	 */
+	int i, index=0;
+
+	i = strlen(envname);
+
+	while(prom_envp(index)) {
+		if(strncmp(envname, prom_envp(index), i) == 0) {
+			return(prom_envp(index+1));
+		}
+		index += 2;
+	}
+
+	return(NULL);
+}
+
+static inline unsigned char str2hexnum(unsigned char c)
+{
+	if(c >= '0' && c <= '9')
+		return c - '0';
+	if(c >= 'a' && c <= 'f')
+		return c - 'a' + 10;
+	return 0; /* foo */
+}
+
+static inline void str2eaddr(unsigned char *ea, unsigned char *str)
+{
+	int i;
+
+	for(i = 0; i < 6; i++) {
+		unsigned char num;
+
+		if((*str == '.') || (*str == ':'))
+			str++;
+		num = str2hexnum(*str++) << 4;
+		num |= (str2hexnum(*str++));
+		ea[i] = num;
+	}
+}
+ 
+int get_ethernet_addr(char *ethernet_addr)
+{
+        char *ethaddr_str;
+
+        ethaddr_str = prom_getenv("ethaddr");
+	if (!ethaddr_str) {
+	        printk("ethaddr not set in boot prom\n");
+		return -1;
+	}
+	str2eaddr(ethernet_addr, ethaddr_str);
+
+	if (init_debug > 1)
+	{
+	        int i;
+		printk("get_ethernet_addr: ");
+	        for (i=0; i<5; i++)
+		        printk("%02x:", (unsigned char)*(ethernet_addr+i));
+		printk("%02x\n", *(ethernet_addr+i));
+	}
+
+	return 0;
+}
+
+int __init prom_init(int argc, char **argv, char **envp)
+{
+	prom_argc = argc;
+	_prom_argv = (int *)argv;
+	_prom_envp = (int *)envp;
+
+	mips_display_message("LINUX");
+
+	/*
+	 * Setup the North bridge to do Master byte-lane swapping when 
+	 * running in bigendian.
+	 */
+#if defined(__MIPSEL__)
+	GT_WRITE(GT_PCI0_CMD_OFS, GT_PCI0_CMD_MBYTESWAP_BIT |
+		 GT_PCI0_CMD_SBYTESWAP_BIT);
+#else
+	GT_WRITE(GT_PCI0_CMD_OFS, 0);
+#endif
+
+#if defined(CONFIG_MIPS_MALTA)
+	mips_io_port_base = MALTA_PORT_BASE;
+#else
+	mips_io_port_base = KSEG1;
+#endif
+
+	setup_prom_printf(0);
+	prom_printf("\nLINUX started...\n");
+	prom_init_cmdline();
+	prom_meminit();
+
+	return 0;
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/mips-boards/generic/memory.c linux/arch/mips64/mips-boards/generic/memory.c
--- v2.4.9/linux/arch/mips64/mips-boards/generic/memory.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/mips-boards/generic/memory.c	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,263 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope 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.
+ *
+ * ########################################################################
+ *
+ * PROM library functions for acquiring/using memory descriptors given to 
+ * us from the YAMON.
+ * 
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+
+#include <asm/bootinfo.h>
+#include <asm/page.h>
+
+#include <asm/mips-boards/prom.h>
+
+/*#define DEBUG*/
+
+enum yamon_memtypes {
+	yamon_dontuse,
+	yamon_prom,
+	yamon_free,
+};
+struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS];
+
+#define MEMTYPE_DONTUSE 0
+#define MEMTYPE_PROM    1
+#define MEMTYPE_FREE    2
+
+#ifdef DEBUG
+static char *mtypes[3] = {
+	"Dont use memory",
+	"YAMON PROM memory",
+	"Free memmory",
+};
+#endif
+
+/* References to section boundaries */
+extern char _end;
+
+#define PFN_ALIGN(x)    (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK)
+
+struct prom_pmemblock * __init prom_getmdesc(void)
+{
+	char *memsize_str;
+	unsigned int memsize;
+
+	memsize_str = prom_getenv("memsize");
+	if (!memsize_str) {
+		prom_printf("memsize not set in boot prom, set to default (32Mb)\n");
+		memsize = 0x02000000;
+	} else {
+#ifdef DEBUG
+		prom_printf("prom_memsize = %s\n", memsize_str);
+#endif
+		memsize = simple_strtol(memsize_str, NULL, 0);
+	}
+
+	memset(mdesc, 0, sizeof(mdesc));
+
+	mdesc[0].type = yamon_dontuse;
+	mdesc[0].base = 0x00000000;
+	mdesc[0].size = 0x00001000;
+
+	mdesc[1].type = yamon_prom;
+	mdesc[1].base = 0x00001000;
+	mdesc[1].size = 0x000ef000;
+
+#if (CONFIG_MIPS_MALTA)
+	/* 
+	 * The area 0x000f0000-0x000fffff is allocated for BIOS memory by the
+	 * south bridge and PCI access always forwarded to the ISA Bus and 
+	 * BIOSCS# is always generated.
+	 * This mean that this area can't be used as DMA memory for PCI 
+	 * devices.
+	 */
+	mdesc[2].type = yamon_dontuse;
+	mdesc[2].base = 0x000f0000;
+	mdesc[2].size = 0x00010000;
+#else
+	mdesc[2].type = yamon_prom;
+	mdesc[2].base = 0x000f0000;
+	mdesc[2].size = 0x00010000;
+#endif
+
+	mdesc[3].type = yamon_dontuse;
+	mdesc[3].base = 0x00100000;
+	mdesc[3].size = CPHYSADDR(PFN_ALIGN(&_end)) - mdesc[3].base;
+
+	mdesc[4].type = yamon_free;
+	mdesc[4].base = CPHYSADDR(PFN_ALIGN(&_end));
+	mdesc[4].size = memsize - mdesc[4].base;
+
+	return &mdesc[0];
+}
+
+int __init page_is_ram(unsigned long pagenr)
+{
+	if ((pagenr << PAGE_SHIFT) < mdesc[4].base + mdesc[4].size)
+		return 1;
+
+	return 0;
+}
+
+static struct prom_pmemblock pblocks[PROM_MAX_PMEMBLOCKS];
+
+static int __init prom_memtype_classify (unsigned int type)
+{
+	switch (type) {
+	case yamon_free:
+		return MEMTYPE_FREE;
+	case yamon_prom:
+		return MEMTYPE_PROM;
+	default:
+		return MEMTYPE_DONTUSE;
+	}
+}
+
+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, *p;
+	unsigned long bootmap_size;
+	int totram;
+	int i = 0;
+
+#ifdef DEBUG
+	prom_printf("YAMON MEMORY DESCRIPTOR dump:\n");
+	p = prom_getmdesc();
+	while (p->size) {
+		prom_printf("[%d,%p]: base<%08lx> size<%08lx> type<%s>\n",
+			    i, p, p->base, p->size, mtypes[p->type]);
+		p++;
+		i++;
+	}
+#endif
+	totram = 0;
+	i = 0;
+	p = prom_getmdesc();
+
+	while (p->size) {
+		pblocks[i].type = prom_memtype_classify (p->type);
+		pblocks[i].base = p->base;
+		pblocks[i].size = p->size;
+		switch (pblocks[i].type) {
+		case MEMTYPE_FREE:
+			totram += pblocks[i].size;
+#ifdef DEBUG
+			prom_printf("free_chunk[%d]: base=%08lx size=%d\n",
+				    i, pblocks[i].base, pblocks[i].size);
+#endif
+			i++;
+			break;
+		case MEMTYPE_PROM:
+#ifdef DEBUG
+		        prom_printf("prom_chunk[%d]: base=%08lx size=%d\n",
+				    i, pblocks[i].base, pblocks[i].size);
+#endif
+			i++;
+			break;
+		default:
+			break;
+		}
+		p++;
+	}
+	pblocks[i].base = 0xdeadbeef;
+	pblocks[i].size = 0; /* indicates last elem. of array */
+
+	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 PROM memory areas.  */
+	if (bootmap_size > largest->size) {
+		prom_printf("CRITIAL: overwriting PROM data.\n");
+		BUG();
+	}
+
+	/* Reserve the memory bootmap itself */
+	reserve_bootmem(largest->base, bootmap_size);
+	printk("PROMLIB: Total free ram %d bytes (%dK,%dMB)\n",
+	       totram, (totram/1024), (totram/1024/1024));
+}
+
+void prom_free_prom_memory (void)
+{
+	struct prom_pmemblock *p;
+	unsigned long freed = 0;
+	unsigned long addr;
+
+	for (p = pblocks; p->size != 0; p++) {
+		if (p->type != MEMTYPE_PROM)
+			continue;
+
+		addr = p->base;
+		while (addr < p->base + p->size) {
+		        ClearPageReserved(virt_to_page(__va(addr)));
+			set_page_count(virt_to_page(__va(addr)), 1);
+			free_page(__va(addr));
+			addr += PAGE_SIZE;
+			freed += PAGE_SIZE;
+		}
+	}
+	printk("Freeing prom memory: %ldkb freed\n", freed >> 10);
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/mips-boards/generic/mipsIRQ.S linux/arch/mips64/mips-boards/generic/mipsIRQ.S
--- v2.4.9/linux/arch/mips64/mips-boards/generic/mipsIRQ.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/mips-boards/generic/mipsIRQ.S	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,122 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope 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.
+ *
+ * ########################################################################
+ *
+ * Interrupt exception dispatch code.
+ *
+ */
+#include <linux/config.h>
+
+#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 MIPS board look basically (barring software
+ * IRQs which we don't use at all and all external interrupt sources are
+ * combined together on hardware interrupt 0 (MIPS IRQ 2)) like:
+ *
+ *	MIPS IRQ	Source
+ *      --------        ------
+ *             0	Software (ignored)
+ *             1        Software (ignored)
+ *             2        Combined hardware interrupt (hw0)
+ *             3        Hardware (ignored)
+ *             4        Hardware (ignored)
+ *             5        Hardware (ignored)
+ *             6        Hardware (ignored)
+ *             7        R4k timer (what we use)
+ *
+ * We handle the IRQ according to _our_ priority which is:
+ *
+ * Highest ----     R4k Timer
+ * Lowest  ----     Combined hardware interrupt
+ *
+ * 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(mipsIRQ, 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 hw0 interrupt
+
+	/* Wheee, a timer interrupt. */
+	move	a0, sp
+	jal	mips_timer_interrupt
+	 nop
+
+	j	ret_from_irq
+	 nop
+
+1:
+	beq	a0, zero, 1f
+	 nop
+
+	/* Wheee, combined hardware level zero interrupt. */
+#if defined(CONFIG_MIPS_ATLAS)
+	jal	atlas_hw0_irqdispatch
+#elif defined(CONFIG_MIPS_MALTA)
+	jal	malta_hw0_irqdispatch
+#else
+#error "MIPS board not supported\n"	
+#endif
+	 move	a0, sp			# delay slot
+
+	j	ret_from_irq
+	 nop				# delay slot
+
+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.
+	 */
+	move	a1,s0
+	PRINT("Got interrupt: c0_cause = %08x\n")
+	mfc0	a1, CP0_EPC
+	PRINT("c0_epc = %08x\n")
+
+	j	ret_from_irq
+	 nop
+	END(mipsIRQ)
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/mips-boards/generic/pci.c linux/arch/mips64/mips-boards/generic/pci.c
--- v2.4.9/linux/arch/mips64/mips-boards/generic/pci.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/mips-boards/generic/pci.c	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,337 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope 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.
+ *
+ * ########################################################################
+ *
+ * MIPS boards specific PCI support.
+ *
+ */
+#include <linux/config.h>
+
+#ifdef CONFIG_PCI
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/mips-boards/generic.h>
+#include <asm/mips-boards/gt64120.h>
+#ifdef CONFIG_MIPS_MALTA
+#include <asm/mips-boards/malta.h>
+#endif
+
+#define PCI_ACCESS_READ  0
+#define PCI_ACCESS_WRITE 1
+
+static int
+mips_pcibios_config_access(unsigned char access_type, struct pci_dev *dev,
+                           unsigned char where, u32 *data)
+{
+	unsigned char bus = dev->bus->number;
+	unsigned char dev_fn = dev->devfn;
+        u32 intr;
+
+	if ((bus == 0) && (dev_fn >= PCI_DEVFN(31,0)))
+	        return -1; /* Because of a bug in the galileo (for slot 31). */
+
+	/* Clear cause register bits */
+	GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | 
+	                             GT_INTRCAUSE_TARABORT0_BIT));
+
+	/* Setup address */
+	GT_WRITE(GT_PCI0_CFGADDR_OFS, 
+		 (bus         << GT_PCI0_CFGADDR_BUSNUM_SHF)   |
+		 (dev_fn      << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
+		 ((where / 4) << GT_PCI0_CFGADDR_REGNUM_SHF)   |
+		 GT_PCI0_CFGADDR_CONFIGEN_BIT);
+
+	if (access_type == PCI_ACCESS_WRITE) {
+	        if (bus == 0 && dev_fn == 0) {
+		        /* 
+			 * Galileo is acting differently than other devices. 
+			 */
+		        GT_WRITE(GT_PCI0_CFGDATA_OFS, *data);
+		} else {
+		        GT_PCI_WRITE(GT_PCI0_CFGDATA_OFS, *data);
+		}
+	} else {
+	        if (bus == 0 && dev_fn == 0) {
+		        /* 
+			 * Galileo is acting differently than other devices. 
+			 */
+		        GT_READ(GT_PCI0_CFGDATA_OFS, *data);
+		} else {
+		        GT_PCI_READ(GT_PCI0_CFGDATA_OFS, *data);
+		}
+	}
+
+	/* Check for master or target abort */
+	GT_READ(GT_INTRCAUSE_OFS, intr);
+
+	if (intr & (GT_INTRCAUSE_MASABORT0_BIT | GT_INTRCAUSE_TARABORT0_BIT))
+	{
+	        /* Error occured */
+
+	        /* Clear bits */
+	        GT_WRITE( GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | 
+					      GT_INTRCAUSE_TARABORT0_BIT) );
+
+		return -1;
+	}
+
+	return 0;
+}
+
+
+/*
+ * 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
+mips_pcibios_read_config_byte (struct pci_dev *dev, int where, u8 *val)
+{
+	u32 data = 0;
+
+	if (mips_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
+		return -1;
+
+	*val = (data >> ((where & 3) << 3)) & 0xff;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int
+mips_pcibios_read_config_word (struct pci_dev *dev, int where, u16 *val)
+{
+	u32 data = 0;
+
+	if (where & 1)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	if (mips_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
+	       return -1;
+
+	*val = (data >> ((where & 3) << 3)) & 0xffff;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+mips_pcibios_read_config_dword (struct pci_dev *dev, int where, u32 *val)
+{
+	u32 data = 0;
+
+	if (where & 3)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	
+	if (mips_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
+		return -1;
+
+	*val = data;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int
+mips_pcibios_write_config_byte (struct pci_dev *dev, int where, u8 val)
+{
+	u32 data = 0;
+       
+	if (mips_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
+		return -1;
+
+	data = (data & ~(0xff << ((where & 3) << 3))) |
+	       (val << ((where & 3) << 3));
+
+	if (mips_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &data))
+		return -1;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+mips_pcibios_write_config_word (struct pci_dev *dev, int where, u16 val)
+{
+        u32 data = 0;
+
+	if (where & 1)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+       
+        if (mips_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
+	       return -1;
+
+	data = (data & ~(0xffff << ((where & 3) << 3))) | 
+	       (val << ((where & 3) << 3));
+
+	if (mips_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &data))
+	       return -1;
+
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+mips_pcibios_write_config_dword(struct pci_dev *dev, int where, u32 val)
+{
+	if (where & 3)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	if (mips_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &val))
+	       return -1;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops mips_pci_ops = {
+	mips_pcibios_read_config_byte,
+        mips_pcibios_read_config_word,
+	mips_pcibios_read_config_dword,
+	mips_pcibios_write_config_byte,
+	mips_pcibios_write_config_word,
+	mips_pcibios_write_config_dword
+};
+
+void __init pcibios_init(void)
+{
+#ifdef CONFIG_MIPS_MALTA
+	struct pci_dev *pdev;
+	unsigned char reg_val;
+#endif
+
+	printk("PCI: Probing PCI hardware on host bus 0.\n");
+	pci_scan_bus(0, &mips_pci_ops, NULL);
+
+	/* 
+	 * Due to a bug in the Galileo system controller, we need to setup 
+	 * the PCI BAR for the Galileo internal registers.
+	 * This should be done in the bios/bootprom and will be fixed in
+	 * a later revision of YAMON (the MIPS boards boot prom).
+	 */
+	GT_WRITE(GT_PCI0_CFGADDR_OFS,
+		 (0 << GT_PCI0_CFGADDR_BUSNUM_SHF)   |  /* Local bus */
+		 (0 << GT_PCI0_CFGADDR_DEVNUM_SHF)   |  /* GT64120 device */
+		 (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |  /* Function 0 */
+		 ((0x20/4) << GT_PCI0_CFGADDR_REGNUM_SHF) |  /* BAR 4 */
+		 GT_PCI0_CFGADDR_CONFIGEN_BIT );
+
+	/* Perform the write */
+	GT_WRITE( GT_PCI0_CFGDATA_OFS, CPHYSADDR(MIPS_GT_BASE)); 
+
+#ifdef CONFIG_MIPS_MALTA
+	pci_for_each_dev(pdev) {
+		if ((pdev->vendor == PCI_VENDOR_ID_INTEL)
+		    && (pdev->device == PCI_DEVICE_ID_INTEL_82371AB)
+		    && (PCI_SLOT(pdev->devfn) == 0x0a)) {
+			/*
+			 * IDE Decode enable.
+			 */
+			pci_read_config_byte(pdev, 0x41, &reg_val);
+        		pci_write_config_byte(pdev, 0x41, reg_val | 0x80);
+			pci_read_config_byte(pdev, 0x43, &reg_val);
+        		pci_write_config_byte(pdev, 0x43, reg_val | 0x80);
+		}
+
+		if ((pdev->vendor == PCI_VENDOR_ID_INTEL)
+		    && (pdev->device == PCI_DEVICE_ID_INTEL_82371AB_0)
+		    && (PCI_SLOT(pdev->devfn) == 0x0a)) {
+			/*
+			 * Set top of main memory accessible by ISA or DMA
+			 * devices to 16 Mb.
+			 */
+			pci_read_config_byte(pdev, 0x69, &reg_val);
+			pci_write_config_byte(pdev, 0x69, reg_val | 0xf0);
+		}
+	}
+
+	/* 
+	 * Activate Floppy Controller in the SMSC FDC37M817 Super I/O 
+	 * Controller.
+	 * This should be done in the bios/bootprom and will be fixed in
+         * a later revision of YAMON (the MIPS boards boot prom).
+	 */
+	/* Entering config state. */
+	SMSC_WRITE(SMSC_CONFIG_ENTER, SMSC_CONFIG_REG); 
+       
+	/* Activate floppy controller. */
+	SMSC_WRITE(SMSC_CONFIG_DEVNUM, SMSC_CONFIG_REG);
+	SMSC_WRITE(SMSC_CONFIG_DEVNUM_FLOPPY, SMSC_DATA_REG);
+	SMSC_WRITE(SMSC_CONFIG_ACTIVATE, SMSC_CONFIG_REG);
+	SMSC_WRITE(SMSC_CONFIG_ACTIVATE_ENABLE, SMSC_DATA_REG);
+
+	/* Exit config state. */
+	SMSC_WRITE(SMSC_CONFIG_EXIT, SMSC_CONFIG_REG);
+#endif
+}
+
+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;
+}
+
+struct pci_fixup pcibios_fixups[] = {
+	{ 0 }
+};
+
+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);
+}
+
+unsigned __init int pcibios_assign_all_busses(void)
+{
+	return 1;
+}
+
+/*
+ *  Called after each bus is probed, but before its children
+ *  are examined.
+ */
+void __init pcibios_fixup_bus(struct pci_bus *b)
+{
+	pci_read_bridge_bases(b);
+}
+
+#endif /* CONFIG_PCI */
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/mips-boards/generic/printf.c linux/arch/mips64/mips-boards/generic/printf.c
--- v2.4.9/linux/arch/mips64/mips-boards/generic/printf.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/mips-boards/generic/printf.c	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,140 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope 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.
+ *
+ * ########################################################################
+ *
+ * Putting things on the screen/serial line using YAMONs facilities.
+ *
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/serialP.h>
+#include <linux/serial_reg.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/serial.h>
+
+
+#ifdef CONFIG_MIPS_ATLAS 
+/* 
+ * Atlas registers are memory mapped on 64-bit aligned boundaries and 
+ * only word access are allowed.
+ * When reading the UART 8 bit registers only the LSB are valid.
+ */
+unsigned int atlas_serial_in(struct async_struct *info, int offset)
+{
+	return (*(volatile unsigned int *)(info->port + mips_io_port_base + offset*8) & 0xff);
+}
+
+void atlas_serial_out(struct async_struct *info, int offset, int value)
+{
+	*(volatile unsigned int *)(info->port + mips_io_port_base + offset*8) = value;
+}
+
+#define serial_in  atlas_serial_in
+#define serial_out atlas_serial_out
+
+#else
+
+static unsigned int serial_in(struct async_struct *info, int offset)
+{
+	return inb(info->port + offset);
+}
+
+static void serial_out(struct async_struct *info, int offset,
+				int value)
+{
+	outb(value, info->port + offset);
+}
+#endif
+
+static struct serial_state rs_table[] = {
+	SERIAL_PORT_DFNS	/* Defined in serial.h */
+};
+
+/*
+ * Hooks to fake "prom" console I/O before devices 
+ * are fully initialized. 
+ */
+static struct async_struct prom_port_info = {0};
+
+void __init setup_prom_printf(int tty_no) {
+	struct serial_state *ser = &rs_table[tty_no];
+
+	prom_port_info.state = ser;
+	prom_port_info.magic = SERIAL_MAGIC;
+	prom_port_info.port = ser->port;
+	prom_port_info.flags = ser->flags;
+
+	/* No setup of UART - assume YAMON left in sane state */
+}
+
+int putPromChar(char c)
+{
+        if (!prom_port_info.state) { 	/* need to init device first */
+		return 0;
+	}
+
+	while ((serial_in(&prom_port_info, UART_LSR) & UART_LSR_THRE) == 0)
+		;
+
+	serial_out(&prom_port_info, UART_TX, c);
+
+	return 1;
+}
+
+char getPromChar(void)
+{
+	if (!prom_port_info.state) { 	/* need to init device first */
+		return 0;
+	}
+
+	while (!(serial_in(&prom_port_info, UART_LSR) & 1))
+		;
+
+	return(serial_in(&prom_port_info, UART_RX));
+}
+
+static char buf[1024];
+
+void __init prom_printf(char *fmt, ...)
+{
+	va_list args;
+	int l;
+	char *p, *buf_end;
+	long flags;
+
+	int putPromChar(char);
+
+	/* Low level, brute force, not SMP safe... */
+	save_and_cli(flags);
+	va_start(args, fmt);
+	l = vsprintf(buf, fmt, args); /* hopefully i < sizeof(buf) */
+	va_end(args);
+
+	buf_end = buf + l;
+
+	for (p = buf; p < buf_end; p++) {
+		/* Crude cr/nl handling is better than none */
+		if(*p == '\n')putPromChar('\r');
+		putPromChar(*p);
+	}
+	restore_flags(flags);
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/mips-boards/generic/reset.c linux/arch/mips64/mips-boards/generic/reset.c
--- v2.4.9/linux/arch/mips64/mips-boards/generic/reset.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/mips-boards/generic/reset.c	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,61 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope 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.
+ *
+ * ########################################################################
+ *
+ * Reset the MIPS boards.
+ *
+ */
+#include <linux/config.h>
+
+#include <asm/mips-boards/generic.h>
+#if defined(CONFIG_MIPS_ATLAS)
+#include <asm/mips-boards/atlas.h>
+#endif
+
+void machine_restart(char *command) __attribute__((noreturn));
+void machine_halt(void) __attribute__((noreturn));
+#if defined(CONFIG_MIPS_ATLAS)
+void machine_power_off(void) __attribute__((noreturn));
+#endif
+
+void machine_restart(char *command)
+{
+        volatile unsigned int *softres_reg = (void *)SOFTRES_REG;
+
+	*softres_reg = GORESET;
+}
+
+void machine_halt(void)
+{
+        volatile unsigned int *softres_reg = (void *)SOFTRES_REG;
+
+	*softres_reg = GORESET;
+}
+
+void machine_power_off(void)
+{
+#if defined(CONFIG_MIPS_ATLAS)
+        volatile unsigned int *psustby_reg = (void *)ATLAS_PSUSTBY_REG;
+
+	*psustby_reg = ATLAS_GOSTBY;
+#else
+	machine_halt();
+#endif
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/mips-boards/generic/time.c linux/arch/mips64/mips-boards/generic/time.c
--- v2.4.9/linux/arch/mips64/mips-boards/generic/time.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/mips-boards/generic/time.c	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,399 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope 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.
+ *
+ * ########################################################################
+ *
+ * Setting up the clock on the MIPS boards.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+
+#include <asm/mipsregs.h>
+#include <asm/ptrace.h>
+
+#include <linux/mc146818rtc.h>
+#include <linux/timex.h>
+
+#include <asm/mips-boards/generic.h>
+#include <asm/mips-boards/prom.h>
+
+extern volatile unsigned long wall_jiffies;
+static long last_rtc_update = 0;
+unsigned long missed_heart_beats = 0;
+
+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;
+
+#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
+
+#if defined(CONFIG_MIPS_ATLAS)
+static char display_string[] = "        LINUX ON ATLAS       ";
+#endif
+#if defined(CONFIG_MIPS_MALTA)
+static char display_string[] = "        LINUX ON MALTA       ";
+#endif
+static unsigned int display_count = 0;
+#define MAX_DISPLAY_COUNT (sizeof(display_string) - 8) 
+
+static unsigned int timer_tick_count=0;
+
+
+static inline void ack_r4ktimer(unsigned long newval)
+{
+	write_32bit_cp0_register(CP0_COMPARE, newval);
+}
+
+
+/*
+ * In order to set the CMOS clock precisely, set_rtc_mmss has to be
+ * called 500 ms after the second nowtime has started, because when
+ * nowtime is written into the registers of the CMOS clock, it will
+ * jump to the next second precisely 500 ms later. Check the Motorola
+ * MC146818A or Dallas DS12887 data sheet for details.
+ *
+ * BUG: This routine does not handle hour overflow properly; it just
+ *      sets the minutes. Usually you won't notice until after reboot!
+ */
+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;
+
+	save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */
+	CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
+
+	save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */
+	CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
+
+	cmos_minutes = CMOS_READ(RTC_MINUTES);
+
+	/*
+	 * 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) {
+		CMOS_WRITE(real_seconds,RTC_SECONDS);
+		CMOS_WRITE(real_minutes,RTC_MINUTES);
+	} else {
+		printk(KERN_WARNING
+		       "set_rtc_mmss: can't update from %d to %d\n",
+		       cmos_minutes, real_minutes);
+ 		retval = -1;
+	}
+
+	/* The following flags have to be released exactly in this order,
+	 * otherwise the DS12887 (popular MC146818A clone with integrated
+	 * battery and quartz) will not reset the oscillator and will not
+	 * update precisely 500 ms later. You won't find this mentioned in
+	 * the Dallas Semiconductor data sheets, but who believes data
+	 * sheets anyway ...                           -- Markus Kuhn
+	 */
+	CMOS_WRITE(save_control, RTC_CONTROL);
+	CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
+
+	return retval;
+}
+
+/*
+ * There are a lot of conceptually broken versions of the MIPS timer interrupt
+ * handler floating around.  This one is rather different, but the algorithm
+ * is provably more robust.
+ */
+void mips_timer_interrupt(struct pt_regs *regs)
+{
+	int irq = 7;
+
+	if (r4k_offset == 0)
+		goto null;
+
+	do {
+		kstat.irqs[0][irq]++;
+		do_timer(regs);
+
+		/* Historical comment/code:
+ 		 * RTC time of day s updated 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.
+ 		 */
+		read_lock(&xtime_lock);
+		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 60 s */
+	    			last_rtc_update = xtime.tv_sec - 600; 
+		read_unlock(&xtime_lock);
+
+		if ((timer_tick_count++ % HZ) == 0) {
+		    mips_display_message(&display_string[display_count++]);
+		    if (display_count == MAX_DISPLAY_COUNT)
+		        display_count = 0;
+		}
+
+		r4k_cur += r4k_offset;
+		ack_r4ktimer(r4k_cur);
+
+	} while (((unsigned int)read_32bit_cp0_register(CP0_COUNT)
+	         - (unsigned int)r4k_cur) < 0x7fffffff);
+
+	return;
+
+null:
+	ack_r4ktimer(0);
+}
+
+/* 
+ * Figure out the r4k offset, the amount to increment the compare
+ * register for each time tick. 
+ * Use the RTC to calculate offset.
+ */
+static unsigned long __init cal_r4koff(void)
+{
+	unsigned long count;
+	unsigned int flags;
+
+	__save_and_cli(flags);
+
+	/* Start counter exactly on falling edge of update flag */
+	while (CMOS_READ(RTC_REG_A) & RTC_UIP);
+	while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
+
+	/* Start r4k counter. */
+	write_32bit_cp0_register(CP0_COUNT, 0);
+
+	/* Read counter exactly on falling edge of update flag */
+	while (CMOS_READ(RTC_REG_A) & RTC_UIP);
+	while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
+
+	count = read_32bit_cp0_register(CP0_COUNT);
+
+	/* restore interrupts */
+	__restore_flags(flags);
+
+	return (count / HZ);
+}
+
+static unsigned long __init get_mips_time(void)
+{
+	unsigned int year, mon, day, hour, min, sec;
+	unsigned char save_control;
+
+	save_control = CMOS_READ(RTC_CONTROL);
+
+	/* Freeze it. */
+	CMOS_WRITE(save_control | RTC_SET, RTC_CONTROL);
+
+	/* Read regs. */
+	sec = CMOS_READ(RTC_SECONDS);
+	min = CMOS_READ(RTC_MINUTES);
+	hour = CMOS_READ(RTC_HOURS);
+
+	if (!(save_control & RTC_24H))
+	{
+		if ((hour & 0xf) == 0xc)
+		        hour &= 0x80;
+	        if (hour & 0x80)
+		        hour = (hour & 0xf) + 12;     
+	}
+	day = CMOS_READ(RTC_DAY_OF_MONTH);
+	mon = CMOS_READ(RTC_MONTH);
+	year = CMOS_READ(RTC_YEAR);
+
+	/* Unfreeze clock. */
+	CMOS_WRITE(save_control, RTC_CONTROL);
+
+	if ((year += 1900) < 1970)
+	        year += 100;
+
+	return mktime(year, mon, day, hour, min, sec);
+}
+
+void __init time_init(void)
+{
+        unsigned int est_freq, flags;
+
+        /* Set Data mode - binary. */ 
+        CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL);
+
+	printk("calculating r4koff... ");
+	r4k_offset = cal_r4koff();
+	printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset);
+
+	est_freq = 2*r4k_offset*HZ;	
+	est_freq += 5000;    /* round */
+	est_freq -= est_freq%10000;
+	printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, 
+	       (est_freq%1000000)*100/1000000);
+	r4k_cur = (read_32bit_cp0_register(CP0_COUNT) + r4k_offset);
+
+	write_32bit_cp0_register(CP0_COMPARE, r4k_cur);
+	set_cp0_status(ST0_IM, ALLINTS);
+
+	/* Read time from the RTC chipset. */
+	write_lock_irqsave (&xtime_lock, flags);
+	xtime.tv_sec = get_mips_time();
+	xtime.tv_usec = 0;
+	write_unlock_irqrestore(&xtime_lock, flags);
+}
+
+/* This is for machines which generate the exact clock. */
+#define USECS_PER_JIFFY (1000000/HZ)
+#define USECS_PER_JIFFY_FRAC (0x100000000*1000000/HZ&0xffffffff)
+
+/* Cycle counter value at the previous timer interrupt.. */
+
+static unsigned int timerhi = 0, timerlo = 0;
+
+/*
+ * FIXME: Does playing with the RP bit in c0_status interfere with this code?
+ */
+static unsigned long do_fast_gettimeoffset(void)
+{
+	u32 count;
+	unsigned long res, tmp;
+
+	/* Last jiffy when do_fast_gettimeoffset() was called. */
+	static unsigned long last_jiffies=0;
+	unsigned long quotient;
+
+	/*
+	 * Cached "1/(clocks per usec)*2^32" value.
+	 * It has to be recalculated once each jiffy.
+	 */
+	static unsigned long cached_quotient=0;
+
+	tmp = jiffies;
+
+	quotient = cached_quotient;
+
+	if (tmp && last_jiffies != tmp) {
+		last_jiffies = tmp;
+		__asm__(".set\tnoreorder\n\t"
+			".set\tnoat\n\t"
+			".set\tmips3\n\t"
+			"lwu\t%0,%2\n\t"
+			"dsll32\t$1,%1,0\n\t"
+			"or\t$1,$1,%0\n\t"
+			"ddivu\t$0,$1,%3\n\t"
+			"mflo\t$1\n\t"
+			"dsll32\t%0,%4,0\n\t"
+			"nop\n\t"
+			"ddivu\t$0,%0,$1\n\t"
+			"mflo\t%0\n\t"
+			".set\tmips0\n\t"
+			".set\tat\n\t"
+			".set\treorder"
+			:"=&r" (quotient)
+			:"r" (timerhi),
+			 "m" (timerlo),
+			 "r" (tmp),
+			 "r" (USECS_PER_JIFFY)
+			:"$1");
+		cached_quotient = quotient;
+	}
+
+	/* Get last timer tick in absolute kernel time */
+	count = read_32bit_cp0_register(CP0_COUNT);
+
+	/* .. relative to previous jiffy (32 bits is enough) */
+	count -= timerlo;
+
+	__asm__("multu\t%1,%2\n\t"
+		"mfhi\t%0"
+		:"=r" (res)
+		:"r" (count),
+		 "r" (quotient));
+
+	/*
+ 	 * Due to possible jiffies inconsistencies, we need to check 
+	 * the result so that we'll get a timer that is monotonic.
+	 */
+	if (res >= USECS_PER_JIFFY)
+		res = USECS_PER_JIFFY-1;
+
+	return res;
+}
+
+void do_gettimeofday(struct timeval *tv)
+{
+	unsigned int flags;
+
+	read_lock_irqsave (&xtime_lock, flags);
+	*tv = xtime;
+	tv->tv_usec += do_fast_gettimeoffset();
+
+	/*
+	 * xtime is atomically updated in timer_bh. jiffies - wall_jiffies
+	 * is nonzero if the timer bottom half hasnt executed yet.
+	 */
+	if (jiffies - wall_jiffies)
+		tv->tv_usec += USECS_PER_JIFFY;
+
+	read_unlock_irqrestore (&xtime_lock, flags);
+
+	if (tv->tv_usec >= 1000000) {
+		tv->tv_usec -= 1000000;
+		tv->tv_sec++;
+	}
+}
+
+void do_settimeofday(struct timeval *tv)
+{
+	write_lock_irq (&xtime_lock);
+
+	/* This is revolting. We need to set the xtime.tv_usec correctly.
+	 * However, the value in this location is is value at the last tick.
+	 * Discover what correction gettimeofday would have done, and then
+	 * undo it!
+	 */
+	tv->tv_usec -= do_fast_gettimeoffset();
+
+	if (tv->tv_usec < 0) {
+		tv->tv_usec += 1000000;
+		tv->tv_sec--;
+	}
+
+	xtime = *tv;
+	time_adjust = 0;		/* stop active adjtime() */
+	time_status |= STA_UNSYNC;
+	time_maxerror = NTP_PHASE_LIMIT;
+	time_esterror = NTP_PHASE_LIMIT;
+
+	write_unlock_irq (&xtime_lock);
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/mips-boards/malta/Makefile linux/arch/mips64/mips-boards/malta/Makefile
--- v2.4.9/linux/arch/mips64/mips-boards/malta/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/mips-boards/malta/Makefile	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,42 @@
+#
+# Carsten Langgaard, carstenl@mips.com
+# Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+#
+# ########################################################################
+#
+# This program is free software; you can distribute it and/or modify it
+# under the terms of the GNU General Public License (Version 2) as
+# published by the Free Software Foundation.
+# 
+# This program is distributed in the hope 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.
+#
+# #######################################################################
+#
+# Makefile for the MIPS Malta 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...
+
+.S.s:
+	$(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+	$(CC) $(CFLAGS) -c $< -o $*.o
+
+all: malta.o
+
+O_TARGET := malta.o
+
+obj-y := malta_int.o malta_rtc.o malta_setup.o
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/mips-boards/malta/malta_int.c linux/arch/mips64/mips-boards/malta/malta_int.c
--- v2.4.9/linux/arch/mips64/mips-boards/malta/malta_int.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/mips-boards/malta/malta_int.c	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,383 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope 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.
+ *
+ * ########################################################################
+ *
+ * Routines for generic manipulation of the interrupts found on the MIPS 
+ * Malta board.
+ * The interrupt controller is located in the South Bridge a PIIX4 device 
+ * with two internal 82C95 interrupt controllers.
+ *
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/random.h>
+
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/mips-boards/malta.h>
+#include <asm/mips-boards/maltaint.h>
+#include <asm/mips-boards/piix4.h>
+#include <asm/mips-boards/gt64120.h>
+#include <asm/mips-boards/generic.h>
+
+extern asmlinkage void mipsIRQ(void);
+
+unsigned int local_bh_count[NR_CPUS];
+unsigned int local_irq_count[NR_CPUS];
+unsigned long spurious_count = 0;
+
+static struct irqaction *hw0_irq_action[MALTAINT_END] = {
+	NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL
+};
+
+static struct irqaction r4ktimer_action = {
+	NULL, 0, 0, "R4000 timer/counter", NULL, NULL,
+};
+
+static struct irqaction *irq_action[8] = {
+	NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, &r4ktimer_action
+};
+
+#if 0
+#define DEBUG_INT(x...) printk(x)
+#else
+#define DEBUG_INT(x...)
+#endif
+
+/*
+ * This contains the interrupt mask for both 82C59 interrupt controllers.
+ */
+static unsigned int cached_int_mask = 0xffff;
+
+
+void disable_irq(unsigned int irq_nr)
+{
+        unsigned long flags;
+
+	if(irq_nr >= MALTAINT_END) {
+		printk("whee, invalid irq_nr %d\n", irq_nr);
+		panic("IRQ, you lose...");
+	}
+
+	save_and_cli(flags);
+	cached_int_mask |= (1 << irq_nr);
+	if (irq_nr & 8) {
+	        outb((cached_int_mask >> 8) & 0xff, PIIX4_ICTLR2_OCW1);
+	} else {
+		outb(cached_int_mask & 0xff, PIIX4_ICTLR1_OCW1);
+	}
+	restore_flags(flags);
+}
+
+
+void enable_irq(unsigned int irq_nr)
+{
+        unsigned long flags;
+
+	if(irq_nr >= MALTAINT_END) {
+		printk("whee, invalid irq_nr %d\n", irq_nr);
+		panic("IRQ, you lose...");
+	}
+
+	save_and_cli(flags);
+	cached_int_mask &= ~(1 << irq_nr);
+	if (irq_nr & 8) {
+		outb((cached_int_mask >> 8) & 0xff, PIIX4_ICTLR2_OCW1);
+
+		/* Enable irq 2 (cascade interrupt). */
+	        cached_int_mask &= ~(1 << 2); 
+		outb(cached_int_mask & 0xff, PIIX4_ICTLR1_OCW1);
+	} else {
+		outb(cached_int_mask & 0xff, PIIX4_ICTLR1_OCW1);
+	}	
+	restore_flags(flags);
+}
+
+
+int get_irq_list(char *buf)
+{
+	int i, len = 0;
+	int num = 0;
+	struct irqaction *action;
+
+	for (i = 0; i < 8; 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 < MALTAINT_END; i++, num++) {
+		action = hw0_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, " [hw0]\n");
+	}
+	return len;
+}
+
+int request_irq(unsigned int irq, 
+		void (*handler)(int, void *, struct pt_regs *),
+		unsigned long irqflags, 
+		const char * devname,
+		void *dev_id)
+{  
+        struct irqaction *action;
+	int retval;
+
+	DEBUG_INT("request_irq: irq=%d, devname = %s\n", irq, devname);
+
+        if (irq >= MALTAINT_END)
+	        return -EINVAL;
+	if (!handler)
+	        return -EINVAL;
+
+	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->dev_id = dev_id;
+	action->next = 0;
+
+	retval = setup_irq(irq, action);
+	if (retval)
+		kfree(action);
+
+	return retval;	
+}
+
+
+void free_irq(unsigned int irq, void *dev_id)
+{
+	struct irqaction *action, **p;
+
+	if (irq >= MALTAINT_END) {
+		printk("Trying to free IRQ%d\n",irq);
+		return;
+	}
+	
+	for (p = &hw0_irq_action[irq]; (action = *p) != NULL; 
+	     p = &action->next) 
+	{
+		if (action->dev_id != dev_id)
+			continue;
+
+		/* Found it - now free it */
+		*p = action->next;
+		kfree(action);
+		if (!hw0_irq_action[irq])
+			disable_irq(irq);
+		return;
+	}
+	printk("Trying to free IRQ%d\n",irq);
+}
+
+void __init init_IRQ(void)
+{
+	irq_setup();
+}
+
+static int setup_irq(unsigned int irq, struct irqaction * new)
+{
+	int shared = 0;
+	struct irqaction *old, **p;
+
+	p = &hw0_irq_action[irq];
+	if ((old = *p) != NULL) {
+		/* Can't share interrupts unless both agree to */
+		if (!(old->flags & new->flags & SA_SHIRQ))
+			return -EBUSY;
+
+		/* Can't share interrupts unless both are same type */
+		if ((old->flags ^ new->flags) & SA_INTERRUPT)
+			return -EBUSY;
+
+		/* add new interrupt at end of irq queue */
+		do {
+			p = &old->next;
+			old = *p;
+		} while (old);
+		shared = 1;
+	}
+
+	if (new->flags & SA_SAMPLE_RANDOM)
+		rand_initialize_irq(irq);
+
+	*p = new;
+	if (!shared)
+		enable_irq(irq);
+
+	return 0;
+}
+
+static inline int get_int(int *irq)
+{
+	/*  
+	 * Determine highest priority pending interrupt by performing
+         * a PCI Interrupt Acknowledge cycle.
+	 */
+	GT_READ(GT_PCI0_IACK_OFS, *irq);
+	*irq &= 0xFF;
+
+	/*  
+	 * IRQ7 is used to detect spurious interrupts.
+	 * The interrupt acknowledge cycle returns IRQ7, if no 
+	 * interrupts is requested.
+	 * We can differentiate between this situation and a
+	 * "Normal" IRQ7 by reading the ISR.
+	 */
+	if (*irq == 7) 
+	{
+		outb(PIIX4_OCW3_SEL | PIIX4_OCW3_ISR, PIIX4_ICTLR1_OCW3);
+		if (!(inb(PIIX4_ICTLR1_OCW3) & (1 << 7)))
+		        return -1;    /* Spurious interrupt. */
+	}
+
+	return 0;
+}
+
+static inline void ack_int(int irq)
+{
+	if (irq & 8) {
+	        /* Specific EOI to cascade */
+		outb(PIIX4_OCW2_SEL | PIIX4_OCW2_NSEOI | PIIX4_OCW2_ILS_2, 
+		     PIIX4_ICTLR1_OCW2);
+
+	        /* Non specific EOI to cascade */
+		outb(PIIX4_OCW2_SEL | PIIX4_OCW2_NSEOI, PIIX4_ICTLR2_OCW2);
+	} else {
+	        /* Non specific EOI to cascade */
+		outb(PIIX4_OCW2_SEL | PIIX4_OCW2_NSEOI, PIIX4_ICTLR1_OCW2);
+	}
+}
+
+void malta_hw0_irqdispatch(struct pt_regs *regs)
+{
+        struct irqaction *action;
+	int irq=0, cpu = smp_processor_id();
+
+	DEBUG_INT("malta_hw0_irqdispatch\n");
+	
+	if (get_int(&irq))
+	        return;  /* interrupt has already been cleared */
+
+	disable_irq(irq);
+	ack_int(irq);
+
+	DEBUG_INT("malta_hw0_irqdispatch: irq=%d\n", irq);
+	action = hw0_irq_action[irq];
+
+	/* 
+	 * if action == NULL, then we don't have a handler 
+	 * for the irq 
+	 */
+	if ( action == NULL )
+		return;
+
+	irq_enter(cpu, irq);
+	kstat.irqs[0][irq + 8]++;
+	do {
+	        action->handler(irq, action->dev_id, regs);
+		action = action->next;
+	} while (action);
+
+	enable_irq(irq);
+	irq_exit(cpu, irq);
+}
+
+
+unsigned long probe_irq_on (void)
+{
+	unsigned int i, irqs = 0;
+	unsigned long delay;
+
+	/* first, enable any unassigned irqs */
+	for (i = MALTAINT_END-1; i > 0; i--) {
+		if (!hw0_irq_action[i]) {
+			enable_irq(i);
+			irqs |= (1 << i);
+		}
+	}
+
+	/* wait for spurious interrupts to mask themselves out again */
+	for (delay = jiffies + HZ/10; time_before(jiffies, delay); )
+		/* about 100ms delay */;
+
+	/* now filter out any obviously spurious interrupts */
+	return irqs & ~cached_int_mask;
+}
+
+
+int probe_irq_off (unsigned long irqs)
+{
+	unsigned int i;
+
+	irqs &= cached_int_mask;
+	if (!irqs)
+		return 0;
+	i = ffz(~irqs);
+	if (irqs != (irqs & (1 << i)))
+		i = -i;
+
+	return i;
+}
+
+
+void __init maltaint_init(void)
+{
+        /* 
+	 * Mask out all interrupt by writing "1" to all bit position in 
+	 * the IMR register. 
+	 */
+	outb(cached_int_mask & 0xff, PIIX4_ICTLR1_OCW1);
+	outb((cached_int_mask >> 8) & 0xff, PIIX4_ICTLR2_OCW1);
+
+	/* Now safe to set the exception vector. */
+	set_except_vector(0, mipsIRQ);
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/mips-boards/malta/malta_rtc.c linux/arch/mips64/mips-boards/malta/malta_rtc.c
--- v2.4.9/linux/arch/mips64/mips-boards/malta/malta_rtc.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/mips-boards/malta/malta_rtc.c	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,50 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope 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.
+ *
+ * ########################################################################
+ *
+ * RTC routines for Malta style attached PIIX4 device, which contains a
+ * Motorola MC146818A-compatible Real Time Clock.
+ *
+ */
+#include <asm/mc146818rtc.h>
+#include <asm/mips-boards/malta.h>
+
+static unsigned char malta_rtc_read_data(unsigned long addr)
+{
+	outb(addr, MALTA_RTC_ADR_REG);
+	return inb(MALTA_RTC_DAT_REG);
+}
+
+static void malta_rtc_write_data(unsigned char data, unsigned long addr)
+{
+	outb(addr, MALTA_RTC_ADR_REG);
+	outb(data, MALTA_RTC_DAT_REG);
+}
+
+static int malta_rtc_bcd_mode(void)
+{
+	return 0;
+}
+
+struct rtc_ops malta_rtc_ops = {
+	&malta_rtc_read_data,
+	&malta_rtc_write_data,
+	&malta_rtc_bcd_mode
+};
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/mips-boards/malta/malta_setup.c linux/arch/mips64/mips-boards/malta/malta_setup.c
--- v2.4.9/linux/arch/mips64/mips-boards/malta/malta_setup.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/mips-boards/malta/malta_setup.c	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,170 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope 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.
+ *
+ * ########################################################################
+ *
+ * Malta specific setup, including init of the feature struct.
+ *
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/mc146818rtc.h>
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#ifdef CONFIG_BLK_DEV_IDE
+#include <linux/ide.h>
+#endif
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/mips-boards/generic.h>
+#include <asm/mips-boards/prom.h>
+#include <asm/mips-boards/gt64120.h>
+#include <asm/mips-boards/malta.h>
+#include <asm/mips-boards/maltaint.h>
+#ifdef CONFIG_BLK_DEV_FD
+#include <asm/floppy.h>
+#endif
+#include <asm/dma.h>
+#include <asm/mmu_context.h>
+
+#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_PROM_CONSOLE)
+extern void console_setup(char *, int *);
+char serial_console[20];
+#endif
+
+#ifdef CONFIG_REMOTE_DEBUG
+extern void set_debug_traps(void);
+extern void rs_kgdb_hook(int);
+extern void breakpoint(void);
+static int remote_debug = 0;
+#endif
+
+#ifdef CONFIG_BLK_DEV_IDE
+extern struct ide_ops std_ide_ops;
+#endif
+#ifdef CONFIG_BLK_DEV_FD
+extern struct fd_ops std_fd_ops;
+#endif
+extern struct rtc_ops malta_rtc_ops;
+
+extern void mips_reboot_setup(void);
+
+struct resource standard_io_resources[] = {
+	{ "dma1", 0x00, 0x1f, IORESOURCE_BUSY },
+	{ "pic1", 0x20, 0x3f, IORESOURCE_BUSY },
+	{ "timer", 0x40, 0x5f, IORESOURCE_BUSY },
+	{ "dma page reg", 0x80, 0x8f, IORESOURCE_BUSY },
+	{ "pic2", 0xa0, 0xbf, IORESOURCE_BUSY },
+	{ "dma2", 0xc0, 0xdf, IORESOURCE_BUSY },
+};
+
+#define STANDARD_IO_RESOURCES (sizeof(standard_io_resources)/sizeof(struct resource))
+
+static void __init malta_irq_setup(void)
+{
+  	maltaint_init();
+
+#ifdef CONFIG_REMOTE_DEBUG
+	if (remote_debug) {
+		set_debug_traps();
+		breakpoint(); 
+	}
+#endif
+}
+
+
+void __init malta_setup(void)
+{
+#ifdef CONFIG_REMOTE_DEBUG
+	int rs_putDebugChar(char);
+	char rs_getDebugChar(void);
+	extern int (*putDebugChar)(char);
+	extern char (*getDebugChar)(void);
+#endif
+	char *argptr;
+	int i;
+
+	current_cpu_data.asid_cache = ASID_FIRST_VERSION;
+	TLBMISS_HANDLER_SETUP();
+
+	irq_setup = malta_irq_setup;
+
+	/* Request I/O space for devices used on the Malta board. */
+	for (i = 0; i < STANDARD_IO_RESOURCES; i++)
+		request_resource(&ioport_resource, standard_io_resources+i);
+
+	/* 
+	 * Enable DMA channel 4 (cascade channel) in the PIIX4 south bridge.
+	 */
+	enable_dma(4);
+
+#ifdef CONFIG_SERIAL_CONSOLE
+        argptr = prom_getcmdline();
+	if ((argptr = strstr(argptr, "console=ttyS0")) == NULL) 
+	{
+	        int i=0;
+	        char *s = prom_getenv("modetty0");
+		while(s[i] >= '0' && s[i] <= '9')
+			i++;
+		strcpy(serial_console, "ttyS0,");
+		strncpy(serial_console + 6, s, i);
+		prom_printf("Config serial console: %s\n", serial_console);
+	        console_setup(serial_console, NULL);
+	}
+#endif	  
+
+#ifdef CONFIG_REMOTE_DEBUG
+	argptr = prom_getcmdline();
+	if ((argptr = strstr(argptr, "kgdb=ttyS")) != NULL) {
+		int line;
+		argptr += strlen("kgdb=ttyS");
+		if (*argptr != '0' && *argptr != '1')
+			printk("KGDB: Uknown serial line /dev/ttyS%c, "
+			       "falling back to /dev/ttyS1\n", *argptr);
+		line = *argptr == '0' ? 0 : 1;
+		printk("KGDB: Using serial line /dev/ttyS%d for session\n",
+		       line ? 1 : 0);
+
+		rs_kgdb_hook(line);
+		putDebugChar = rs_putDebugChar;
+		getDebugChar = rs_getDebugChar;
+
+		prom_printf("KGDB: Using serial line /dev/ttyS%d for session, "
+			    "please connect your debugger\n", line ? 1 : 0);
+
+		remote_debug = 1;
+		/* Breakpoints and stuff are in malta_irq_setup() */
+	}
+#endif
+
+	argptr = prom_getcmdline();
+	if ((argptr = strstr(argptr, "nofpu")) != NULL)
+		mips_cpu.options &= ~MIPS_CPU_FPU;
+
+	rtc_ops = &malta_rtc_ops;
+#ifdef CONFIG_BLK_DEV_IDE
+        ide_ops = &std_ide_ops;
+#endif
+#ifdef CONFIG_BLK_DEV_FD
+        fd_ops = &std_fd_ops;
+#endif
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/mm/andes.c linux/arch/mips64/mm/andes.c
--- v2.4.9/linux/arch/mips64/mm/andes.c	Wed Jul 25 17:10:18 2001
+++ linux/arch/mips64/mm/andes.c	Sun Sep  9 10:43:02 2001
@@ -125,14 +125,8 @@
 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);
+	protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
+	protected_flush_icache_line(addr & ~(ic_lsize - 1));
 }
 
 #define NTLB_ENTRIES       64
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/mm/extable.c linux/arch/mips64/mm/extable.c
--- v2.4.9/linux/arch/mips64/mm/extable.c	Wed Jul 25 17:10:18 2001
+++ linux/arch/mips64/mm/extable.c	Sun Sep  9 10:43:02 2001
@@ -1,5 +1,4 @@
-/* $Id: extable.c,v 1.2 1999/11/23 17:12: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.
@@ -38,8 +37,7 @@
 
 extern spinlock_t modlist_lock;
 
-unsigned long
-search_exception_table(unsigned long addr)
+unsigned long search_exception_table(unsigned long addr)
 {
 	unsigned long ret = 0;
 	unsigned long flags;
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/mm/fault.c linux/arch/mips64/mm/fault.c
--- v2.4.9/linux/arch/mips64/mm/fault.c	Wed Jul 25 17:10:18 2001
+++ linux/arch/mips64/mm/fault.c	Sun Sep  9 10:43:02 2001
@@ -32,7 +32,6 @@
 #define development_version (LINUX_VERSION_CODE & 0x100)
 
 extern void die(char *, struct pt_regs *, unsigned long write);
-extern int console_loglevel;
 
 /*
  * Macro for exception fixup code to access integer registers.
@@ -59,11 +58,11 @@
 	printk("Got exception 0x%lx at 0x%lx\n", retaddr, regs.cp0_epc);
 }
 
-extern spinlock_t timerlist_lock;
+extern spinlock_t console_lock, timerlist_lock;
 
 /*
  * Unlock any spinlocks which will prevent us from getting the
- * message out (timerlist_lock is aquired through the
+ * message out (timerlist_lock is acquired through the
  * console unblank code)
  */
 void bust_spinlocks(int yes)
@@ -71,12 +70,11 @@
 	spin_lock_init(&timerlist_lock);
 	if (yes) {
 		oops_in_progress = 1;
-#ifdef CONFIG_SMP
-		global_irq_lock = 0;	/* Many serial drivers do __global_cli() */
-#endif
 	} else {
 		int loglevel_save = console_loglevel;
+#ifdef CONFIG_VT
 		unblank_screen();
+#endif
 		oops_in_progress = 0;
 		/*
 		 * OK, the message is on the console.  Now we call printk()
@@ -228,7 +226,6 @@
                (unsigned int) regs->regs[31]);
 	die("Oops", regs, write);
 	do_exit(SIGKILL);
-	bust_spinlocks(0);
 
 /*
  * We ran out of memory, or some other thing happened to us that made
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/mm/loadmmu.c linux/arch/mips64/mm/loadmmu.c
--- v2.4.9/linux/arch/mips64/mm/loadmmu.c	Tue Nov 28 21:42:04 2000
+++ linux/arch/mips64/mm/loadmmu.c	Sun Sep  9 10:43:02 2001
@@ -1,5 +1,4 @@
-/* $Id: loadmmu.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.
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/mm/r4xx0.c linux/arch/mips64/mm/r4xx0.c
--- v2.4.9/linux/arch/mips64/mm/r4xx0.c	Wed Jul 25 17:10:18 2001
+++ linux/arch/mips64/mm/r4xx0.c	Sun Sep  9 10:43:02 2001
@@ -776,9 +776,9 @@
 	__restore_flags(flags);
 }
 
-static void
-r4k_flush_cache_range_s16d16i16(struct mm_struct *mm, unsigned long start,
-                                unsigned long end)
+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;
@@ -815,9 +815,9 @@
 	}
 }
 
-static void
-r4k_flush_cache_range_s32d16i16(struct mm_struct *mm, unsigned long start,
-                                unsigned long end)
+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;
@@ -854,9 +854,9 @@
 	}
 }
 
-static void
-r4k_flush_cache_range_s64d16i16(struct mm_struct *mm, unsigned long start,
-                                unsigned long end)
+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;
@@ -893,9 +893,9 @@
 	}
 }
 
-static void
-r4k_flush_cache_range_s128d16i16(struct mm_struct *mm, unsigned long start,
-                                 unsigned long end)
+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;
@@ -932,9 +932,9 @@
 	}
 }
 
-static void
-r4k_flush_cache_range_s32d32i32(struct mm_struct *mm, unsigned long start,
-                                unsigned long end)
+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;
@@ -971,9 +971,9 @@
 	}
 }
 
-static void
-r4k_flush_cache_range_s64d32i32(struct mm_struct *mm, unsigned long start,
-                                unsigned long end)
+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;
@@ -1010,9 +1010,9 @@
 	}
 }
 
-static void
-r4k_flush_cache_range_s128d32i32(struct mm_struct *mm, unsigned long start,
-                                 unsigned long end)
+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;
@@ -1049,9 +1049,9 @@
 	}
 }
 
-static void
-r4k_flush_cache_range_d16i16(struct mm_struct *mm, unsigned long start,
-                             unsigned long end)
+static void r4k_flush_cache_range_d16i16(struct mm_struct *mm,
+					 unsigned long start,
+					 unsigned long end)
 {
 	if (CPU_CONTEXT(smp_processor_id(), mm) != 0) {
 		unsigned long flags;
@@ -1065,9 +1065,9 @@
 	}
 }
 
-static void
-r4k_flush_cache_range_d32i32(struct mm_struct *mm, unsigned long start,
-                             unsigned long end)
+static void r4k_flush_cache_range_d32i32(struct mm_struct *mm,
+					 unsigned long start,
+					 unsigned long end)
 {
 	if (CPU_CONTEXT(smp_processor_id(), mm) != 0) {
 		unsigned long flags;
@@ -1176,8 +1176,8 @@
 	}
 }
 
-static void
-r4k_flush_cache_page_s16d16i16(struct vm_area_struct *vma, unsigned long page)
+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;
@@ -1213,8 +1213,8 @@
 	 * for every cache flush operation.  So we do indexed flushes
 	 * in that case, which doesn't overly flush the cache too much.
 	 */
-	if (CPU_CONTEXT(smp_processor_id(), mm) != 
-				CPU_CONTEXT(smp_processor_id(), current->mm)) {
+	if (CPU_CONTEXT(smp_processor_id(), mm) !=
+	    CPU_CONTEXT(smp_processor_id(), current->mm)) {
 		/* Do indexed flush, too much work to get the (possible)
 		 * tlb refills to work correctly.
 		 */
@@ -1227,8 +1227,8 @@
 	__restore_flags(flags);
 }
 
-static void
-r4k_flush_cache_page_s32d16i16(struct vm_area_struct *vma, unsigned long page)
+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;
@@ -1263,8 +1263,8 @@
 	 * for every cache flush operation.  So we do indexed flushes
 	 * in that case, which doesn't overly flush the cache too much.
 	 */
-	if (CPU_CONTEXT(smp_processor_id(), mm) != 
-				CPU_CONTEXT(smp_processor_id(), current->mm)) {
+	if (CPU_CONTEXT(smp_processor_id(), mm) !=
+	    CPU_CONTEXT(smp_processor_id(), current->mm)) {
 		/* Do indexed flush, too much work to get the (possible)
 		 * tlb refills to work correctly.
 		 */
@@ -1277,8 +1277,8 @@
 	__restore_flags(flags);
 }
 
-static void
-r4k_flush_cache_page_s64d16i16(struct vm_area_struct *vma, unsigned long page)
+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;
@@ -1315,7 +1315,7 @@
 	 * in that case, which doesn't overly flush the cache too much.
 	 */
 	if (CPU_CONTEXT(smp_processor_id(), mm) != 
-				CPU_CONTEXT(smp_processor_id(), current->mm)) {
+	    CPU_CONTEXT(smp_processor_id(), current->mm)) {
 		/* Do indexed flush, too much work to get the (possible)
 		 * tlb refills to work correctly.
 		 */
@@ -1328,8 +1328,8 @@
 	__restore_flags(flags);
 }
 
-static void
-r4k_flush_cache_page_s128d16i16(struct vm_area_struct *vma, unsigned long page)
+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;
@@ -1366,7 +1366,7 @@
 	 * in that case, which doesn't overly flush the cache too much.
 	 */
 	if (CPU_CONTEXT(smp_processor_id(), mm) != 
-				CPU_CONTEXT(smp_processor_id(), current->mm)) {
+	    CPU_CONTEXT(smp_processor_id(), current->mm)) {
 		/*
 		 * Do indexed flush, too much work to get the (possible)
 		 * tlb refills to work correctly.
@@ -1380,8 +1380,8 @@
 	__restore_flags(flags);
 }
 
-static void
-r4k_flush_cache_page_s32d32i32(struct vm_area_struct *vma, unsigned long page)
+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;
@@ -1419,7 +1419,7 @@
 	 * in that case, which doesn't overly flush the cache too much.
 	 */
 	if (CPU_CONTEXT(smp_processor_id(), mm) != 
-				CPU_CONTEXT(smp_processor_id(), current->mm)) {
+	    CPU_CONTEXT(smp_processor_id(), current->mm)) {
 		/*
 		 * Do indexed flush, too much work to get the (possible)
 		 * tlb refills to work correctly.
@@ -1433,8 +1433,8 @@
 	__restore_flags(flags);
 }
 
-static void
-r4k_flush_cache_page_s64d32i32(struct vm_area_struct *vma, unsigned long page)
+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;
@@ -1472,7 +1472,7 @@
 	 * in that case, which doesn't overly flush the cache too much.
 	 */
 	if (CPU_CONTEXT(smp_processor_id(), mm) != 
-				CPU_CONTEXT(smp_processor_id(), current->mm)) {
+	    CPU_CONTEXT(smp_processor_id(), current->mm)) {
 		/*
 		 * Do indexed flush, too much work to get the (possible)
 		 * tlb refills to work correctly.
@@ -1486,8 +1486,8 @@
 	__restore_flags(flags);
 }
 
-static void
-r4k_flush_cache_page_s128d32i32(struct vm_area_struct *vma, unsigned long page)
+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;
@@ -1524,7 +1524,7 @@
 	 * in that case, which doesn't overly flush the cache too much.
 	 */
 	if (CPU_CONTEXT(smp_processor_id(), mm) != 
-				CPU_CONTEXT(smp_processor_id(), current->mm)) {
+	    CPU_CONTEXT(smp_processor_id(), current->mm)) {
 		/* Do indexed flush, too much work to get the (possible)
 		 * tlb refills to work correctly.
 		 */
@@ -1537,8 +1537,8 @@
 	__restore_flags(flags);
 }
 
-static void
-r4k_flush_cache_page_d16i16(struct vm_area_struct *vma, unsigned long page)
+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;
@@ -1587,8 +1587,8 @@
 	__restore_flags(flags);
 }
 
-static void
-r4k_flush_cache_page_d32i32(struct vm_area_struct *vma, unsigned long page)
+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;
@@ -1639,9 +1639,8 @@
 	__restore_flags(flags);
 }
 
-static void
-r4k_flush_cache_page_d32i32_r4600(struct vm_area_struct *vma,
-                                  unsigned long page)
+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;
@@ -1741,8 +1740,7 @@
  * (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)
+static void r4k_dma_cache_wback_inv_pc(unsigned long addr, unsigned long size)
 {
 	unsigned long end, a;
 	unsigned int flags;
@@ -1766,8 +1764,7 @@
 	bc_wback_inv(addr, size);
 }
 
-static void
-r4k_dma_cache_wback_inv_sc(unsigned long addr, unsigned long size)
+static void r4k_dma_cache_wback_inv_sc(unsigned long addr, unsigned long size)
 {
 	unsigned long end, a;
 
@@ -1785,8 +1782,7 @@
 	}
 }
 
-static void
-r4k_dma_cache_inv_pc(unsigned long addr, unsigned long size)
+static void r4k_dma_cache_inv_pc(unsigned long addr, unsigned long size)
 {
 	unsigned long end, a;
 	unsigned int flags;
@@ -1811,8 +1807,7 @@
 	bc_inv(addr, size);
 }
 
-static void
-r4k_dma_cache_inv_sc(unsigned long addr, unsigned long size)
+static void r4k_dma_cache_inv_sc(unsigned long addr, unsigned long size)
 {
 	unsigned long end, a;
 
@@ -1830,8 +1825,7 @@
 	}
 }
 
-static void
-r4k_dma_cache_wback(unsigned long addr, unsigned long size)
+static void r4k_dma_cache_wback(unsigned long addr, unsigned long size)
 {
 	panic("r4k_dma_cache called - should not happen.\n");
 }
@@ -1843,33 +1837,24 @@
  */
 static void r4k_flush_cache_sigtramp(unsigned long addr)
 {
-	unsigned long daddr, iaddr;
-
-	daddr = addr & ~((unsigned long)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 & ~((unsigned long)ic_lsize - 1);
-	protected_flush_icache_line(iaddr);
-	protected_flush_icache_line(iaddr + ic_lsize);
+
+	protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
+	protected_flush_icache_line(addr & ~(ic_lsize - 1));
 }
 
 static void r4600v20k_flush_cache_sigtramp(unsigned long addr)
 {
-	unsigned long daddr, iaddr;
 	unsigned int flags;
 
-	daddr = addr & ~((unsigned long)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 & ~((unsigned long)ic_lsize - 1);
-	protected_flush_icache_line(iaddr);
-	protected_flush_icache_line(iaddr + ic_lsize);
+	protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
+	protected_flush_icache_line(addr & ~(ic_lsize - 1));
+
 	__restore_flags(flags);
 }
 
@@ -2011,8 +1996,7 @@
 	}
 }
 
-static void
-r4k_flush_cache_l2(void)
+static void r4k_flush_cache_l2(void)
 {
 }
 
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/mm/umap.c linux/arch/mips64/mm/umap.c
--- v2.4.9/linux/arch/mips64/mm/umap.c	Wed Jul 25 17:10:18 2001
+++ linux/arch/mips64/mm/umap.c	Sun Sep  9 10:43:02 2001
@@ -25,8 +25,8 @@
 #include <asm/pgalloc.h>
 #include <asm/page.h>
 
-static inline void
-remove_mapping_pte_range (pmd_t *pmd, unsigned long address, unsigned long size)
+static inline void remove_mapping_pte_range (pmd_t *pmd, unsigned long address,
+					     unsigned long size)
 {
 	pte_t *pte;
 	unsigned long end;
@@ -34,7 +34,8 @@
 	if (pmd_none (*pmd))
 		return;
 	if (pmd_bad (*pmd)){
-		printk ("remove_graphics_pte_range: bad pmd (%08lx)\n", pmd_val (*pmd));
+		printk ("remove_graphics_pte_range: bad pmd (%08lx)\n",
+			pmd_val (*pmd));
 		pmd_clear (pmd);
 		return;
 	}
@@ -53,8 +54,8 @@
 						  
 }
 
-static inline void
-remove_mapping_pmd_range (pgd_t *pgd, unsigned long address, unsigned long size)
+static inline void remove_mapping_pmd_range (pgd_t *pgd, unsigned long address,
+					     unsigned long size)
 {
 	pmd_t *pmd;
 	unsigned long end;
@@ -63,7 +64,8 @@
 		return;
 
 	if (pgd_bad (*pgd)){
-		printk ("remove_graphics_pmd_range: bad pgd (%08lx)\n", pgd_val (*pgd));
+		printk ("remove_graphics_pmd_range: bad pgd (%08lx)\n",
+			pgd_val (*pgd));
 		pgd_clear (pgd);
 		return;
 	}
@@ -84,8 +86,8 @@
  * 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)
+void remove_mapping (struct task_struct *task, unsigned long start,
+		     unsigned long end)
 {
 	unsigned long beg = start;
 	pgd_t *dir;
@@ -137,8 +139,8 @@
  * 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)
+static inline void vmap_pte_range (pte_t *pte, unsigned long address,
+				   unsigned long size, unsigned long vaddr)
 {
 	unsigned long end;
 	pgd_t *vdir;
@@ -167,8 +169,8 @@
 	} while (address < end);
 }
 
-static inline int
-vmap_pmd_range (pmd_t *pmd, unsigned long address, unsigned long size, unsigned long vaddr)
+static inline int vmap_pmd_range (pmd_t *pmd, unsigned long address,
+				  unsigned long size, unsigned long vaddr)
 {
 	unsigned long end;
 
@@ -178,7 +180,7 @@
 		end = PGDIR_SIZE;
 	vaddr -= address;
 	do {
-		pte_t * pte = pte_alloc(pmd, address);
+		pte_t * pte = pte_alloc(current->mm, pmd, address);
 		if (!pte)
 			return -ENOMEM;
 		vmap_pte_range(pte, address, end - address, address + vaddr);
@@ -188,8 +190,8 @@
 	return 0;
 }
 
-int
-vmap_page_range (unsigned long from, unsigned long size, unsigned long vaddr)
+int vmap_page_range (unsigned long from, unsigned long size,
+		     unsigned long vaddr)
 {
 	int error = 0;
 	pgd_t * dir;
@@ -200,7 +202,7 @@
 	dir = pgd_offset(current->mm, from);
 	flush_cache_range(current->mm, beg, end);
 	while (from < end) {
-		pmd_t *pmd = pmd_alloc(dir, from);
+		pmd_t *pmd = pmd_alloc(current->mm, dir, from);
 		error = -ENOMEM;
 		if (!pmd)
 			break;
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/sgi-ip22/ip22-berr.c linux/arch/mips64/sgi-ip22/ip22-berr.c
--- v2.4.9/linux/arch/mips64/sgi-ip22/ip22-berr.c	Sat May 13 08:30:17 2000
+++ linux/arch/mips64/sgi-ip22/ip22-berr.c	Sun Sep  9 10:43:02 2001
@@ -1,5 +1,4 @@
-/* $Id: ip22-berr.c,v 1.1 2000/01/21 22:34:03 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.
@@ -9,6 +8,9 @@
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <asm/module.h>
 #include <asm/uaccess.h>
 #include <asm/paccess.h>
 #include <asm/addrspace.h>
@@ -41,16 +43,43 @@
 	return 0;
 }
 
+extern spinlock_t modlist_lock;
+
 static inline unsigned long
 search_dbe_table(unsigned long addr)
 {
-	unsigned long ret;
+	unsigned long ret = 0;
 
+#ifndef CONFIG_MODULES
 	/* 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;
+	return ret;
+#else
+	unsigned long flags;
+
+	/* The kernel is the last "module" -- no need to treat it special.  */
+	struct module *mp;
+	struct archdata *ap;
+
+	spin_lock_irqsave(&modlist_lock, flags);
+	for (mp = module_list; mp != NULL; mp = mp->next) {
+		if (!mod_member_present(mp, archdata_end) ||
+        	    !mod_archdata_member_present(mp, struct archdata,
+						 dbe_table_end))
+			continue;
+		ap = (struct archdata *)(mod->archdata_start);
+
+		if (ap->dbe_table_start == NULL ||
+		    !(mp->flags & (MOD_RUNNING | MOD_INITIALIZING)))
+			continue;
+		ret = search_one_table(ap->dbe_table_start,
+				       ap->dbe_table_end - 1, addr);
+		if (ret)
+			break;
+	}
+	spin_unlock_irqrestore(&modlist_lock, flags);
+	return ret;
+#endif
 }
 
 void do_ibe(struct pt_regs *regs)
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/sgi-ip22/ip22-hpc.c linux/arch/mips64/sgi-ip22/ip22-hpc.c
--- v2.4.9/linux/arch/mips64/sgi-ip22/ip22-hpc.c	Tue Nov 28 21:42:04 2000
+++ linux/arch/mips64/sgi-ip22/ip22-hpc.c	Sun Sep  9 10:43:02 2001
@@ -1,9 +1,8 @@
-/* $Id: ip22-hpc.c,v 1.2 1999/10/19 20:51:52 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
+ * Copyright (C) 1998, 1999, 2001 Ralf Baechle
  */
 #include <linux/init.h>
 #include <linux/types.h>
@@ -11,7 +10,6 @@
 #include <asm/addrspace.h>
 #include <asm/sgi/sgihpc.h>
 #include <asm/sgi/sgint23.h>
-#include <asm/sgialib.h>
 #include <asm/bootinfo.h>
 
 #undef DEBUG_SGIHPC
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/sgi-ip22/ip22-int.c linux/arch/mips64/sgi-ip22/ip22-int.c
--- v2.4.9/linux/arch/mips64/sgi-ip22/ip22-int.c	Fri Feb  9 11:29:44 2001
+++ linux/arch/mips64/sgi-ip22/ip22-int.c	Sun Sep  9 10:43:02 2001
@@ -34,7 +34,6 @@
 #include <asm/sgi/sgi.h>
 #include <asm/sgi/sgihpc.h>
 #include <asm/sgi/sgint23.h>
-#include <asm/sgialib.h>
 
 /*
  * Linux has a controller-independent x86 interrupt architecture.
@@ -287,9 +286,7 @@
 	irq_enter(cpu, irq);
 	kstat.irqs[0][irq]++;
 
-	printk("Got irq %d, press a key.", irq);
-	prom_getchar();
-	ArcEnterInteractiveMode();
+	panic(KERN_DEBUG "Got irq %d, press a key.", irq);
 
 	/*
 	 * mask and ack quickly, we don't want the irq controller
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/sgi-ip22/ip22-irq.S linux/arch/mips64/sgi-ip22/ip22-irq.S
--- v2.4.9/linux/arch/mips64/sgi-ip22/ip22-irq.S	Sat May 13 08:30:17 2000
+++ linux/arch/mips64/sgi-ip22/ip22-irq.S	Sun Sep  9 10:43:02 2001
@@ -1,5 +1,4 @@
-/* $Id: ip22-irq.S,v 1.1 1999/08/20 21:13: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.
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/sgi-ip22/ip22-mc.c linux/arch/mips64/sgi-ip22/ip22-mc.c
--- v2.4.9/linux/arch/mips64/sgi-ip22/ip22-mc.c	Sat May 13 08:30:17 2000
+++ linux/arch/mips64/sgi-ip22/ip22-mc.c	Sun Sep  9 10:43:02 2001
@@ -1,12 +1,10 @@
-/* $Id: ip22-mc.c,v 1.2 1999/10/19 20:51: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.
  *
- * indy_mc.c: Routines for manipulating the INDY memory controller.
- *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 2001 Ralf Baechle (ralf@gnu.org)
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -15,7 +13,6 @@
 #include <asm/ptrace.h>
 #include <asm/sgi/sgimc.h>
 #include <asm/sgi/sgihpc.h>
-#include <asm/sgialib.h>
 
 /* #define DEBUG_SGIMC */
 
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/sgi-ip22/ip22-reset.c linux/arch/mips64/sgi-ip22/ip22-reset.c
--- v2.4.9/linux/arch/mips64/sgi-ip22/ip22-reset.c	Sat May 13 08:30:17 2000
+++ linux/arch/mips64/sgi-ip22/ip22-reset.c	Sun Sep  9 10:43:02 2001
@@ -1,12 +1,11 @@
-/* $Id: ip22-reset.c,v 1.3 1999/10/08 21:07: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.
  *
  * Reset an IP22.
  *
- * Copyright (C) 1997, 1998, 1999 by Ralf Baechle
+ * Copyright (C) 1997, 1998, 1999, 2001 by Ralf Baechle
  */
 #include <linux/kernel.h>
 #include <linux/sched.h>
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/sgi-ip22/ip22-rtc.c linux/arch/mips64/sgi-ip22/ip22-rtc.c
--- v2.4.9/linux/arch/mips64/sgi-ip22/ip22-rtc.c	Sat May 13 08:30:17 2000
+++ linux/arch/mips64/sgi-ip22/ip22-rtc.c	Sun Sep  9 10:43:02 2001
@@ -1,12 +1,11 @@
-/* $Id: ip22-rtc.c,v 1.1 1999/08/20 21:13: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.
  *
  * RTC routines for Indy style attached Dallas chip.
  *
- * Copyright (C) 1998 by Ralf Baechle
+ * Copyright (C) 1998, 2001 by Ralf Baechle
  */
 #include <linux/mc146818rtc.h>
 #include <asm/sgi/sgihpc.h>
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/sgi-ip22/ip22-sc.c linux/arch/mips64/sgi-ip22/ip22-sc.c
--- v2.4.9/linux/arch/mips64/sgi-ip22/ip22-sc.c	Tue Mar  6 19:44:36 2001
+++ linux/arch/mips64/sgi-ip22/ip22-sc.c	Sun Sep  9 10:43:02 2001
@@ -1,5 +1,4 @@
-/* $Id: ip22-sc.c,v 1.2 1999/12/04 03:59:01 ralf Exp $
- *
+/*
  * indy_sc.c: Indy cache management functions.
  *
  * Copyright (C) 1997 Ralf Baechle (ralf@gnu.org),
@@ -16,7 +15,6 @@
 #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.  */
@@ -31,17 +29,17 @@
 
 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");
+	__asm__ __volatile__(
+	".set\tnoreorder\n\t"
+	"or\t%0, %4\t\t\t# first line to flush\n\t"
+	"or\t%1, %4\t\t\t# last line to flush\n"
+	"1:\tsw	$0, 0(%0)\n\t"
+	"bne\t%0, %1, 1b\n\t"
+	"daddu\t%0, 32\n\t"
+	".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)
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/sgi-ip22/ip22-setup.c linux/arch/mips64/sgi-ip22/ip22-setup.c
--- v2.4.9/linux/arch/mips64/sgi-ip22/ip22-setup.c	Tue Nov 28 21:42:04 2000
+++ linux/arch/mips64/sgi-ip22/ip22-setup.c	Sun Sep  9 10:43:02 2001
@@ -1,5 +1,4 @@
-/* $Id: ip22-setup.c,v 1.4 1999/10/08 21:07: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.
@@ -145,7 +144,7 @@
 	 * graphics console, it is set to "d" for the first serial
 	 * line and "d2" for the second serial line.
 	 */
-	ctype = ArcArcGetEnvironmentVariable("console");
+	ctype = ArcGetEnvironmentVariable("console");
 	if(*ctype == 'd') {
 		if(*(ctype+1)=='2')
 			console_setup ("ttyS1");
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/sgi-ip22/ip22-timer.c linux/arch/mips64/sgi-ip22/ip22-timer.c
--- v2.4.9/linux/arch/mips64/sgi-ip22/ip22-timer.c	Tue Nov 28 21:42:04 2000
+++ linux/arch/mips64/sgi-ip22/ip22-timer.c	Sun Sep  9 10:43:02 2001
@@ -1,5 +1,4 @@
-/* $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)
@@ -238,9 +237,7 @@
 
 	irq_enter(cpu, irq);
 	kstat.irqs[0][irq]++;
-	printk("indy_8254timer_irq: Whoops, should not have gotten this IRQ\n");
-	prom_getchar();
-	ArcEnterInteractiveMode();
+	panic("indy_8254timer_irq: Whoops, should not have gotten this IRQ\n");
 	irq_exit(cpu, irq);
 }
 
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/sgi-ip22/system.c linux/arch/mips64/sgi-ip22/system.c
--- v2.4.9/linux/arch/mips64/sgi-ip22/system.c	Sat May 13 08:30:17 2000
+++ linux/arch/mips64/sgi-ip22/system.c	Sun Sep  9 10:43:02 2001
@@ -1,5 +1,4 @@
-/* $Id: system.c,v 1.3 1999/10/19 20:51: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.
@@ -7,6 +6,7 @@
  * system.c: Probe the system type using ARCS prom interface library.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org)
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -17,8 +17,6 @@
 #include <asm/sgialib.h>
 #include <asm/bootinfo.h>
 
-enum sgi_mach sgimach;
-
 struct smatch {
 	char *name;
 	int type;
@@ -46,10 +44,7 @@
 		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();
+	panic("\nYeee, could not determine MIPS cpu type <%s>", s);
 	return 0;
 }
 
@@ -74,23 +69,16 @@
 		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();
-			}
+			if (++ncpus > 1)
+				panic("\nYeee, SGI MP not ready yet");
 			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();
+	if (cputype == -1) {
+		panic("\nYeee, could not find cpu ARCS component");
 	}
 	p = ArcGetChild(cpup);
 	while(p) {
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/sgi-ip22/time.c linux/arch/mips64/sgi-ip22/time.c
--- v2.4.9/linux/arch/mips64/sgi-ip22/time.c	Sat May 13 08:30:17 2000
+++ linux/arch/mips64/sgi-ip22/time.c	Sun Sep  9 10:43:02 2001
@@ -1,5 +1,4 @@
-/* $Id: time.c,v 1.1 1999/08/20 21:13: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.
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/sgi-ip27/Makefile linux/arch/mips64/sgi-ip27/Makefile
--- v2.4.9/linux/arch/mips64/sgi-ip27/Makefile	Sun Feb  4 21:48:46 2001
+++ linux/arch/mips64/sgi-ip27/Makefile	Sun Sep  9 10:43:02 2001
@@ -7,7 +7,7 @@
 .S.o:
 	$(CC) $(CFLAGS) -c $< -o $*.o
 
-O_TARGET = ip27.a
+O_TARGET = ip27.o
 
 obj-y	:= ip27-berr.o ip27-console.o ip27-irq.o ip27-init.o ip27-irq-glue.o \
 	   ip27-klconfig.o ip27-klnuma.o ip27-memory.o ip27-nmi.o ip27-pci.o \
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/sgi-ip27/ip27-berr.c linux/arch/mips64/sgi-ip27/ip27-berr.c
--- v2.4.9/linux/arch/mips64/sgi-ip27/ip27-berr.c	Sun Jul  9 22:18:16 2000
+++ linux/arch/mips64/sgi-ip27/ip27-berr.c	Sun Sep  9 10:43:02 2001
@@ -8,6 +8,9 @@
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <asm/module.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/arch.h>
 #include <asm/sn/sn0/hub.h>
@@ -43,16 +46,43 @@
 	return 0;
 }
 
+extern spinlock_t modlist_lock;
+
 static inline unsigned long
 search_dbe_table(unsigned long addr)
 {
 	unsigned long ret;
 
+#ifndef CONFIG_MODULES
 	/* 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;
+	return ret;
+#else
+	unsigned long flags;
+
+	/* The kernel is the last "module" -- no need to treat it special.  */
+	struct module *mp;
+	struct archdata *ap;
+
+	spin_lock_irqsave(&modlist_lock, flags);
+	for (mp = module_list; mp != NULL; mp = mp->next) {
+		if (!mod_member_present(mp, archdata_end) ||
+        	    !mod_archdata_member_present(mp, struct archdata,
+						 dbe_table_end))
+			continue;
+		ap = (struct archdata *)(mod->archdata_start);
+
+		if (ap->dbe_table_start == NULL ||
+		    !(mp->flags & (MOD_RUNNING | MOD_INITIALIZING)))
+			continue;
+		ret = search_one_table(ap->dbe_table_start,
+				       ap->dbe_table_end - 1, addr);
+		if (ret)
+			break;
+	}
+	spin_unlock_irqrestore(&modlist_lock, flags);
+	return ret;
+#endif
 }
 
 void do_ibe(struct pt_regs *regs)
@@ -64,9 +94,43 @@
 	while(1);
 }
 
+static void dump_hub_information(unsigned long errst0, unsigned long errst1)
+{
+	static char *err_type[2][8] = {
+		{ NULL, "Uncached Partial Read PRERR", "DERR", "Read Timeout",
+		  NULL, NULL, NULL, NULL },
+		{ "WERR", "Uncached Partial Write", "PWERR", "Write Timeout",
+		  NULL, NULL, NULL, NULL }
+	};
+	int wrb = errst1 & PI_ERR_ST1_WRBRRB_MASK;
+
+	if (!(errst0 & PI_ERR_ST0_VALID_MASK)) {
+		printk("Hub does not contain valid error information\n");
+		return;
+	}
+
+	
+	printk("Hub has valid error information:\n");
+	if (errst0 & PI_ERR_ST0_OVERRUN_MASK)
+		printk("Overrun is set.  Error stack may contain additional "
+		       "information.\n");
+	printk("Hub error address is %08lx\n",
+	       (errst0 & PI_ERR_ST0_ADDR_MASK) >> (PI_ERR_ST0_ADDR_SHFT - 3));
+	printk("Incoming message command 0x%lx\n",
+	       (errst0 & PI_ERR_ST0_CMD_MASK) >> PI_ERR_ST0_CMD_SHFT);
+	printk("Supplemental field of incoming message is 0x%lx\n",
+	       (errst0 & PI_ERR_ST0_SUPPL_MASK) >> PI_ERR_ST0_SUPPL_SHFT);
+	printk("T5 Rn (for RRB only) is 0x%lx\n",
+	       (errst0 & PI_ERR_ST0_REQNUM_MASK) >> PI_ERR_ST0_REQNUM_SHFT);
+	printk("Error type is %s\n", err_type[wrb]
+	       [(errst0 & PI_ERR_ST0_TYPE_MASK) >> PI_ERR_ST0_TYPE_SHFT]
+		? : "invalid");
+}
+
 void do_dbe(struct pt_regs *regs)
 {
-	unsigned long fixup;
+	unsigned long fixup, errst0, errst1;
+	int cpu = LOCAL_HUB_L(PI_CPU_NUM);
 
 	fixup = search_dbe_table(regs->cp0_epc);
 	if (fixup) {
@@ -77,7 +141,12 @@
 		return;
 	}
 
-	printk("Got dbe at 0x%lx\n", regs->cp0_epc);
+	printk("Slice %c got dbe at 0x%lx\n", 'A' + cpu, regs->cp0_epc);
+	printk("Hub information:\n");
+	printk("ERR_INT_PEND = 0x%06lx\n", LOCAL_HUB_L(PI_ERR_INT_PEND));
+	errst0 = LOCAL_HUB_L(cpu ? PI_ERR_STATUS0_B : PI_ERR_STATUS0_A);
+	errst1 = LOCAL_HUB_L(cpu ? PI_ERR_STATUS1_B : PI_ERR_STATUS1_A);
+	dump_hub_information(errst0, errst1);
 	show_regs(regs);
 	dump_tlb_all();
 	while(1);
@@ -95,7 +164,7 @@
 	set_except_vector(7, handle_dbe);
 
 	LOCAL_HUB_S(PI_ERR_INT_PEND,
-	            cpu ? PI_ERR_CLEAR_ALL_A : PI_ERR_CLEAR_ALL_B);
+	            cpu ? PI_ERR_CLEAR_ALL_B : PI_ERR_CLEAR_ALL_A);
 	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 */
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/sgi-ip27/ip27-console.c linux/arch/mips64/sgi-ip27/ip27-console.c
--- v2.4.9/linux/arch/mips64/sgi-ip27/ip27-console.c	Tue Nov 28 21:42:04 2000
+++ linux/arch/mips64/sgi-ip27/ip27-console.c	Sun Sep  9 10:43:02 2001
@@ -2,6 +2,8 @@
  * This file 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) 2001 Ralf Baechle
  */
 #include <linux/init.h>
 #include <linux/console.h>
@@ -11,7 +13,6 @@
 #include <asm/sn/sn0/hub.h>
 #include <asm/sn/klconfig.h>
 #include <asm/sn/ioc3.h>
-#include <asm/sgialib.h>
 #include <asm/sn/sn_private.h>
 
 void prom_putchar(char c)
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/sgi-ip27/ip27-init.c linux/arch/mips64/sgi-ip27/ip27-init.c
--- v2.4.9/linux/arch/mips64/sgi-ip27/ip27-init.c	Sun Feb  4 21:48:46 2001
+++ linux/arch/mips64/sgi-ip27/ip27-init.c	Sun Sep  9 10:43:02 2001
@@ -1,3 +1,12 @@
+/*
+ * This file 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 - 2001 by Kanoj Sarcar (kanoj@sgi.com)
+ * Copyright (C) 2000 - 2001 by Silicon Graphics, Inc.
+ */
+
 #include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -23,14 +32,14 @@
 #include <asm/sn/sn_private.h>
 #include <asm/sn/sn0/ip27.h>
 #include <asm/sn/mapped_kernel.h>
+#include <asm/sn/sn0/addrs.h>
+#include <asm/sn/gda.h>
 
 #define CPU_NONE		(cpuid_t)-1
 
-#define	CPUMASK_CLRALL(p)	(p) = 0
-#define CPUMASK_SETB(p, bit)	(p) |= 1 << (bit)
-#define CPUMASK_CLRB(p, bit)	(p) &= ~(1ULL << (bit))
-#define CPUMASK_TSTB(p, bit)	((p) & (1ULL << (bit)))
-
+/*
+ * The following should work till 64 nodes, ie 128p SN0s.
+ */
 #define CNODEMASK_CLRALL(p)	(p) = 0
 #define CNODEMASK_TSTB(p, bit)	((p) & (1ULL << (bit)))
 #define CNODEMASK_SETB(p, bit)	((p) |= 1ULL << (bit))
@@ -42,11 +51,13 @@
 static spinlock_t hub_mask_lock = SPIN_LOCK_UNLOCKED;
 static cnodemask_t hub_init_mask;
 static atomic_t numstarted = ATOMIC_INIT(1);
+static int router_distance;
 nasid_t master_nasid = INVALID_NASID;
 
 cnodeid_t	nasid_to_compact_node[MAX_NASIDS];
 nasid_t		compact_to_nasid_node[MAX_COMPACT_NODES];
 cnodeid_t	cpuid_to_compact_node[MAXCPUS];
+char		node_distances[MAX_COMPACT_NODES][MAX_COMPACT_NODES];
 
 hubreg_t get_region(cnodeid_t cnode)
 {
@@ -89,9 +100,13 @@
 		return brd->brd_nasid;
 }
 
+/* Tweak this for maximum number of CPUs to activate */
+static int max_cpus = NR_CPUS;
+
 int do_cpumask(cnodeid_t cnode, nasid_t nasid, cpumask_t *boot_cpumask, 
 							int *highest)
 {
+	static int tot_cpus_found = 0;
 	lboard_t *brd;
 	klcpu_t *acpu;
 	int cpus_found = 0;
@@ -109,9 +124,11 @@
 			if (cpuid > *highest)
 				*highest = cpuid;
 			/* Only let it join in if it's marked enabled */
-			if (acpu->cpu_info.flags & KLINFO_ENABLE) {
+			if ((acpu->cpu_info.flags & KLINFO_ENABLE) &&
+						(tot_cpus_found != max_cpus)) {
 				CPUMASK_SETB(*boot_cpumask, cpuid);
 				cpus_found++;
+				tot_cpus_found++;
 			}
 			acpu = (klcpu_t *)find_component(brd, (klinfo_t *)acpu, 
 								KLSTRUCT_CPU);
@@ -172,6 +189,9 @@
 void mlreset (void)
 {
 	int i;
+	void init_topology_matrix(void);
+	void dump_topology(void);
+
 
 	master_nasid = get_nasid();
 	fine_mode = is_fine_dirmode();
@@ -184,6 +204,9 @@
 	maxcpus = cpu_node_probe(&boot_cpumask, &numnodes);
 	printk("Discovered %d cpus on %d nodes\n", maxcpus, numnodes);
 
+	init_topology_matrix();
+	dump_topology();
+
 	gen_region_mask(&region_mask, numnodes);
 	CNODEMASK_CLRALL(hub_init_mask);
 
@@ -534,3 +557,284 @@
 #else /* CONFIG_SMP */
 void cboot(void) {}
 #endif /* CONFIG_SMP */
+
+
+#define	rou_rflag	rou_flags
+
+void
+router_recurse(klrou_t *router_a, klrou_t *router_b, int depth)
+{
+	klrou_t *router;
+	lboard_t *brd;
+	int	port;
+
+	if (router_a->rou_rflag == 1)
+		return;
+
+	if (depth >= router_distance)
+		return;
+
+	router_a->rou_rflag = 1;
+
+	for (port = 1; port <= MAX_ROUTER_PORTS; port++) {
+		if (router_a->rou_port[port].port_nasid == INVALID_NASID)
+			continue;
+
+		brd = (lboard_t *)NODE_OFFSET_TO_K0(
+			router_a->rou_port[port].port_nasid,
+			router_a->rou_port[port].port_offset);
+
+		if (brd->brd_type == KLTYPE_ROUTER) {
+			router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), brd->brd_compts[0]);
+			if (router == router_b) {
+				if (depth < router_distance)
+					router_distance = depth;
+			}
+			else
+				router_recurse(router, router_b, depth + 1);
+		}
+	}
+
+	router_a->rou_rflag = 0;
+}
+
+int
+node_distance(nasid_t nasid_a, nasid_t nasid_b)
+{
+	nasid_t nasid;
+	cnodeid_t cnode;
+	lboard_t *brd, *dest_brd;
+	int port;
+	klrou_t *router, *router_a = NULL, *router_b = NULL;
+
+	/* Figure out which routers nodes in question are connected to */
+	for (cnode = 0; cnode < numnodes; cnode++) {
+		nasid = COMPACT_TO_NASID_NODEID(cnode);
+
+		if (nasid == -1) continue;
+
+		brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid),
+					KLTYPE_ROUTER);
+
+		if (!brd)
+			continue;
+
+		do {
+			if (brd->brd_flags & DUPLICATE_BOARD)
+				continue;
+
+			router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), brd->brd_compts[0]);
+			router->rou_rflag = 0;
+
+			for (port = 1; port <= MAX_ROUTER_PORTS; port++) {
+				if (router->rou_port[port].port_nasid == INVALID_NASID)
+					continue;
+
+				dest_brd = (lboard_t *)NODE_OFFSET_TO_K0(
+					router->rou_port[port].port_nasid,
+					router->rou_port[port].port_offset);
+
+				if (dest_brd->brd_type == KLTYPE_IP27) {
+					if (dest_brd->brd_nasid == nasid_a)
+						router_a = router;
+					if (dest_brd->brd_nasid == nasid_b)
+						router_b = router;
+				}
+			}
+			
+		} while ( (brd = find_lboard_class(KLCF_NEXT(brd), KLTYPE_ROUTER)) );
+	}
+
+	if (router_a == NULL) {
+		printk("node_distance: router_a NULL\n");
+		return -1;
+	}
+	if (router_b == NULL) {
+		printk("node_distance: router_b NULL\n");
+		return -1;
+	}
+
+	if (nasid_a == nasid_b)
+		return 0;
+
+	if (router_a == router_b)
+		return 1;
+
+	router_distance = 100;
+	router_recurse(router_a, router_b, 2);
+
+	return router_distance;
+}
+
+void
+init_topology_matrix(void)
+{
+	nasid_t nasid, nasid2;
+	cnodeid_t row, col;
+
+	for (row = 0; row < MAX_COMPACT_NODES; row++)
+		for (col = 0; col < MAX_COMPACT_NODES; col++)
+			node_distances[row][col] = -1;
+
+	for (row = 0; row < numnodes; row++) {
+		nasid = COMPACT_TO_NASID_NODEID(row);
+		for (col = 0; col < numnodes; col++) {
+			nasid2 = COMPACT_TO_NASID_NODEID(col);
+			node_distances[row][col] = node_distance(nasid, nasid2);
+		}
+	}
+}
+
+void
+dump_topology(void)
+{
+	nasid_t nasid;
+	cnodeid_t cnode;
+	lboard_t *brd, *dest_brd;
+	int port;
+	int router_num = 0;
+	klrou_t *router;
+	cnodeid_t row, col;
+
+	printk("************** Topology ********************\n");
+
+	printk("    ");
+	for (col = 0; col < numnodes; col++)
+		printk("%02d ", col);
+	printk("\n");
+	for (row = 0; row < numnodes; row++) {
+		printk("%02d  ", row);
+		for (col = 0; col < numnodes; col++)
+			printk("%2d ", node_distances[row][col]);
+		printk("\n");
+	}
+
+	for (cnode = 0; cnode < numnodes; cnode++) {
+		nasid = COMPACT_TO_NASID_NODEID(cnode);
+
+		if (nasid == -1) continue;
+
+		brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid),
+					KLTYPE_ROUTER);
+
+		if (!brd)
+			continue;
+
+		do {
+			if (brd->brd_flags & DUPLICATE_BOARD)
+				continue;
+			printk("Router %d:", router_num);
+			router_num++;
+
+			router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), brd->brd_compts[0]);
+
+			for (port = 1; port <= MAX_ROUTER_PORTS; port++) {
+				if (router->rou_port[port].port_nasid == INVALID_NASID)
+					continue;
+
+				dest_brd = (lboard_t *)NODE_OFFSET_TO_K0(
+					router->rou_port[port].port_nasid,
+					router->rou_port[port].port_offset);
+
+				if (dest_brd->brd_type == KLTYPE_IP27)
+					printk(" %d", dest_brd->brd_nasid);
+				if (dest_brd->brd_type == KLTYPE_ROUTER)
+					printk(" r");
+			}
+			printk("\n");
+			
+		} while ( (brd = find_lboard_class(KLCF_NEXT(brd), KLTYPE_ROUTER)) );
+	}
+}
+
+#if 0
+#define		brd_widgetnum	brd_slot
+#define NODE_OFFSET_TO_KLINFO(n,off)    ((klinfo_t*) TO_NODE_CAC(n,off))
+void
+dump_klcfg(void)
+{
+	cnodeid_t       cnode;
+	int i;
+	nasid_t         nasid;
+	lboard_t        *lbptr;
+	gda_t           *gdap;
+	
+	gdap = (gda_t *)GDA_ADDR(get_nasid());
+	if (gdap->g_magic != GDA_MAGIC) {
+		printk("dumpklcfg_cmd: Invalid GDA MAGIC\n");
+		return;
+	}
+
+	for (cnode = 0; cnode < MAX_COMPACT_NODES; cnode ++) {
+		nasid = gdap->g_nasidtable[cnode];
+
+		if (nasid == INVALID_NASID)
+			continue;
+
+		printk("\nDumpping klconfig Nasid %d:\n", nasid);
+	
+		lbptr = KL_CONFIG_INFO(nasid);
+
+		while (lbptr) {
+			printk("    %s, Nasid %d, Module %d, widget 0x%x, partition %d, NIC 0x%x lboard 0x%lx",
+				"board name here", /* BOARD_NAME(lbptr->brd_type), */
+				lbptr->brd_nasid, lbptr->brd_module, 
+				lbptr->brd_widgetnum,
+				lbptr->brd_partition, 
+				(lbptr->brd_nic), lbptr);
+			if (lbptr->brd_flags & DUPLICATE_BOARD)
+				printk(" -D");
+			printk("\n");
+			for (i = 0; i < lbptr->brd_numcompts; i++) {
+				klinfo_t *kli;
+				kli = NODE_OFFSET_TO_KLINFO(NASID_GET(lbptr), lbptr->brd_compts[i]);                       
+				printk("        type %2d, flags 0x%04x, diagval %3d, physid %4d, virtid %2d: %s\n", 
+					kli->struct_type, 
+					kli->flags,
+					kli->diagval,
+					kli->physid,
+					kli->virtid,
+					"comp. name here");
+					/* COMPONENT_NAME(kli->struct_type)); */
+			}
+			lbptr = KLCF_NEXT(lbptr);
+		}
+	}
+	printk("\n");
+
+	/* Useful to print router maps also */
+
+	for (cnode = 0; cnode < MAX_COMPACT_NODES; cnode ++) {
+		klrou_t *kr;
+		int i;
+
+        	nasid = gdap->g_nasidtable[cnode];
+        	if (nasid == INVALID_NASID)
+            		continue;
+        	lbptr = KL_CONFIG_INFO(nasid);
+
+        	while (lbptr) {
+			
+			lbptr = find_lboard_class(lbptr, KLCLASS_ROUTER);
+			if(!lbptr)
+				break;
+			if (!KL_CONFIG_DUPLICATE_BOARD(lbptr)) {
+				printk("%llx -> \n", lbptr->brd_nic);
+				kr = (klrou_t *)find_first_component(lbptr,
+					KLSTRUCT_ROU);
+				for (i = 1; i <= MAX_ROUTER_PORTS; i++) {
+					printk("[%d, %llx]; ",
+						kr->rou_port[i].port_nasid,
+						kr->rou_port[i].port_offset);
+				}
+				printk("\n");
+			}
+			lbptr = KLCF_NEXT(lbptr);
+        	}
+        	printk("\n");
+    	}
+
+	dump_topology();
+}
+#endif
+
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/sgi-ip27/ip27-irq-glue.S linux/arch/mips64/sgi-ip27/ip27-irq-glue.S
--- v2.4.9/linux/arch/mips64/sgi-ip27/ip27-irq-glue.S	Sat May 13 08:30:17 2000
+++ linux/arch/mips64/sgi-ip27/ip27-irq-glue.S	Sun Sep  9 10:43:02 2001
@@ -1,5 +1,4 @@
-/* $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.
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/sgi-ip27/ip27-irq.c linux/arch/mips64/sgi-ip27/ip27-irq.c
--- v2.4.9/linux/arch/mips64/sgi-ip27/ip27-irq.c	Fri Feb  9 11:29:44 2001
+++ linux/arch/mips64/sgi-ip27/ip27-irq.c	Sun Sep  9 10:43:02 2001
@@ -3,6 +3,7 @@
  *
  * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 1999 - 2001 Kanoj Sarcar
  */
 #include <linux/config.h>
 #include <linux/init.h>
@@ -25,6 +26,7 @@
 #include <asm/io.h>
 #include <asm/mipsregs.h>
 #include <asm/system.h>
+#include <asm/irq.h>
 
 #include <asm/ptrace.h>
 #include <asm/processor.h>
@@ -42,6 +44,10 @@
 #define DBG(x...)
 #endif
 
+/* These should die */
+unsigned char bus_to_wid[256];	/* widget id for linux pci bus */
+unsigned char bus_to_nid[256];	/* nasid for linux pci bus */
+unsigned char num_bridges;	/* number of bridges in the system */
 
 /*
  * Linux has a controller-independent x86 interrupt architecture.
@@ -67,11 +73,11 @@
 unsigned long spurious_count = 0;
 
 /*
- * we need to map irq's up to at least bit 7 of the INT_MASK0_A register
- * since bits 0-6 are pre-allocated for other purposes.
+ * There is a single intpend register per node, and we want to have
+ * distinct levels for intercpu intrs for both cpus A and B on a node.
  */
-#define IRQ_TO_SWLEVEL(cpu, i)	i + 7
-#define SWLEVEL_TO_IRQ(cpu, s)	s - 7
+int node_level_to_irq[MAX_COMPACT_NODES][PERNODE_LEVELS];
+
 /*
  * use these macros to get the encoded nasid and widget id
  * from the irq value
@@ -82,6 +88,41 @@
 #define WID_FROM_PCI_IRQ(i)		bus_to_wid[IRQ_TO_BUS(i)]
 #define	SLOT_FROM_PCI_IRQ(i)		irq_to_slot[i]
 
+static inline int alloc_level(cpuid_t cpunum, int irq)
+{
+	cnodeid_t nodenum = CPUID_TO_COMPACT_NODEID(cpunum);
+	int j = LEAST_LEVEL + 3;	/* resched & crosscall entries taken */
+
+	while (++j < PERNODE_LEVELS) {
+		if (node_level_to_irq[nodenum][j] == -1) {
+			node_level_to_irq[nodenum][j] = irq;
+			return j;
+		}
+	}
+	printk("Cpu %ld flooded with devices\n", cpunum);
+	while(1);
+	return -1;
+}
+
+static inline int find_level(cpuid_t *cpunum, int irq)
+{
+	int j;
+	cnodeid_t nodenum = INVALID_CNODEID;
+
+	while (++nodenum < MAX_COMPACT_NODES) {
+		j = LEAST_LEVEL + 3;	/* resched & crosscall entries taken */
+		while (++j < PERNODE_LEVELS)
+			if (node_level_to_irq[nodenum][j] == irq) {
+				*cpunum = 0;	/* XXX Fixme */
+				return(j);
+			}
+	}
+	printk("Could not identify cpu/level for irq %d\n", irq);
+	while(1);
+	return(-1);
+}
+
+
 void disable_irq(unsigned int irq_nr)
 {
 	panic("disable_irq() called ...");
@@ -146,7 +187,8 @@
 	}
 	irq_exit(thiscpu, irq);
 
-	/* unmasking and bottom half handling is done magically for us. */
+	if (softirq_pending(thiscpu))
+		do_softirq();
 }
 
 /*
@@ -196,7 +238,7 @@
 				swlevel = ms1bit(pend0);
 				LOCAL_HUB_CLR_INTR(swlevel);
 				/* "map" swlevel to irq */
-				irq = SWLEVEL_TO_IRQ(thiscpu, swlevel);
+				irq = LEVEL_TO_IRQ(thiscpu, swlevel);
 				do_IRQ(thiscpu, irq, regs);
 				/* clear bit in pend0 */
 				pend0 ^= 1ULL << swlevel;
@@ -227,7 +269,7 @@
 	 * "map" irq to a swlevel greater than 6 since the first 6 bits
 	 * of INT_PEND0 are taken
 	 */
-	swlevel = IRQ_TO_SWLEVEL(cpu, irq);
+	swlevel = alloc_level(cpu, irq);
 	intr_connect_level(cpu, swlevel);
 
 	bridge->b_int_addr[pin].addr = (0x20000 | swlevel | (master << 8));
@@ -254,6 +296,7 @@
 {
 	bridge_t *bridge;
 	int pin, swlevel;
+	cpuid_t cpu;
 
 	bridge = (bridge_t *) NODE_SWIN_BASE(NASID_FROM_PCI_IRQ(irq), 
 	                                     WID_FROM_PCI_IRQ(irq));
@@ -264,8 +307,9 @@
 	 * map irq to a swlevel greater than 6 since the first 6 bits
 	 * of INT_PEND0 are taken
 	 */
-	swlevel = IRQ_TO_SWLEVEL(cpu, irq);
-	intr_disconnect_level(smp_processor_id(), swlevel);
+	swlevel = find_level(&cpu, irq);
+	intr_disconnect_level(cpu, swlevel);
+	LEVEL_TO_IRQ(cpu, swlevel) = -1;
 
 	bridge->b_int_enable &= ~(1 << pin);
 	bridge->b_widget.w_tflush;                      /* Flush */
@@ -423,7 +467,6 @@
 
 	printk(" ]\nStack dumps:");
 	for(i = 0; i < smp_num_cpus; i++) {
-		unsigned long esp;
 		if (i == cpu)
 			continue;
 		printk("\nCPU %d:",i);
@@ -661,37 +704,50 @@
 #ifdef CONFIG_SMP
 #if (CPUS_PER_NODE == 2)
 	static int done = 0;
-	int irq;
 
 	/*
 	 * This is a hack till we have a pernode irqlist. Currently,
 	 * just have the master cpu set up the handlers for the per
 	 * cpu irqs.
 	 */
+	if (done == 0) {
+		int j;
 
-	irq = CPU_RESCHED_A_IRQ + cputoslice(cpu);
-	intr_connect_level(cpu, IRQ_TO_SWLEVEL(cpu, irq));
-	if (done == 0)
-	if (request_irq(irq, handle_resched_intr, 0, "resched", 0))
-		panic("intercpu intr unconnectible\n");
-	irq = CPU_CALL_A_IRQ + cputoslice(cpu);
-	intr_connect_level(cpu, IRQ_TO_SWLEVEL(cpu, irq));
-	if (done == 0)
-	if (request_irq(irq, smp_call_function_interrupt, 0,
-						"callfunc", 0))
-		panic("intercpu intr unconnectible\n");
-	/* HACK STARTS */
-	if (done)
-		return;
-	irq = CPU_RESCHED_A_IRQ + cputoslice(cpu) + 1;
-	if (request_irq(irq, handle_resched_intr, 0, "resched", 0))
-		panic("intercpu intr unconnectible\n");
-	irq = CPU_CALL_A_IRQ + cputoslice(cpu) + 1;
-	if (request_irq(irq, smp_call_function_interrupt, 0,
-						"callfunc", 0))
-		panic("intercpu intr unconnectible\n");
-	done = 1;
-	/* HACK ENDS */
+		if (request_irq(CPU_RESCHED_A_IRQ, handle_resched_intr, 
+							0, "resched", 0))
+			panic("intercpu intr unconnectible\n");
+		if (request_irq(CPU_RESCHED_B_IRQ, handle_resched_intr, 
+							0, "resched", 0))
+			panic("intercpu intr unconnectible\n");
+		if (request_irq(CPU_CALL_A_IRQ, smp_call_function_interrupt,
+							0, "callfunc", 0))
+			panic("intercpu intr unconnectible\n");
+		if (request_irq(CPU_CALL_B_IRQ, smp_call_function_interrupt,
+							0, "callfunc", 0))
+			panic("intercpu intr unconnectible\n");
+
+		for (j = 0; j < PERNODE_LEVELS; j++)
+			LEVEL_TO_IRQ(0, j) = -1;
+		LEVEL_TO_IRQ(0, FAST_IRQ_TO_LEVEL(CPU_RESCHED_A_IRQ)) = 
+							CPU_RESCHED_A_IRQ;
+		LEVEL_TO_IRQ(0, FAST_IRQ_TO_LEVEL(CPU_RESCHED_B_IRQ)) = 
+							CPU_RESCHED_B_IRQ;
+		LEVEL_TO_IRQ(0, FAST_IRQ_TO_LEVEL(CPU_CALL_A_IRQ)) = 
+							CPU_CALL_A_IRQ;
+		LEVEL_TO_IRQ(0, FAST_IRQ_TO_LEVEL(CPU_CALL_B_IRQ)) = 
+							CPU_CALL_B_IRQ;
+		for (j = 1; j < MAX_COMPACT_NODES; j++)
+			memcpy(&node_level_to_irq[j][0], 
+			&node_level_to_irq[0][0], 
+			sizeof(node_level_to_irq[0][0])*PERNODE_LEVELS);
+
+		done = 1;
+	}
+
+	intr_connect_level(cpu, FAST_IRQ_TO_LEVEL(CPU_RESCHED_A_IRQ + 
+							cputoslice(cpu)));
+	intr_connect_level(cpu, FAST_IRQ_TO_LEVEL(CPU_CALL_A_IRQ +
+							cputoslice(cpu)));
 #else /* CPUS_PER_NODE */
 #error Must redefine this for more than 2 CPUS.
 #endif /* CPUS_PER_NODE */
@@ -700,7 +756,9 @@
 
 void install_tlbintr(int cpu)
 {
+#if 0
 	int intr_bit = N_INTPEND_BITS + TLB_INTR_A + cputoslice(cpu);
 
 	intr_connect_level(cpu, intr_bit);
+#endif
 }
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/sgi-ip27/ip27-klconfig.c linux/arch/mips64/sgi-ip27/ip27-klconfig.c
--- v2.4.9/linux/arch/mips64/sgi-ip27/ip27-klconfig.c	Sun Jul  9 22:18:16 2000
+++ linux/arch/mips64/sgi-ip27/ip27-klconfig.c	Sun Sep  9 10:43:02 2001
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
  * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  */
@@ -57,6 +56,19 @@
 			return start;
 		start = KLCF_NEXT(start);
 	}
+	/* Didn't find it. */
+	return (lboard_t *)NULL;
+}
+
+lboard_t * find_lboard_class(lboard_t *start, unsigned char brd_type)
+{
+	/* Search all boards stored on this node. */
+	while (start) {
+		if (KLCLASS(start->brd_type) == KLCLASS(brd_type))
+			return start;
+		start = KLCF_NEXT(start);
+	}
+
 	/* Didn't find it. */
 	return (lboard_t *)NULL;
 }
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/sgi-ip27/ip27-klnuma.c linux/arch/mips64/sgi-ip27/ip27-klnuma.c
--- v2.4.9/linux/arch/mips64/sgi-ip27/ip27-klnuma.c	Tue Nov 28 21:42:04 2000
+++ linux/arch/mips64/sgi-ip27/ip27-klnuma.c	Sun Sep  9 10:43:02 2001
@@ -1,6 +1,7 @@
 /*
  * Ported from IRIX to Linux by Kanoj Sarcar, 06/08/00.
- * Copyright 2000 Silicon Graphics, Inc.
+ * Copyright 2000 - 2001 Silicon Graphics, Inc.
+ * Copyright 2000 - 2001 Kanoj Sarcar (kanoj@sgi.com)
  */
 #include <linux/config.h>
 #include <linux/init.h>
@@ -9,6 +10,7 @@
 #include <linux/string.h>
 
 #include <asm/page.h>
+#include <asm/smp.h>
 #include <asm/sn/types.h>
 #include <asm/sn/arch.h>
 #include <asm/sn/gda.h>
@@ -16,10 +18,6 @@
 #include <asm/sn/klkernvars.h>
 #include <asm/sn/mapped_kernel.h>
 #include <asm/sn/sn_private.h>
-
-#define CPUMASK_CLRALL(p)	(p) = 0
-#define CPUMASK_SETB(p, bit)	(p) |= 1 << (bit)
-#define CPUMASK_TSTB(p, bit)	((p) & (1ULL << (bit)))
 
 extern char _end;
 static cpumask_t ktext_repmask;
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/sgi-ip27/ip27-memory.c linux/arch/mips64/sgi-ip27/ip27-memory.c
--- v2.4.9/linux/arch/mips64/sgi-ip27/ip27-memory.c	Tue Nov 28 21:42:04 2000
+++ linux/arch/mips64/sgi-ip27/ip27-memory.c	Sun Sep  9 10:43:02 2001
@@ -20,6 +20,7 @@
 #include <asm/bootinfo.h>
 #include <asm/addrspace.h>
 #include <asm/pgtable.h>
+#include <asm/pgalloc.h>
 #include <asm/sn/types.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/klconfig.h>
@@ -227,15 +228,24 @@
 
 void __init paging_init(void)
 {
+	pmd_t *pmd = kpmdtbl;
+	pte_t *pte = kptbl;
+
 	cnodeid_t node;
 	unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
+	int i;
 
 	/* Initialize the entire pgd.  */
 	pgd_init((unsigned long)swapper_pg_dir);
 	pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table);
 	memset((void *)invalid_pte_table, 0, sizeof(pte_t) * PTRS_PER_PTE);
-	pmd_init((unsigned long)empty_bad_pmd_table, (unsigned long)empty_bad_page_table);
-	memset((void *)empty_bad_page_table, 0, sizeof(pte_t) * PTRS_PER_PTE);
+
+	/* This is for vmalloc  */
+	memset((void *)kptbl, 0, PAGE_SIZE << KPTBL_PAGE_ORDER);
+	memset((void *)kpmdtbl, 0, PAGE_SIZE);
+	pgd_set(swapper_pg_dir, kpmdtbl);
+	for (i = 0; i < (1 << KPTBL_PAGE_ORDER); pmd++,i++,pte+=PTRS_PER_PTE)
+		pmd_val(*pmd) = (unsigned long)pte;
 
 	for (node = 0; node < numnodes; node++) {
 		pfn_t start_pfn = slot_getbasepfn(node, 0);
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/sgi-ip27/ip27-pci-dma.c linux/arch/mips64/sgi-ip27/ip27-pci-dma.c
--- v2.4.9/linux/arch/mips64/sgi-ip27/ip27-pci-dma.c	Tue Nov 28 21:42:04 2000
+++ linux/arch/mips64/sgi-ip27/ip27-pci-dma.c	Sun Sep  9 10:43:02 2001
@@ -1,5 +1,4 @@
-/* $Id: ip27-pci-dma.c,v 1.1 2000/02/16 21:22:00 ralf Exp $
- *
+/*
  * Dynamic DMA mapping support.
  *
  * On the Origin there is dynamic DMA address translation for all PCI DMA.
@@ -52,4 +51,114 @@
 			 void *vaddr, dma_addr_t dma_handle)
 {
 	free_pages((unsigned long)vaddr, __get_order(size));
+}
+
+/*
+ * 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.
+ */
+dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size,
+                          int direction)
+{
+	if (direction == PCI_DMA_NONE)
+		BUG();
+
+	return (bus_to_baddr[hwdev->bus->number] | __pa(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.
+ */
+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.
+ */
+int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents,
+               int direction)
+{
+	int i;
+
+	if (direction == PCI_DMA_NONE)
+		BUG();
+
+	/* Make sure that gcc doesn't leave the empty loop body.  */
+	for (i = 0; i < nents; i++, sg++) {
+		sg->address = (char *)(bus_to_baddr[hwdev->bus->number] | __pa(sg->address));
+	}
+
+	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.
+ */
+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.
+ */
+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();
+}
+
+/*
+ * 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.
+ */
+void pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg,
+                     int nelems, int direction)
+{
+	if (direction == PCI_DMA_NONE)
+		BUG();
 }
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/sgi-ip27/ip27-pci.c linux/arch/mips64/sgi-ip27/ip27-pci.c
--- v2.4.9/linux/arch/mips64/sgi-ip27/ip27-pci.c	Tue Nov 28 21:42:04 2000
+++ linux/arch/mips64/sgi-ip27/ip27-pci.c	Sun Sep  9 10:43:02 2001
@@ -18,7 +18,7 @@
 /*
  * Max #PCI busses we can handle; ie, max #PCI bridges.
  */
-#define MAX_PCI_BUSSES		20
+#define MAX_PCI_BUSSES		40
 
 /*
  * Max #PCI devices (like scsi controllers) we handle on a bus.
@@ -55,8 +55,12 @@
 	bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id],        \
                                              bus_to_wid[bus_id]);       \
                                                                         \
-	/*if (dev->bus->number)			 */			\
-	/*	return PCIBIOS_DEVICE_NOT_FOUND; */			\
+	if (dev->vendor == PCI_VENDOR_ID_SGI				\
+	    && dev->device == PCI_DEVICE_ID_SGI_IOC3			\
+	    && ((where >= 0x14 && where < 0x40) || (where >= 0x48))) {	\
+		*value = 0;						\
+		return PCIBIOS_SUCCESSFUL;				\
+	}								\
 									\
 	__bit = (((where) & (bm)) << 3);				\
 	addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];	\
@@ -96,11 +100,9 @@
 	bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id],        \
                                              bus_to_wid[bus_id]);       \
                                                                         \
-	/* if (dev->bus->number)		 */			\
-	/* 	return PCIBIOS_DEVICE_NOT_FOUND; */			\
-									\
 	if (dev->vendor == PCI_VENDOR_ID_SGI				\
-	    && dev->device == PCI_DEVICE_ID_SGI_IOC3)			\
+	    && dev->device == PCI_DEVICE_ID_SGI_IOC3			\
+	    && ((where >= 0x14 && where < 0x40) || (where >= 0x48)))	\
 		return PCIBIOS_SUCCESSFUL;				\
 									\
 	__bit = (((where) & (bm)) << 3);				\
@@ -147,6 +149,7 @@
 	int	i;
 
 	ioport_resource.end = ~0UL;
+	iomem_resource.end = ~0UL;
 
 	for (i=0; i<num_bridges; i++) {
 		printk("PCI: Probing PCI hardware on host bus %2d.\n", i);
@@ -178,7 +181,7 @@
  * All observed requests have pin == 1. We could have a global here, that
  * gets incremented and returned every time - unfortunately, pci_map_irq
  * may be called on the same device over and over, and need to return the
- * same value. On o2000, pin can be 0 or 1, and PCI slots can be [0..7]. 
+ * same value. On O2000, pin can be 0 or 1, and PCI slots can be [0..7]. 
  *
  * A given PCI device, in general, should be able to intr any of the cpus
  * on any one of the hubs connected to its xbow.
@@ -186,25 +189,23 @@
 static int __init
 pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
 {
-	if ((dev->bus->number >= MAX_PCI_BUSSES) || (pin != 1) || \
-					(slot >= MAX_DEVICES_PER_PCIBUS)) {
-		printk("Increase supported PCI busses %d,%d,%d\n", \
-						dev->bus->number, slot, pin);
-		while(1);
-	}
+	if ((dev->bus->number >= MAX_PCI_BUSSES)
+	    || (pin != 1)
+	    || (slot >= MAX_DEVICES_PER_PCIBUS))
+		panic("Increase supported PCI busses %d,%d,%d\n",
+		      dev->bus->number, slot, pin);
 
 	/*
 	 * Already assigned? Then return previously assigned value ...
 	 */
 	if (irqstore[dev->bus->number][slot])
-		return(irqstore[dev->bus->number][slot]);
-	else {
-		irq_to_bus[lastirq] = dev->bus->number;
-		irq_to_slot[lastirq] = slot;
-		irqstore[dev->bus->number][slot] = lastirq;
-		lastirq++;
-		return (lastirq - 1);
-	}
+		return irqstore[dev->bus->number][slot];
+
+	irq_to_bus[lastirq] = dev->bus->number;
+	irq_to_slot[lastirq] = slot;
+	irqstore[dev->bus->number][slot] = lastirq;
+	lastirq++;
+	return lastirq - 1;
 }
 
 void __init
@@ -237,10 +238,10 @@
 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->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;
+	ranges->mem_end   -= bus->resource[1]->start;
 }
 
 int __init
@@ -255,6 +256,11 @@
 {
 }
 
+unsigned __init int pcibios_assign_all_busses(void)
+{
+	return 0;
+}
+
 char * __init
 pcibios_setup(char *str)
 {
@@ -263,19 +269,23 @@
 	return str;
 }
 
+/*
+ * Device might live on a subordinate PCI bus.  XXX Walk up the chain of buses
+ * to find the slot number in sense of the bridge device register.
+ * XXX This also means multiple devices might rely on conflicting bridge
+ * settings.
+ */
+
 static void __init
 pci_disable_swapping(struct pci_dev *dev)
 {
 	unsigned int bus_id = (unsigned) dev->bus->number;
 	bridge_t *bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id],
-				     bus_to_wid[bus_id]);
+	                                               bus_to_wid[bus_id]);
 	int		slot = PCI_SLOT(dev->devfn);
-	bridgereg_t 	devreg;
-
-	devreg = bridge->b_device[slot].reg;
-	devreg &= ~BRIDGE_DEV_SWAP_DIR;		/* turn off byte swapping */
-	bridge->b_device[slot].reg = devreg;
 
+	/* Turn off byte swapping */
+	bridge->b_device[slot].reg &= ~BRIDGE_DEV_SWAP_DIR;
 	bridge->b_widget.w_tflush;		/* Flush */
 }
 
@@ -284,56 +294,25 @@
 {
 	unsigned int bus_id = (unsigned) dev->bus->number;
 	bridge_t *bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id],
-				     bus_to_wid[bus_id]);
+	                                               bus_to_wid[bus_id]);
 	int		slot = PCI_SLOT(dev->devfn);
-	bridgereg_t 	devreg;
-
-	devreg = bridge->b_device[slot].reg;
-	devreg |= BRIDGE_DEV_SWAP_DIR;		/* turn on byte swapping */
-	bridge->b_device[slot].reg = devreg;
 
+	/* Turn on byte swapping */
+	bridge->b_device[slot].reg |= BRIDGE_DEV_SWAP_DIR;
 	bridge->b_widget.w_tflush;		/* Flush */
 }
 
 static void __init
 pci_fixup_ioc3(struct pci_dev *d)
 {
-	unsigned int bus_id = (unsigned) d->bus->number;
-	int i;
+	unsigned long bus_id = (unsigned) d->bus->number;
 
-	/* 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 IOC3 device %s\n", d->slot_name);
 
 	d->resource[0].start |= NODE_OFFSET(bus_to_nid[bus_id]);
-	d->resource[0].end |= NODE_OFFSET(bus_to_nid[bus_id]);
-
-	for (i = 1; i <= PCI_ROM_RESOURCE; i++) {
-		d->resource[i].start = 0UL;
-		d->resource[i].end = 0UL;
-		d->resource[i].flags = 0UL;
-	}
+	d->resource[0].end   |= NODE_OFFSET(bus_to_nid[bus_id]);
 
 	pci_disable_swapping(d);
-
-	/*
-	 * The serial driver will try to probe for serial ports
-	 * later on. MENET boards dbe out unrecoverably on sio space
-	 * access to the 4th ioc3. (The first 3 iocs work okay, they
-	 * have kbd/ms ports; all have ethernet ports). Catch this
-	 * case now and disable the serial driver from looking at 
-	 * these ioc3s. Identify MENET cards by seeing if an ioc3 is
-	 * at slot 3.
-	 */
-	d->subsystem_vendor = 0xFF00;
-	if (PCI_SLOT(d->devfn) == 3) {
-		struct list_head *p;
-		list_for_each(p, &d->bus->devices) {
-			list_entry(p, struct pci_dev, bus_list)->subsystem_vendor = 0;
-		}
-	}
 }
 
 static void __init
@@ -344,7 +323,8 @@
 	d->resource[0].start |= ((unsigned long)(bus_to_nid[d->bus->number])<<32);
 	printk("PCI: Fixing isp1020 in [bus:slot.fn] %s\n", d->slot_name);
 
-	/* Configure device to allow bus mastering, i/o and memory mapping. 
+	/*
+	 * Configure device to allow bus mastering, i/o and memory mapping. 
 	 * Older qlogicisp driver expects to have the IO space enable 
 	 * bit set. Things stop working if we program the controllers as not 
 	 * having PCI_COMMAND_MEMORY, so we have to fudge the mem_flags.
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/sgi-ip27/ip27-setup.c linux/arch/mips64/sgi-ip27/ip27-setup.c
--- v2.4.9/linux/arch/mips64/sgi-ip27/ip27-setup.c	Tue Nov 28 21:42:04 2000
+++ linux/arch/mips64/sgi-ip27/ip27-setup.c	Sun Sep  9 10:43:02 2001
@@ -14,6 +14,7 @@
 #include <linux/spinlock.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
+#include <asm/io.h>
 #include <asm/sn/types.h>
 #include <asm/sn/sn0/addrs.h>
 #include <asm/sn/sn0/hubni.h>
@@ -39,6 +40,7 @@
 #define DBG(x...)
 #endif
 
+unsigned long mips_io_port_base = IO_BASE;
 
 /*
  * get_nasid() returns the physical node id number of the caller.
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/sgi-ip27/ip27-timer.c linux/arch/mips64/sgi-ip27/ip27-timer.c
--- v2.4.9/linux/arch/mips64/sgi-ip27/ip27-timer.c	Tue Nov 28 21:42:04 2000
+++ linux/arch/mips64/sgi-ip27/ip27-timer.c	Sun Sep  9 10:43:02 2001
@@ -145,6 +145,9 @@
         }
 
 	write_unlock(&xtime_lock);
+
+	if (softirq_pending(cpu))
+		do_softirq();
 }
 
 unsigned long inline do_gettimeoffset(void)
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/sgi-ip32/Makefile linux/arch/mips64/sgi-ip32/Makefile
--- v2.4.9/linux/arch/mips64/sgi-ip32/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/sgi-ip32/Makefile	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,27 @@
+#
+# Makefile for the SGI 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...
+
+.S.s:
+	$(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+	$(CC) $(CFLAGS) -c $< -o $*.o
+
+O_TARGET := ip32-kern.a
+
+all: ip32-kern.a ip32-irq-glue.o
+
+obj-y	+= ip32-irq.o ip32-rtc.o ip32-setup.o ip32-irq-glue.o \
+	 ip32-berr.o ip32-timer.o crime.o
+
+ifdef CONFIG_PCI
+obj-y   += ip32-pci.o ip32-pci-dma.o
+endif
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/sgi-ip32/crime.c linux/arch/mips64/sgi-ip32/crime.c
--- v2.4.9/linux/arch/mips64/sgi-ip32/crime.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/sgi-ip32/crime.c	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,50 @@
+/*
+ * This file 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) 2001 Keith M Wesolowski
+ */
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <asm/ip32/crime.h>
+#include <asm/ptrace.h>
+#include <asm/promlib.h>
+
+void __init crime_init (void)
+{
+	u64 id = crime_read_64 (CRIME_ID);
+	u64 rev = id & CRIME_ID_REV;
+
+	id = (id & CRIME_ID_IDBITS) >> 4;
+
+	printk ("CRIME id %1lx rev %ld detected at %016lx\n", id, rev,
+		(unsigned long) CRIME_BASE);
+}
+
+/* XXX Like on Sun, these give us various useful information to printk. */
+void crime_memerr_intr (unsigned int irq, void *dev_id, struct pt_regs *regs)
+{
+	u64 memerr = crime_read_64 (CRIME_MEM_ERROR_STAT);
+	u64 addr = crime_read_64 (CRIME_MEM_ERROR_ADDR);
+	memerr &= CRIME_MEM_ERROR_STAT_MASK;
+	
+	printk ("CRIME memory error at physaddr 0x%08lx status %08lx\n",
+		addr << 2, memerr);
+
+	crime_write_64 (CRIME_MEM_ERROR_STAT, 0);
+}
+
+void crime_cpuerr_intr (unsigned int irq, void *dev_id, struct pt_regs *regs)
+{
+	u64 cpuerr = crime_read_64 (CRIME_CPU_ERROR_STAT);
+	u64 addr = crime_read_64 (CRIME_CPU_ERROR_ADDR);
+	cpuerr &= CRIME_CPU_ERROR_MASK;
+	addr <<= 2UL;
+
+	printk ("CRIME CPU interface error detected at %09lx status %08lx\n",
+		addr, cpuerr);
+
+	crime_write_64 (CRIME_CPU_ERROR_STAT, 0);
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/sgi-ip32/ip32-berr.c linux/arch/mips64/sgi-ip32/ip32-berr.c
--- v2.4.9/linux/arch/mips64/sgi-ip32/ip32-berr.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/sgi-ip32/ip32-berr.c	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,97 @@
+/*
+ * This file 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>
+
+/* XXX I have no idea what this does --kmw */
+
+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
+	   O2, so this here is needed to make the kernel link.  */
+	get_dbe(dummy, (int *)KSEG0);
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/sgi-ip32/ip32-irq-glue.S linux/arch/mips64/sgi-ip32/ip32-irq-glue.S
--- v2.4.9/linux/arch/mips64/sgi-ip32/ip32-irq-glue.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/sgi-ip32/ip32-irq-glue.S	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,87 @@
+/*
+ * Low level interrupt handler for the SGI O2 aka IP32 aka Moosehead
+ *
+ * This file 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 Harald Koerfgen
+ * Copyright (C) 2001 Keith M Wesolowski
+ */
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+#include <asm/addrspace.h>
+#include <asm/ip32/ip32_ints.h>
+
+		.text
+		.set    noreorder
+		.set    noat
+		.align  5
+		NESTED(ip32_handle_int, PT_SIZE, ra)
+		.set    noat
+		SAVE_ALL
+		CLI			# TEST: interrupts should be off
+		.set    at
+		.set    noreorder
+
+		mfc0	s0,CP0_CAUSE
+
+		andi	t1, s0, IE_IRQ0
+		bnez	t1, handle_irq0
+		 andi	t1, s0, IE_IRQ1
+		bnez	t1, handle_irq1
+		 andi	t1, s0, IE_IRQ2
+		bnez	t1, handle_irq2
+		 andi	t1, s0, IE_IRQ3
+		bnez	t1, handle_irq3
+		 andi	t1, s0, IE_IRQ4
+		bnez	t1, handle_irq4
+		 andi	t1, s0, IE_IRQ5
+		bnez	t1, handle_irq5
+		 nop
+
+		/* Either someone has triggered the "software interrupts"
+		 * or we lost an interrupt somehow.  Ignore it.
+		 */
+		j	ret_from_irq
+		 nop
+
+handle_irq0:
+		jal	ip32_irq0
+		 move	a0, sp
+		j	ret_from_irq
+		 nop
+
+handle_irq1:
+		jal	ip32_irq1
+		 move	a0, sp
+		j	ret_from_irq
+		 nop
+
+handle_irq2:
+		jal	ip32_irq2
+		 move	a0, sp
+		j	ret_from_irq
+		 nop
+
+handle_irq3:
+		jal	ip32_irq3
+		 move	a0, sp
+		j	ret_from_irq
+		 nop
+
+handle_irq4:
+		jal	ip32_irq4
+		 move	a0, sp
+		j	ret_from_irq
+		 nop
+
+handle_irq5:
+		jal	ip32_irq5
+		move	a0, sp
+		j	ret_from_irq
+		 nop
+
+		END(ip32_handle_int)
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/sgi-ip32/ip32-irq.c linux/arch/mips64/sgi-ip32/ip32-irq.c
--- v2.4.9/linux/arch/mips64/sgi-ip32/ip32-irq.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/sgi-ip32/ip32-irq.c	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,556 @@
+/*
+ * Code to handle IP32 IRQs
+ *
+ * This file 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 Harald Koerfgen
+ * Copyright (C) 2001 Keith M Wesolowski
+ */
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/bitops.h>
+
+#include <asm/bitops.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/ip32/ip32_ints.h>
+#include <asm/ip32/crime.h>
+#include <asm/ip32/mace.h>
+#include <asm/signal.h>
+
+#undef DEBUG_IRQ
+#ifdef DEBUG_IRQ
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+/* O2 irq map
+ *
+ * IP0 -> software (ignored)
+ * IP1 -> software (ignored)
+ * IP2 -> (irq0) C crime 1.1 all interrupts; crime 1.5 ???
+ * IP3 -> (irq1) X unknown
+ * IP4 -> (irq2) X unknown
+ * IP5 -> (irq3) X unknown
+ * IP6 -> (irq4) X unknown
+ * IP7 -> (irq5) 0 CPU count/compare timer (system timer)
+ *
+ * crime: (C)
+ *
+ * CRIME_INT_STAT 31:0:
+ *
+ * 0 -> 1 Video in 1
+ * 1 -> 2 Video in 2
+ * 2 -> 3 Video out
+ * 3 -> 4 Mace ethernet
+ * 4 -> S  SuperIO sub-interrupt
+ * 5 -> M  Miscellaneous sub-interrupt
+ * 6 -> A  Audio sub-interrupt
+ * 7 -> 8  PCI bridge errors
+ * 8 -> 9  PCI SCSI aic7xxx 0
+ * 9 -> 10  PCI SCSI aic7xxx 1
+ * 10 -> 11 PCI slot 0
+ * 11 -> 12 unused (PCI slot 1)
+ * 12 -> 13 unused (PCI slot 2)
+ * 13 -> 14 unused (PCI shared 0)
+ * 14 -> 15 unused (PCI shared 1)
+ * 15 -> 16 unused (PCI shared 2)
+ * 16 -> 17 GBE0 (E)
+ * 17 -> 18 GBE1 (E)
+ * 18 -> 19 GBE2 (E)
+ * 19 -> 20 GBE3 (E)
+ * 20 -> 21 CPU errors
+ * 21 -> 22 Memory errors
+ * 22 -> 23 RE empty edge (E)
+ * 23 -> 24 RE full edge (E)
+ * 24 -> 25 RE idle edge (E)
+ * 25 -> 26 RE empty level
+ * 26 -> 27 RE full level
+ * 27 -> 28 RE idle level
+ * 28 -> 29  unused (software 0) (E)
+ * 29 -> 30  unused (software 1) (E)
+ * 30 -> 31  unused (software 2) - crime 1.5 CPU SysCorError (E)
+ * 31 -> 32 VICE
+ *
+ * S, M, A: Use the MACE ISA interrupt register
+ * MACE_ISA_INT_STAT 31:0
+ *
+ * 0-7 -> 33-40 Audio
+ * 8 -> 41 RTC
+ * 9 -> 42 Keyboard
+ * 10 -> X Keyboard polled
+ * 11 -> 44 Mouse
+ * 12 -> X Mouse polled
+ * 13-15 -> 46-48 Count/compare timers
+ * 16-19 -> 49-52 Parallel (16 E)
+ * 20-25 -> 53-58 Serial 1 (22 E)
+ * 26-31 -> 59-64 Serial 2 (28 E)
+ *
+ * Note that this means IRQs 5-7, 43, and 45 do not exist.  This is a
+ * different IRQ map than IRIX uses, but that's OK as Linux irq handling
+ * is quite different anyway.
+ */
+
+/* Some initial interrupts to set up */
+extern void crime_memerr_intr (unsigned int irq, void *dev_id,
+			       struct pt_regs *regs);
+extern void crime_cpuerr_intr (unsigned int irq, void *dev_id,
+			       struct pt_regs *regs);
+
+struct irqaction memerr_irq = { crime_memerr_intr, SA_INTERRUPT,
+			       0, "CRIME memory error", NULL,
+			       NULL };
+struct irqaction cpuerr_irq = { crime_cpuerr_intr, SA_INTERRUPT,
+			       0, "CRIME CPU error", NULL,
+			       NULL };
+
+unsigned long spurious_count = 0;
+extern void ip32_handle_int (void);
+extern void do_IRQ (unsigned int irq, struct pt_regs *regs);
+
+/* For interrupts wired from a single device to the CPU.  Only the clock
+ * uses this it seems, which is IRQ 0 and IP7.
+ */
+
+static void enable_cpu_irq (unsigned int irq)
+{
+	set_cp0_status (STATUSF_IP7);
+}
+
+static unsigned int startup_cpu_irq (unsigned int irq) {
+	enable_cpu_irq (irq);
+	return 0;
+}
+
+static void disable_cpu_irq (unsigned int irq)
+{
+	clear_cp0_status (STATUSF_IP7);
+}
+
+static void end_cpu_irq (unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_cpu_irq (irq);
+}
+
+#define shutdown_cpu_irq disable_cpu_irq
+#define mask_and_ack_cpu_irq disable_cpu_irq
+
+static struct hw_interrupt_type ip32_cpu_interrupt = {
+	"IP32 CPU",
+	startup_cpu_irq,
+	shutdown_cpu_irq,
+	enable_cpu_irq,
+	disable_cpu_irq,
+	mask_and_ack_cpu_irq,
+	end_cpu_irq,
+	NULL
+};
+
+/*
+ * This is for pure CRIME interrupts - ie not MACE.  The advantage?
+ * We get to split the register in half and do faster lookups.
+ */
+
+static void enable_crime_irq (unsigned int irq)
+{
+	u64 crime_mask;
+	unsigned long flags;
+
+	save_and_cli (flags);
+	crime_mask = crime_read_64 (CRIME_INT_MASK);
+	crime_mask |= 1 << (irq - 1);
+	crime_write_64 (CRIME_INT_MASK, crime_mask);
+	restore_flags (flags);
+}
+
+static unsigned int startup_crime_irq (unsigned int irq)
+{
+	enable_crime_irq (irq);
+	return 0; /* This is probably not right; we could have pending irqs */
+}
+
+static void disable_crime_irq (unsigned int irq)
+{
+	u64 crime_mask;
+	unsigned long flags;
+
+	save_and_cli (flags);
+	crime_mask = crime_read_64 (CRIME_INT_MASK);
+	crime_mask &= ~(1 << (irq - 1));
+	crime_write_64 (CRIME_INT_MASK, crime_mask);
+	restore_flags (flags);
+}
+
+static void mask_and_ack_crime_irq (unsigned int irq)
+{
+	u64 crime_mask;
+	unsigned long flags;
+
+	/* Edge triggered interrupts must be cleared. */
+	if ((irq <= CRIME_GBE0_IRQ && irq >= CRIME_GBE3_IRQ)
+	    || (irq <= CRIME_RE_EMPTY_E_IRQ && irq >= CRIME_RE_IDLE_E_IRQ)
+	    || (irq <= CRIME_SOFT0_IRQ && irq >= CRIME_SOFT2_IRQ)) {
+		save_and_cli (flags);
+		crime_mask = crime_read_64 (CRIME_HARD_INT);
+		crime_mask &= ~(1 << (irq - 1));
+		crime_write_64 (CRIME_HARD_INT, crime_mask);
+		restore_flags (flags);
+	}
+	disable_crime_irq (irq);
+}
+	
+static void end_crime_irq (unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_crime_irq (irq);
+}
+
+#define shutdown_crime_irq disable_crime_irq
+
+static struct hw_interrupt_type ip32_crime_interrupt = {
+	"IP32 CRIME",
+	startup_crime_irq,
+	shutdown_crime_irq,
+	enable_crime_irq,
+	disable_crime_irq,
+	mask_and_ack_crime_irq,
+	end_crime_irq,
+	NULL
+};
+
+/* This is for MACE PCI interrupts.  We can decrease bus traffic by masking
+ * as close to the source as possible.  This also means we can take the
+ * next chunk of the CRIME register in one piece.
+ */
+
+static void enable_macepci_irq (unsigned int irq)
+{
+	u32 mace_mask;
+	u64 crime_mask;
+	unsigned long flags;
+
+	save_and_cli (flags);
+	mace_mask = mace_read_32 (MACEPCI_CONTROL);
+	mace_mask |= MACEPCI_CONTROL_INT (irq - 9);
+	mace_write_32 (MACEPCI_CONTROL, mace_mask);
+	/* In case the CRIME interrupt isn't enabled, we must enable it;
+	 * however, we never disable interrupts at that level.
+	 */
+	crime_mask = crime_read_64 (CRIME_INT_MASK);
+	crime_mask |= 1 << (irq - 1);
+	crime_write_64 (CRIME_INT_MASK, crime_mask);
+	restore_flags (flags);
+}
+
+static unsigned int startup_macepci_irq (unsigned int irq) {
+	enable_macepci_irq (irq);
+	return 0; /* XXX */
+}
+
+static void disable_macepci_irq (unsigned int irq)
+{
+	u32 mace_mask;
+	unsigned long flags;
+
+	save_and_cli (flags);
+	mace_mask = mace_read_32 (MACEPCI_CONTROL);
+	mace_mask &= ~MACEPCI_CONTROL_INT (irq - 9);
+	mace_write_32 (MACEPCI_CONTROL, mace_mask);
+	restore_flags (flags);
+}
+
+static void end_macepci_irq (unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_macepci_irq (irq);
+}
+
+#define shutdown_macepci_irq disable_macepci_irq
+#define mask_and_ack_macepci_irq disable_macepci_irq
+
+static struct hw_interrupt_type ip32_macepci_interrupt = {
+	"IP32 MACE PCI",
+	startup_macepci_irq,
+	shutdown_macepci_irq,
+	enable_macepci_irq,
+	disable_macepci_irq,
+	mask_and_ack_macepci_irq,
+	end_macepci_irq,
+	NULL
+};
+
+/* This is used for MACE ISA interrupts.  That means bits 4-6 in the
+ * CRIME register.
+ */
+
+static void enable_maceisa_irq (unsigned int irq)
+{
+	u64 crime_mask;
+	u32 mace_mask;
+	unsigned int crime_int = 0;
+	unsigned long flags;
+
+	DBG ("maceisa enable: %u\n", irq);
+	
+	switch (irq) {
+	case MACEISA_AUDIO_SW_IRQ ... MACEISA_AUDIO3_MERR_IRQ:
+		crime_int = MACE_AUDIO_INT;
+		break;
+	case MACEISA_RTC_IRQ ... MACEISA_TIMER2_IRQ:
+		crime_int = MACE_MISC_INT;
+		break;
+	case MACEISA_PARALLEL_IRQ ... MACEISA_SERIAL2_RDMAOR_IRQ:
+		crime_int = MACE_SUPERIO_INT;
+		break;
+	}
+	DBG ("crime_int %016lx enabled\n", crime_int);
+	save_and_cli (flags);
+	crime_mask = crime_read_64 (CRIME_INT_MASK);
+	crime_mask |= crime_int;
+	crime_write_64 (CRIME_INT_MASK, crime_mask);
+	mace_mask = mace_read_32 (MACEISA_INT_MASK);
+	mace_mask |= 1 << (irq - 33);
+	mace_write_32 (MACEISA_INT_MASK, mace_mask);
+	restore_flags (flags);
+}
+
+static unsigned int startup_maceisa_irq (unsigned int irq) {
+	enable_maceisa_irq (irq);
+	return 0;
+}
+
+static void disable_maceisa_irq (unsigned int irq)
+{
+	u32 mace_mask;
+	unsigned long flags;
+
+	save_and_cli (flags);
+	mace_mask = mace_read_32 (MACEISA_INT_MASK);
+	mace_mask &= ~(1 << (irq - 33));
+	mace_write_32 (MACEISA_INT_MASK, mace_mask);
+	restore_flags (flags);
+}
+
+static void mask_and_ack_maceisa_irq (unsigned int irq)
+{
+	u32 mace_mask;
+	unsigned long flags;
+
+	switch (irq) {
+	case MACEISA_PARALLEL_IRQ:
+	case MACEISA_SERIAL1_TDMAPR_IRQ:
+	case MACEISA_SERIAL2_TDMAPR_IRQ:
+		save_and_cli (flags);
+		mace_mask = mace_read_32 (MACEISA_INT_STAT);
+		mace_mask &= ~(1 << (irq - 33));
+		mace_write_32 (MACEISA_INT_STAT, mace_mask);
+		restore_flags (flags);
+		break;
+	}
+	disable_maceisa_irq (irq);
+}
+
+static void end_maceisa_irq (unsigned irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_maceisa_irq (irq);
+}
+
+#define shutdown_maceisa_irq disable_maceisa_irq
+
+static struct hw_interrupt_type ip32_maceisa_interrupt = {
+	"IP32 MACE ISA",
+	startup_maceisa_irq,
+	shutdown_maceisa_irq,
+	enable_maceisa_irq,
+	disable_maceisa_irq,
+	mask_and_ack_maceisa_irq,
+	end_maceisa_irq,
+	NULL
+};
+
+/* This is used for regular non-ISA, non-PCI MACE interrupts.  That means
+ * bits 0-3 and 7 in the CRIME register.
+ */
+
+static void enable_mace_irq (unsigned int irq)
+{
+	u64 crime_mask;
+	unsigned long flags;
+
+	save_and_cli (flags);
+	crime_mask = crime_read_64 (CRIME_INT_MASK);
+	crime_mask |= 1 << (irq - 1);
+	crime_write_64 (CRIME_INT_MASK, crime_mask);
+	restore_flags (flags);
+}
+
+static unsigned int startup_mace_irq (unsigned int irq)
+{
+	enable_mace_irq (irq);
+	return 0;
+}
+
+static void disable_mace_irq (unsigned int irq)
+{
+	u64 crime_mask;
+	unsigned long flags;
+
+	save_and_cli (flags);
+	crime_mask = crime_read_64 (CRIME_INT_MASK);
+	crime_mask &= ~(1 << (irq - 1));
+	crime_write_64 (CRIME_INT_MASK, crime_mask);
+	restore_flags (flags);
+}
+
+static void end_mace_irq (unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_mace_irq (irq);
+}
+
+#define shutdown_mace_irq disable_mace_irq
+#define mask_and_ack_mace_irq disable_mace_irq
+
+static struct hw_interrupt_type ip32_mace_interrupt = {
+	"IP32 MACE",
+	startup_mace_irq,
+	shutdown_mace_irq,
+	enable_mace_irq,
+	disable_mace_irq,
+	mask_and_ack_mace_irq,
+	end_mace_irq,
+	NULL
+};
+
+static void ip32_unknown_interrupt (struct pt_regs *regs)
+{
+	u64 crime;
+	u32 mace;
+	
+	printk ("Unknown interrupt occurred!\n");
+	printk ("cp0_status: %08x\tcp0_cause: %08x\n",
+		read_32bit_cp0_register (CP0_STATUS),
+		read_32bit_cp0_register (CP0_CAUSE));
+	crime = crime_read_64 (CRIME_INT_MASK);
+	printk ("CRIME interrupt mask: %016lx\n", crime);
+	crime = crime_read_64 (CRIME_INT_STAT);
+	printk ("CRIME interrupt status: %016lx\n", crime);
+	crime = crime_read_64 (CRIME_HARD_INT);
+	printk ("CRIME hardware interrupt register: %016lx\n", crime);
+	mace = mace_read_32 (MACEISA_INT_MASK);
+	printk ("MACE ISA interrupt mask: %08x\n", mace);
+	mace = mace_read_32 (MACEISA_INT_STAT);
+	printk ("MACE ISA interrupt status: %08x\n", mace);
+	mace = mace_read_32 (MACEPCI_CONTROL);
+	printk ("MACE PCI control register: %08x\n", mace);
+
+	printk ("Register dump:\n");
+	show_regs (regs);
+
+	printk ("Please mail this report to linux-mips@oss.sgi.com\n");
+	printk ("Spinning...");
+	while (1) ;
+}
+
+void __init ip32_irq_init(void)
+{
+	unsigned int irq;
+	extern void init_generic_irq (void);
+	
+	/* Install our interrupt handler, then clear and disable all
+	 * CRIME and MACE interrupts.
+	 */
+	crime_write_64 (CRIME_INT_MASK, 0);
+	crime_write_64 (CRIME_HARD_INT, 0);
+	crime_write_64 (CRIME_SOFT_INT, 0);
+	mace_write_32 (MACEISA_INT_STAT, 0);
+	mace_write_32 (MACEISA_INT_MASK, 0);
+	set_except_vector(0, ip32_handle_int);
+
+	init_generic_irq ();
+
+	for (irq = 0; irq <= IP32_IRQ_MAX; irq++) {
+		hw_irq_controller *controller;
+
+		if (irq == CLOCK_IRQ)
+			controller = &ip32_cpu_interrupt;
+		else if (irq <= MACE_PCI_BRIDGE_IRQ && irq >= MACE_VID_IN1_IRQ)
+			controller = &ip32_mace_interrupt;
+		else if (irq <= MACEPCI_SHARED2_IRQ && irq >= MACEPCI_SCSI0_IRQ)
+			controller = &ip32_macepci_interrupt;
+		else if (irq <= CRIME_VICE_IRQ && irq >= CRIME_GBE0_IRQ)
+			controller = &ip32_crime_interrupt;
+		else
+			controller = &ip32_maceisa_interrupt;
+
+		irq_desc[irq].status = IRQ_DISABLED;
+		irq_desc[irq].action = 0;
+		irq_desc[irq].depth = 0;
+		irq_desc[irq].handler = controller;
+	}
+	setup_irq (CRIME_MEMERR_IRQ, &memerr_irq);
+	setup_irq (CRIME_CPUERR_IRQ, &cpuerr_irq);
+}
+
+/* CRIME 1.1 appears to deliver all interrupts to this one pin. */
+void ip32_irq0 (struct pt_regs *regs)
+{
+	u64 crime_int = crime_read_64 (CRIME_INT_STAT);
+	int irq = 0;
+	
+	if (crime_int & CRIME_MACE_INT_MASK) {
+		crime_int &= CRIME_MACE_INT_MASK;
+		irq = ffs (crime_int);
+	} else if (crime_int & CRIME_MACEISA_INT_MASK) {
+		u32 mace_int;
+		mace_int = mace_read_32 (MACEISA_INT_STAT);
+		if (mace_int == 0)
+			irq = 0;
+		else
+			irq = ffs (mace_int) + 32;
+	} else if (crime_int & CRIME_MACEPCI_INT_MASK) {
+		crime_int &= CRIME_MACEPCI_INT_MASK;
+		crime_int >>= 8;
+		irq = ffs (crime_int) + 8;
+	} else if (crime_int & 0xffff0000) {
+		crime_int >>= 16;
+		irq = ffs (crime_int) + 16;
+	}
+	if (irq == 0)
+		ip32_unknown_interrupt (regs);
+	DBG ("*irq %u*\n", irq);
+	do_IRQ (irq, regs);
+}
+
+void ip32_irq1 (struct pt_regs *regs)
+{
+	ip32_unknown_interrupt (regs);
+}
+
+void ip32_irq2 (struct pt_regs *regs)
+{
+	ip32_unknown_interrupt (regs);
+}
+
+void ip32_irq3 (struct pt_regs *regs)
+{
+	ip32_unknown_interrupt (regs);
+}
+
+void ip32_irq4 (struct pt_regs *regs)
+{
+	ip32_unknown_interrupt (regs);
+}
+
+void ip32_irq5 (struct pt_regs *regs)
+{
+	do_IRQ (CLOCK_IRQ, regs);
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/sgi-ip32/ip32-pci-dma.c linux/arch/mips64/sgi-ip32/ip32-pci-dma.c
--- v2.4.9/linux/arch/mips64/sgi-ip32/ip32-pci-dma.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/sgi-ip32/ip32-pci-dma.c	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,41 @@
+/*
+ * This file 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  Ani Joshi <ajoshi@unixbox.com>
+ * Copyright (C) 2000  Ralf Baechle <ralf@gnu.org>
+ * swiped from i386, and cloned for MIPS by Geert, polished by Ralf.
+ */
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/pci.h>
+
+#include <asm/io.h>
+#include <asm/addrspace.h>
+#include <asm/ip32/mace.h>
+
+void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
+			   dma_addr_t * dma_handle)
+{
+	void *ret;
+	int gfp = GFP_ATOMIC;
+
+	if (hwdev == NULL || hwdev->dma_mask != 0xffffffff)
+		gfp |= GFP_DMA;
+	ret = (void *) __get_free_pages(gfp, get_order(size));
+
+	if (ret != NULL) {
+		memset(ret, 0, size);
+		dma_cache_wback_inv((unsigned long) ret, 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.4.9/linux/arch/mips64/sgi-ip32/ip32-pci.c linux/arch/mips64/sgi-ip32/ip32-pci.c
--- v2.4.9/linux/arch/mips64/sgi-ip32/ip32-pci.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/sgi-ip32/ip32-pci.c	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,438 @@
+/*
+ * This file 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, 2001 Keith M Wesolowski
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+#include <asm/pci.h>
+#include <asm/ip32/mace.h>
+#include <asm/ip32/crime.h>
+#include <asm/ip32/ip32_ints.h>
+#include <linux/delay.h>
+
+#undef DEBUG_MACE_PCI
+
+/*
+ * O2 has up to 5 PCI devices connected into the MACE bridge.  The device
+ * map looks like this:
+ *
+ * 0  aic7xxx 0
+ * 1  aic7xxx 1
+ * 2  expansion slot
+ * 3  N/C
+ * 4  N/C
+ */
+
+#define chkslot(dev)							\
+do {									\
+	if ((dev)->bus->number > 0 || PCI_SLOT ((dev)->devfn) < 1	\
+	    || PCI_SLOT ((dev)->devfn) > 3)				\
+		return PCIBIOS_DEVICE_NOT_FOUND;			\
+} while (0)
+		
+#define mkaddr(dev, where) \
+((((dev)->devfn & 0xffUL) << 8) | ((where) & 0xfcUL))
+
+void macepci_error (int irq, void *dev, struct pt_regs *regs);
+
+static int macepci_read_config_byte (struct pci_dev *dev, int where,
+				     u8 *val)
+{
+	*val = 0xff;
+	chkslot (dev);
+	mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
+	*val = mace_read_8 (MACEPCI_CONFIG_DATA + ((where & 3UL) ^ 3UL));
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int macepci_read_config_word (struct pci_dev *dev, int where,
+				     u16 *val)
+{
+	*val = 0xffff;
+	chkslot (dev);
+	if (where & 1)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+ 	mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
+	*val = mace_read_16 (MACEPCI_CONFIG_DATA + ((where & 2UL) ^ 2UL));
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int macepci_read_config_dword (struct pci_dev *dev, int where,
+				      u32 *val)
+{
+	*val = 0xffffffff;
+	chkslot (dev);
+	if (where & 3)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
+	*val = mace_read_32 (MACEPCI_CONFIG_DATA);
+	
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int macepci_write_config_byte (struct pci_dev *dev, int where,
+				      u8 val)
+{
+	chkslot (dev);
+	mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
+	mace_write_8 (MACEPCI_CONFIG_DATA + ((where & 3UL) ^ 3UL), val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int macepci_write_config_word (struct pci_dev *dev, int where,
+				      u16 val)
+{
+	chkslot (dev);
+	if (where & 1)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
+	mace_write_16 (MACEPCI_CONFIG_DATA + ((where & 2UL) ^ 2UL), val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int macepci_write_config_dword (struct pci_dev *dev, int where,
+                                          u32 val)
+{
+	chkslot (dev);
+	if (where & 3)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
+	mace_write_32 (MACEPCI_CONFIG_DATA, val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops macepci_ops = {
+	macepci_read_config_byte,
+	macepci_read_config_word,
+	macepci_read_config_dword,
+	macepci_write_config_byte,
+	macepci_write_config_word,
+	macepci_write_config_dword
+};
+
+struct pci_fixup pcibios_fixups[] = { { 0 } };
+
+void __init pcibios_init (void)
+{
+	struct pci_dev *dev;
+	u32 start, size;
+	u16 cmd;
+	u32 base_io = 0x3000; /* The first i/o address to assign after SCSI */
+	u32 base_mem = 0x80100000; /* Likewise */
+	u32 rev = mace_read_32 (MACEPCI_REV);
+	int i;
+
+	printk ("MACE: PCI rev %d detected at %016lx\n", rev,
+		(u64) MACE_BASE + MACE_PCI);
+
+	/* These are *bus* addresses */
+	ioport_resource.start = 0;
+	ioport_resource.end = 0xffffffffUL;
+	iomem_resource.start = 0x80000000UL;
+	iomem_resource.end = 0xffffffffUL;
+
+	/* Clear any outstanding errors and enable interrupts */
+	mace_write_32 (MACEPCI_ERROR_ADDR, 0);
+	mace_write_32 (MACEPCI_ERROR_FLAGS, 0);
+	mace_write_32 (MACEPCI_CONTROL, 0xff008500);
+	crime_write_64 (CRIME_HARD_INT, 0UL);
+	crime_write_64 (CRIME_SOFT_INT, 0UL);
+	crime_write_64 (CRIME_INT_STAT, 0x000000000000ff00UL);
+
+	if (request_irq (MACE_PCI_BRIDGE_IRQ, macepci_error, 0,
+			 "MACE PCI error", NULL))
+		panic ("PCI bridge can't get interrupt; can't happen.\n");
+
+	pci_scan_bus (0, &macepci_ops, NULL);
+
+#ifdef DEBUG_MACE_PCI
+	pci_for_each_dev (dev) {
+		printk ("Device: %d/%d/%d ARCS-assigned bus resource map\n",
+			dev->bus->number, PCI_SLOT (dev->devfn),
+			PCI_FUNC (dev->devfn));
+		for (i=0; i < DEVICE_COUNT_RESOURCE; i++) {
+			if (dev->resource[i].start == 0)
+				continue;
+			printk ("%d: %016lx - %016lx (flags %04lx)\n",
+				i, dev->resource[i].start,
+				dev->resource[i].end, dev->resource[i].flags);
+		}
+	}
+#endif
+	/*
+	 * Assign sane resources to and enable all devices.  The requirement
+	 * for the SCSI controllers is well-known: a 256-byte I/O region
+	 * which we must assign, and a 1-page memory region which is
+	 * assigned by the system firmware.
+	 */
+	pci_for_each_dev (dev) {
+		switch (PCI_SLOT (dev->devfn)) {
+		case 1: /* SCSI bus 0 */
+			dev->resource[0].start = 0x1000UL;
+			dev->resource[0].end = 0x10ffUL;
+			break;
+		case 2: /* SCSI bus 1 */
+			dev->resource[0].start = 0x2000UL;
+			dev->resource[0].end = 0x20ffUL;
+			break;
+		default: /* Slots - I guess we have only 1 */
+			for (i=0; i < 6; i++) {
+				size = dev->resource[i].end
+					- dev->resource[i].start;
+				if (!size
+				    || !(dev->resource[i].flags
+					 & (IORESOURCE_IO|IORESOURCE_MEM))) {
+					dev->resource[i].start
+						= dev->resource[i].end = 0UL;
+					continue;
+				}
+				if (dev->resource[i].flags & IORESOURCE_IO) {
+					dev->resource[i].start = base_io;
+					base_io += PAGE_ALIGN (size);
+				} else {
+					dev->resource[i].start = base_mem;
+					base_mem += 0x100000UL;
+				}
+				dev->resource[i].end =
+					dev->resource[i].start + size;
+			}
+			break;
+		}
+		for (i=0; i < 6; i++) {
+			if (dev->resource[i].start == 0)
+				continue;
+			start = dev->resource[i].start;
+			if (dev->resource[i].flags & IORESOURCE_IO)
+				start |= 1;
+			pci_write_config_dword (dev, 
+				PCI_BASE_ADDRESS_0 + (i << 2), (u32) start);
+		}
+		pci_write_config_byte (dev, PCI_CACHE_LINE_SIZE, 0x20);
+		pci_write_config_byte (dev, PCI_LATENCY_TIMER, 0x30);
+		pci_read_config_word (dev, PCI_COMMAND, &cmd);
+		cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_PARITY);
+		pci_write_config_word (dev, PCI_COMMAND, cmd);
+		pci_set_master (dev);
+	}
+
+#ifdef DEBUG_MACE_PCI
+	printk ("Triggering PCI bridge interrupt...\n");
+	mace_write_32 (MACEPCI_ERROR_FLAGS, MACEPCI_ERROR_INTERRUPT_TEST);
+
+	pci_for_each_dev (dev) {
+		printk ("Device: %d/%d/%d final bus resource map\n",
+			dev->bus->number, PCI_SLOT (dev->devfn),
+			PCI_FUNC (dev->devfn));
+		for (i=0; i < DEVICE_COUNT_RESOURCE; i++) {
+			if (dev->resource[i].start == 0)
+				continue;
+			printk ("%d: %016lx - %016lx (flags %04lx)\n",
+				i, dev->resource[i].start,
+				dev->resource[i].end, dev->resource[i].flags);
+		}
+	}
+#endif
+}
+
+/*
+ * Given a PCI slot number (a la PCI_SLOT(...)) and the interrupt pin of
+ * the device (1-4 => A-D), tell what irq to use.  Note that we don't
+ * in theory have slots 4 and 5, and we never normally use the shared
+ * irqs.  I suppose a device without a pin A will thank us for doing it
+ * right if there exists such a broken piece of crap.
+ */
+static int __init macepci_map_irq (struct pci_dev *dev, u8 slot, u8 pin)
+{
+	chkslot (dev);
+	if (pin == 0)
+		pin = 1;
+	switch (slot) {
+	case 1:
+		return MACEPCI_SCSI0_IRQ;
+	case 2:
+		return MACEPCI_SCSI1_IRQ;
+	case 3:
+		switch (pin) {
+		case 2:
+			return MACEPCI_SHARED0_IRQ;
+		case 3:
+			return MACEPCI_SHARED1_IRQ;
+		case 4:
+			return MACEPCI_SHARED2_IRQ;
+		case 1:
+		default:
+			return MACEPCI_SLOT0_IRQ;
+		}
+	case 4:
+		switch (pin) {
+		case 2:
+			return MACEPCI_SHARED2_IRQ;
+		case 3:
+			return MACEPCI_SHARED0_IRQ;
+		case 4:
+			return MACEPCI_SHARED1_IRQ;
+		case 1:
+		default:
+			return MACEPCI_SLOT1_IRQ;
+		}
+		return MACEPCI_SLOT1_IRQ;
+	case 5:
+		switch (pin) {
+		case 2:
+			return MACEPCI_SHARED1_IRQ;
+		case 3:
+			return MACEPCI_SHARED2_IRQ;
+		case 4:
+			return MACEPCI_SHARED0_IRQ;
+		case 1:
+		default:
+			return MACEPCI_SLOT2_IRQ;
+		}
+	default:
+		return 0;
+	}
+}
+
+/*
+ * It's not entirely clear what this does in a system with no bridges.
+ * In any case, bridges are not supported by Linux in O2.
+ */
+static u8 __init macepci_swizzle (struct pci_dev *dev, u8 *pinp)
+{
+	if (PCI_SLOT (dev->devfn) == 2)
+		*pinp = 2;
+	else
+		*pinp = 1;
+	return PCI_SLOT (dev->devfn);
+}
+
+/* All devices are enabled during initialization. */
+int pcibios_enable_device (struct pci_dev *dev)
+{
+	return PCIBIOS_SUCCESSFUL;
+}
+
+char * __init pcibios_setup (char *str)
+{
+	return str;
+}
+
+void __init pcibios_align_resource (void *data, struct resource *res,
+				    unsigned long size)
+{
+}
+
+void __init pcibios_update_resource (struct pci_dev *dev, struct resource *root,
+				     struct resource *res, int resource)
+{
+}
+
+void __init pcibios_update_irq (struct pci_dev *dev, int irq)
+{
+	pci_write_config_byte (dev, PCI_INTERRUPT_LINE, irq);
+}
+
+void __init pcibios_fixup_bus (struct pci_bus *b)
+{
+	pci_fixup_irqs (macepci_swizzle, macepci_map_irq);
+}
+
+/* XXX anybody know what this is supposed to do? */
+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;
+}
+
+/*
+ * Handle errors from the bridge.  This includes master and target aborts,
+ * various command and address errors, and the interrupt test.  This gets
+ * registered on the bridge error irq.  It's conceivable that some of these
+ * conditions warrant a panic.  Anybody care to say which ones?
+ */
+void macepci_error (int irq, void *dev, struct pt_regs *regs) {
+	u32 flags, error_addr;
+	char space;
+
+	flags = mace_read_32 (MACEPCI_ERROR_FLAGS);
+	error_addr = mace_read_32 (MACEPCI_ERROR_ADDR);
+
+	if (flags & MACEPCI_ERROR_MEMORY_ADDR)
+		space = 'M';
+	else if (flags & MACEPCI_ERROR_CONFIG_ADDR)
+		space = 'C';
+	else space = 'X';
+	
+	if (flags & MACEPCI_ERROR_MASTER_ABORT) {
+		printk ("MACEPCI: Master abort at 0x%08x (%c)\n", error_addr,
+			space);
+		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
+			       & ~MACEPCI_ERROR_MASTER_ABORT);
+	}
+	if (flags & MACEPCI_ERROR_TARGET_ABORT) {
+		printk ("MACEPCI: Target abort at 0x%08x (%c)\n", error_addr,
+			space);
+		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
+			       & ~MACEPCI_ERROR_TARGET_ABORT);
+	}
+	if (flags & MACEPCI_ERROR_DATA_PARITY_ERR) {
+		printk ("MACEPCI: Data parity error at 0x%08x (%c)\n",
+			error_addr, space);
+		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
+			       & ~MACEPCI_ERROR_DATA_PARITY_ERR);
+	}
+	if (flags & MACEPCI_ERROR_RETRY_ERR) {
+		printk ("MACEPCI: Retry error at 0x%08x (%c)\n", error_addr,
+			space);
+		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
+			       & ~MACEPCI_ERROR_RETRY_ERR);
+	}
+	if (flags & MACEPCI_ERROR_ILLEGAL_CMD) {
+		printk ("MACEPCI: Illegal command at 0x%08x (%c)\n",
+			error_addr, space);
+		mace_write_32 (MACEPCI_ERROR_FLAGS,
+			       flags & ~MACEPCI_ERROR_ILLEGAL_CMD);
+	}
+	if (flags & MACEPCI_ERROR_SYSTEM_ERR) {
+		printk ("MACEPCI: System error at 0x%08x (%c)\n",
+			error_addr, space);
+		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
+			       & ~MACEPCI_ERROR_SYSTEM_ERR);
+	}
+	if (flags & MACEPCI_ERROR_PARITY_ERR) {
+		printk ("MACEPCI: Parity error at 0x%08x (%c)\n", error_addr,
+			space);
+		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
+			       & ~MACEPCI_ERROR_PARITY_ERR);
+	}
+	if (flags & MACEPCI_ERROR_OVERRUN) {
+		printk ("MACEPCI: Overrun error at 0x%08x (%c)\n",
+			error_addr, space);
+		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
+			       & ~MACEPCI_ERROR_OVERRUN);
+	}
+	if (flags & MACEPCI_ERROR_SIG_TABORT) {
+		printk ("MACEPCI: Signaled target abort (clearing)\n");
+		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
+			       & ~MACEPCI_ERROR_SIG_TABORT);
+	}
+	if (flags & MACEPCI_ERROR_INTERRUPT_TEST) {
+		printk ("MACEPCI: Interrupt test triggered (clearing)\n");
+		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
+			       & ~MACEPCI_ERROR_INTERRUPT_TEST);
+	}
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/sgi-ip32/ip32-rtc.c linux/arch/mips64/sgi-ip32/ip32-rtc.c
--- v2.4.9/linux/arch/mips64/sgi-ip32/ip32-rtc.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/sgi-ip32/ip32-rtc.c	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,32 @@
+/*
+ * RTC routines for IP32 style attached Dallas chip.
+ *
+ * This file 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 Harald Koerfgen
+ */
+#include <linux/mc146818rtc.h>
+#include <asm/ip32/mace.h>
+
+static unsigned char ip32_rtc_read_data(unsigned long addr)
+{
+	return (unsigned char) mace_read_8 (MACEISA_RTC_BASE + (addr << 8));
+}
+
+static void ip32_rtc_write_data(unsigned char data, unsigned long addr)
+{
+	mace_write_8 (MACEISA_RTC_BASE + (addr << 8), data);
+}
+
+static int ip32_rtc_bcd_mode(void)
+{
+	return 0;
+}
+
+struct rtc_ops ip32_rtc_ops = {
+	&ip32_rtc_read_data,
+	&ip32_rtc_write_data,
+	&ip32_rtc_bcd_mode
+};
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/sgi-ip32/ip32-setup.c linux/arch/mips64/sgi-ip32/ip32-setup.c
--- v2.4.9/linux/arch/mips64/sgi-ip32/ip32-setup.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/sgi-ip32/ip32-setup.c	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,62 @@
+/*
+ * IP32 basic setup
+ *
+ * This file 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 Harald Koerfgen
+ */
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/mc146818rtc.h>
+#include <linux/param.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/mmu_context.h>
+#include <asm/ip32/crime.h>
+#include <asm/ip32/mace.h>
+#include <asm/ip32/ip32_ints.h>
+#include <asm/sgialib.h>
+
+extern struct rtc_ops ip32_rtc_ops;
+extern u32 cc_interval;
+
+void __init ip32_init (int argc, char **argv, char **envp) {
+	arc_meminit ();
+}
+
+void __init ip32_setup(void)
+{
+#ifdef CONFIG_SERIAL_CONSOLE
+	char *ctype;
+#endif
+	TLBMISS_HANDLER_SETUP ();
+
+#ifdef CONFIG_SERIAL_CONSOLE
+	ctype = ArcGetEnvironmentVariable("console");
+	if (*ctype == 'd') {
+		if (ctype[1] == '2')
+			console_setup ("ttyS1");
+		else
+			console_setup ("ttyS0");
+	}
+#endif
+
+#ifdef CONFIG_VT
+	conswitchp = &dummy_con;
+#endif
+
+	rtc_ops = &ip32_rtc_ops;
+
+	crime_init ();
+}
+
+int __init page_is_ram (unsigned long pagenr)
+{
+	/* XXX: to do? */
+	return 1;
+}
diff -u --recursive --new-file v2.4.9/linux/arch/mips64/sgi-ip32/ip32-timer.c linux/arch/mips64/sgi-ip32/ip32-timer.c
--- v2.4.9/linux/arch/mips64/sgi-ip32/ip32-timer.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips64/sgi-ip32/ip32-timer.c	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,47 @@
+/*
+ * IP32 timer calibration
+ *
+ * This file 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) 2001 Keith M Wesolowski
+ */
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <asm/mipsregs.h>
+#include <asm/param.h>
+#include <asm/ip32/crime.h>
+#include <asm/ip32/ip32_ints.h>
+
+extern u32 cc_interval;
+
+/* An arbitrary time; this can be decreased if reliability looks good */
+#define WAIT_MS 10
+#define PER_MHZ (1000000 / 2 / HZ)
+
+void __init ip32_timer_setup (struct irqaction *irq) {
+	u64 crime_time;
+	u32 cc_tick;
+
+	printk("Calibrating system timer... ");
+
+	crime_time = crime_read_64 (CRIME_TIME) & CRIME_TIME_MASK;
+	cc_tick = read_32bit_cp0_register (CP0_COUNT);
+
+	while ((crime_read_64 (CRIME_TIME) & CRIME_TIME_MASK) - crime_time 
+		< WAIT_MS * 1000000 / CRIME_NS_PER_TICK)
+		;
+	cc_tick = read_32bit_cp0_register (CP0_COUNT) - cc_tick;
+	cc_interval = cc_tick / HZ * (1000 / WAIT_MS);
+	/* The round-off seems unnecessary; in testing, the error of the
+	 * above procedure is < 100 ticks, which means it gets filtered
+	 * out by the HZ adjustment. 
+	 */
+	cc_interval = (cc_interval / PER_MHZ) * PER_MHZ;
+
+	printk("%d MHz CPU detected\n", (int) (cc_interval / PER_MHZ));
+
+	setup_irq (CLOCK_IRQ, irq);
+}
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/8xx_io/Config.in linux/arch/ppc/8xx_io/Config.in
--- v2.4.9/linux/arch/ppc/8xx_io/Config.in	Wed May 16 09:57:20 2001
+++ linux/arch/ppc/8xx_io/Config.in	Sat Sep  8 12:39:33 2001
@@ -31,6 +31,7 @@
 comment 'Generic MPC8xx Options'
 bool 'Copy-Back Data Cache (else Writethrough)' CONFIG_8xx_COPYBACK
 bool 'CPU6 Silicon Errata (860 Pre Rev. C)' CONFIG_8xx_CPU6
+bool 'I2C/SPI Microcode Patch' CONFIG_UCODE_PATCH
 
 if [ "$CONFIG_IDE" = "y" ]; then
 	bool 'MPC8xx direct IDE support on PCMCIA port' CONFIG_BLK_DEV_MPC8xx_IDE
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/8xx_io/Makefile linux/arch/ppc/8xx_io/Makefile
--- v2.4.9/linux/arch/ppc/8xx_io/Makefile	Mon May 21 17:04:46 2001
+++ linux/arch/ppc/8xx_io/Makefile	Sat Sep  8 12:39:33 2001
@@ -1,4 +1,4 @@
-# BK Id: SCCS/s.Makefile 1.3 05/17/01 18:14:20 cort
+# BK Id: SCCS/s.Makefile 1.6 08/30/01 09:33:48 trini
 #
 #
 # Makefile for the linux MPC8xx ppc-specific parts of comm processor
@@ -15,5 +15,6 @@
 
 obj-$(CONFIG_FEC_ENET)	+= fec.o
 obj-$(CONFIG_SCC_ENET)	+= enet.o
+obj-$(CONFIG_UCODE_PATCH) += micropatch.o
 
 include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/8xx_io/enet.c linux/arch/ppc/8xx_io/enet.c
--- v2.4.9/linux/arch/ppc/8xx_io/enet.c	Mon May 21 17:04:46 2001
+++ linux/arch/ppc/8xx_io/enet.c	Sun Sep  2 07:48:02 2001
@@ -651,11 +651,10 @@
 	volatile	scc_t		*sccp;
 	volatile	scc_enet_t	*ep;
 	volatile	immap_t		*immap;
-	extern unsigned long _get_IMMR(void);
 
 	cp = cpmp;	/* Get pointer to Communication Processor */
 
-	immap = (immap_t *)(_get_IMMR() & 0xFFFF0000);	/* and to internal registers */
+	immap = (immap_t *)(mfspr(IMMR) & 0xFFFF0000);	/* and to internal registers */
 
 	bd = (bd_t *)__res;
 
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/8xx_io/fec.c linux/arch/ppc/8xx_io/fec.c
--- v2.4.9/linux/arch/ppc/8xx_io/fec.c	Mon May 21 17:04:46 2001
+++ linux/arch/ppc/8xx_io/fec.c	Sun Sep  2 07:48:02 2001
@@ -1509,7 +1509,6 @@
 	volatile	immap_t	*immap;
 	volatile	fec_t	*fecp;
 	bd_t		*bd;
-	extern		uint	_get_IMMR(void);
 #ifdef CONFIG_SCC_ENET
 	unsigned char	tmpaddr[6];
 #endif
@@ -1680,7 +1679,7 @@
 
 	/* Bits moved from Rev. D onward.
 	*/
-	if ((_get_IMMR() & 0xffff) < 0x0501)
+	if ((mfspr(IMMR) & 0xffff) < 0x0501)
 		immap->im_ioport.iop_pddir = 0x1c58;	/* Pre rev. D */
 	else
 		immap->im_ioport.iop_pddir = 0x1fff;	/* Rev. D and later */
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/8xx_io/micropatch.c linux/arch/ppc/8xx_io/micropatch.c
--- v2.4.9/linux/arch/ppc/8xx_io/micropatch.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/8xx_io/micropatch.c	Sat Sep  8 12:39:33 2001
@@ -0,0 +1,777 @@
+
+/* Microcode patches for the CPM as supplied by Motorola.
+ * This is the one for IIC/SPI.  There is a newer one that
+ * also relocates SMC2, but this would require additional changes
+ * to uart.c, so I am holding off on that for a moment.
+ */
+#include <linux/config.h>
+#include <linux/errno.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 <asm/irq.h>
+#include <asm/mpc8xx.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/8xx_immap.h>
+#include "commproc.h"
+
+/* Define this to get SMC patches as well.  You need to modify the uart
+ * driver as well......
+#define USE_SMC_PATCH 1
+ */
+
+#ifdef CONFIG_USB_MPC8xx
+#define USE_USB_SOF_PATCH
+#endif
+
+#ifdef USE_IIC_PATCH
+#define PATCH_DEFINED
+	/* IIC/SPI */
+uint patch_2000[] = {
+	0x7FFFEFD9,
+	0x3FFD0000,
+	0x7FFB49F7,
+	0x7FF90000,
+	0x5FEFADF7,
+	0x5F89ADF7,
+	0x5FEFAFF7,
+	0x5F89AFF7,
+	0x3A9CFBC8,
+	0xE7C0EDF0,
+	0x77C1E1BB,
+	0xF4DC7F1D,
+	0xABAD932F,
+	0x4E08FDCF,
+	0x6E0FAFF8,
+	0x7CCF76CF,
+	0xFD1FF9CF,
+	0xABF88DC6,
+	0xAB5679F7,
+	0xB0937383,
+	0xDFCE79F7,
+	0xB091E6BB,
+	0xE5BBE74F,
+	0xB3FA6F0F,
+	0x6FFB76CE,
+	0xEE0DF9CF,
+	0x2BFBEFEF,
+	0xCFEEF9CF,
+	0x76CEAD24,
+	0x90B2DF9A,
+	0x7FDDD0BF,
+	0x4BF847FD,
+	0x7CCF76CE,
+	0xCFEF7E1F,
+	0x7F1D7DFD,
+	0xF0B6EF71,
+	0x7FC177C1,
+	0xFBC86079,
+	0xE722FBC8,
+	0x5FFFDFFF,
+	0x5FB2FFFB,
+	0xFBC8F3C8,
+	0x94A67F01,
+	0x7F1D5F39,
+	0xAFE85F5E,
+	0xFFDFDF96,
+	0xCB9FAF7D,
+	0x5FC1AFED,
+	0x8C1C5FC1,
+	0xAFDD5FC3,
+	0xDF9A7EFD,
+	0xB0B25FB2,
+	0xFFFEABAD,
+	0x5FB2FFFE,
+	0x5FCE600B,
+	0xE6BB600B,
+	0x5FCEDFC6,
+	0x27FBEFDF,
+	0x5FC8CFDE,
+	0x3A9CE7C0,
+	0xEDF0F3C8,
+	0x7F0154CD,
+	0x7F1D2D3D,
+	0x363A7570,
+	0x7E0AF1CE,
+	0x37EF2E68,
+	0x7FEE10EC,
+	0xADF8EFDE,
+	0xCFEAE52F,
+	0x7D0FE12B,
+	0xF1CE5F65,
+	0x7E0A4DF8,
+	0xCFEA5F72,
+	0x7D0BEFEE,
+	0xCFEA5F74,
+	0xE522EFDE,
+	0x5F74CFDA,
+	0x0B627385,
+	0xDF627E0A,
+	0x30D8145B,
+	0xBFFFF3C8,
+	0x5FFFDFFF,
+	0xA7F85F5E,
+	0xBFFE7F7D,
+	0x10D31450,
+	0x5F36BFFF,
+	0xAF785F5E,
+	0xBFFDA7F8,
+	0x5F36BFFE,
+	0x77FD30C0,
+	0x4E08FDCF,
+	0xE5FF6E0F,
+	0xAFF87E1F,
+	0x7E0FFD1F,
+	0xF1CF5F1B,
+	0xABF80D5E,
+	0x5F5EFFEF,
+	0x79F730A2,
+	0xAFDD5F34,
+	0x47F85F34,
+	0xAFED7FDD,
+	0x50B24978,
+	0x47FD7F1D,
+	0x7DFD70AD,
+	0xEF717EC1,
+	0x6BA47F01,
+	0x2D267EFD,
+	0x30DE5F5E,
+	0xFFFD5F5E,
+	0xFFEF5F5E,
+	0xFFDF0CA0,
+	0xAFED0A9E,
+	0xAFDD0C3A,
+	0x5F3AAFBD,
+	0x7FBDB082,
+	0x5F8247F8
+};
+
+uint patch_2f00[] = {
+	0x3E303430,
+	0x34343737,
+	0xABF7BF9B,
+	0x994B4FBD,
+	0xBD599493,
+	0x349FFF37,
+	0xFB9B177D,
+	0xD9936956,
+	0xBBFDD697,
+	0xBDD2FD11,
+	0x31DB9BB3,
+	0x63139637,
+	0x93733693,
+	0x193137F7,
+	0x331737AF,
+	0x7BB9B999,
+	0xBB197957,
+	0x7FDFD3D5,
+	0x73B773F7,
+	0x37933B99,
+	0x1D115316,
+	0x99315315,
+	0x31694BF4,
+	0xFBDBD359,
+	0x31497353,
+	0x76956D69,
+	0x7B9D9693,
+	0x13131979,
+	0x79376935
+};
+#endif
+
+#ifdef USE_SMC_PATCH
+#define PATCH_DEFINED
+/* SMC2/IIC/SPI Patch */
+/* This is the area from 0x2000 to 0x23ff.
+*/
+uint patch_2000[] = {
+	0x3fff0000,
+	0x3ffd0000,
+	0x3ffb0000,
+	0x3ff90000,
+	0x5f13eff8,
+	0x5eb5eff8,
+	0x5f88adf7,
+	0x5fefadf7,
+	0x3a9cfbc8,
+	0x77cae1bb,
+	0xf4de7fad,
+	0xabae9330,
+	0x4e08fdcf,
+	0x6e0faff8,
+	0x7ccf76cf,
+	0xfdaff9cf,
+	0xabf88dc8,
+	0xab5879f7,
+	0xb0925d8d,
+	0xdfd079f7,
+	0xb090e6bb,
+	0xe5bbe74f,
+	0x9e046f0f,
+	0x6ffb76ce,
+	0xee0cf9cf,
+	0x2bfbefef,
+	0xcfeef9cf,
+	0x76cead23,
+	0x90b3df99,
+	0x7fddd0c1,
+	0x4bf847fd,
+	0x7ccf76ce,
+	0xcfef77ca,
+	0x7eaf7fad,
+	0x7dfdf0b7,
+	0xef7a7fca,
+	0x77cafbc8,
+	0x6079e722,
+	0xfbc85fff,
+	0xdfff5fb3,
+	0xfffbfbc8,
+	0xf3c894a5,
+	0xe7c9edf9,
+	0x7f9a7fad,
+	0x5f36afe8,
+	0x5f5bffdf,
+	0xdf95cb9e,
+	0xaf7d5fc3,
+	0xafed8c1b,
+	0x5fc3afdd,
+	0x5fc5df99,
+	0x7efdb0b3,
+	0x5fb3fffe,
+	0xabae5fb3,
+	0xfffe5fd0,
+	0x600be6bb,
+	0x600b5fd0,
+	0xdfc827fb,
+	0xefdf5fca,
+	0xcfde3a9c,
+	0xe7c9edf9,
+	0xf3c87f9e,
+	0x54ca7fed,
+	0x2d3a3637,
+	0x756f7e9a,
+	0xf1ce37ef,
+	0x2e677fee,
+	0x10ebadf8,
+	0xefdecfea,
+	0xe52f7d9f,
+	0xe12bf1ce,
+	0x5f647e9a,
+	0x4df8cfea,
+	0x5f717d9b,
+	0xefeecfea,
+	0x5f73e522,
+	0xefde5f73,
+	0xcfda0b61,
+	0x5d8fdf61,
+	0xe7c9edf9,
+	0x7e9a30d5,
+	0x1458bfff,
+	0xf3c85fff,
+	0xdfffa7f8,
+	0x5f5bbffe,
+	0x7f7d10d0,
+	0x144d5f33,
+	0xbfffaf78,
+	0x5f5bbffd,
+	0xa7f85f33,
+	0xbffe77fd,
+	0x30bd4e08,
+	0xfdcfe5ff,
+	0x6e0faff8,
+	0x7eef7e9f,
+	0xfdeff1cf,
+	0x5f17abf8,
+	0x0d5b5f5b,
+	0xffef79f7,
+	0x309eafdd,
+	0x5f3147f8,
+	0x5f31afed,
+	0x7fdd50af,
+	0x497847fd,
+	0x7f9e7fed,
+	0x7dfd70a9,
+	0xef7e7ece,
+	0x6ba07f9e,
+	0x2d227efd,
+	0x30db5f5b,
+	0xfffd5f5b,
+	0xffef5f5b,
+	0xffdf0c9c,
+	0xafed0a9a,
+	0xafdd0c37,
+	0x5f37afbd,
+	0x7fbdb081,
+	0x5f8147f8,
+	0x3a11e710,
+	0xedf0ccdd,
+	0xf3186d0a,
+	0x7f0e5f06,
+	0x7fedbb38,
+	0x3afe7468,
+	0x7fedf4fc,
+	0x8ffbb951,
+	0xb85f77fd,
+	0xb0df5ddd,
+	0xdefe7fed,
+	0x90e1e74d,
+	0x6f0dcbf7,
+	0xe7decfed,
+	0xcb74cfed,
+	0xcfeddf6d,
+	0x91714f74,
+	0x5dd2deef,
+	0x9e04e7df,
+	0xefbb6ffb,
+	0xe7ef7f0e,
+	0x9e097fed,
+	0xebdbeffa,
+	0xeb54affb,
+	0x7fea90d7,
+	0x7e0cf0c3,
+	0xbffff318,
+	0x5fffdfff,
+	0xac59efea,
+	0x7fce1ee5,
+	0xe2ff5ee1,
+	0xaffbe2ff,
+	0x5ee3affb,
+	0xf9cc7d0f,
+	0xaef8770f,
+	0x7d0fb0c6,
+	0xeffbbfff,
+	0xcfef5ede,
+	0x7d0fbfff,
+	0x5ede4cf8,
+	0x7fddd0bf,
+	0x49f847fd,
+	0x7efdf0bb,
+	0x7fedfffd,
+	0x7dfdf0b7,
+	0xef7e7e1e,
+	0x5ede7f0e,
+	0x3a11e710,
+	0xedf0ccab,
+	0xfb18ad2e,
+	0x1ea9bbb8,
+	0x74283b7e,
+	0x73c2e4bb,
+	0x2ada4fb8,
+	0xdc21e4bb,
+	0xb2a1ffbf,
+	0x5e2c43f8,
+	0xfc87e1bb,
+	0xe74ffd91,
+	0x6f0f4fe8,
+	0xc7ba32e2,
+	0xf396efeb,
+	0x600b4f78,
+	0xe5bb760b,
+	0x53acaef8,
+	0x4ef88b0e,
+	0xcfef9e09,
+	0xabf8751f,
+	0xefef5bac,
+	0x741f4fe8,
+	0x751e760d,
+	0x7fdbf081,
+	0x741cafce,
+	0xefcc7fce,
+	0x751e70ac,
+	0x741ce7bb,
+	0x3372cfed,
+	0xafdbefeb,
+	0xe5bb760b,
+	0x53f2aef8,
+	0xafe8e7eb,
+	0x4bf8771e,
+	0x7e247fed,
+	0x4fcbe2cc,
+	0x7fbc30a9,
+	0x7b0f7a0f,
+	0x34d577fd,
+	0x308b5db7,
+	0xde553e5f,
+	0xaf78741f,
+	0x741f30f0,
+	0xcfef5e2c,
+	0x741f3eac,
+	0xafb8771e,
+	0x5e677fed,
+	0x0bd3e2cc,
+	0x741ccfec,
+	0xe5ca53cd,
+	0x6fcb4f74,
+	0x5dadde4b,
+	0x2ab63d38,
+	0x4bb3de30,
+	0x751f741c,
+	0x6c42effa,
+	0xefea7fce,
+	0x6ffc30be,
+	0xefec3fca,
+	0x30b3de2e,
+	0xadf85d9e,
+	0xaf7daefd,
+	0x5d9ede2e,
+	0x5d9eafdd,
+	0x761f10ac,
+	0x1da07efd,
+	0x30adfffe,
+	0x4908fb18,
+	0x5fffdfff,
+	0xafbb709b,
+	0x4ef85e67,
+	0xadf814ad,
+	0x7a0f70ad,
+	0xcfef50ad,
+	0x7a0fde30,
+	0x5da0afed,
+	0x3c12780f,
+	0xefef780f,
+	0xefef790f,
+	0xa7f85e0f,
+	0xffef790f,
+	0xefef790f,
+	0x14adde2e,
+	0x5d9eadfd,
+	0x5e2dfffb,
+	0xe79addfd,
+	0xeff96079,
+	0x607ae79a,
+	0xddfceff9,
+	0x60795dff,
+	0x607acfef,
+	0xefefefdf,
+	0xefbfef7f,
+	0xeeffedff,
+	0xebffe7ff,
+	0xafefafdf,
+	0xafbfaf7f,
+	0xaeffadff,
+	0xabffa7ff,
+	0x6fef6fdf,
+	0x6fbf6f7f,
+	0x6eff6dff,
+	0x6bff67ff,
+	0x2fef2fdf,
+	0x2fbf2f7f,
+	0x2eff2dff,
+	0x2bff27ff,
+	0x4e08fd1f,
+	0xe5ff6e0f,
+	0xaff87eef,
+	0x7e0ffdef,
+	0xf11f6079,
+	0xabf8f542,
+	0x7e0af11c,
+	0x37cfae3a,
+	0x7fec90be,
+	0xadf8efdc,
+	0xcfeae52f,
+	0x7d0fe12b,
+	0xf11c6079,
+	0x7e0a4df8,
+	0xcfea5dc4,
+	0x7d0befec,
+	0xcfea5dc6,
+	0xe522efdc,
+	0x5dc6cfda,
+	0x4e08fd1f,
+	0x6e0faff8,
+	0x7c1f761f,
+	0xfdeff91f,
+	0x6079abf8,
+	0x761cee24,
+	0xf91f2bfb,
+	0xefefcfec,
+	0xf91f6079,
+	0x761c27fb,
+	0xefdf5da7,
+	0xcfdc7fdd,
+	0xd09c4bf8,
+	0x47fd7c1f,
+	0x761ccfcf,
+	0x7eef7fed,
+	0x7dfdf093,
+	0xef7e7f1e,
+	0x771efb18,
+	0x6079e722,
+	0xe6bbe5bb,
+	0xae0ae5bb,
+	0x600bae85,
+	0xe2bbe2bb,
+	0xe2bbe2bb,
+	0xaf02e2bb,
+	0xe2bb2ff9,
+	0x6079e2bb
+};
+
+	/* This is from 0x2f00 to 0x2fff
+	*/
+uint patch_2f00[] = {
+	0x30303030,
+	0x3e3e3434,
+	0xabbf9b99,
+	0x4b4fbdbd,
+	0x59949334,
+	0x9fff37fb,
+	0x9b177dd9,
+	0x936956bb,
+	0xfbdd697b,
+	0xdd2fd113,
+	0x1db9f7bb,
+	0x36313963,
+	0x79373369,
+	0x3193137f,
+	0x7331737a,
+	0xf7bb9b99,
+	0x9bb19795,
+	0x77fdfd3d,
+	0x573b773f,
+	0x737933f7,
+	0xb991d115,
+	0x31699315,
+	0x31531694,
+	0xbf4fbdbd,
+	0x35931497,
+	0x35376956,
+	0xbd697b9d,
+	0x96931313,
+	0x19797937,
+	0x6935af78,
+	0xb9b3baa3,
+	0xb8788683,
+	0x368f78f7,
+	0x87778733,
+	0x3ffffb3b,
+	0x8e8f78b8,
+	0x1d118e13,
+	0xf3ff3f8b,
+	0x6bd8e173,
+	0xd1366856,
+	0x68d1687b,
+	0x3daf78b8,
+	0x3a3a3f87,
+	0x8f81378f,
+	0xf876f887,
+	0x77fd8778,
+	0x737de8d6,
+	0xbbf8bfff,
+	0xd8df87f7,
+	0xfd876f7b,
+	0x8bfff8bd,
+	0x8683387d,
+	0xb873d87b,
+	0x3b8fd7f8,
+	0xf7338883,
+	0xbb8ee1f8,
+	0xef837377,
+	0x3337b836,
+	0x817d11f8,
+	0x7378b878,
+	0xd3368b7d,
+	0xed731b7d,
+	0x833731f3,
+	0xf22f3f23
+};
+
+uint patch_2e00[] = {
+	/* This is from 0x2e00 to 0x2e3c
+	*/
+	0x27eeeeee,
+	0xeeeeeeee,
+	0xeeeeeeee,
+	0xeeeeeeee,
+	0xee4bf4fb,
+	0xdbd259bb,
+	0x1979577f,
+	0xdfd2d573,
+	0xb773f737,
+	0x4b4fbdbd,
+	0x25b9b177,
+	0xd2d17376,
+	0x956bbfdd,
+	0x697bdd2f,
+	0xff9f79ff,
+	0xff9ff22f
+};
+#endif
+
+#ifdef USE_USB_SOF_PATCH
+#define PATCH_DEFINED
+uint patch_2000[] = {
+	0x7fff0000,
+	0x7ffd0000,
+	0x7ffb0000,
+	0x49f7ba5b,
+	0xba383ffb,
+	0xf9b8b46d,
+	0xe5ab4e07,
+	0xaf77bffe,
+	0x3f7bbf79,
+	0xba5bba38,
+	0xe7676076,
+	0x60750000
+};
+
+uint patch_2f00[] = {
+	0x3030304c,
+	0xcab9e441,
+	0xa1aaf220
+};
+#endif
+
+/* Load the microcode patch.  This is called early in the CPM initialization
+ * with the controller in the reset state.  We enable the processor after
+ * we load the patch.
+ */
+void
+cpm_load_patch(volatile immap_t *immr)
+{
+#ifdef PATCH_DEFINED
+	volatile uint		*dp;
+	volatile cpm8xx_t	*commproc;
+	volatile iic_t		*iip;
+	volatile spi_t		*spp;
+	int	i;
+
+	commproc = (cpm8xx_t *)&immr->im_cpm;
+
+	/* We work closely with commproc.c.  We know it only allocates
+	 * from data only space.
+	 * For this particular patch, we only use the bottom 512 bytes
+	 * and the upper 256 byte extension.  We will use the space
+	 * starting at 1K for the relocated parameters, as the general
+	 * CPM allocation won't come from that area.
+	 */
+	commproc->cp_rccr = 0;
+
+	/* Copy the patch into DPRAM.
+	*/
+	dp = (uint *)(commproc->cp_dpmem);
+	for (i=0; i<(sizeof(patch_2000)/4); i++)
+		*dp++ = patch_2000[i];
+
+	dp = (uint *)&(commproc->cp_dpmem[0x0f00]);
+	for (i=0; i<(sizeof(patch_2f00)/4); i++)
+		*dp++ = patch_2f00[i];
+
+#ifdef USE_USB_SOF_PATCH
+#if 0 /* usb patch should not relocate iic */
+	iip = (iic_t *)&commproc->cp_dparam[PROFF_IIC];
+#define RPBASE 0x0030
+	iip->iic_rpbase = RPBASE;
+
+	/* Put SPI above the IIC, also 32-byte aligned.
+	*/
+	i = (RPBASE + sizeof(iic_t) + 31) & ~31;
+	spp = (spi_t *)&commproc->cp_dparam[PROFF_SPI];
+	spp->spi_rpbase = i;
+#endif
+
+	/* Enable uCode fetches from DPRAM. */
+	commproc->cp_rccr = 0x0009;
+
+	printk("USB uCode patch installed\n");
+#endif /* USE_USB_SOF_PATCH */
+
+#if defined(USE_SMC_PATCH) || defined(USE_IIC_PATCH)
+
+	iip = (iic_t *)&commproc->cp_dparam[PROFF_IIC];
+#define RPBASE 0x0400
+	iip->iic_rpbase = RPBASE;
+
+	/* Put SPI above the IIC, also 32-byte aligned.
+	*/
+	i = (RPBASE + sizeof(iic_t) + 31) & ~31;
+	spp = (spi_t *)&commproc->cp_dparam[PROFF_SPI];
+	spp->spi_rpbase = i;
+
+#ifdef USE_SMC_PATCH
+	dp = (uint *)&(commproc->cp_dpmem[0x0e00]);
+	for (i=0; i<(sizeof(patch_2e00)/4); i++)
+		*dp++ = patch_2e00[i];
+
+	/* Enable the traps to get to it.
+	*/
+	commproc->cp_cpmcr1 = 0x8080;
+	commproc->cp_cpmcr2 = 0x808a;
+	commproc->cp_cpmcr3 = 0x8028;
+	commproc->cp_cpmcr4 = 0x802a;
+
+	/* Enable uCode fetches from DPRAM.
+	*/
+	commproc->cp_rccr = 3;
+#endif
+
+#ifdef USE_IIC_PATCH
+	/* Enable the traps to get to it.
+	*/
+	commproc->cp_cpmcr1 = 0x802a;
+	commproc->cp_cpmcr2 = 0x8028;
+	commproc->cp_cpmcr3 = 0x802e;
+	commproc->cp_cpmcr4 = 0x802c;
+
+	/* Enable uCode fetches from DPRAM.
+	*/
+	commproc->cp_rccr = 1;
+
+	printk("I2C uCode patch installed\n");
+#endif
+
+	/* Relocate the IIC and SPI parameter areas.  These have to
+	 * aligned on 32-byte boundaries.
+	 */
+	iip = (iic_t *)&commproc->cp_dparam[PROFF_IIC];
+	iip->iic_rpbase = RPBASE;
+
+	/* Put SPI above the IIC, also 32-byte aligned.
+	*/
+	i = (RPBASE + sizeof(iic_t) + 31) & ~31;
+	spp = (spi_t *)&commproc->cp_dparam[PROFF_SPI];
+	spp->spi_rpbase = i;
+
+#endif /* USE_SMC_PATCH || USE_IIC_PATCH */
+#endif /* PATCH_DEFINED */
+}
+
+void
+verify_patch(volatile immap_t *immr)
+{
+#ifdef PATCH_DEFINED
+	volatile uint		*dp;
+	volatile cpm8xx_t	*commproc;
+	int i;
+
+	commproc = (cpm8xx_t *)&immr->im_cpm;
+
+	printk("cp_rccr %x\n", commproc->cp_rccr);
+	commproc->cp_rccr = 0;
+
+	dp = (uint *)(commproc->cp_dpmem);
+	for (i=0; i<(sizeof(patch_2000)/4); i++)
+		if (*dp++ != patch_2000[i]) {
+			printk("patch_2000 bad at %d\n", i);
+			dp--;
+			printk("found 0x%X, wanted 0x%X\n", *dp, patch_2000[i]);
+			break;
+		}
+
+	dp = (uint *)&(commproc->cp_dpmem[0x0f00]);
+	for (i=0; i<(sizeof(patch_2f00)/4); i++)
+		if (*dp++ != patch_2f00[i]) {
+			printk("patch_2f00 bad at %d\n", i);
+			dp--;
+			printk("found 0x%X, wanted 0x%X\n", *dp, patch_2f00[i]);
+			break;
+		}
+
+	commproc->cp_rccr = 0x0009;
+#endif /* PATCH_DEFINED */
+}
+
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/Makefile linux/arch/ppc/Makefile
--- v2.4.9/linux/arch/ppc/Makefile	Wed Jul 25 17:10:18 2001
+++ linux/arch/ppc/Makefile	Tue Aug 28 06:58:33 2001
@@ -1,4 +1,4 @@
-# BK Id: SCCS/s.Makefile 1.18 07/07/01 13:37:26 paulus
+# BK Id: SCCS/s.Makefile 1.21 08/19/01 20:06:47 paulus
 #
 # 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
@@ -14,6 +14,7 @@
 # Rewritten by Cort Dougan and Paul Mackerras
 #
 
+# Be sure to change PAGE_OFFSET in include/asm-ppc/page.h to match
 KERNELLOAD	=0xc0000000
 
 ifeq ($(shell uname -m),ppc)
@@ -99,5 +100,5 @@
 
 archmrproper:
 
-archdep:
+archdep: scripts/mkdep
 	$(MAKEBOOT) fastdep
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/amiga/config.c linux/arch/ppc/amiga/config.c
--- v2.4.9/linux/arch/ppc/amiga/config.c	Mon May 21 17:04:46 2001
+++ linux/arch/ppc/amiga/config.c	Fri Sep  7 09:28:38 2001
@@ -51,22 +51,22 @@
 unsigned char amiga_psfreq;
 struct amiga_hw_present amiga_hw_present;
 
-static const char s_a500[] __initdata = "A500";
-static const char s_a500p[] __initdata = "A500+";
-static const char s_a600[] __initdata = "A600";
-static const char s_a1000[] __initdata = "A1000";
-static const char s_a1200[] __initdata = "A1200";
-static const char s_a2000[] __initdata = "A2000";
-static const char s_a2500[] __initdata = "A2500";
-static const char s_a3000[] __initdata = "A3000";
-static const char s_a3000t[] __initdata = "A3000T";
-static const char s_a3000p[] __initdata = "A3000+";
-static const char s_a4000[] __initdata = "A4000";
-static const char s_a4000t[] __initdata = "A4000T";
-static const char s_cdtv[] __initdata = "CDTV";
-static const char s_cd32[] __initdata = "CD32";
-static const char s_draco[] __initdata = "Draco";
-static const char *amiga_models[] __initdata = {
+static char s_a500[] __initdata = "A500";
+static char s_a500p[] __initdata = "A500+";
+static char s_a600[] __initdata = "A600";
+static char s_a1000[] __initdata = "A1000";
+static char s_a1200[] __initdata = "A1200";
+static char s_a2000[] __initdata = "A2000";
+static char s_a2500[] __initdata = "A2500";
+static char s_a3000[] __initdata = "A3000";
+static char s_a3000t[] __initdata = "A3000T";
+static char s_a3000p[] __initdata = "A3000+";
+static char s_a4000[] __initdata = "A4000";
+static char s_a4000t[] __initdata = "A4000T";
+static char s_cdtv[] __initdata = "CDTV";
+static char s_cd32[] __initdata = "CD32";
+static char s_draco[] __initdata = "Draco";
+static char *amiga_models[] __initdata = {
     s_a500, s_a500p, s_a600, s_a1000, s_a1200, s_a2000, s_a2500, s_a3000,
     s_a3000t, s_a3000p, s_a4000, s_a4000t, s_cdtv, s_cd32, s_draco,
 };
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/boot/Makefile linux/arch/ppc/boot/Makefile
--- v2.4.9/linux/arch/ppc/boot/Makefile	Wed Jul 25 17:10:18 2001
+++ linux/arch/ppc/boot/Makefile	Tue Aug 28 06:58:33 2001
@@ -12,8 +12,8 @@
 
 GZIP_FLAGS = -v9f
 
-CFLAGS	:= $(CPPFLAGS) -O2 -DSTDC_HEADERS -fno-builtin -D__BOOTER__ \
-		-I$(TOPDIR)/arch/$(ARCH)/boot/include
+CFLAGS	+= -fno-builtin -D__BOOTER__ -I$(TOPDIR)/arch/$(ARCH)/boot/include
+
 AFLAGS	+= -D__BOOTER__
 OBJCOPY_ARGS = -O elf32-powerpc
 
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/boot/chrp/Makefile linux/arch/ppc/boot/chrp/Makefile
--- v2.4.9/linux/arch/ppc/boot/chrp/Makefile	Wed Jul 25 17:10:18 2001
+++ linux/arch/ppc/boot/chrp/Makefile	Tue Aug 28 06:58:33 2001
@@ -1,4 +1,4 @@
-# BK Id: SCCS/s.Makefile 1.10 07/19/01 09:11:27 trini
+# BK Id: SCCS/s.Makefile 1.13 07/27/01 20:24:17 trini
 #
 # Makefile for making ELF bootable images for booting on CHRP
 # using Open Firmware.
@@ -14,8 +14,6 @@
 MSIZE=
 endif
 
-CFLAGS += -fno-builtin
-
 .c.o:
 	$(CC) $(CFLAGS) -DKERNELBASE=$(KERNELBASE) -c -o $*.o $<
 .S.o:
@@ -23,7 +21,8 @@
 
 LD_ARGS = -Ttext 0x00400000
 
-OBJS = ../common/crt0.o start.o main.o misc.o ../common/string.o image.o
+OBJS = ../common/crt0.o start.o main.o misc.o ../common/string.o image.o \
+	../common/ofcommon.o
 LIBS = $(TOPDIR)/lib/lib.a ../lib/zlib.a
 ADDNOTE = ../utils/addnote
 PIGGYBACK = ../utils/piggyback
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/boot/chrp/main.c linux/arch/ppc/boot/chrp/main.c
--- v2.4.9/linux/arch/ppc/boot/chrp/main.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/ppc/boot/chrp/main.c	Tue Aug 28 06:58:33 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.main.c 1.9 06/12/01 16:42:26 paulus
+ * BK Id: SCCS/s.main.c 1.13 07/27/01 20:24:17 trini
  */
 /*
  * Copyright (C) Paul Mackerras 1997.
@@ -10,14 +10,28 @@
  * 2 of the License, or (at your option) any later version.
  */
 #include "nonstdio.h"
-#include "zlib.h"
-#include <asm/bootinfo.h>
 #include <asm/processor.h>
-#include <asm/page.h>
 
-extern void *finddevice(const char *);
+extern char _end[];
+extern char initrd_data[];
+extern char image_data[];
+extern char sysmap_data[];
 extern int getprop(void *, const char *, void *, int);
-void gunzip(void *, int, unsigned char *, int *);
+extern int initrd_len;
+extern int image_len;
+extern int sysmap_len;
+extern unsigned int heap_max;
+extern void claim(unsigned int virt, unsigned int size, unsigned int align);
+extern void *finddevice(const char *);
+extern void flush_cache(void *, unsigned long);
+extern void gunzip(void *, int, unsigned char *, int *);
+extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach,
+		unsigned int progend);
+extern void pause(void);
+
+char *avail_ram;
+char *begin_avail, *end_avail;
+char *avail_high;
 
 #define RAM_START	0x00000000
 #define RAM_END		(64<<20)
@@ -27,38 +41,28 @@
 
 #define RAM_FREE	((unsigned long)(_end+0x1000)&~0xFFF)
 #define PROG_START	0x00010000
+#define PROG_SIZE	0x00400000 /* 4MB */
 
-char *avail_ram;
-char *end_avail;
-
-extern char _end[];
-extern char image_data[];
-extern int image_len;
-extern char initrd_data[];
-extern int initrd_len;
-extern char sysmap_data[];
-extern int sysmap_len;
+#define SCRATCH_SIZE	(128 << 10)
 
-static char scratch[1024<<10];	/* 1MB of scratch space for gunzip */
+static char scratch[SCRATCH_SIZE];	/* 1MB of scratch space for gunzip */
 
+void
 chrpboot(int a1, int a2, void *prom)
 {
-    int ns, oh, i;
     unsigned sa, len;
     void *dst;
     unsigned char *im;
-    unsigned initrd_start, initrd_size;
+    unsigned initrd_start=0, initrd_size=0;
     extern char _start;
     
-    printf("chrpboot starting: loaded at 0x%x\n\r", &_start);
+    printf("chrpboot starting: loaded at 0x%p\n\r", &_start);
 
     if (initrd_len) {
 	initrd_size = initrd_len;
 	initrd_start = (RAM_END - initrd_size) & ~0xFFF;
-	a1 = initrd_start;
-	a2 = initrd_size;
 	claim(initrd_start, RAM_END - initrd_start, 0);
-	printf("initial ramdisk moving 0x%x <- 0x%x (%x bytes)\n\r",
+	printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n\r",
 	       initrd_start, initrd_data, initrd_size);
 	memcpy((char *)initrd_start, initrd_data, initrd_size);
     }
@@ -66,133 +70,31 @@
     im = image_data;
     len = image_len;
     /* claim 4MB starting at PROG_START */
-    claim(PROG_START, (4<<20) - PROG_START, 0);
+    claim(PROG_START, PROG_SIZE - PROG_START, 0);
     dst = (void *) PROG_START;
     if (im[0] == 0x1f && im[1] == 0x8b) {
 	avail_ram = scratch;
+	begin_avail = avail_high = avail_ram;
 	end_avail = scratch + sizeof(scratch);
-	printf("gunzipping (0x%x <- 0x%x:0x%0x)...", dst, im, im+len);
+	printf("gunzipping (0x%p <- 0x%p:0x%p)...", dst, im, im+len);
 	gunzip(dst, 0x400000, im, &len);
 	printf("done %u bytes\n\r", len);
+	printf("%u bytes of heap consumed, max in use %u\n\r",
+	       avail_high - begin_avail, heap_max);
     } else {
 	memmove(dst, im, len);
     }
 
     flush_cache(dst, len);
+    make_bi_recs(((unsigned long) dst + len), "chrpboot", _MACH_chrp,
+		    (PROG_START + PROG_SIZE));
     
     sa = (unsigned long)PROG_START;
     printf("start address = 0x%x\n\r", sa);
 
-    {
-	    struct bi_record *rec;
-	    
-	    rec = (struct bi_record *)_ALIGN((unsigned long)dst+len+(1<<20)-1,(1<<20));
-
-	    rec->tag = BI_FIRST;
-	    rec->size = sizeof(struct bi_record);
-	    rec = (struct bi_record *)((unsigned long)rec + rec->size);
-	    
-	    rec->tag = BI_BOOTLOADER_ID;
-	    sprintf( (char *)rec->data, "chrpboot");
-	    rec->size = sizeof(struct bi_record) + strlen("chrpboot") + 1;
-	    rec = (struct bi_record *)((unsigned long)rec + rec->size);
-	    
-	    rec->tag = BI_MACHTYPE;
-	    rec->data[0] = _MACH_chrp;
-	    rec->data[1] = 1;
-	    rec->size = sizeof(struct bi_record) + 2 * sizeof(unsigned long);
-	    rec = (struct bi_record *)((unsigned long)rec + rec->size);
-#if 0
-	    rec->tag = BI_SYSMAP;
-	    rec->data[0] = (unsigned long)sysmap_data;
-	    rec->data[1] = sysmap_len;
-	    rec->size = sizeof(struct bi_record) + 2 * sizeof(unsigned long);
-	    rec = (struct bi_record *)((unsigned long)rec + rec->size);
-#endif
-	    rec->tag = BI_LAST;
-	    rec->size = sizeof(struct bi_record);
-	    rec = (struct bi_record *)((unsigned long)rec + rec->size);
-    }
-    (*(void (*)())sa)(a1, a2, prom);
+    (*(void (*)())sa)(a1, a2, prom, initrd_start, initrd_size);
 
     printf("returned?\n\r");
 
     pause();
-}
-
-void *zalloc(void *x, unsigned items, unsigned size)
-{
-    void *p = avail_ram;
-
-    size *= items;
-    size = (size + 7) & -8;
-    avail_ram += size;
-    if (avail_ram > end_avail) {
-	printf("oops... out of memory\n\r");
-	pause();
-    }
-    return p;
-}
-
-void zfree(void *x, void *addr, unsigned nb)
-{
-    nb = (nb + 7) & -8;
-    if (addr == (avail_ram - nb)) {
-	avail_ram -= nb;
-    }
-}
-
-#define HEAD_CRC	2
-#define EXTRA_FIELD	4
-#define ORIG_NAME	8
-#define COMMENT		0x10
-#define RESERVED	0xe0
-
-#define DEFLATED	8
-
-void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
-{
-    z_stream s;
-    int r, i, flags;
-
-    /* skip header */
-    i = 10;
-    flags = src[3];
-    if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
-	printf("bad gzipped data\n\r");
-	exit();
-    }
-    if ((flags & EXTRA_FIELD) != 0)
-	i = 12 + src[10] + (src[11] << 8);
-    if ((flags & ORIG_NAME) != 0)
-	while (src[i++] != 0)
-	    ;
-    if ((flags & COMMENT) != 0)
-	while (src[i++] != 0)
-	    ;
-    if ((flags & HEAD_CRC) != 0)
-	i += 2;
-    if (i >= *lenp) {
-	printf("gunzip: ran out of data in header\n\r");
-	exit();
-    }
-
-    s.zalloc = zalloc;
-    s.zfree = zfree;
-    r = inflateInit2(&s, -MAX_WBITS);
-    if (r != Z_OK) {
-	printf("inflateInit2 returned %d\n\r", r);
-	exit();
-    }
-    s.next_in = src + i;
-    s.avail_in = *lenp - i;
-    s.next_out = dst;
-    s.avail_out = dstlen;
-    r = inflate(&s, Z_FINISH);
-    if (r != Z_OK && r != Z_STREAM_END) {
-	printf("inflate returned %d msg: %s\n\r", r, s.msg);
-	exit();
-    }
-    *lenp = s.next_out - (unsigned char *) dst;
-    inflateEnd(&s);
 }
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/boot/chrp/start.c linux/arch/ppc/boot/chrp/start.c
--- v2.4.9/linux/arch/ppc/boot/chrp/start.c	Thu May 24 15:02:06 2001
+++ linux/arch/ppc/boot/chrp/start.c	Tue Aug 28 06:58:33 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.start.c 1.6 05/18/01 15:16:59 cort
+ * BK Id: SCCS/s.start.c 1.8 07/25/01 18:13:07 trini
  */
 /*
  * Copyright (C) Paul Mackerras 1997.
@@ -24,6 +24,9 @@
 
 void printk(char *fmt, ...);
 
+extern void chrpboot(int a1, int a2, void *prom);
+extern int strlen(const char *s);
+
 void
 start(int a1, int a2, void *promptr)
 {
@@ -91,7 +94,7 @@
 }
 
 void
-exit()
+exit(void)
 {
     struct prom_args {
 	char *service;
@@ -104,7 +107,7 @@
 }
 
 void
-pause()
+pause(void)
 {
     struct prom_args {
 	char *service;
@@ -228,7 +231,7 @@
 static int lineleft;
 
 int
-getchar()
+getchar(void)
 {
     int c;
 
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/boot/common/crt0.S linux/arch/ppc/boot/common/crt0.S
--- v2.4.9/linux/arch/ppc/boot/common/crt0.S	Thu May 24 15:02:06 2001
+++ linux/arch/ppc/boot/common/crt0.S	Tue Aug 28 06:58:33 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.crt0.S 1.10 05/21/01 00:49:49 cort
+ * BK Id: SCCS/s.crt0.S 1.12 08/09/01 17:09:10 paulus
  */
 /*    Copyright (c) 1997 Paul Mackerras <paulus@cs.anu.edu.au>
  *      Initial Power Macintosh COFF version.
@@ -34,7 +34,21 @@
 	.globl	__start
 __start:
 #endif
-#ifdef CONFIG_4xx
+
+	## Flush and invalidate the caches for the range in memory covering
+	## the .text section of the boot loader
+	
+	lis	r9,_start@h		# r9 = &_start
+	lis	r8,_etext@ha		# 
+	addi	r8,r8,_etext@l		# r8 = &_etext
+3:	dcbf	r0,r9			# Flush the data cache
+	icbi	r0,r9			# Invalidate the instruction cache
+	addi	r9,r9,0x10		# Increment by one cache line
+	cmplw	cr0,r9,r8		# Are we at the end yet?
+	blt	3b			# No, keep flushing and invalidating
+	sync				# sync ; isync after flushing the icache
+	isync
+
 	## Clear out the BSS as per ANSI C requirements
 
 	lis	r7,_end@ha
@@ -53,21 +67,7 @@
 	li	r0,0			# r0 = 0
 1:	stwu	r0,4(r8)		# Clear out a word
 	bdnz	1b			# If we are not done yet, keep clearing
-#endif
-
-	## Flush and invalidate the caches for the range in memory covering
-	## the .text section of the boot loader
-	
-2:	lis	r9,_start@h		# r9 = &_start
-	lis	r8,_etext@ha		# 
-	addi	r8,r8,_etext@l		# r8 = &_etext
-3:	dcbf	r0,r9			# Flush the data cache
-	icbi	r0,r9			# Invalidate the instruction cache
-	addi	r9,r9,0x10		# Increment by one cache line
-	cmplw	cr0,r9,r8		# Are we at the end yet?
-	blt	3b			# No, keep flushing and invalidating
-	sync				# sync ; isync after flushing the icache
-	isync
+2:
 
 #ifdef CONFIG_4xx
 	## Set up the stack
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/boot/common/misc-common.c linux/arch/ppc/boot/common/misc-common.c
--- v2.4.9/linux/arch/ppc/boot/common/misc-common.c	Wed Jul 25 17:10:18 2001
+++ linux/arch/ppc/boot/common/misc-common.c	Tue Aug 28 06:58:33 2001
@@ -31,9 +31,10 @@
  * 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <stdarg.h>	/* for va_ bits */
 #include <linux/config.h>
 #include "zlib.h"
-#include <linux/pci.h>
+#include "nonstdio.h"
 
 /* If we're on a ALL_PPC, assume we have a keyboard controller
  * Also note, if we're not ALL_PPC, we assume you are a serial
@@ -71,14 +72,15 @@
 void gunzip(void *, int, unsigned char *, int *);
 static int _cvt(unsigned long val, char *buf, long radix, char *digits);
 
-void _vprintk(void(*)(const char), const char *, va_list);
+void _vprintk(void(*putc)(const char), const char *fmt0, va_list ap);
+unsigned char *ISA_io = NULL;
 
 #if defined(CONFIG_SERIAL_CONSOLE)
 extern unsigned long com_port;
 
-extern int serial_tstc(volatile unsigned long com_port);
-extern unsigned char serial_getc(volatile unsigned long com_port);
-extern void serial_putc(volatile unsigned long com_port, unsigned char c);
+extern int serial_tstc(unsigned long com_port);
+extern unsigned char serial_getc(unsigned long com_port);
+extern void serial_putc(unsigned long com_port, unsigned char c);
 #endif
 
 void pause(void)
@@ -301,7 +303,6 @@
 
 #define FALSE 0
 #define TRUE  1
-#include <stdarg.h>
 
 void
 _printk(char const *fmt, ...)
@@ -528,6 +529,28 @@
 {
 	_printk("\n");
 	_dump_buf_with_offset(p, s, 0);
+}
+
+/* Very simple inb/outb routines.  We declare ISA_io to be 0 above, and
+ * then modify it on platforms which need to.  We do it like this
+ * because on some platforms we give inb/outb an exact location, and
+ * on others it's an offset from a given location. -- Tom
+ */
+
+void
+outb(int port, unsigned char val)
+{
+	/* Ensure I/O operations complete */
+	__asm__ volatile("eieio");
+	ISA_io[port] = val;
+}
+
+unsigned char
+inb(int port)
+{
+	/* Ensure I/O operations complete */
+	__asm__ volatile("eieio");
+	return (ISA_io[port]);
 }
 
 /*
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/boot/common/misc-simple.c linux/arch/ppc/boot/common/misc-simple.c
--- v2.4.9/linux/arch/ppc/boot/common/misc-simple.c	Thu May 24 15:02:06 2001
+++ linux/arch/ppc/boot/common/misc-simple.c	Tue Aug 28 06:58:33 2001
@@ -26,6 +26,7 @@
 #include <asm/processor.h>
 #include <asm/mmu.h>
 
+#include "nonstdio.h"
 #include "zlib.h"
 
 unsigned long com_port;
@@ -47,16 +48,8 @@
 char *zimage_start;
 int zimage_size;
 
-extern void puts(const char *);
-extern void putc(const char c);
-extern void puthex(unsigned long val);
-extern void *memcpy(void * __dest, __const void * __src,
-			    __kernel_size_t __n);
 extern void gunzip(void *, int, unsigned char *, int *);
-extern void udelay(long delay);
-extern int tstc(void);
-extern int getc(void);
-extern volatile unsigned long serial_init(int chan);
+extern unsigned long serial_init(int chan);
 
 void
 decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum)
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/boot/common/ns16550.c linux/arch/ppc/boot/common/ns16550.c
--- v2.4.9/linux/arch/ppc/boot/common/ns16550.c	Thu May 24 15:02:06 2001
+++ linux/arch/ppc/boot/common/ns16550.c	Tue Aug 28 06:58:33 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.ns16550.c 1.7 05/18/01 06:20:29 patch
+ * BK Id: SCCS/s.ns16550.c 1.9 07/30/01 17:19:40 trini
  */
 /*
  * COM1 NS16550 support
@@ -10,12 +10,9 @@
 #include <linux/serial_reg.h>
 #include <asm/serial.h>
 
-/* Some machines, such as ones with a PReP memory map, initally have
- * their serial port at an offset of 0x80000000 from where they are
- * in <asm/serial.h>.  This tries to take that into account. */
-#ifndef IOOFFSET
-#define IOOFFSET 0
-#endif
+extern void outb(int port, unsigned char val);
+extern unsigned char inb(int port);
+extern unsigned long ISA_io;
 
 static struct serial_state rs_table[RS_TABLE_SIZE] = {
 	SERIAL_PORT_DFNS	/* Defined in <asm/serial.h> */
@@ -23,58 +20,67 @@
 
 static int shift;
 
-volatile unsigned long serial_init(int chan) {
+unsigned long serial_init(int chan) {
 	unsigned long com_port;
 
-	/* Get the base, and add any offset we need to deal with. */
-	com_port = rs_table[chan].port + IOOFFSET;
+	/* We need to find out which type io we're expecting.  If it's
+	 * 'SERIAL_IO_PORT', we get an offset from the isa_io_base.
+	 * If it's 'SERIAL_IO_MEM', we can the exact location.  -- Tom */
+	switch (rs_table[chan].io_type) {
+		case SERIAL_IO_PORT:
+			com_port = rs_table[chan].port;
+			break;
+		case SERIAL_IO_MEM:
+			com_port = (unsigned long)rs_table[chan].iomem_base;
+			break;
+		default:
+			/* We can't deal with it. */
+			return -1;
+	}
 
 	/* How far apart the registers are. */
 	shift = rs_table[chan].iomem_reg_shift;
 
 	/* See if port is present */
-	*((unsigned char *)com_port + (UART_LCR << shift)) = 0x00;
-	*((unsigned char *)com_port + (UART_IER << shift)) = 0x00;
+	outb(com_port + (UART_LCR << shift), 0x00);
+	outb(com_port + (UART_IER << shift), 0x00);
 	/* Access baud rate */
-	*((unsigned char *)com_port + (UART_LCR << shift)) = 0x00;
+	outb(com_port + (UART_LCR << shift), 0x80);
 #ifdef CONFIG_SERIAL_CONSOLE_NONSTD
 	/* Input clock. */
-	*((unsigned char *)com_port + (UART_DLL << shift)) = 
-			(BASE_BAUD / CONFIG_SERIAL_CONSOLE_BAUD);
-	*((unsigned char *)com_port + (UART_DLM << shift)) = 
-		(BASE_BAUD / CONFIG_SERIAL_CONSOLE_BAUD) >> 8;
+	outb(com_port + (UART_DLL << shift), 
+			(BASE_BAUD / CONFIG_SERIAL_CONSOLE_BAUD));
+	outb(com_port + (UART_DLM << shift), 
+		(BASE_BAUD / CONFIG_SERIAL_CONSOLE_BAUD) >> 8);
 #endif
 	 /* 8 data, 1 stop, no parity */
-	*((unsigned char *)com_port + (UART_LCR << shift)) = 0x03;
+	outb(com_port + (UART_LCR << shift), 0x03);
 	/* RTS/DTR */
-	*((unsigned char *)com_port + (UART_MCR << shift)) = 0x03;
+	outb(com_port + (UART_MCR << shift), 0x03);
 	/* Clear & enable FIFOs */
-	*((unsigned char *)com_port + (UART_FCR << shift)) = 0x07;
+	outb(com_port + (UART_FCR << shift), 0x07);
 
 	return (com_port);
 }
 
 void
-serial_putc(volatile unsigned long com_port, unsigned char c)
+serial_putc(unsigned long com_port, unsigned char c)
 {
-	while ((*((volatile unsigned char *)com_port + (UART_LSR << shift)) &
-				UART_LSR_THRE) == 0)
+	while ((inb(com_port + (UART_LSR << shift)) & UART_LSR_THRE) == 0)
 		;
-	*(volatile unsigned char *)com_port = c;
+	outb(com_port, c);
 }
 
 unsigned char
-serial_getc(volatile unsigned long com_port)
+serial_getc(unsigned long com_port)
 {
-	while ((*((volatile unsigned char *)com_port + (UART_LSR << shift))
-			& UART_LSR_DR) == 0)
+	while ((inb(com_port + (UART_LSR << shift)) & UART_LSR_DR) == 0)
 		;
-	return (*(volatile unsigned char *)com_port);
+	return inb(com_port);
 }
 
 int
-serial_tstc(volatile unsigned long com_port)
+serial_tstc(unsigned long com_port)
 {
-	return ((*((volatile unsigned char *)com_port + (UART_LSR << shift))
-				& UART_LSR_DR) != 0);
+	return ((inb(com_port + (UART_LSR << shift)) & UART_LSR_DR) != 0);
 }
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/boot/common/ofcommon.c linux/arch/ppc/boot/common/ofcommon.c
--- v2.4.9/linux/arch/ppc/boot/common/ofcommon.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/boot/common/ofcommon.c	Tue Aug 28 06:58:33 2001
@@ -0,0 +1,171 @@
+/*
+ * BK Id: SCCS/s.ofcommon.c 1.1 07/27/01 20:24:18 trini
+ *
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * 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 "zlib.h"
+#include "nonstdio.h"
+#include <asm/bootinfo.h>
+#include <asm/page.h>
+
+extern int strcmp(const char *s1, const char *s2);
+extern char *avail_ram, *avail_high;
+extern char *end_avail;
+extern void claim(unsigned int virt, unsigned int size, unsigned int align);
+extern void pause(void);
+
+unsigned int heap_use, heap_max;
+
+struct memchunk {
+    unsigned int size;
+    struct memchunk *next;
+};
+
+static struct memchunk *freechunks;
+
+static void *zalloc(void *x, unsigned items, unsigned size)
+{
+    void *p;
+    struct memchunk **mpp, *mp;
+
+    size *= items;
+    size = (size + 7) & -8;
+    heap_use += size;
+    if (heap_use > heap_max)
+	heap_max = heap_use;
+    for (mpp = &freechunks; (mp = *mpp) != 0; mpp = &mp->next) {
+	if (mp->size == size) {
+	    *mpp = mp->next;
+	    return mp;
+	}
+    }
+    p = avail_ram;
+    avail_ram += size;
+    if (avail_ram > avail_high)
+	avail_high = avail_ram;
+    if (avail_ram > end_avail) {
+	printf("oops... out of memory\n\r");
+	pause();
+    }
+    return p;
+}
+
+static void zfree(void *x, void *addr, unsigned nb)
+{
+    struct memchunk *mp = addr;
+
+    nb = (nb + 7) & -8;
+    heap_use -= nb;
+    if (avail_ram == addr + nb) {
+	avail_ram = addr;
+	return;
+    }
+    mp->size = nb;
+    mp->next = freechunks;
+    freechunks = mp;
+}
+
+#define HEAD_CRC	2
+#define EXTRA_FIELD	4
+#define ORIG_NAME	8
+#define COMMENT		0x10
+#define RESERVED	0xe0
+
+#define DEFLATED	8
+
+void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
+{
+    z_stream s;
+    int r, i, flags;
+
+    /* skip header */
+    i = 10;
+    flags = src[3];
+    if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
+	printf("bad gzipped data\n\r");
+	exit();
+    }
+    if ((flags & EXTRA_FIELD) != 0)
+	i = 12 + src[10] + (src[11] << 8);
+    if ((flags & ORIG_NAME) != 0)
+	while (src[i++] != 0)
+	    ;
+    if ((flags & COMMENT) != 0)
+	while (src[i++] != 0)
+	    ;
+    if ((flags & HEAD_CRC) != 0)
+	i += 2;
+    if (i >= *lenp) {
+	printf("gunzip: ran out of data in header\n\r");
+	exit();
+    }
+
+    s.zalloc = zalloc;
+    s.zfree = zfree;
+    r = inflateInit2(&s, -MAX_WBITS);
+    if (r != Z_OK) {
+	printf("inflateInit2 returned %d\n\r", r);
+	exit();
+    }
+    s.next_in = src + i;
+    s.avail_in = *lenp - i;
+    s.next_out = dst;
+    s.avail_out = dstlen;
+    r = inflate(&s, Z_FINISH);
+    if (r != Z_OK && r != Z_STREAM_END) {
+	printf("inflate returned %d msg: %s\n\r", r, s.msg);
+	exit();
+    }
+    *lenp = s.next_out - (unsigned char *) dst;
+    inflateEnd(&s);
+}
+
+/* Make a bi_rec in OF.  We need to be passed a name for BI_BOOTLOADER_ID, 
+ * a machine type for BI_MACHTYPE, and the location where the end of the
+ * bootloader is (PROG_START + PROG_SIZE)
+ */
+void make_bi_recs(unsigned long addr, char *name, unsigned int mach,
+		unsigned long progend)
+{
+	struct bi_record *rec;
+
+	/* leave a 1MB gap then align to the next 1MB boundary */
+	addr = _ALIGN(addr+ (1<<20) - 1, (1<<20));
+	/* oldworld machine seem very unhappy about this. -- Tom */
+	if (addr >= progend)
+		claim(addr, 0x1000, 0);
+
+	rec = (struct bi_record *)addr;
+	rec->tag = BI_FIRST;
+	rec->size = sizeof(struct bi_record);
+	rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+	rec->tag = BI_BOOTLOADER_ID;
+	sprintf( (char *)rec->data, name);
+	rec->size = sizeof(struct bi_record) + strlen(name) + 1;
+	rec = (struct bi_record *)((unsigned long)rec + rec->size);
+	    
+	rec->tag = BI_MACHTYPE;
+	rec->data[0] = mach;
+	rec->data[1] = 1;
+	rec->size = sizeof(struct bi_record) + 2 * sizeof(unsigned long);
+	rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+#ifdef SYSMAP_OFFSET
+	rec->tag = BI_SYSMAP;
+	rec->data[0] = SYSMAP_OFFSET;
+	rec->data[1] = SYSMAP_SIZE;
+	rec->size = sizeof(struct bi_record) + 2 * sizeof(unsigned long);
+	rec = (struct bi_record *)((unsigned long)rec + rec->size);
+#endif /* SYSMAP_OFFSET */
+	
+	rec->tag = BI_LAST;
+	rec->size = sizeof(struct bi_record);
+	rec = (struct bi_record *)((unsigned long)rec + rec->size);
+}
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/boot/include/nonstdio.h linux/arch/ppc/boot/include/nonstdio.h
--- v2.4.9/linux/arch/ppc/boot/include/nonstdio.h	Thu May 24 15:02:06 2001
+++ linux/arch/ppc/boot/include/nonstdio.h	Tue Aug 28 06:58:33 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.nonstdio.h 1.7 05/18/01 15:17:23 cort
+ * BK Id: SCCS/s.nonstdio.h 1.9 07/25/01 18:13:07 trini
  */
 /*
  * Copyright (C) Paul Mackerras 1997.
@@ -8,14 +8,31 @@
  * 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 is sort of a catchall for I/O related functions.  Stuff that
+ * wouldn't be in 'stdio.h' normally is here, and it's 'nonstdio.h'
+ * for a reason.  -- Tom
  */
-typedef int	FILE;
+typedef int FILE;
 extern FILE *stdin, *stdout;
-#define NULL	((void *)0)
-#define EOF	(-1)
-#define fopen(n, m)	NULL
-#define fflush(f)	0
-#define fclose(f)	0
-extern char *fgets();
+#define NULL ((void *)0)
+#define EOF (-1)
+#define fopen(n, m) NULL
+#define fflush(f) 0
+#define fclose(f) 0
+#define perror(s) printf("%s: no files!\n", (s))
 
-#define perror(s)	printf("%s: no files!\n", (s))
+extern int getc(void);
+extern int printf(const char *format, ...);
+extern int strlen(const char *s);
+extern int sprintf(char *str, const char *format, ...);
+extern int tstc(void);
+extern void exit(void);
+extern void *memcpy(void *dest, const void *src, int n);
+extern void *memmove(void *dest, const void *src, int n);
+extern void outb(int port, unsigned char val);
+extern void putc(const char c);
+extern void puthex(unsigned long val);
+extern void puts(const char *);
+extern void udelay(long delay);
+extern unsigned char inb(int port);
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/boot/mbx/misc.c linux/arch/ppc/boot/mbx/misc.c
--- v2.4.9/linux/arch/ppc/boot/mbx/misc.c	Wed Jul 25 17:10:18 2001
+++ linux/arch/ppc/boot/mbx/misc.c	Tue Aug 28 06:58:33 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.misc.c 1.11 07/18/01 15:46:50 trini
+ * BK Id: SCCS/s.misc.c 1.13 07/27/01 11:44:37 trini
  */
 /*
  * Adapted for PowerPC by Gary Thomas
@@ -23,6 +23,8 @@
 #include <asm/mpc8260.h>
 #endif
 
+#include "nonstdio.h"
+
 /*
  * The following references are needed to cause the linker to pull in the
  * gzimage.o and rdimage.o files.  These object files are special,
@@ -75,14 +77,7 @@
 char *zimage_start;
 int zimage_size;
 
-extern void puts(const char *);
-extern void putc(const char c);
-extern void udelay(long x);
-extern void puthex(unsigned long val);
-extern void * memcpy(void * __dest, __const void * __src, __kernel_size_t __n);
 extern void gunzip(void *, int, unsigned char *, int *);
-extern int tstc(void);
-extern int getc(void);
 
 unsigned long
 decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, bd_t *bp)
@@ -267,33 +262,4 @@
 	puts("done.\n");
 	puts("Now booting the kernel\n");
 	return (unsigned long)hold_residual;
-}
-
-/*
- * PCI/ISA I/O support
- */
-
-volatile unsigned char *ISA_io  = (unsigned char *)0x80000000;
-volatile unsigned char *ISA_mem = (unsigned char *)0xC0000000;
-
-void
-outb(int port, char val)
-{
-	/* Ensure I/O operations complete */
-	__asm__ volatile("eieio");
-	ISA_io[port] = val;
-}
-
-unsigned char
-inb(int port)
-{
-	/* Ensure I/O operations complete */
-	__asm__ volatile("eieio");
-	return (ISA_io[port]);
-}
-
-unsigned long
-local_to_PCI(unsigned long addr)
-{
-	return ((addr & 0x7FFFFFFF) | 0x80000000);
 }
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/boot/pmac/Makefile linux/arch/ppc/boot/pmac/Makefile
--- v2.4.9/linux/arch/ppc/boot/pmac/Makefile	Wed Jul 25 17:10:18 2001
+++ linux/arch/ppc/boot/pmac/Makefile	Tue Aug 28 06:58:33 2001
@@ -1,4 +1,4 @@
-# BK Id: SCCS/s.Makefile 1.12 07/19/01 09:11:28 trini
+# BK Id: SCCS/s.Makefile 1.14 07/27/01 20:24:17 trini
 #
 # Makefile for making XCOFF bootable images for booting on PowerMacs
 # using Open Firmware.
@@ -12,12 +12,10 @@
 COFF_LD_ARGS = -e _start -T ld.script -Ttext 500000 -Tdata 510000 -Bstatic
 CHRP_LD_ARGS = -Ttext 0x01000000
 
-COMMONOBJS = start.o misc.o ../common/string.o image.o
+COMMONOBJS = start.o misc.o ../common/string.o image.o ../common/ofcommon.o
 COFFOBJS = ../common/coffcrt0.o $(COMMONOBJS) coffmain.o
 CHRPOBJS = ../common/crt0.o $(COMMONOBJS) chrpmain.o
 LIBS = $(TOPDIR)/lib/lib.a ../lib/zlib.a
-
-CFLAGS += -fno-builtin
 
 MKNOTE := ../utils/mknote
 SIZE := ../utils/size
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/boot/pmac/chrpmain.c linux/arch/ppc/boot/pmac/chrpmain.c
--- v2.4.9/linux/arch/ppc/boot/pmac/chrpmain.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/ppc/boot/pmac/chrpmain.c	Tue Aug 28 06:58:33 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.chrpmain.c 1.12 06/12/01 16:42:26 paulus
+ * BK Id: SCCS/s.chrpmain.c 1.16 07/27/01 20:24:18 trini
  */
 /*
  * Copyright (C) Paul Mackerras 1997.
@@ -11,21 +11,26 @@
  */
 #include "nonstdio.h"
 #include "zlib.h"
-#include <asm/bootinfo.h>
 #include <asm/processor.h>
-#include <asm/page.h>
 
-extern void *finddevice(const char *);
+extern char _end[];
+extern char image_data[], initrd_data[];
+extern int image_len, initrd_len;
 extern int getprop(void *, const char *, void *, int);
+extern unsigned int heap_max;
 extern void *claim(unsigned int, unsigned int, unsigned int);
+extern void *finddevice(const char *);
+extern void flush_cache(void *start, unsigned int len);
+extern void gunzip(void *, int, unsigned char *, int *);
+extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach,
+		unsigned int progend);
+extern void pause(void);
 extern void release(void *ptr, unsigned int len);
-void make_bi_recs(unsigned long);
-void gunzip(void *, int, unsigned char *, int *);
-void stop_imac_ethernet(void);
-void stop_imac_usb(void);
 
-#define get_16be(x)	(*(unsigned short *)(x))
-#define get_32be(x)	(*(unsigned *)(x))
+char *avail_ram;
+char *begin_avail, *end_avail;
+char *avail_high;
+
 
 #define RAM_END		(16 << 20)
 
@@ -34,36 +39,22 @@
 
 #define SCRATCH_SIZE	(128 << 10)
 
-char *avail_ram;
-char *begin_avail, *end_avail;
-char *avail_high;
-unsigned int heap_use;
-unsigned int heap_max;
-
-extern char _end[];
-extern char image_data[];
-extern int image_len;
-extern char initrd_data[];
-extern int initrd_len;
-
-
-boot(int a1, int a2, void *prom)
+void boot(int a1, int a2, void *prom)
 {
-    int ns, oh, i;
     unsigned sa, len;
     void *dst;
     unsigned char *im;
     unsigned initrd_start, initrd_size;
     extern char _start;
     
-    printf("chrpboot starting: loaded at 0x%x\n", &_start);
+    printf("chrpboot starting: loaded at 0x%p\n", &_start);
     if (initrd_len) {
 	initrd_size = initrd_len;
 	initrd_start = (RAM_END - initrd_size) & ~0xFFF;
 	a1 = initrd_start;
 	a2 = initrd_size;
 	claim(initrd_start, RAM_END - initrd_start, 0);
-	printf("initial ramdisk moving 0x%x <- 0x%x (%x bytes)\n", initrd_start,
+	printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n", initrd_start,
 	       initrd_data,initrd_size);
 	memcpy((char *)initrd_start, initrd_data, initrd_size);
     }
@@ -77,8 +68,8 @@
 	avail_ram = (char *) claim(0, SCRATCH_SIZE, 0x10);
 	begin_avail = avail_high = avail_ram;
 	end_avail = avail_ram + SCRATCH_SIZE;
-	printf("heap at 0x%x\n", avail_ram);
-	printf("gunzipping (0x%x <- 0x%x:0x%0x)...", dst, im, im+len);
+	printf("heap at 0x%p\n", avail_ram);
+	printf("gunzipping (0x%p <- 0x%p:0x%p)...", dst, im, im+len);
 	gunzip(dst, PROG_SIZE, im, &len);
 	printf("done %u bytes\n", len);
 	printf("%u bytes of heap consumed, max in use %u\n",
@@ -89,7 +80,8 @@
     }
 
     flush_cache(dst, len);
-    make_bi_recs((unsigned long) dst + len);
+    make_bi_recs(((unsigned long) dst + len), "chrpboot", _MACH_Pmac,
+		    (PROG_START + PROG_SIZE));
 
     sa = (unsigned long)PROG_START;
     printf("start address = 0x%x\n", sa);
@@ -99,199 +91,4 @@
     printf("returned?\n");
 
     pause();
-}
-
-void make_bi_recs(unsigned long addr)
-{
-	struct bi_record *rec;
-
-	/* leave a 1MB gap then align to the next 1MB boundary */
-	addr = _ALIGN(addr+ (1<<20) - 1, (1<<20));
-	if (addr >= PROG_START + PROG_SIZE)
-		claim(addr, 0x1000, 0);
-
-	rec = (struct bi_record *)addr;
-	rec->tag = BI_FIRST;
-	rec->size = sizeof(struct bi_record);
-	rec = (struct bi_record *)((unsigned long)rec + rec->size);
-
-	rec->tag = BI_BOOTLOADER_ID;
-	sprintf( (char *)rec->data, "coffboot");
-	rec->size = sizeof(struct bi_record) + strlen("coffboot") + 1;
-	rec = (struct bi_record *)((unsigned long)rec + rec->size);
-	    
-	rec->tag = BI_MACHTYPE;
-	rec->data[0] = _MACH_Pmac;
-	rec->data[1] = 1;
-	rec->size = sizeof(struct bi_record) + 2 * sizeof(unsigned long);
-	rec = (struct bi_record *)((unsigned long)rec + rec->size);
-
-#ifdef SYSMAP_OFFSET
-	rec->tag = BI_SYSMAP;
-	rec->data[0] = SYSMAP_OFFSET;
-	rec->data[1] = SYSMAP_SIZE;
-	rec->size = sizeof(struct bi_record) + 2 * sizeof(unsigned long);
-	rec = (struct bi_record *)((unsigned long)rec + rec->size);
-#endif /* SYSMAP_OFFSET */
-	
-	rec->tag = BI_LAST;
-	rec->size = sizeof(struct bi_record);
-	rec = (struct bi_record *)((unsigned long)rec + rec->size);
-}
-
-#if 0
-#define eieio()	asm volatile("eieio");
-
-void stop_imac_ethernet(void)
-{
-    void *macio, *enet;
-    unsigned int macio_addr[5], enet_reg[6];
-    int len;
-    volatile unsigned int *dbdma;
-
-    macio = finddevice("/pci/mac-io");
-    enet = finddevice("/pci/mac-io/ethernet");
-    if (macio == NULL || enet == NULL)
-	return;
-    len = getprop(macio, "assigned-addresses", macio_addr, sizeof(macio_addr));
-    if (len != sizeof(macio_addr))
-	return;
-    len = getprop(enet, "reg", enet_reg, sizeof(enet_reg));
-    if (len != sizeof(enet_reg))
-	return;
-    printf("macio base %x, dma at %x & %x\n",
-	   macio_addr[2], enet_reg[2], enet_reg[4]);
-
-    /* hope this is mapped... */
-    dbdma = (volatile unsigned int *) (macio_addr[2] + enet_reg[2]);
-    *dbdma = 0x80;	/* clear the RUN bit */
-    eieio();
-    dbdma = (volatile unsigned int *) (macio_addr[2] + enet_reg[4]);
-    *dbdma = 0x80;	/* clear the RUN bit */
-    eieio();
-}
-
-void stop_imac_usb(void)
-{
-    void *usb;
-    unsigned int usb_addr[5];
-    int len;
-    volatile unsigned int *usb_ctrl;
-
-    usb = finddevice("/pci/usb");
-    if (usb == NULL)
-	return;
-    len = getprop(usb, "assigned-addresses", usb_addr, sizeof(usb_addr));
-    if (len != sizeof(usb_addr))
-	return;
-    printf("usb base %x\n", usb_addr[2]);
-
-    usb_ctrl = (volatile unsigned int *) (usb_addr[2] + 8);
-    *usb_ctrl = 0x01000000;	/* cpu_to_le32(1) */
-    eieio();
-}
-#endif
-
-struct memchunk {
-    unsigned int size;
-    struct memchunk *next;
-};
-
-static struct memchunk *freechunks;
-
-void *zalloc(void *x, unsigned items, unsigned size)
-{
-    void *p;
-    struct memchunk **mpp, *mp;
-
-    size *= items;
-    size = (size + 7) & -8;
-    heap_use += size;
-    if (heap_use > heap_max)
-	heap_max = heap_use;
-    for (mpp = &freechunks; (mp = *mpp) != 0; mpp = &mp->next) {
-	if (mp->size == size) {
-	    *mpp = mp->next;
-	    return mp;
-	}
-    }
-    p = avail_ram;
-    avail_ram += size;
-    if (avail_ram > avail_high)
-	avail_high = avail_ram;
-    if (avail_ram > end_avail) {
-	printf("oops... out of memory\n");
-	pause();
-    }
-    return p;
-}
-
-void zfree(void *x, void *addr, unsigned nb)
-{
-    struct memchunk *mp = addr;
-
-    nb = (nb + 7) & -8;
-    heap_use -= nb;
-    if (avail_ram == addr + nb) {
-	avail_ram = addr;
-	return;
-    }
-    mp->size = nb;
-    mp->next = freechunks;
-    freechunks = mp;
-}
-
-#define HEAD_CRC	2
-#define EXTRA_FIELD	4
-#define ORIG_NAME	8
-#define COMMENT		0x10
-#define RESERVED	0xe0
-
-#define DEFLATED	8
-
-void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
-{
-    z_stream s;
-    int r, i, flags;
-
-    /* skip header */
-    i = 10;
-    flags = src[3];
-    if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
-	printf("bad gzipped data\n");
-	exit();
-    }
-    if ((flags & EXTRA_FIELD) != 0)
-	i = 12 + src[10] + (src[11] << 8);
-    if ((flags & ORIG_NAME) != 0)
-	while (src[i++] != 0)
-	    ;
-    if ((flags & COMMENT) != 0)
-	while (src[i++] != 0)
-	    ;
-    if ((flags & HEAD_CRC) != 0)
-	i += 2;
-    if (i >= *lenp) {
-	printf("gunzip: ran out of data in header\n");
-	exit();
-    }
-
-    s.zalloc = zalloc;
-    s.zfree = zfree;
-    r = inflateInit2(&s, -MAX_WBITS);
-    if (r != Z_OK) {
-	printf("inflateInit2 returned %d\n", r);
-	exit();
-    }
-    s.next_in = src + i;
-    s.avail_in = *lenp - i;
-    s.next_out = dst;
-    s.avail_out = dstlen;
-    r = inflate(&s, Z_FINISH);
-    if (r != Z_OK && r != Z_STREAM_END) {
-	printf("inflate returned %d msg: %s\n", r, s.msg);
-	exit();
-    }
-    *lenp = s.next_out - (unsigned char *) dst;
-    inflateEnd(&s);
 }
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/boot/pmac/coffmain.c linux/arch/ppc/boot/pmac/coffmain.c
--- v2.4.9/linux/arch/ppc/boot/pmac/coffmain.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/ppc/boot/pmac/coffmain.c	Tue Aug 28 06:58:33 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.coffmain.c 1.12 06/12/01 16:42:26 paulus
+ * BK Id: SCCS/s.coffmain.c 1.14 07/27/01 20:24:18 trini
  */
 /*
  * Copyright (C) Paul Mackerras 1997.
@@ -11,18 +11,25 @@
  */
 #include "nonstdio.h"
 #include "zlib.h"
-#include <asm/bootinfo.h>
 #include <asm/processor.h>
-#include <asm/page.h>
 
-extern void *finddevice(const char *);
-extern int getprop(void *, const char *, void *, int);
+extern char _start[], _end[];
 extern char *claim(unsigned, unsigned, unsigned);
-void make_bi_recs(unsigned long);
-void gunzip(void *, int, unsigned char *, int *);
+extern char image_data[], initrd_data[];
+extern int initrd_len, image_len;
+extern int getprop(void *, const char *, void *, int);
+extern unsigned int heap_max;
+extern void *finddevice(const char *);
+extern void flush_cache(void *start, unsigned int len);
+extern void gunzip(void *, int, unsigned char *, int *);
+extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach,
+		unsigned int progend);
+extern void pause(void);
+extern void setup_bats(unsigned long start);
 
-#define get_16be(x)	(*(unsigned short *)(x))
-#define get_32be(x)	(*(unsigned *)(x))
+char *avail_ram;
+char *begin_avail, *end_avail;
+char *avail_high;
 
 #define RAM_START	0
 #define RAM_END		(RAM_START + 0x800000)	/* only 8M mapped with BATs */
@@ -32,29 +39,16 @@
 
 #define SCRATCH_SIZE	(128 << 10)
 
-char *avail_ram;
-char *begin_avail, *end_avail;
-char *avail_high;
-unsigned int heap_use;
-unsigned int heap_max;
-
-extern char _start[], _end[];
-extern char image_data[];
-extern int image_len;
-extern char initrd_data[];
-extern int initrd_len;
+static char heap[SCRATCH_SIZE];
 
-char heap[SCRATCH_SIZE];
-
-boot(int a1, int a2, void *prom)
+void boot(int a1, int a2, void *prom)
 {
-    int ns, oh, i;
     unsigned sa, len;
     void *dst;
     unsigned char *im;
     unsigned initrd_start, initrd_size;
     
-    printf("coffboot starting: loaded at 0x%x\n", _start);
+    printf("coffboot starting: loaded at 0x%p\n", &_start);
     setup_bats(RAM_START);
     if (initrd_len) {
 	initrd_size = initrd_len;
@@ -62,21 +56,21 @@
 	a1 = initrd_start;
 	a2 = initrd_size;
 	claim(initrd_start - RAM_START, RAM_END - initrd_start, 0);
-	printf("initial ramdisk moving 0x%x <- 0x%x (%x bytes)\n",
+	printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n",
 	       initrd_start, initrd_data, initrd_size);
 	memcpy((char *)initrd_start, initrd_data, initrd_size);
     }
     im = image_data;
     len = image_len;
-    /* claim 3MB starting at 0 */
+    /* claim 4MB starting at 0 */
     claim(0, PROG_SIZE, 0);
     dst = (void *) RAM_START;
     if (im[0] == 0x1f && im[1] == 0x8b) {
 	/* set up scratch space */
 	begin_avail = avail_high = avail_ram = heap;
 	end_avail = heap + sizeof(heap);
-	printf("heap at 0x%x\n", avail_ram);
-	printf("gunzipping (0x%x <- 0x%x:0x%0x)...", dst, im, im+len);
+	printf("heap at 0x%p\n", avail_ram);
+	printf("gunzipping (0x%p <- 0x%p:0x%p)...", dst, im, im+len);
 	gunzip(dst, PROG_SIZE, im, &len);
 	printf("done %u bytes\n", len);
 	printf("%u bytes of heap consumed, max in use %u\n",
@@ -86,8 +80,9 @@
     }
 
     flush_cache(dst, len);
-    make_bi_recs((unsigned long)dst + len);
-    
+    make_bi_recs(((unsigned long) dst + len), "coffboot", _MACH_Pmac,
+		    (PROG_START + PROG_SIZE));
+
     sa = (unsigned long)PROG_START;
     printf("start address = 0x%x\n", sa);
 
@@ -96,139 +91,4 @@
     printf("returned?\n");
 
     pause();
-}
-
-void make_bi_recs(unsigned long addr)
-{
-	struct bi_record *rec;
-
-	addr = _ALIGN(addr+ (1<<20) - 1, (1<<20));
-#if 0
-	if (addr >= PROG_START + PROG_SIZE)
-		claim(addr, 0x1000, 0);
-#endif
-
-	rec = (struct bi_record *)addr;
-	rec->tag = BI_FIRST;
-	rec->size = sizeof(struct bi_record);
-	rec = (struct bi_record *)((unsigned long)rec + rec->size);
-
-	rec->tag = BI_BOOTLOADER_ID;
-	sprintf( (char *)rec->data, "coffboot");
-	rec->size = sizeof(struct bi_record) + strlen("coffboot") + 1;
-	rec = (struct bi_record *)((unsigned long)rec + rec->size);
-
-	rec->tag = BI_MACHTYPE;
-	rec->data[0] = _MACH_Pmac;
-	rec->data[1] = 1;
-	rec->size = sizeof(struct bi_record) + 2 * sizeof(unsigned long);
-	rec = (struct bi_record *)((unsigned long)rec + rec->size);
-
-	rec->tag = BI_LAST;
-	rec->size = sizeof(struct bi_record);
-	rec = (struct bi_record *)((unsigned long)rec + rec->size);
-}
-
-struct memchunk {
-    unsigned int size;
-    struct memchunk *next;
-};
-
-static struct memchunk *freechunks;
-
-void *zalloc(void *x, unsigned items, unsigned size)
-{
-    void *p;
-    struct memchunk **mpp, *mp;
-
-    size *= items;
-    size = (size + 7) & -8;
-    heap_use += size;
-    if (heap_use > heap_max)
-	heap_max = heap_use;
-    for (mpp = &freechunks; (mp = *mpp) != 0; mpp = &mp->next) {
-	if (mp->size == size) {
-	    *mpp = mp->next;
-	    return mp;
-	}
-    }
-    p = avail_ram;
-    avail_ram += size;
-    if (avail_ram > avail_high)
-	avail_high = avail_ram;
-    if (avail_ram > end_avail) {
-	printf("oops... out of memory\n");
-	pause();
-    }
-    return p;
-}
-
-void zfree(void *x, void *addr, unsigned nb)
-{
-    struct memchunk *mp = addr;
-
-    nb = (nb + 7) & -8;
-    heap_use -= nb;
-    if (avail_ram == addr + nb) {
-	avail_ram = addr;
-	return;
-    }
-    mp->size = nb;
-    mp->next = freechunks;
-    freechunks = mp;
-}
-
-#define HEAD_CRC	2
-#define EXTRA_FIELD	4
-#define ORIG_NAME	8
-#define COMMENT		0x10
-#define RESERVED	0xe0
-
-#define DEFLATED	8
-
-void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
-{
-    z_stream s;
-    int r, i, flags;
-
-    /* skip header */
-    i = 10;
-    flags = src[3];
-    if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
-	printf("bad gzipped data\n");
-	exit();
-    }
-    if ((flags & EXTRA_FIELD) != 0)
-	i = 12 + src[10] + (src[11] << 8);
-    if ((flags & ORIG_NAME) != 0)
-	while (src[i++] != 0)
-	    ;
-    if ((flags & COMMENT) != 0)
-	while (src[i++] != 0)
-	    ;
-    if ((flags & HEAD_CRC) != 0)
-	i += 2;
-    if (i >= *lenp) {
-	printf("gunzip: ran out of data in header\n");
-	exit();
-    }
-
-    s.zalloc = zalloc;
-    s.zfree = zfree;
-    r = inflateInit2(&s, -MAX_WBITS);
-    if (r != Z_OK) {
-	printf("inflateInit2 returned %d\n", r);
-	exit();
-    }
-    s.next_in = src + i;
-    s.avail_in = *lenp - i;
-    s.next_out = dst;
-    s.avail_out = dstlen;
-    r = inflate(&s, Z_FINISH);
-    if (r != Z_OK && r != Z_STREAM_END) {
-	printf("inflate returned %d msg: %s\n", r, s.msg);
-	exit();
-    }
-    *lenp = s.next_out - (unsigned char *) dst;
-    inflateEnd(&s);
 }
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/boot/pmac/start.c linux/arch/ppc/boot/pmac/start.c
--- v2.4.9/linux/arch/ppc/boot/pmac/start.c	Thu May 24 15:02:07 2001
+++ linux/arch/ppc/boot/pmac/start.c	Tue Aug 28 06:58:33 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.start.c 1.8 05/18/01 15:17:15 cort
+ * BK Id: SCCS/s.start.c 1.10 07/25/01 18:13:07 trini
  */
 /*
  * Copyright (C) Paul Mackerras 1997.
@@ -11,6 +11,9 @@
  */
 #include <stdarg.h>
 
+extern int strlen(const char *s);
+extern void boot(int a1, int a2, void *prom);
+
 int (*prom)();
 
 void *chosen_handle;
@@ -109,7 +112,7 @@
 }
 
 void
-exit()
+exit(void)
 {
     struct prom_args {
 	char *service;
@@ -122,7 +125,7 @@
 }
 
 void
-pause()
+pause(void)
 {
     struct prom_args {
 	char *service;
@@ -243,7 +246,7 @@
 }
 
 int
-readchar()
+readchar(void)
 {
     char ch;
 
@@ -263,7 +266,7 @@
 static int lineleft;
 
 int
-getchar()
+getchar(void)
 {
     int c;
 
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/boot/prep/Makefile linux/arch/ppc/boot/prep/Makefile
--- v2.4.9/linux/arch/ppc/boot/prep/Makefile	Wed Jul 25 17:10:18 2001
+++ linux/arch/ppc/boot/prep/Makefile	Tue Aug 28 06:58:33 2001
@@ -1,4 +1,4 @@
-# BK Id: SCCS/s.Makefile 1.19 07/19/01 09:11:28 trini
+# BK Id: SCCS/s.Makefile 1.24 08/01/01 13:25:40 trini
 #
 # arch/ppc/boot/Makefile
 #
@@ -17,8 +17,6 @@
 
 USE_STANDARD_AS_RULE		:= true
 
-CFLAGS				+= -fno-builtin
-
 ifeq ($(CONFIG_SMP),y)
 TFTPIMAGE			= /tftpboot/zImage.prep.smp
 else
@@ -32,7 +30,7 @@
 OBJCOPY_ARGS			= -O elf32-powerpc
 LIBS 				= ../lib/zlib.a
 
-obj-$(CONFIG_SERIAL_CONSOLE)	+= ns16550.o
+obj-$(CONFIG_SERIAL_CONSOLE)	+= ../common/ns16550.o
 obj-$(CONFIG_VGA_CONSOLE)	+= vreset.o kbd.o
 
 # Tools
@@ -45,9 +43,6 @@
 misc.o: misc.c
 	$(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 -DZIMAGE_OFFSET=0 \
 		-DZIMAGE_SIZE=0 -c -o $@ $*.c
-
-ns16550.o: ../common/ns16550.c
-	$(CC) $(CFLAGS) -DIOOFFSET=0x80000000 -c -o $@ ../common/$*.c
 
 zvmlinux.initrd: zvmlinux ../images/vmlinux.gz
 	$(LD) $(ZLINKFLAGS) -o $@.tmp $(obj-y) $(LIBS)
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/boot/prep/head.S linux/arch/ppc/boot/prep/head.S
--- v2.4.9/linux/arch/ppc/boot/prep/head.S	Thu May 24 15:02:07 2001
+++ linux/arch/ppc/boot/prep/head.S	Tue Aug 28 06:58:33 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.head.S 1.8 05/18/01 06:20:29 patch
+ * BK Id: SCCS/s.head.S 1.11 07/31/01 16:36:06 trini
  */
 #include "../../kernel/ppc_defs.h"
 #include "../../kernel/ppc_asm.tmpl"
@@ -95,6 +95,11 @@
 	subi	r1,r1,256
 	li	r2,0x000F		/* Mask pointer to 16-byte boundary */
 	andc	r1,r1,r2
+/* Setup ISA_io */
+	lis	r3,ISA_io@h
+	ori	r3,r3,ISA_io@l
+	lis	r4,0x8000
+	stw	r4,0(r3)
 /* Run loader */
 	mr	r3,r8			/* Load point */
 	mr	r4,r7			/* Program length */
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/boot/prep/misc.c linux/arch/ppc/boot/prep/misc.c
--- v2.4.9/linux/arch/ppc/boot/prep/misc.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/ppc/boot/prep/misc.c	Tue Aug 28 06:58:33 2001
@@ -1,8 +1,7 @@
 /*
- * BK Id: SCCS/s.misc.c 1.14 06/16/01 20:43:20 trini
- */
-/*
- * misc.c
+ * BK Id: SCCS/s.misc.c 1.18 07/30/01 17:19:40 trini
+ *
+ * arch/ppc/boot/prep/misc.c
  *
  * Adapted for PowerPC by Gary Thomas
  *
@@ -11,7 +10,6 @@
  */
 
 #include <linux/types.h>
-#include "zlib.h"
 #include <asm/residual.h>
 #include <linux/config.h>
 #include <linux/threads.h>
@@ -22,9 +20,8 @@
 #include <asm/bootinfo.h>
 #include <asm/mmu.h>
 #include <asm/byteorder.h>
-#if defined(CONFIG_SERIAL_CONSOLE)
-unsigned long com_port;
-#endif /* CONFIG_SERIAL_CONSOLE */
+#include "nonstdio.h"
+#include "zlib.h"
 
 /*
  * Please send me load/board info and such data for hardware not
@@ -53,26 +50,28 @@
 char *zimage_start;
 int zimage_size;
 
+#if defined(CONFIG_SERIAL_CONSOLE)
+unsigned long com_port;
+#endif /* CONFIG_SERIAL_CONSOLE */
+#ifdef CONFIG_VGA_CONSOLE
 char *vidmem = (char *)0xC00B8000;
-int lines, cols;
-int orig_x, orig_y;
+int lines = 25, cols = 80;
+int orig_x, orig_y = 24;
+#endif /* CONFIG_VGA_CONSOLE */
 
-extern void puts(const char *);
-extern void putc(const char c);
-extern int tstc(void);
-extern int getc(void);
-extern void puthex(unsigned long val);
-extern void * memcpy(void * __dest, __const void * __src, __kernel_size_t __n);
 extern int CRT_tstc(void);
 extern void of_init(void *handler);
 extern int of_finddevice(const char *device_specifier, int *phandle);
 extern int of_getprop(int phandle, const char *name, void *buf, int buflen, 
 		int *size);
-extern __kernel_size_t strlen(const char *s);
 extern int vga_init(unsigned char *ISA_mem);
-extern void udelay(long x);
-void gunzip(void *, int, unsigned char *, int *);
-unsigned char inb(int);
+extern void gunzip(void *, int, unsigned char *, int *);
+
+extern void _put_HID0(unsigned int val);
+extern void _put_MSR(unsigned int val);
+extern unsigned int _get_HID0(void);
+extern unsigned int _get_MSR(void);
+extern unsigned long serial_init(int chan);
 
 void
 writel(unsigned int val, unsigned int address)
@@ -105,7 +104,7 @@
 
 #ifdef CONFIG_VGA_CONSOLE
 void
-scroll()
+scroll(void)
 {
 	int i;
 
@@ -120,7 +119,7 @@
  * Motorola dual processor platforms.  
  */
 void
-park_cpus()
+park_cpus(void)
 {
 	volatile void (*go)(RESIDUAL *, int, int, char *, int);
 	unsigned int i;
@@ -154,11 +153,6 @@
 	unsigned char base_mod;
 	int start_multi = 0;
 	unsigned int pci_viddid, pci_did, tulip_pci_base, tulip_base;
-
-	lines = 25;
-	cols = 80;
-	orig_x = 0;
-	orig_y = 24;
 	
 	/*
 	 * IBM's have the MMU on, so we have to disable it or
@@ -438,28 +432,8 @@
 /*
  * PCI/ISA I/O support
  */
-
-volatile unsigned char *ISA_io  = (unsigned char *)0x80000000;
-volatile unsigned char *ISA_mem = (unsigned char *)0xC0000000;
-
-void
-outb(int port, char val)
-{
-	/* Ensure I/O operations complete */
-	__asm__ volatile("eieio");
-	ISA_io[port] = val;
-}
-
-unsigned char
-inb(int port)
-{
-	/* Ensure I/O operations complete */
-	__asm__ volatile("eieio");
-	return (ISA_io[port]);
-}
-
 unsigned long
 local_to_PCI(unsigned long addr)
 {
-	return ((addr & 0x7FFFFFFF) | 0x80000000);
+	return (addr | 0x80000000);
 }
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/boot/prep/vreset.c linux/arch/ppc/boot/prep/vreset.c
--- v2.4.9/linux/arch/ppc/boot/prep/vreset.c	Thu May 24 15:02:07 2001
+++ linux/arch/ppc/boot/prep/vreset.c	Tue Aug 28 06:58:33 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.vreset.c 1.9 05/18/01 06:20:29 patch
+ * BK Id: SCCS/s.vreset.c 1.11 07/25/01 18:13:07 trini
  */
 /*
  * vreset.c
@@ -22,12 +22,10 @@
  */
 
 #include "iso_font.h"
+#include "nonstdio.h"
 
 extern char *vidmem;
 extern int lines, cols;
-extern void udelay(long x);
-extern void outb(int port, char val);
-extern unsigned char inb(int port);
 struct VaRegs;
 
 /*
@@ -43,7 +41,7 @@
 void unlockVideo(int slot);
 void setTextRegs(struct VgaRegs *svp);
 void setTextCLUT(int shift);
-void clearVideoMemory();
+void clearVideoMemory(void);
 void loadFont(unsigned char *ISA_mem);
 
 static void mdelay(int ms)
@@ -59,100 +57,100 @@
 #define NREGS 54
 #define ENDMK  0xFFFF  /* End marker */
 
-#define S3Vendor        0x5333
+#define S3Vendor	0x5333
 #define CirrusVendor    0x1013
 #define DiamondVendor   0x100E
 #define MatroxVendor    0x102B
 #define ParadiseVendor  0x101C
 
 struct VgaRegs GenVgaTextRegs[NREGS+1] = {
-/*      port    index   value  */
-  /* SR Regs */
-        0x3c4,  0x1,    0x0,
-        0x3c4,  0x2,    0x3,
-        0x3c4,  0x3,    0x0,
-        0x3c4,  0x4,    0x2,
-   /* CR Regs */
-        0x3d4,  0x0,    0x5f,
-        0x3d4,  0x1,    0x4f,
-        0x3d4,  0x2,    0x50,
-        0x3d4,  0x3,    0x82,
-        0x3d4,  0x4,    0x55,
-        0x3d4,  0x5,    0x81,
-        0x3d4,  0x6,    0xbf,
-        0x3d4,  0x7,    0x1f,
-        0x3d4,  0x8,    0x00,
-        0x3d4,  0x9,    0x4f,
-        0x3d4,  0xa,    0x0d,
-        0x3d4,  0xb,    0x0e,
-        0x3d4,  0xc,    0x00,
-        0x3d4,  0xd,    0x00,
-        0x3d4,  0xe,    0x00,
-        0x3d4,  0xf,    0x00,
-        0x3d4,  0x10,   0x9c,
-        0x3d4,  0x11,   0x8e,
-        0x3d4,  0x12,   0x8f,
-        0x3d4,  0x13,   0x28,
-        0x3d4,  0x14,   0x1f,
-        0x3d4,  0x15,   0x96,
-        0x3d4,  0x16,   0xb9,
-        0x3d4,  0x17,   0xa3,
-   /* GR Regs */
-        0x3ce,  0x0,    0x0,
-        0x3ce,  0x1,    0x0,
-        0x3ce,  0x2,    0x0,
-        0x3ce,  0x3,    0x0,
-        0x3ce,  0x4,    0x0,
-        0x3ce,  0x5,    0x10,
-        0x3ce,  0x6,    0xe,
-        0x3ce,  0x7,    0x0,
-        0x3ce,  0x8,    0xff,
-        ENDMK
+	/* port		index	value  */
+	/* SR Regs */
+	{ 0x3c4,	0x1,	0x0 },
+	{ 0x3c4,	0x2,	0x3 },
+	{ 0x3c4,	0x3,	0x0 },
+	{ 0x3c4,	0x4,	0x2 },
+	 /* CR Regs */
+	{ 0x3d4,	0x0,	0x5f },
+	{ 0x3d4,	0x1,	0x4f },
+	{ 0x3d4,	0x2,	0x50 },
+	{ 0x3d4,	0x3,	0x82 },
+	{ 0x3d4,	0x4,	0x55 },
+	{ 0x3d4,	0x5,	0x81 },
+	{ 0x3d4,	0x6,	0xbf },
+	{ 0x3d4,	0x7,	0x1f },
+	{ 0x3d4,	0x8,	0x00 },
+	{ 0x3d4,	0x9,	0x4f },
+	{ 0x3d4,	0xa,	0x0d },
+	{ 0x3d4,	0xb,	0x0e },
+	{ 0x3d4,	0xc,	0x00 },
+	{ 0x3d4,	0xd,	0x00 },
+	{ 0x3d4,	0xe,	0x00 },
+	{ 0x3d4,	0xf,	0x00 },
+	{ 0x3d4,	0x10,	0x9c },
+	{ 0x3d4,	0x11,	0x8e },
+	{ 0x3d4,	0x12,	0x8f },
+	{ 0x3d4,	0x13,	0x28 },
+	{ 0x3d4,	0x14,	0x1f },
+	{ 0x3d4,	0x15,	0x96 },
+	{ 0x3d4,	0x16,	0xb9 },
+	{ 0x3d4,	0x17,	0xa3 },
+	 /* GR Regs */
+	{ 0x3ce,	0x0,	0x0 },
+	{ 0x3ce,	0x1,	0x0 },
+	{ 0x3ce,	0x2,	0x0 },
+	{ 0x3ce,	0x3,	0x0 },
+	{ 0x3ce,	0x4,	0x0 },
+	{ 0x3ce,	0x5,	0x10 },
+	{ 0x3ce,	0x6,	0xe },
+	{ 0x3ce,	0x7,	0x0 },
+	{ 0x3ce,	0x8,	0xff },
+	{ ENDMK }
 };
 
 struct VgaRegs S3TextRegs[NREGS+1] = {
-/*	port	index	value  */
-  /* SR Regs */
-	0x3c4,	0x1,	0x0,
-	0x3c4,	0x2,	0x3,
-	0x3c4,	0x3,	0x0,
-	0x3c4,	0x4,	0x2,
-   /* CR Regs */
-	0x3d4,	0x0,	0x5f,
-	0x3d4,	0x1,	0x4f,
-	0x3d4,	0x2,	0x50,
-	0x3d4,	0x3,	0x82,
-	0x3d4,	0x4,	0x55,
-	0x3d4,	0x5,	0x81,
-	0x3d4,	0x6,	0xbf,
-	0x3d4,	0x7,	0x1f,
-	0x3d4,	0x8,	0x00,
-	0x3d4,	0x9,	0x4f,
-	0x3d4,	0xa,	0x0d,
-	0x3d4,	0xb,	0x0e,
-	0x3d4,	0xc,	0x00,
-	0x3d4,	0xd,	0x00,
-	0x3d4,	0xe,	0x00,
-	0x3d4,	0xf,	0x00,
-	0x3d4,	0x10,	0x9c,
-	0x3d4,	0x11,	0x8e,
-	0x3d4,	0x12,	0x8f,
-	0x3d4,	0x13,	0x28,
-	0x3d4,	0x14,	0x1f,
-	0x3d4,	0x15,	0x96,
-	0x3d4,	0x16,	0xb9,
-	0x3d4,	0x17,	0xa3,
-   /* GR Regs */
-	0x3ce,	0x0,	0x0,
-	0x3ce,	0x1,	0x0,
-	0x3ce,	0x2,	0x0,
-	0x3ce,	0x3,	0x0,
-	0x3ce,	0x4,	0x0,
-	0x3ce,	0x5,	0x10,
-	0x3ce,	0x6,	0xe,
-	0x3ce,	0x7,	0x0,
-	0x3ce,	0x8,	0xff,
-        ENDMK
+	/* port		index	value */
+	/* SR Regs */
+	{ 0x3c4,	0x1,	0x0 },
+	{ 0x3c4,	0x2,	0x3 },
+	{ 0x3c4,	0x3,	0x0 },
+	{ 0x3c4,	0x4,	0x2 },
+	/* CR Regs */
+	{ 0x3d4,	0x0,	0x5f },
+	{ 0x3d4,	0x1,	0x4f },
+	{ 0x3d4,	0x2,	0x50 },
+	{ 0x3d4,	0x3,	0x82 },
+	{ 0x3d4,	0x4,	0x55 },
+	{ 0x3d4,	0x5,	0x81 },
+	{ 0x3d4,	0x6,	0xbf },
+	{ 0x3d4,	0x7,	0x1f },
+	{ 0x3d4,	0x8,	0x00 },
+	{ 0x3d4,	0x9,	0x4f },
+	{ 0x3d4,	0xa,	0x0d },
+	{ 0x3d4,	0xb,	0x0e },
+	{ 0x3d4,	0xc,	0x00 },
+	{ 0x3d4,	0xd,	0x00 },
+	{ 0x3d4,	0xe,	0x00 },
+	{ 0x3d4,	0xf,	0x00 },
+	{ 0x3d4,	0x10,	0x9c },
+	{ 0x3d4,	0x11,	0x8e },
+	{ 0x3d4,	0x12,	0x8f },
+	{ 0x3d4,	0x13,	0x28 },
+	{ 0x3d4,	0x14,	0x1f },
+	{ 0x3d4,	0x15,	0x96 },
+	{ 0x3d4,	0x16,	0xb9 },
+	{ 0x3d4,	0x17,	0xa3 },
+	/* GR Regs */
+	{ 0x3ce,	0x0,	0x0 },
+	{ 0x3ce,	0x1,	0x0 },
+	{ 0x3ce,	0x2,	0x0 },
+	{ 0x3ce,	0x3,	0x0 },
+	{ 0x3ce,	0x4,	0x0 },
+	{ 0x3ce,	0x5,	0x10 },
+	{ 0x3ce,	0x6,	0xe },
+	{ 0x3ce,	0x7,	0x0 },
+	{ 0x3ce,	0x8,	0xff },
+	{ ENDMK }
 };
 
 struct RGBColors
@@ -167,262 +165,262 @@
  */
 struct RGBColors TextCLUT[256] = 
 {
-  /*	red	green	blue  */
-	0x0,	0x0,	0x0,
-	0x0,	0x0,	0x2a,
-	0x0,	0x2a,	0x0,
-	0x0,	0x2a,	0x2a,
-	0x2a,	0x0,	0x0,
-	0x2a,	0x0,	0x2a,
-	0x2a,	0x2a,	0x0,
-	0x2a,	0x2a,	0x2a,
-	0x0,	0x0,	0x15,
-	0x0,	0x0,	0x3f,
-	0x0,	0x2a,	0x15,
-	0x0,	0x2a,	0x3f,
-	0x2a,	0x0,	0x15,
-	0x2a,	0x0,	0x3f,
-	0x2a,	0x2a,	0x15,
-	0x2a,	0x2a,	0x3f,
-	0x0,	0x15,	0x0,
-	0x0,	0x15,	0x2a,
-	0x0,	0x3f,	0x0,
-	0x0,	0x3f,	0x2a,
-	0x2a,	0x15,	0x0,
-	0x2a,	0x15,	0x2a,
-	0x2a,	0x3f,	0x0,
-	0x2a,	0x3f,	0x2a,
-	0x0,	0x15,	0x15,
-	0x0,	0x15,	0x3f,
-	0x0,	0x3f,	0x15,
-	0x0,	0x3f,	0x3f,
-	0x2a,	0x15,	0x15,
-	0x2a,	0x15,	0x3f,
-	0x2a,	0x3f,	0x15,
-	0x2a,	0x3f,	0x3f,
-	0x15,	0x0,	0x0,
-	0x15,	0x0,	0x2a,
-	0x15,	0x2a,	0x0,
-	0x15,	0x2a,	0x2a,
-	0x3f,	0x0,	0x0,
-	0x3f,	0x0,	0x2a,
-	0x3f,	0x2a,	0x0,
-	0x3f,	0x2a,	0x2a,
-	0x15,	0x0,	0x15,
-	0x15,	0x0,	0x3f,
-	0x15,	0x2a,	0x15,
-	0x15,	0x2a,	0x3f,
-	0x3f,	0x0,	0x15,
-	0x3f,	0x0,	0x3f,
-	0x3f,	0x2a,	0x15,
-	0x3f,	0x2a,	0x3f,
-	0x15,	0x15,	0x0,
-	0x15,	0x15,	0x2a,
-	0x15,	0x3f,	0x0,
-	0x15,	0x3f,	0x2a,
-	0x3f,	0x15,	0x0,
-	0x3f,	0x15,	0x2a,
-	0x3f,	0x3f,	0x0,
-	0x3f,	0x3f,	0x2a,
-	0x15,	0x15,	0x15,
-	0x15,	0x15,	0x3f,
-	0x15,	0x3f,	0x15,
-	0x15,	0x3f,	0x3f,
-	0x3f,	0x15,	0x15,
-	0x3f,	0x15,	0x3f,
-	0x3f,	0x3f,	0x15,
-	0x3f,	0x3f,	0x3f,
-	0x39,	0xc,	0x5,
-	0x15,	0x2c,	0xf,
-	0x26,	0x10,	0x3d,
-	0x29,	0x29,	0x38,
-	0x4,	0x1a,	0xe,
-	0x2,	0x1e,	0x3a,
-	0x3c,	0x25,	0x33,
-	0x3c,	0xc,	0x2c,
-	0x3f,	0x3,	0x2b,
-	0x1c,	0x9,	0x13,
-	0x25,	0x2a,	0x35,
-	0x1e,	0xa,	0x38,
-	0x24,	0x8,	0x3,
-	0x3,	0xe,	0x36,
-	0xc,	0x6,	0x2a,
-	0x26,	0x3,	0x32,
-	0x5,	0x2f,	0x33,
-	0x3c,	0x35,	0x2f,
-	0x2d,	0x26,	0x3e,
-	0xd,	0xa,	0x10,
-	0x25,	0x3c,	0x11,
-	0xd,	0x4,	0x2e,
-	0x5,	0x19,	0x3e,
-	0xc,	0x13,	0x34,
-	0x2b,	0x6,	0x24,
-	0x4,	0x3,	0xd,
-	0x2f,	0x3c,	0xc,
-	0x2a,	0x37,	0x1f,
-	0xf,	0x12,	0x38,
-	0x38,	0xe,	0x2a,
-	0x12,	0x2f,	0x19,
-	0x29,	0x2e,	0x31,
-	0x25,	0x13,	0x3e,
-	0x33,	0x3e,	0x33,
-	0x1d,	0x2c,	0x25,
-	0x15,	0x15,	0x5,
-	0x32,	0x25,	0x39,
-	0x1a,	0x7,	0x1f,
-	0x13,	0xe,	0x1d,
-	0x36,	0x17,	0x34,
-	0xf,	0x15,	0x23,
-	0x2,	0x35,	0xd,
-	0x15,	0x3f,	0xc,
-	0x14,	0x2f,	0xf,
-	0x19,	0x21,	0x3e,
-	0x27,	0x11,	0x2f,
-	0x38,	0x3f,	0x3c,
-	0x36,	0x2d,	0x15,
-	0x16,	0x17,	0x2,
-	0x1,	0xa,	0x3d,
-	0x1b,	0x11,	0x3f,
-	0x21,	0x3c,	0xd,
-	0x1a,	0x39,	0x3d,
-	0x8,	0xe,	0xe,
-	0x22,	0x21,	0x23,
-	0x1e,	0x30,	0x5,
-	0x1f,	0x22,	0x3d,
-	0x1e,	0x2f,	0xa,
-	0x0,	0x1c,	0xe,
-	0x0,	0x1c,	0x15,
-	0x0,	0x1c,	0x1c,
-	0x0,	0x15,	0x1c,
-	0x0,	0xe,	0x1c,
-	0x0,	0x7,	0x1c,
-	0xe,	0xe,	0x1c,
-	0x11,	0xe,	0x1c,
-	0x15,	0xe,	0x1c,
-	0x18,	0xe,	0x1c,
-	0x1c,	0xe,	0x1c,
-	0x1c,	0xe,	0x18,
-	0x1c,	0xe,	0x15,
-	0x1c,	0xe,	0x11,
-	0x1c,	0xe,	0xe,
-	0x1c,	0x11,	0xe,
-	0x1c,	0x15,	0xe,
-	0x1c,	0x18,	0xe,
-	0x1c,	0x1c,	0xe,
-	0x18,	0x1c,	0xe,
-	0x15,	0x1c,	0xe,
-	0x11,	0x1c,	0xe,
-	0xe,	0x1c,	0xe,
-	0xe,	0x1c,	0x11,
-	0xe,	0x1c,	0x15,
-	0xe,	0x1c,	0x18,
-	0xe,	0x1c,	0x1c,
-	0xe,	0x18,	0x1c,
-	0xe,	0x15,	0x1c,
-	0xe,	0x11,	0x1c,
-	0x14,	0x14,	0x1c,
-	0x16,	0x14,	0x1c,
-	0x18,	0x14,	0x1c,
-	0x1a,	0x14,	0x1c,
-	0x1c,	0x14,	0x1c,
-	0x1c,	0x14,	0x1a,
-	0x1c,	0x14,	0x18,
-	0x1c,	0x14,	0x16,
-	0x1c,	0x14,	0x14,
-	0x1c,	0x16,	0x14,
-	0x1c,	0x18,	0x14,
-	0x1c,	0x1a,	0x14,
-	0x1c,	0x1c,	0x14,
-	0x1a,	0x1c,	0x14,
-	0x18,	0x1c,	0x14,
-	0x16,	0x1c,	0x14,
-	0x14,	0x1c,	0x14,
-	0x14,	0x1c,	0x16,
-	0x14,	0x1c,	0x18,
-	0x14,	0x1c,	0x1a,
-	0x14,	0x1c,	0x1c,
-	0x14,	0x1a,	0x1c,
-	0x14,	0x18,	0x1c,
-	0x14,	0x16,	0x1c,
-	0x0,	0x0,	0x10,
-	0x4,	0x0,	0x10,
-	0x8,	0x0,	0x10,
-	0xc,	0x0,	0x10,
-	0x10,	0x0,	0x10,
-	0x10,	0x0,	0xc,
-	0x10,	0x0,	0x8,
-	0x10,	0x0,	0x4,
-	0x10,	0x0,	0x0,
-	0x10,	0x4,	0x0,
-	0x10,	0x8,	0x0,
-	0x10,	0xc,	0x0,
-	0x10,	0x10,	0x0,
-	0xc,	0x10,	0x0,
-	0x8,	0x10,	0x0,
-	0x4,	0x10,	0x0,
-	0x0,	0x10,	0x0,
-	0x0,	0x10,	0x4,
-	0x0,	0x10,	0x8,
-	0x0,	0x10,	0xc,
-	0x0,	0x10,	0x10,
-	0x0,	0xc,	0x10,
-	0x0,	0x8,	0x10,
-	0x0,	0x4,	0x10,
-	0x8,	0x8,	0x10,
-	0xa,	0x8,	0x10,
-	0xc,	0x8,	0x10,
-	0xe,	0x8,	0x10,
-	0x10,	0x8,	0x10,
-	0x10,	0x8,	0xe,
-	0x10,	0x8,	0xc,
-	0x10,	0x8,	0xa,
-	0x10,	0x8,	0x8,
-	0x10,	0xa,	0x8,
-	0x10,	0xc,	0x8,
-	0x10,	0xe,	0x8,
-	0x10,	0x10,	0x8,
-	0xe,	0x10,	0x8,
-	0xc,	0x10,	0x8,
-	0xa,	0x10,	0x8,
-	0x8,	0x10,	0x8,
-	0x8,	0x10,	0xa,
-	0x8,	0x10,	0xc,
-	0x8,	0x10,	0xe,
-	0x8,	0x10,	0x10,
-	0x8,	0xe,	0x10,
-	0x8,	0xc,	0x10,
-	0x8,	0xa,	0x10,
-	0xb,	0xb,	0x10,
-	0xc,	0xb,	0x10,
-	0xd,	0xb,	0x10,
-	0xf,	0xb,	0x10,
-	0x10,	0xb,	0x10,
-	0x10,	0xb,	0xf,
-	0x10,	0xb,	0xd,
-	0x10,	0xb,	0xc,
-	0x10,	0xb,	0xb,
-	0x10,	0xc,	0xb,
-	0x10,	0xd,	0xb,
-	0x10,	0xf,	0xb,
-	0x10,	0x10,	0xb,
-	0xf,	0x10,	0xb,
-	0xd,	0x10,	0xb,
-	0xc,	0x10,	0xb,
-	0xb,	0x10,	0xb,
-	0xb,	0x10,	0xc,
-	0xb,	0x10,	0xd,
-	0xb,	0x10,	0xf,
-	0xb,	0x10,	0x10,
-	0xb,	0xf,	0x10,
-	0xb,	0xd,	0x10,
-	0xb,	0xc,	0x10,
-	0x0,	0x0,	0x0,
-	0x0,	0x0,	0x0,
-	0x0,	0x0,	0x0,
-	0x0,	0x0,	0x0,
-	0x0,	0x0,	0x0,
-	0x0,	0x0,	0x0,
-	0x0,	0x0,	0x0
+	/* red	green	blue  */
+	{ 0x0,	0x0,	0x0 },
+	{ 0x0,	0x0,	0x2a },
+	{ 0x0,	0x2a,	0x0 },
+	{ 0x0,	0x2a,	0x2a },
+	{ 0x2a,	0x0,	0x0 },
+	{ 0x2a,	0x0,	0x2a },
+	{ 0x2a,	0x2a,	0x0 },
+	{ 0x2a,	0x2a,	0x2a },
+	{ 0x0,	0x0,	0x15 },
+	{ 0x0,	0x0,	0x3f },
+	{ 0x0,	0x2a,	0x15 },
+	{ 0x0,	0x2a,	0x3f },
+	{ 0x2a,	0x0,	0x15 },
+	{ 0x2a,	0x0,	0x3f },
+	{ 0x2a,	0x2a,	0x15 },
+	{ 0x2a,	0x2a,	0x3f },
+	{ 0x0,	0x15,	0x0 },
+	{ 0x0,	0x15,	0x2a },
+	{ 0x0,	0x3f,	0x0 },
+	{ 0x0,	0x3f,	0x2a },
+	{ 0x2a,	0x15,	0x0 },
+	{ 0x2a,	0x15,	0x2a },
+	{ 0x2a,	0x3f,	0x0 },
+	{ 0x2a,	0x3f,	0x2a },
+	{ 0x0,	0x15,	0x15 },
+	{ 0x0,	0x15,	0x3f },
+	{ 0x0,	0x3f,	0x15 },
+	{ 0x0,	0x3f,	0x3f },
+	{ 0x2a,	0x15,	0x15 },
+	{ 0x2a,	0x15,	0x3f },
+	{ 0x2a,	0x3f,	0x15 },
+	{ 0x2a,	0x3f,	0x3f },
+	{ 0x15,	0x0,	0x0 },
+	{ 0x15,	0x0,	0x2a },
+	{ 0x15,	0x2a,	0x0 },
+	{ 0x15,	0x2a,	0x2a },
+	{ 0x3f,	0x0,	0x0 },
+	{ 0x3f,	0x0,	0x2a },
+	{ 0x3f,	0x2a,	0x0 },
+	{ 0x3f,	0x2a,	0x2a },
+	{ 0x15,	0x0,	0x15 },
+	{ 0x15,	0x0,	0x3f },
+	{ 0x15,	0x2a,	0x15 },
+	{ 0x15,	0x2a,	0x3f },
+	{ 0x3f,	0x0,	0x15 },
+	{ 0x3f,	0x0,	0x3f },
+	{ 0x3f,	0x2a,	0x15 },
+	{ 0x3f,	0x2a,	0x3f },
+	{ 0x15,	0x15,	0x0 },
+	{ 0x15,	0x15,	0x2a },
+	{ 0x15,	0x3f,	0x0 },
+	{ 0x15,	0x3f,	0x2a },
+	{ 0x3f,	0x15,	0x0 },
+	{ 0x3f,	0x15,	0x2a },
+	{ 0x3f,	0x3f,	0x0 },
+	{ 0x3f,	0x3f,	0x2a },
+	{ 0x15,	0x15,	0x15 },
+	{ 0x15,	0x15,	0x3f },
+	{ 0x15,	0x3f,	0x15 },
+	{ 0x15,	0x3f,	0x3f },
+	{ 0x3f,	0x15,	0x15 },
+	{ 0x3f,	0x15,	0x3f },
+	{ 0x3f,	0x3f,	0x15 },
+	{ 0x3f,	0x3f,	0x3f },
+	{ 0x39,	0xc,	0x5 },
+	{ 0x15,	0x2c,	0xf },
+	{ 0x26,	0x10,	0x3d },
+	{ 0x29,	0x29,	0x38 },
+	{ 0x4,	0x1a,	0xe },
+	{ 0x2,	0x1e,	0x3a },
+	{ 0x3c,	0x25,	0x33 },
+	{ 0x3c,	0xc,	0x2c },
+	{ 0x3f,	0x3,	0x2b },
+	{ 0x1c,	0x9,	0x13 },
+	{ 0x25,	0x2a,	0x35 },
+	{ 0x1e,	0xa,	0x38 },
+	{ 0x24,	0x8,	0x3 },
+	{ 0x3,	0xe,	0x36 },
+	{ 0xc,	0x6,	0x2a },
+	{ 0x26,	0x3,	0x32 },
+	{ 0x5,	0x2f,	0x33 },
+	{ 0x3c,	0x35,	0x2f },
+	{ 0x2d,	0x26,	0x3e },
+	{ 0xd,	0xa,	0x10 },
+	{ 0x25,	0x3c,	0x11 },
+	{ 0xd,	0x4,	0x2e },
+	{ 0x5,	0x19,	0x3e },
+	{ 0xc,	0x13,	0x34 },
+	{ 0x2b,	0x6,	0x24 },
+	{ 0x4,	0x3,	0xd },
+	{ 0x2f,	0x3c,	0xc },
+	{ 0x2a,	0x37,	0x1f },
+	{ 0xf,	0x12,	0x38 },
+	{ 0x38,	0xe,	0x2a },
+	{ 0x12,	0x2f,	0x19 },
+	{ 0x29,	0x2e,	0x31 },
+	{ 0x25,	0x13,	0x3e },
+	{ 0x33,	0x3e,	0x33 },
+	{ 0x1d,	0x2c,	0x25 },
+	{ 0x15,	0x15,	0x5 },
+	{ 0x32,	0x25,	0x39 },
+	{ 0x1a,	0x7,	0x1f },
+	{ 0x13,	0xe,	0x1d },
+	{ 0x36,	0x17,	0x34 },
+	{ 0xf,	0x15,	0x23 },
+	{ 0x2,	0x35,	0xd },
+	{ 0x15,	0x3f,	0xc },
+	{ 0x14,	0x2f,	0xf },
+	{ 0x19,	0x21,	0x3e },
+	{ 0x27,	0x11,	0x2f },
+	{ 0x38,	0x3f,	0x3c },
+	{ 0x36,	0x2d,	0x15 },
+	{ 0x16,	0x17,	0x2 },
+	{ 0x1,	0xa,	0x3d },
+	{ 0x1b,	0x11,	0x3f },
+	{ 0x21,	0x3c,	0xd },
+	{ 0x1a,	0x39,	0x3d },
+	{ 0x8,	0xe,	0xe },
+	{ 0x22,	0x21,	0x23 },
+	{ 0x1e,	0x30,	0x5 },
+	{ 0x1f,	0x22,	0x3d },
+	{ 0x1e,	0x2f,	0xa },
+	{ 0x0,	0x1c,	0xe },
+	{ 0x0,	0x1c,	0x15 },
+	{ 0x0,	0x1c,	0x1c },
+	{ 0x0,	0x15,	0x1c },
+	{ 0x0,	0xe,	0x1c },
+	{ 0x0,	0x7,	0x1c },
+	{ 0xe,	0xe,	0x1c },
+	{ 0x11,	0xe,	0x1c },
+	{ 0x15,	0xe,	0x1c },
+	{ 0x18,	0xe,	0x1c },
+	{ 0x1c,	0xe,	0x1c },
+	{ 0x1c,	0xe,	0x18 },
+	{ 0x1c,	0xe,	0x15 },
+	{ 0x1c,	0xe,	0x11 },
+	{ 0x1c,	0xe,	0xe },
+	{ 0x1c,	0x11,	0xe },
+	{ 0x1c,	0x15,	0xe },
+	{ 0x1c,	0x18,	0xe },
+	{ 0x1c,	0x1c,	0xe },
+	{ 0x18,	0x1c,	0xe },
+	{ 0x15,	0x1c,	0xe },
+	{ 0x11,	0x1c,	0xe },
+	{ 0xe,	0x1c,	0xe },
+	{ 0xe,	0x1c,	0x11 },
+	{ 0xe,	0x1c,	0x15 },
+	{ 0xe,	0x1c,	0x18 },
+	{ 0xe,	0x1c,	0x1c },
+	{ 0xe,	0x18,	0x1c },
+	{ 0xe,	0x15,	0x1c },
+	{ 0xe,	0x11,	0x1c },
+	{ 0x14,	0x14,	0x1c },
+	{ 0x16,	0x14,	0x1c },
+	{ 0x18,	0x14,	0x1c },
+	{ 0x1a,	0x14,	0x1c },
+	{ 0x1c,	0x14,	0x1c },
+	{ 0x1c,	0x14,	0x1a },
+	{ 0x1c,	0x14,	0x18 },
+	{ 0x1c,	0x14,	0x16 },
+	{ 0x1c,	0x14,	0x14 },
+	{ 0x1c,	0x16,	0x14 },
+	{ 0x1c,	0x18,	0x14 },
+	{ 0x1c,	0x1a,	0x14 },
+	{ 0x1c,	0x1c,	0x14 },
+	{ 0x1a,	0x1c,	0x14 },
+	{ 0x18,	0x1c,	0x14 },
+	{ 0x16,	0x1c,	0x14 },
+	{ 0x14,	0x1c,	0x14 },
+	{ 0x14,	0x1c,	0x16 },
+	{ 0x14,	0x1c,	0x18 },
+	{ 0x14,	0x1c,	0x1a },
+	{ 0x14,	0x1c,	0x1c },
+	{ 0x14,	0x1a,	0x1c },
+	{ 0x14,	0x18,	0x1c },
+	{ 0x14,	0x16,	0x1c },
+	{ 0x0,	0x0,	0x10 },
+	{ 0x4,	0x0,	0x10 },
+	{ 0x8,	0x0,	0x10 },
+	{ 0xc,	0x0,	0x10 },
+	{ 0x10,	0x0,	0x10 },
+	{ 0x10,	0x0,	0xc },
+	{ 0x10,	0x0,	0x8 },
+	{ 0x10,	0x0,	0x4 },
+	{ 0x10,	0x0,	0x0 },
+	{ 0x10,	0x4,	0x0 },
+	{ 0x10,	0x8,	0x0 },
+	{ 0x10,	0xc,	0x0 },
+	{ 0x10,	0x10,	0x0 },
+	{ 0xc,	0x10,	0x0 },
+	{ 0x8,	0x10,	0x0 },
+	{ 0x4,	0x10,	0x0 },
+	{ 0x0,	0x10,	0x0 },
+	{ 0x0,	0x10,	0x4 },
+	{ 0x0,	0x10,	0x8 },
+	{ 0x0,	0x10,	0xc },
+	{ 0x0,	0x10,	0x10 },
+	{ 0x0,	0xc,	0x10 },
+	{ 0x0,	0x8,	0x10 },
+	{ 0x0,	0x4,	0x10 },
+	{ 0x8,	0x8,	0x10 },
+	{ 0xa,	0x8,	0x10 },
+	{ 0xc,	0x8,	0x10 },
+	{ 0xe,	0x8,	0x10 },
+	{ 0x10,	0x8,	0x10 },
+	{ 0x10,	0x8,	0xe },
+	{ 0x10,	0x8,	0xc },
+	{ 0x10,	0x8,	0xa },
+	{ 0x10,	0x8,	0x8 },
+	{ 0x10,	0xa,	0x8 },
+	{ 0x10,	0xc,	0x8 },
+	{ 0x10,	0xe,	0x8 },
+	{ 0x10,	0x10,	0x8 },
+	{ 0xe,	0x10,	0x8 },
+	{ 0xc,	0x10,	0x8 },
+	{ 0xa,	0x10,	0x8 },
+	{ 0x8,	0x10,	0x8 },
+	{ 0x8,	0x10,	0xa },
+	{ 0x8,	0x10,	0xc },
+	{ 0x8,	0x10,	0xe },
+	{ 0x8,	0x10,	0x10 },
+	{ 0x8,	0xe,	0x10 },
+	{ 0x8,	0xc,	0x10 },
+	{ 0x8,	0xa,	0x10 },
+	{ 0xb,	0xb,	0x10 },
+	{ 0xc,	0xb,	0x10 },
+	{ 0xd,	0xb,	0x10 },
+	{ 0xf,	0xb,	0x10 },
+	{ 0x10,	0xb,	0x10 },
+	{ 0x10,	0xb,	0xf },
+	{ 0x10,	0xb,	0xd },
+	{ 0x10,	0xb,	0xc },
+	{ 0x10,	0xb,	0xb },
+	{ 0x10,	0xc,	0xb },
+	{ 0x10,	0xd,	0xb },
+	{ 0x10,	0xf,	0xb },
+	{ 0x10,	0x10,	0xb },
+	{ 0xf,	0x10,	0xb },
+	{ 0xd,	0x10,	0xb },
+	{ 0xc,	0x10,	0xb },
+	{ 0xb,	0x10,	0xb },
+	{ 0xb,	0x10,	0xc },
+	{ 0xb,	0x10,	0xd },
+	{ 0xb,	0x10,	0xf },
+	{ 0xb,	0x10,	0x10 },
+	{ 0xb,	0xf,	0x10 },
+	{ 0xb,	0xd,	0x10 },
+	{ 0xb,	0xc,	0x10 },
+	{ 0x0,	0x0,	0x0 },
+	{ 0x0,	0x0,	0x0 },
+	{ 0x0,	0x0,	0x0 },
+	{ 0x0,	0x0,	0x0 },
+	{ 0x0,	0x0,	0x0 },
+	{ 0x0,	0x0,	0x0 },
+	{ 0x0,	0x0,	0x0 }
 };
 
 unsigned char AC[21] = {
@@ -721,7 +719,7 @@
 }
 
 void
-clearVideoMemory()
+clearVideoMemory(void)
 {
 	int i, j;
 	for (i = 0;  i < lines;  i++) {
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/config.in linux/arch/ppc/config.in
--- v2.4.9/linux/arch/ppc/config.in	Wed Jul 25 17:10:18 2001
+++ linux/arch/ppc/config.in	Tue Aug 28 07:11:33 2001
@@ -1,4 +1,4 @@
-# BK Id: SCCS/s.config.in 1.34 07/08/01 11:39:11 trini
+# BK Id: SCCS/s.config.in 1.40 08/24/01 20:31:47 paulus
 #
 # For a description of the syntax of this configuration file,
 # see Documentation/kbuild/config-language.txt.
@@ -26,6 +26,7 @@
 mainmenu_option next_comment
 comment 'Platform support'
 define_bool CONFIG_PPC y
+define_bool CONFIG_PPC32 y
 choice 'Processor Type'	\
 	"6xx/7xx/74xx/8260	CONFIG_6xx	\
 	 4xx			CONFIG_4xx	\
@@ -42,6 +43,11 @@
   define_bool CONFIG_ALL_PPC y
 fi
 
+if [ "$CONFIG_6xx" = "y" -o "$CONFIG_POWER3" = "y" -o \
+     "$CONFIG_POWER4" = "y" ]; then
+  define_bool CONFIG_PPC_STD_MMU y
+fi
+
 if [ "$CONFIG_8260" = "y" ]; then
   define_bool CONFIG_SERIAL_CONSOLE y
   bool 'Support for EST8260' CONFIG_EST8260
@@ -93,7 +99,8 @@
   bool 'Workarounds for PPC601 bugs' CONFIG_PPC601_SYNC_FIX
 fi
 
-if [ "$CONFIG_8xx" = "y" -o "$CONFIG_8260" = "y" ]; then
+if [ "$CONFIG_POWER3" = "n" -a "$CONFIG_POWER4" = "n" -a \
+	"$CONFIG_6xx" = "n" ]; then
   define_bool CONFIG_ALL_PPC n
 fi
 
@@ -104,6 +111,11 @@
 
 if [ "$CONFIG_6xx" = "y" -a "$CONFIG_8260" = "n" ];then
   bool 'AltiVec Support' CONFIG_ALTIVEC
+  bool 'Thermal Management Support' CONFIG_TAU
+  if [ "$CONFIG_TAU" = "y" ]; then
+    bool '    Interrupt driven TAU driver (DANGEROUS)' CONFIG_TAU_INT
+    bool '    Average high and low temp' CONFIG_TAU_AVERAGE
+  fi
 fi
 
 if [ "$CONFIG_4xx" = "y" -o "$CONFIG_8xx" = "y" ]; then
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/configs/IVMS8_defconfig linux/arch/ppc/configs/IVMS8_defconfig
--- v2.4.9/linux/arch/ppc/configs/IVMS8_defconfig	Mon Aug 27 12:41:39 2001
+++ linux/arch/ppc/configs/IVMS8_defconfig	Tue Aug 28 06:58:33 2001
@@ -21,6 +21,7 @@
 # Platform support
 #
 CONFIG_PPC=y
+CONFIG_PPC32=y
 # CONFIG_6xx is not set
 # CONFIG_4xx is not set
 # CONFIG_POWER3 is not set
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/configs/SM850_defconfig linux/arch/ppc/configs/SM850_defconfig
--- v2.4.9/linux/arch/ppc/configs/SM850_defconfig	Mon Aug 27 12:41:39 2001
+++ linux/arch/ppc/configs/SM850_defconfig	Tue Aug 28 06:58:33 2001
@@ -21,6 +21,7 @@
 # Platform support
 #
 CONFIG_PPC=y
+CONFIG_PPC32=y
 # CONFIG_6xx is not set
 # CONFIG_4xx is not set
 # CONFIG_POWER3 is not set
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/configs/SPD823TS_defconfig linux/arch/ppc/configs/SPD823TS_defconfig
--- v2.4.9/linux/arch/ppc/configs/SPD823TS_defconfig	Mon Aug 27 12:41:39 2001
+++ linux/arch/ppc/configs/SPD823TS_defconfig	Tue Aug 28 06:58:33 2001
@@ -21,6 +21,7 @@
 # Platform support
 #
 CONFIG_PPC=y
+CONFIG_PPC32=y
 # CONFIG_6xx is not set
 # CONFIG_4xx is not set
 # CONFIG_POWER3 is not set
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/configs/TQM823L_defconfig linux/arch/ppc/configs/TQM823L_defconfig
--- v2.4.9/linux/arch/ppc/configs/TQM823L_defconfig	Mon Aug 27 12:41:39 2001
+++ linux/arch/ppc/configs/TQM823L_defconfig	Tue Aug 28 06:58:33 2001
@@ -21,6 +21,7 @@
 # Platform support
 #
 CONFIG_PPC=y
+CONFIG_PPC32=y
 # CONFIG_6xx is not set
 # CONFIG_4xx is not set
 # CONFIG_POWER3 is not set
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/configs/TQM850L_defconfig linux/arch/ppc/configs/TQM850L_defconfig
--- v2.4.9/linux/arch/ppc/configs/TQM850L_defconfig	Mon Aug 27 12:41:39 2001
+++ linux/arch/ppc/configs/TQM850L_defconfig	Tue Aug 28 06:58:33 2001
@@ -21,6 +21,7 @@
 # Platform support
 #
 CONFIG_PPC=y
+CONFIG_PPC32=y
 # CONFIG_6xx is not set
 # CONFIG_4xx is not set
 # CONFIG_POWER3 is not set
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/configs/TQM860L_defconfig linux/arch/ppc/configs/TQM860L_defconfig
--- v2.4.9/linux/arch/ppc/configs/TQM860L_defconfig	Mon Aug 27 12:41:39 2001
+++ linux/arch/ppc/configs/TQM860L_defconfig	Tue Aug 28 06:58:33 2001
@@ -21,6 +21,7 @@
 # Platform support
 #
 CONFIG_PPC=y
+CONFIG_PPC32=y
 # CONFIG_6xx is not set
 # CONFIG_4xx is not set
 # CONFIG_POWER3 is not set
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/configs/apus_defconfig linux/arch/ppc/configs/apus_defconfig
--- v2.4.9/linux/arch/ppc/configs/apus_defconfig	Mon Aug 27 12:41:39 2001
+++ linux/arch/ppc/configs/apus_defconfig	Tue Aug 28 06:58:33 2001
@@ -21,18 +21,21 @@
 # Platform support
 #
 CONFIG_PPC=y
+CONFIG_PPC32=y
 CONFIG_6xx=y
 # CONFIG_4xx is not set
 # CONFIG_POWER3 is not set
 # CONFIG_POWER4 is not set
 # CONFIG_8xx is not set
 # CONFIG_8260 is not set
+CONFIG_PPC_STD_MMU=y
 # CONFIG_ALL_PPC is not set
 CONFIG_APUS=y
 # CONFIG_GEMINI is not set
 # CONFIG_PPC601_SYNC_FIX is not set
 # CONFIG_SMP is not set
 # CONFIG_ALTIVEC is not set
+# CONFIG_TAU is not set
 
 #
 # General setup
@@ -746,8 +749,10 @@
 CONFIG_SOUND=y
 CONFIG_DMASOUND_PAULA=m
 CONFIG_DMASOUND=m
+# CONFIG_SOUND_BT878 is not set
 # CONFIG_SOUND_CMPCI is not set
 # CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_MIDI_EMU10K1 is not set
 # CONFIG_SOUND_FUSION is not set
 # CONFIG_SOUND_CS4281 is not set
 # CONFIG_SOUND_ES1370 is not set
@@ -756,6 +761,7 @@
 # CONFIG_SOUND_MAESTRO is not set
 # CONFIG_SOUND_MAESTRO3 is not set
 # CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_RME96XX is not set
 # CONFIG_SOUND_SONICVIBES is not set
 # CONFIG_SOUND_TRIDENT is not set
 # CONFIG_SOUND_MSNDCLAS is not set
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/configs/bseip_defconfig linux/arch/ppc/configs/bseip_defconfig
--- v2.4.9/linux/arch/ppc/configs/bseip_defconfig	Mon Aug 27 12:41:39 2001
+++ linux/arch/ppc/configs/bseip_defconfig	Tue Aug 28 06:58:33 2001
@@ -19,6 +19,7 @@
 # Platform support
 #
 CONFIG_PPC=y
+CONFIG_PPC32=y
 # CONFIG_6xx is not set
 # CONFIG_4xx is not set
 # CONFIG_POWER3 is not set
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/configs/common_defconfig linux/arch/ppc/configs/common_defconfig
--- v2.4.9/linux/arch/ppc/configs/common_defconfig	Mon Aug 27 12:41:39 2001
+++ linux/arch/ppc/configs/common_defconfig	Tue Aug 28 06:58:33 2001
@@ -21,18 +21,23 @@
 # Platform support
 #
 CONFIG_PPC=y
+CONFIG_PPC32=y
 CONFIG_6xx=y
 # CONFIG_4xx is not set
 # CONFIG_POWER3 is not set
 # CONFIG_POWER4 is not set
 # CONFIG_8xx is not set
 # CONFIG_8260 is not set
+CONFIG_PPC_STD_MMU=y
 CONFIG_ALL_PPC=y
 # CONFIG_APUS is not set
 # CONFIG_GEMINI is not set
 CONFIG_PPC601_SYNC_FIX=y
 # CONFIG_SMP is not set
 CONFIG_ALTIVEC=y
+CONFIG_TAU=y
+# CONFIG_TAU_INT is not set
+# CONFIG_TAU_AVERAGE is not set
 
 #
 # General setup
@@ -228,6 +233,7 @@
 CONFIG_BLK_DEV_IDEPCI=y
 CONFIG_IDEPCI_SHARE_IRQ=y
 CONFIG_BLK_DEV_IDEDMA_PCI=y
+CONFIG_BLK_DEV_ADMA=y
 # CONFIG_BLK_DEV_OFFBOARD is not set
 CONFIG_IDEDMA_PCI_AUTO=y
 CONFIG_BLK_DEV_IDEDMA=y
@@ -237,8 +243,8 @@
 # CONFIG_AEC62XX_TUNING is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
 # CONFIG_WDC_ALI15X3 is not set
-# CONFIG_BLK_DEV_AMD7409 is not set
-# CONFIG_AMD7409_OVERRIDE is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_AMD74XX_OVERRIDE is not set
 CONFIG_BLK_DEV_CMD64X=y
 # CONFIG_BLK_DEV_CY82C693 is not set
 # CONFIG_BLK_DEV_CS5530 is not set
@@ -249,7 +255,8 @@
 # CONFIG_BLK_DEV_OPTI621 is not set
 # CONFIG_BLK_DEV_PDC202XX is not set
 # CONFIG_PDC202XX_BURST is not set
-# CONFIG_BLK_DEV_OSB4 is not set
+# CONFIG_PDC202XX_FORCE is not set
+# CONFIG_BLK_DEV_SVWKS is not set
 # CONFIG_BLK_DEV_SIS5513 is not set
 # CONFIG_BLK_DEV_SLC90E66 is not set
 # CONFIG_BLK_DEV_TRM290 is not set
@@ -769,8 +776,10 @@
 CONFIG_SOUND=m
 CONFIG_DMASOUND_AWACS=m
 CONFIG_DMASOUND=m
+# CONFIG_SOUND_BT878 is not set
 # CONFIG_SOUND_CMPCI is not set
 # CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_MIDI_EMU10K1 is not set
 # CONFIG_SOUND_FUSION is not set
 # CONFIG_SOUND_CS4281 is not set
 # CONFIG_SOUND_ES1370 is not set
@@ -779,6 +788,7 @@
 # CONFIG_SOUND_MAESTRO is not set
 # CONFIG_SOUND_MAESTRO3 is not set
 # CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_RME96XX is not set
 # CONFIG_SOUND_SONICVIBES is not set
 # CONFIG_SOUND_TRIDENT is not set
 # CONFIG_SOUND_MSNDCLAS is not set
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/configs/est8260_defconfig linux/arch/ppc/configs/est8260_defconfig
--- v2.4.9/linux/arch/ppc/configs/est8260_defconfig	Mon Aug 27 12:41:39 2001
+++ linux/arch/ppc/configs/est8260_defconfig	Tue Aug 28 06:58:33 2001
@@ -19,16 +19,17 @@
 # Platform support
 #
 CONFIG_PPC=y
+CONFIG_PPC32=y
 CONFIG_6xx=y
 # CONFIG_4xx is not set
 # CONFIG_POWER3 is not set
 # CONFIG_POWER4 is not set
 # CONFIG_8xx is not set
 CONFIG_8260=y
+CONFIG_PPC_STD_MMU=y
 CONFIG_SERIAL_CONSOLE=y
 CONFIG_EST8260=y
 CONFIG_PPC601_SYNC_FIX=y
-# CONFIG_ALL_PPC is not set
 # CONFIG_SMP is not set
 
 #
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/configs/gemini_defconfig linux/arch/ppc/configs/gemini_defconfig
--- v2.4.9/linux/arch/ppc/configs/gemini_defconfig	Mon Aug 27 12:41:39 2001
+++ linux/arch/ppc/configs/gemini_defconfig	Tue Aug 28 06:58:33 2001
@@ -21,18 +21,23 @@
 # Platform support
 #
 CONFIG_PPC=y
+CONFIG_PPC32=y
 CONFIG_6xx=y
 # CONFIG_4xx is not set
 # CONFIG_POWER3 is not set
 # CONFIG_POWER4 is not set
 # CONFIG_8xx is not set
 # CONFIG_8260 is not set
+CONFIG_PPC_STD_MMU=y
 # CONFIG_ALL_PPC is not set
 # CONFIG_APUS is not set
 CONFIG_GEMINI=y
 # CONFIG_PPC601_SYNC_FIX is not set
 # CONFIG_SMP is not set
 CONFIG_ALTIVEC=y
+CONFIG_TAU=y
+# CONFIG_TAU_INT is not set
+# CONFIG_TAU_AVERAGE is not set
 
 #
 # General setup
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/configs/ibmchrp_defconfig linux/arch/ppc/configs/ibmchrp_defconfig
--- v2.4.9/linux/arch/ppc/configs/ibmchrp_defconfig	Mon Aug 27 12:41:39 2001
+++ linux/arch/ppc/configs/ibmchrp_defconfig	Tue Aug 28 06:58:33 2001
@@ -21,18 +21,21 @@
 # Platform support
 #
 CONFIG_PPC=y
+CONFIG_PPC32=y
 CONFIG_6xx=y
 # CONFIG_4xx is not set
 # CONFIG_POWER3 is not set
 # CONFIG_POWER4 is not set
 # CONFIG_8xx is not set
 # CONFIG_8260 is not set
+CONFIG_PPC_STD_MMU=y
 CONFIG_ALL_PPC=y
 # CONFIG_APUS is not set
 # CONFIG_GEMINI is not set
 # CONFIG_PPC601_SYNC_FIX is not set
 # CONFIG_SMP is not set
 # CONFIG_ALTIVEC is not set
+# CONFIG_TAU is not set
 
 #
 # General setup
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/configs/mbx_defconfig linux/arch/ppc/configs/mbx_defconfig
--- v2.4.9/linux/arch/ppc/configs/mbx_defconfig	Mon Aug 27 12:41:39 2001
+++ linux/arch/ppc/configs/mbx_defconfig	Tue Aug 28 06:58:33 2001
@@ -19,6 +19,7 @@
 # Platform support
 #
 CONFIG_PPC=y
+CONFIG_PPC32=y
 # CONFIG_6xx is not set
 # CONFIG_4xx is not set
 # CONFIG_POWER3 is not set
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/configs/oak_defconfig linux/arch/ppc/configs/oak_defconfig
--- v2.4.9/linux/arch/ppc/configs/oak_defconfig	Mon Aug 27 12:41:39 2001
+++ linux/arch/ppc/configs/oak_defconfig	Tue Aug 28 06:58:33 2001
@@ -21,6 +21,7 @@
 # Platform support
 #
 CONFIG_PPC=y
+CONFIG_PPC32=y
 # CONFIG_6xx is not set
 CONFIG_4xx=y
 # CONFIG_POWER3 is not set
@@ -29,6 +30,7 @@
 CONFIG_OAK=y
 # CONFIG_WALNUT is not set
 CONFIG_PPC601_SYNC_FIX=y
+# CONFIG_ALL_PPC is not set
 # CONFIG_SMP is not set
 # CONFIG_MATH_EMULATION is not set
 
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/configs/power3_defconfig linux/arch/ppc/configs/power3_defconfig
--- v2.4.9/linux/arch/ppc/configs/power3_defconfig	Mon Aug 27 12:41:39 2001
+++ linux/arch/ppc/configs/power3_defconfig	Tue Aug 28 06:58:33 2001
@@ -21,6 +21,7 @@
 # Platform support
 #
 CONFIG_PPC=y
+CONFIG_PPC32=y
 # CONFIG_6xx is not set
 # CONFIG_4xx is not set
 CONFIG_POWER3=y
@@ -28,6 +29,7 @@
 # CONFIG_8xx is not set
 CONFIG_PPC64BRIDGE=y
 CONFIG_ALL_PPC=y
+CONFIG_PPC_STD_MMU=y
 CONFIG_SMP=y
 # CONFIG_IRQ_ALL_CPUS is not set
 
@@ -640,8 +642,10 @@
 #
 CONFIG_SOUND=y
 # CONFIG_DMASOUND_AWACS is not set
+# CONFIG_SOUND_BT878 is not set
 # CONFIG_SOUND_CMPCI is not set
 # CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_MIDI_EMU10K1 is not set
 # CONFIG_SOUND_FUSION is not set
 # CONFIG_SOUND_CS4281 is not set
 # CONFIG_SOUND_ES1370 is not set
@@ -650,6 +654,7 @@
 # CONFIG_SOUND_MAESTRO is not set
 # CONFIG_SOUND_MAESTRO3 is not set
 # CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_RME96XX is not set
 # CONFIG_SOUND_SONICVIBES is not set
 # CONFIG_SOUND_TRIDENT is not set
 # CONFIG_SOUND_MSNDCLAS is not set
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/configs/rpxcllf_defconfig linux/arch/ppc/configs/rpxcllf_defconfig
--- v2.4.9/linux/arch/ppc/configs/rpxcllf_defconfig	Mon Aug 27 12:41:39 2001
+++ linux/arch/ppc/configs/rpxcllf_defconfig	Tue Aug 28 06:58:33 2001
@@ -19,6 +19,7 @@
 # Platform support
 #
 CONFIG_PPC=y
+CONFIG_PPC32=y
 # CONFIG_6xx is not set
 # CONFIG_4xx is not set
 # CONFIG_POWER3 is not set
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/configs/rpxlite_defconfig linux/arch/ppc/configs/rpxlite_defconfig
--- v2.4.9/linux/arch/ppc/configs/rpxlite_defconfig	Mon Aug 27 12:41:39 2001
+++ linux/arch/ppc/configs/rpxlite_defconfig	Tue Aug 28 06:58:33 2001
@@ -19,6 +19,7 @@
 # Platform support
 #
 CONFIG_PPC=y
+CONFIG_PPC32=y
 # CONFIG_6xx is not set
 # CONFIG_4xx is not set
 # CONFIG_POWER3 is not set
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/configs/walnut_defconfig linux/arch/ppc/configs/walnut_defconfig
--- v2.4.9/linux/arch/ppc/configs/walnut_defconfig	Mon Aug 27 12:41:39 2001
+++ linux/arch/ppc/configs/walnut_defconfig	Tue Aug 28 06:58:33 2001
@@ -21,6 +21,7 @@
 # Platform support
 #
 CONFIG_PPC=y
+CONFIG_PPC32=y
 # CONFIG_6xx is not set
 CONFIG_4xx=y
 # CONFIG_POWER3 is not set
@@ -29,6 +30,7 @@
 # CONFIG_OAK is not set
 CONFIG_WALNUT=y
 CONFIG_PPC601_SYNC_FIX=y
+# CONFIG_ALL_PPC is not set
 # CONFIG_SMP is not set
 # CONFIG_MATH_EMULATION is not set
 
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/defconfig linux/arch/ppc/defconfig
--- v2.4.9/linux/arch/ppc/defconfig	Mon Aug 27 12:41:39 2001
+++ linux/arch/ppc/defconfig	Tue Aug 28 06:58:33 2001
@@ -21,18 +21,23 @@
 # Platform support
 #
 CONFIG_PPC=y
+CONFIG_PPC32=y
 CONFIG_6xx=y
 # CONFIG_4xx is not set
 # CONFIG_POWER3 is not set
 # CONFIG_POWER4 is not set
 # CONFIG_8xx is not set
 # CONFIG_8260 is not set
+CONFIG_PPC_STD_MMU=y
 CONFIG_ALL_PPC=y
 # CONFIG_APUS is not set
 # CONFIG_GEMINI is not set
 CONFIG_PPC601_SYNC_FIX=y
 # CONFIG_SMP is not set
 CONFIG_ALTIVEC=y
+CONFIG_TAU=y
+# CONFIG_TAU_INT is not set
+# CONFIG_TAU_AVERAGE is not set
 
 #
 # General setup
@@ -228,6 +233,7 @@
 CONFIG_BLK_DEV_IDEPCI=y
 CONFIG_IDEPCI_SHARE_IRQ=y
 CONFIG_BLK_DEV_IDEDMA_PCI=y
+CONFIG_BLK_DEV_ADMA=y
 # CONFIG_BLK_DEV_OFFBOARD is not set
 CONFIG_IDEDMA_PCI_AUTO=y
 CONFIG_BLK_DEV_IDEDMA=y
@@ -237,8 +243,8 @@
 # CONFIG_AEC62XX_TUNING is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
 # CONFIG_WDC_ALI15X3 is not set
-# CONFIG_BLK_DEV_AMD7409 is not set
-# CONFIG_AMD7409_OVERRIDE is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_AMD74XX_OVERRIDE is not set
 CONFIG_BLK_DEV_CMD64X=y
 # CONFIG_BLK_DEV_CY82C693 is not set
 # CONFIG_BLK_DEV_CS5530 is not set
@@ -249,7 +255,8 @@
 # CONFIG_BLK_DEV_OPTI621 is not set
 # CONFIG_BLK_DEV_PDC202XX is not set
 # CONFIG_PDC202XX_BURST is not set
-# CONFIG_BLK_DEV_OSB4 is not set
+# CONFIG_PDC202XX_FORCE is not set
+# CONFIG_BLK_DEV_SVWKS is not set
 # CONFIG_BLK_DEV_SIS5513 is not set
 # CONFIG_BLK_DEV_SLC90E66 is not set
 # CONFIG_BLK_DEV_TRM290 is not set
@@ -769,8 +776,10 @@
 CONFIG_SOUND=m
 CONFIG_DMASOUND_AWACS=m
 CONFIG_DMASOUND=m
+# CONFIG_SOUND_BT878 is not set
 # CONFIG_SOUND_CMPCI is not set
 # CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_MIDI_EMU10K1 is not set
 # CONFIG_SOUND_FUSION is not set
 # CONFIG_SOUND_CS4281 is not set
 # CONFIG_SOUND_ES1370 is not set
@@ -779,6 +788,7 @@
 # CONFIG_SOUND_MAESTRO is not set
 # CONFIG_SOUND_MAESTRO3 is not set
 # CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_RME96XX is not set
 # CONFIG_SOUND_SONICVIBES is not set
 # CONFIG_SOUND_TRIDENT is not set
 # CONFIG_SOUND_MSNDCLAS is not set
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/Makefile linux/arch/ppc/kernel/Makefile
--- v2.4.9/linux/arch/ppc/kernel/Makefile	Wed Jul 25 17:10:18 2001
+++ linux/arch/ppc/kernel/Makefile	Tue Aug 28 06:58:33 2001
@@ -1,4 +1,4 @@
-# BK Id: SCCS/s.Makefile 1.24 07/10/01 12:12:22 trini
+# BK Id: SCCS/s.Makefile 1.32 08/24/01 20:07:37 paulus
 #
 #
 # Makefile for the linux kernel.
@@ -29,12 +29,13 @@
 
 O_TARGET := kernel.o
 
-export-objs			:= ppc_ksyms.o prep_setup.o 
+export-objs			:= ppc_ksyms.o prep_setup.o time.o
 
 obj-y				:= entry.o traps.o irq.o idle.o time.o misc.o \
 					process.o signal.o ptrace.o \
 					ppc_htab.o semaphore.o syscalls.o  \
-					align.o setup.o
+					align.o setup.o cputable.o
+obj-$(CONFIG_6xx)		+= l2cr.o
 obj-$(CONFIG_MODULES)		+= ppc_ksyms.o
 obj-$(CONFIG_POWER4)		+= xics.o
 obj-$(CONFIG_PCI)		+= pci.o pci-dma.o
@@ -43,6 +44,7 @@
 obj-$(CONFIG_4xx)		+= ppc4xx_pic.o
 obj-$(CONFIG_OAK)		+= oak_setup.o
 obj-$(CONFIG_WALNUT)		+= walnut_setup.o
+obj-$(CONFIG_TAU)		+= temp.o
 ifeq ($(CONFIG_WALNUT),y)
 obj-$(CONFIG_PCI)		+= galaxy_pci.o
 endif
@@ -71,12 +73,17 @@
 obj-$(CONFIG_GEMINI)		+= gemini_prom.o gemini_pci.o gemini_setup.o \
 					open_pic.o
 obj-$(CONFIG_8260)		+= m8260_setup.o ppc8260_pic.o
+obj-$(CONFIG_BOOTX_TEXT)	+= btext.o
 
+ifeq ($(CONFIG_SMP),y)
+obj-$(CONFIG_ALL_PPC)		+= pmac_smp.o chrp_smp.o
+endif
 
 include $(TOPDIR)/Rules.make
 
 entry.o: entry.S ppc_defs.h
 misc.o: misc.S ppc_defs.h
+l2cr.o: l2cr.S ppc_defs.h
 head.o: head.S ppc_defs.h
 head_4xx.o: head_4xx.S ppc_defs.h
 head_8xx.o: head_8xx.S ppc_defs.h
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/apus_pci.c linux/arch/ppc/kernel/apus_pci.c
--- v2.4.9/linux/arch/ppc/kernel/apus_pci.c	Mon Aug 27 12:41:39 2001
+++ linux/arch/ppc/kernel/apus_pci.c	Sat Sep  8 12:38:41 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.apus_pci.c 1.4 07/06/01 09:19:28 trini
+ * BK Id: SCCS/s.apus_pci.c 1.5 09/08/01 15:47:42 paulus
  */
 /*
  * Copyright (C) Michel Dänzer <michdaen@iiic.ethz.ch>
@@ -21,7 +21,6 @@
 #include <linux/delay.h>
 #include <linux/string.h>
 
-#include <asm/init.h>
 #include <asm/io.h>
 #include <asm/pci-bridge.h>
 #include <asm/machdep.h>
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/apus_setup.c linux/arch/ppc/kernel/apus_setup.c
--- v2.4.9/linux/arch/ppc/kernel/apus_setup.c	Mon Aug 27 12:41:39 2001
+++ linux/arch/ppc/kernel/apus_setup.c	Sat Sep  8 12:38:41 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.apus_setup.c 1.14 07/06/01 09:19:28 trini
+ * BK Id: SCCS/s.apus_setup.c 1.20 09/08/01 15:47:42 paulus
  */
 /*
  *  linux/arch/ppc/kernel/apus_setup.c
@@ -76,7 +76,6 @@
 #include <asm/io.h>
 #include <asm/dma.h>
 #include <asm/machdep.h>
-#include <asm/init.h>
 
 #include "local_irq.h"
 
@@ -611,32 +610,8 @@
 /*
  * IDE stuff.
  */
-void ide_insw(ide_ioreg_t port, void *buf, int ns);
-void ide_outsw(ide_ioreg_t port, void *buf, int ns);
-void
-apus_ide_insw(ide_ioreg_t port, void *buf, int ns)
-{
-	ide_insw(port, buf, ns);
-}
-
-void
-apus_ide_outsw(ide_ioreg_t port, void *buf, int ns)
-{
-	ide_outsw(port, buf, ns);
-}
-
-int
-apus_ide_default_irq(ide_ioreg_t base)
-{
-        return 0;
-}
-
-ide_ioreg_t
-apus_ide_default_io_base(int index)
-{
-        return 0;
-}
 
+#if 0	/* no longer used  -- paulus */
 void
 apus_ide_fix_driveid(struct hd_driveid *id)
 {
@@ -682,6 +657,7 @@
       }
    }
 }
+#endif /* 0 */
 
 __init
 void apus_ide_init_hwif_ports (hw_regs_t *hw, ide_ioreg_t data_port, 
@@ -1039,6 +1015,15 @@
 	return total;
 }
 
+static void __init
+apus_map_io(void)
+{
+	/* Map PPC exception vectors. */
+	io_block_mapping(0xfff00000, 0xfff00000, 0x00020000, _PAGE_KERNEL);
+	/* Map chip and ZorroII memory */
+	io_block_mapping(zTwoBase,   0x00000000, 0x01000000, _PAGE_IO);
+}
+
 __init
 void apus_init_IRQ(void)
 {
@@ -1061,8 +1046,8 @@
 }
 
 __init
-void apus_init(unsigned long r3, unsigned long r4, unsigned long r5,
-	       unsigned long r6, unsigned long r7)
+void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
+		   unsigned long r6, unsigned long r7)
 {
 	extern int parse_bootinfo(const struct bi_record *);
 	extern char _end[];
@@ -1113,6 +1098,7 @@
 	ppc_md.calibrate_decr = apus_calibrate_decr;
 
 	ppc_md.find_end_of_memory = apus_find_end_of_memory;
+	ppc_md.setup_io_mappings = apus_map_io;
 
 	ppc_md.nvram_read_val = NULL;
 	ppc_md.nvram_write_val = NULL;
@@ -1130,14 +1116,7 @@
 #endif
 
 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
-        ppc_ide_md.insw = apus_ide_insw;
-        ppc_ide_md.outsw = apus_ide_outsw;
-        ppc_ide_md.default_irq = apus_ide_default_irq;
-        ppc_ide_md.default_io_base = apus_ide_default_io_base;
-        ppc_ide_md.fix_driveid = apus_ide_fix_driveid;
         ppc_ide_md.ide_init_hwif = apus_ide_init_hwif_ports;
-
-        ppc_ide_md.io_base = _IO_BASE;
 #endif		
 }
 
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/btext.c linux/arch/ppc/kernel/btext.c
--- v2.4.9/linux/arch/ppc/kernel/btext.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/kernel/btext.c	Sat Sep  8 12:38:41 2001
@@ -0,0 +1,868 @@
+/*
+ * BK Id: %F% %I% %G% %U% %#%
+ */
+/*
+ * Procedures for drawing on the screen early on in the boot process.
+ *
+ * Benjamin Herrenschmidt <benh@kernel.crashing.org>
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/version.h>
+
+#include <asm/sections.h>
+#include <asm/bootx.h>
+#include <asm/btext.h>
+#include <asm/prom.h>
+#include <asm/page.h>
+#include <asm/mmu.h>
+#include <asm/pgtable.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+
+#define NO_SCROLL
+
+#ifndef NO_SCROLL
+static void scrollscreen(void);
+#endif
+
+static void draw_byte(unsigned char c, long locX, long locY);
+static void draw_byte_32(unsigned char *bits, unsigned long *base, int rb);
+static void draw_byte_16(unsigned char *bits, unsigned long *base, int rb);
+static void draw_byte_8(unsigned char *bits, unsigned long *base, int rb);
+
+static int g_loc_X;
+static int g_loc_Y;
+static int g_max_loc_X;
+static int g_max_loc_Y;
+
+unsigned long disp_BAT[2] __initdata = {0, 0};
+
+#define cmapsz	(16*256)
+
+static unsigned char vga_font[cmapsz];
+
+int boot_text_mapped = 1;
+
+boot_infos_t *disp_bi;
+boot_infos_t fake_bi;
+
+extern char *klimit;
+
+/*
+ * Powermac can use btext_* after boot for xmon,
+ * chrp only uses it during early boot.
+ */
+#ifdef CONFIG_XMON
+#define BTEXT	__pmac
+#define BTDATA	__pmacdata
+#else
+#define BTEXT	__init
+#define BTDATA	__initdata
+#endif /* CONFIG_XMON */
+
+/*
+ * This is called only when we are booted via BootX.
+ */
+void __init
+btext_init(boot_infos_t *bi)
+{
+	unsigned long offset = reloc_offset();
+
+	RELOC(g_loc_X) = 0;
+	RELOC(g_loc_Y) = 0;
+	RELOC(g_max_loc_X) = (bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) / 8;
+	RELOC(g_max_loc_Y) = (bi->dispDeviceRect[3] - bi->dispDeviceRect[1]) / 16;
+	RELOC(disp_bi) = PTRUNRELOC(bi);
+}
+
+void __init
+btext_welcome(boot_infos_t* bi)
+{
+	unsigned long offset = reloc_offset();
+	unsigned long flags;
+	unsigned long pvr;
+	
+	btext_drawstring(RELOC("Welcome to Linux, kernel " UTS_RELEASE "\n"));
+	btext_drawstring(RELOC("\nlinked at        : 0x"));
+	btext_drawhex(KERNELBASE);
+	btext_drawstring(RELOC("\nframe buffer at  : 0x"));
+	btext_drawhex((unsigned long)bi->dispDeviceBase);
+	btext_drawstring(RELOC(" (phys), 0x"));
+	btext_drawhex((unsigned long)bi->logicalDisplayBase);
+	btext_drawstring(RELOC(" (log)"));
+	btext_drawstring(RELOC("\nklimit           : 0x"));
+	btext_drawhex((unsigned long)RELOC(klimit));
+	btext_drawstring(RELOC("\nMSR              : 0x"));
+	__asm__ __volatile__ ("mfmsr %0" : "=r" (flags));
+	btext_drawhex(flags);
+	__asm__ __volatile__ ("mfspr %0, 287" : "=r" (pvr));
+	pvr >>= 16;
+	if (pvr > 1) {
+	    btext_drawstring(RELOC("\nHID0             : 0x"));
+	    __asm__ __volatile__ ("mfspr %0, 1008" : "=r" (flags));
+	    btext_drawhex(flags);
+	}
+	if (pvr == 8 || pvr == 12 || pvr == 0x800c) {
+	    btext_drawstring(RELOC("\nICTC             : 0x"));
+	    __asm__ __volatile__ ("mfspr %0, 1019" : "=r" (flags));
+	    btext_drawhex(flags);
+	}
+	btext_drawstring(RELOC("\n\n"));
+}
+
+/* Calc BAT values for mapping the display and store them
+ * in disp_BAT.  Those values are then used from head.S to map
+ * the display during identify_machine() and MMU_Init()
+ * 
+ * The display is mapped to virtual address 0xD0000000, rather
+ * than 1:1, because some some CHRP machines put the frame buffer
+ * in the region starting at 0xC0000000 (KERNELBASE).
+ * This mapping is temporary and will disappear as soon as the
+ * setup done by MMU_Init() is applied.
+ * 
+ * For now, we align the BAT and then map 8Mb on 601 and 16Mb
+ * on other PPCs. This may cause trouble if the framebuffer
+ * is really badly aligned, but I didn't encounter this case
+ * yet.
+ */
+void __init
+btext_prepare_BAT(void)
+{
+	unsigned long offset = reloc_offset();
+	boot_infos_t* bi = PTRRELOC(RELOC(disp_bi));
+	unsigned long addr = (unsigned long)bi->dispDeviceBase;
+	unsigned long vaddr = KERNELBASE + 0x10000000;
+	unsigned long lowbits;
+
+	if (!RELOC(disp_bi)) {
+		RELOC(boot_text_mapped) = 0;
+		return;
+	}
+	if (PVR_VER(mfspr(PVR)) != 1) {
+		/* 603, 604, G3, G4, ... */
+		lowbits = addr & ~0xFF000000UL;
+		addr &= 0xFF000000UL;
+		RELOC(disp_BAT[0]) = vaddr | (BL_16M<<2) | 2;
+		RELOC(disp_BAT[1]) = addr | (_PAGE_NO_CACHE | _PAGE_GUARDED | BPP_RW);		
+	} else {
+		/* 601 */
+		lowbits = addr & ~0xFF800000UL;
+		addr &= 0xFF800000UL;
+		RELOC(disp_BAT[0]) = vaddr | (_PAGE_NO_CACHE | PP_RWXX) | 4;
+		RELOC(disp_BAT[1]) = addr | BL_8M | 0x40;
+	}
+	bi->logicalDisplayBase = (void *) (vaddr + lowbits);
+}
+
+/* This function will enable the early boot text when doing OF booting. This
+ * way, xmon output should work too
+ */
+void __init
+btext_setup_display(int width, int height, int depth, int pitch,
+		    unsigned long address)
+{
+	unsigned long offset = reloc_offset();
+	boot_infos_t* bi;
+
+	RELOC(disp_bi) = &fake_bi;
+	bi = PTRRELOC((&fake_bi));
+	RELOC(g_loc_X) = 0;
+	RELOC(g_loc_Y) = 0;
+	RELOC(g_max_loc_X) = width / 8;
+	RELOC(g_max_loc_Y) = height / 16;
+	bi->logicalDisplayBase = (unsigned char *)address;
+	bi->dispDeviceBase = (unsigned char *)address;
+	bi->dispDeviceRowBytes = pitch;
+	bi->dispDeviceDepth = depth;
+	bi->dispDeviceRect[0] = bi->dispDeviceRect[1] = 0;
+	bi->dispDeviceRect[2] = width;
+	bi->dispDeviceRect[3] = height;
+}
+
+/* Here's a small text engine to use during early boot
+ * or for debugging purposes
+ * 
+ * todo:
+ * 
+ *  - build some kind of vgacon with it to enable early printk
+ *  - move to a separate file
+ *  - add a few video driver hooks to keep in sync with display
+ *    changes.
+ */
+
+void __openfirmware
+map_boot_text(void)
+{
+	unsigned long base, offset, size;
+	if (disp_bi == 0)
+		return;
+	base = ((unsigned long) disp_bi->dispDeviceBase) & 0xFFFFF000UL;
+	offset = ((unsigned long) disp_bi->dispDeviceBase) - base;
+	size = disp_bi->dispDeviceRowBytes * disp_bi->dispDeviceRect[3] + offset
+		+ disp_bi->dispDeviceRect[0];
+	disp_bi->logicalDisplayBase = ioremap(base, size);
+	if (disp_bi->logicalDisplayBase == 0)
+		return;
+	disp_bi->logicalDisplayBase += offset;
+	boot_text_mapped = 1;
+}
+
+/* Calc the base address of a given point (x,y) */
+static unsigned char * BTEXT
+calc_base(boot_infos_t *bi, int x, int y)
+{
+	unsigned char *base;
+
+	base = bi->logicalDisplayBase;
+	if (base == 0)
+		base = bi->dispDeviceBase;
+	base += (x + bi->dispDeviceRect[0]) * (bi->dispDeviceDepth >> 3);
+	base += (y + bi->dispDeviceRect[1]) * bi->dispDeviceRowBytes;
+	return base;
+}
+
+/* Adjust the display to a new resolution */
+void
+btext_update_display(unsigned long phys, int width, int height,
+		     int depth, int pitch)
+{
+	if (disp_bi == 0)
+		return;
+	/* check it's the same frame buffer (within 64MB) */
+	if ((phys ^ (unsigned long)disp_bi->dispDeviceBase) & 0xfc000000) {
+		return;
+	}
+
+	disp_bi->dispDeviceBase = (__u8 *) phys;
+	disp_bi->dispDeviceRect[0] = 0;
+	disp_bi->dispDeviceRect[1] = 0;
+	disp_bi->dispDeviceRect[2] = width;
+	disp_bi->dispDeviceRect[3] = height;
+	disp_bi->dispDeviceDepth = depth;
+	disp_bi->dispDeviceRowBytes = pitch;
+	if (boot_text_mapped) {
+		iounmap(disp_bi->logicalDisplayBase);
+		boot_text_mapped = 0;
+	}
+	map_boot_text();
+	g_loc_X = 0;
+	g_loc_Y = 0;
+	g_max_loc_X = width / 8;
+	g_max_loc_Y = height / 16;
+}
+
+void BTEXT btext_clearscreen(void)
+{
+	unsigned long offset	= reloc_offset();
+	boot_infos_t* bi	= PTRRELOC(RELOC(disp_bi));
+	unsigned long *base	= (unsigned long *)calc_base(bi, 0, 0);
+	unsigned long width 	= ((bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) *
+					(bi->dispDeviceDepth >> 3)) >> 2;
+	int i,j;
+	
+	for (i=0; i<(bi->dispDeviceRect[3] - bi->dispDeviceRect[1]); i++)
+	{
+		unsigned long *ptr = base;
+		for(j=width; j; --j)
+			*(ptr++) = 0;
+		base += (bi->dispDeviceRowBytes >> 2);
+	}
+}
+
+__inline__ void dcbst(const void* addr)
+{
+	__asm__ __volatile__ ("dcbst 0,%0" :: "r" (addr));
+}
+
+void BTEXT btext_flushscreen(void)
+{
+	unsigned long offset	= reloc_offset();
+	boot_infos_t* bi	= PTRRELOC(RELOC(disp_bi));
+	unsigned long *base	= (unsigned long *)calc_base(bi, 0, 0);
+	unsigned long width 	= ((bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) *
+					(bi->dispDeviceDepth >> 3)) >> 2;
+	int i,j;
+	
+	for (i=0; i<(bi->dispDeviceRect[3] - bi->dispDeviceRect[1]); i++)
+	{
+		unsigned long *ptr = base;
+		for(j=width; j>0; j-=8) {
+			dcbst(ptr);
+			ptr += 8;
+		}
+		base += (bi->dispDeviceRowBytes >> 2);
+	}
+}
+
+#ifndef NO_SCROLL
+static BTEXT void
+scrollscreen(void)
+{
+	unsigned long offset		= reloc_offset();
+	boot_infos_t* bi		= PTRRELOC(RELOC(disp_bi));
+	unsigned long *src		= (unsigned long *)calc_base(bi,0,16);
+	unsigned long *dst		= (unsigned long *)calc_base(bi,0,0);
+	unsigned long width		= ((bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) *
+						(bi->dispDeviceDepth >> 3)) >> 2;
+	int i,j;
+	
+#ifdef CONFIG_ADB_PMU
+	pmu_suspend();	/* PMU will not shut us down ! */
+#endif
+	for (i=0; i<(bi->dispDeviceRect[3] - bi->dispDeviceRect[1] - 16); i++)
+	{
+		unsigned long *src_ptr = src;
+		unsigned long *dst_ptr = dst;
+		for(j=width; j; --j)
+			*(dst_ptr++) = *(src_ptr++);
+		src += (bi->dispDeviceRowBytes >> 2);
+		dst += (bi->dispDeviceRowBytes >> 2);
+	}
+	for (i=0; i<16; i++)
+	{
+		unsigned long *dst_ptr = dst;
+		for(j=width; j; --j)
+			*(dst_ptr++) = 0;
+		dst += (bi->dispDeviceRowBytes >> 2);
+	}
+#ifdef CONFIG_ADB_PMU
+	pmu_resume();	/* PMU will not shut us down ! */
+#endif
+}
+#endif /* ndef NO_SCROLL */
+
+void BTEXT btext_drawchar(char c)
+{
+	unsigned long offset = reloc_offset();
+	int cline = 0, x;
+
+	if (!RELOC(boot_text_mapped))
+		return;
+
+	switch (c) {
+	case '\b':
+		if (RELOC(g_loc_X) > 0)
+			--RELOC(g_loc_X);
+		break;
+	case '\t':
+		RELOC(g_loc_X) = (RELOC(g_loc_X) & -8) + 8;
+		break;
+	case '\r':
+		RELOC(g_loc_X) = 0;
+		break;
+	case '\n':
+		RELOC(g_loc_X) = 0;
+		RELOC(g_loc_Y)++;
+		cline = 1;
+		break;
+	default:
+		draw_byte(c, RELOC(g_loc_X)++, RELOC(g_loc_Y));
+	}
+	if (RELOC(g_loc_X) >= RELOC(g_max_loc_X)) {
+		RELOC(g_loc_X) = 0;
+		RELOC(g_loc_Y)++;
+		cline = 1;
+	}
+#ifndef NO_SCROLL
+	while (RELOC(g_loc_Y) >= RELOC(g_max_loc_Y)) {
+		scrollscreen();
+		RELOC(g_loc_Y)--;
+	}
+#else
+	/* wrap around from bottom to top of screen so we don't
+	   waste time scrolling each line.  -- paulus. */
+	if (RELOC(g_loc_Y) >= RELOC(g_max_loc_Y))
+		RELOC(g_loc_Y) = 0;
+	if (cline) {
+		for (x = 0; x < RELOC(g_max_loc_X); ++x)
+			draw_byte(' ', x, RELOC(g_loc_Y));
+	}
+#endif
+}
+
+void BTEXT
+btext_drawstring(const char *c)
+{
+	unsigned long offset	= reloc_offset();
+
+	if (!RELOC(boot_text_mapped))
+		return;
+	while (*c)
+		btext_drawchar(*c++);
+}
+
+void BTEXT
+btext_drawhex(unsigned long v)
+{
+	static char hex_table[] = "0123456789abcdef";
+	unsigned long offset	= reloc_offset();
+	
+	if (!RELOC(boot_text_mapped))
+		return;
+	btext_drawchar(RELOC(hex_table)[(v >> 28) & 0x0000000FUL]);
+	btext_drawchar(RELOC(hex_table)[(v >> 24) & 0x0000000FUL]);
+	btext_drawchar(RELOC(hex_table)[(v >> 20) & 0x0000000FUL]);
+	btext_drawchar(RELOC(hex_table)[(v >> 16) & 0x0000000FUL]);
+	btext_drawchar(RELOC(hex_table)[(v >> 12) & 0x0000000FUL]);
+	btext_drawchar(RELOC(hex_table)[(v >>  8) & 0x0000000FUL]);
+	btext_drawchar(RELOC(hex_table)[(v >>  4) & 0x0000000FUL]);
+	btext_drawchar(RELOC(hex_table)[(v >>  0) & 0x0000000FUL]);
+	btext_drawchar(' ');
+}
+
+static void BTEXT
+draw_byte(unsigned char c, long locX, long locY)
+{
+	unsigned long offset	= reloc_offset();
+	boot_infos_t* bi	= PTRRELOC(RELOC(disp_bi));
+	unsigned char *base	= calc_base(bi, locX << 3, locY << 4);
+	unsigned char *font	= &RELOC(vga_font)[((unsigned long)c) * 16];
+	int rb			= bi->dispDeviceRowBytes;
+	
+	switch(bi->dispDeviceDepth) {
+	case 32:
+		draw_byte_32(font, (unsigned long *)base, rb);
+		break;
+	case 16:
+		draw_byte_16(font, (unsigned long *)base, rb);
+		break;
+	case 8:
+		draw_byte_8(font, (unsigned long *)base, rb);
+		break;
+	}
+}
+
+static unsigned long expand_bits_8[16] BTDATA = {
+	0x00000000,
+	0x000000ff,
+	0x0000ff00,
+	0x0000ffff,
+	0x00ff0000,
+	0x00ff00ff,
+	0x00ffff00,
+	0x00ffffff,
+	0xff000000,
+	0xff0000ff,
+	0xff00ff00,
+	0xff00ffff,
+	0xffff0000,
+	0xffff00ff,
+	0xffffff00,
+	0xffffffff
+};
+
+static unsigned long expand_bits_16[4] BTDATA = {
+	0x00000000,
+	0x0000ffff,
+	0xffff0000,
+	0xffffffff
+};
+
+
+static void BTEXT
+draw_byte_32(unsigned char *font, unsigned long *base, int rb)
+{
+	int l, bits;	
+	int fg = 0xFFFFFFFFUL;
+	int bg = 0x00000000UL;
+	
+	for (l = 0; l < 16; ++l)
+	{
+		bits = *font++;
+		base[0] = (-(bits >> 7) & fg) ^ bg;
+		base[1] = (-((bits >> 6) & 1) & fg) ^ bg;
+		base[2] = (-((bits >> 5) & 1) & fg) ^ bg;
+		base[3] = (-((bits >> 4) & 1) & fg) ^ bg;
+		base[4] = (-((bits >> 3) & 1) & fg) ^ bg;
+		base[5] = (-((bits >> 2) & 1) & fg) ^ bg;
+		base[6] = (-((bits >> 1) & 1) & fg) ^ bg;
+		base[7] = (-(bits & 1) & fg) ^ bg;
+		base = (unsigned long *) ((char *)base + rb);
+	}
+}
+
+static void BTEXT
+draw_byte_16(unsigned char *font, unsigned long *base, int rb)
+{
+	int l, bits;	
+	int fg = 0xFFFFFFFFUL;
+	int bg = 0x00000000UL;
+	unsigned long offset = reloc_offset();
+	unsigned long *eb = RELOC(expand_bits_16);
+
+	for (l = 0; l < 16; ++l)
+	{
+		bits = *font++;
+		base[0] = (eb[bits >> 6] & fg) ^ bg;
+		base[1] = (eb[(bits >> 4) & 3] & fg) ^ bg;
+		base[2] = (eb[(bits >> 2) & 3] & fg) ^ bg;
+		base[3] = (eb[bits & 3] & fg) ^ bg;
+		base = (unsigned long *) ((char *)base + rb);
+	}
+}
+
+static void BTEXT
+draw_byte_8(unsigned char *font, unsigned long *base, int rb)
+{
+	int l, bits;	
+	int fg = 0x0F0F0F0FUL;
+	int bg = 0x00000000UL;
+	unsigned long offset = reloc_offset();
+	unsigned long *eb = RELOC(expand_bits_8);
+
+	for (l = 0; l < 16; ++l)
+	{
+		bits = *font++;
+		base[0] = (eb[bits >> 4] & fg) ^ bg;
+		base[1] = (eb[bits & 0xf] & fg) ^ bg;
+		base = (unsigned long *) ((char *)base + rb);
+	}
+}
+
+static unsigned char vga_font[cmapsz] BTDATA = {
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 
+0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff, 
+0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 
+0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 
+0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 
+0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 
+0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 
+0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1e, 0x0e, 
+0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 
+0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x63, 
+0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 
+0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0e, 
+0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 
+0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdb, 
+0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 
+0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 
+0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
+0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 
+0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 
+0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 
+0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 
+0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 
+0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 
+0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 
+0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 
+0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, 
+0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 
+0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 
+0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 
+0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 
+0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 
+0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 
+0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 
+0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 
+0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 
+0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 
+0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xde, 0xde, 
+0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 
+0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 
+0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x6c, 
+0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 
+0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 
+0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 
+0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c, 
+0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 
+0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xe7, 
+0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 
+0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 
+0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 
+0x0c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 
+0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 
+0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 
+0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 
+0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 
+0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 
+0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 
+0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 
+0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 
+0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 
+0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x60, 
+0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 
+0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, 0x00, 0x00, 0xe0, 0x60, 
+0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 
+0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0xe0, 0x60, 
+0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb, 
+0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 
+0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 
+0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30, 
+0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 
+0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 
+0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 
+0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18, 
+0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 
+0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 
+0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00, 
+0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 
+0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 
+0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 
+0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, 
+0x3c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 
+0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 
+0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 
+0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66, 
+0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 
+0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00, 
+0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 
+0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b, 
+0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x6c, 
+0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 
+0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 
+0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 
+0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, 
+0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 
+0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 
+0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18, 
+0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 
+0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 
+0xd8, 0x70, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 
+0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 
+0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 
+0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, 
+0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 
+0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06, 
+0x0c, 0x1f, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 
+0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 
+0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 
+0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x44, 0x11, 0x44, 
+0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 
+0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 
+0x55, 0xaa, 0x55, 0xaa, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 
+0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0x18, 0x18, 0x18, 0x18, 
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 
+0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 
+0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 
+0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
+0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
+0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 
+0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 
+0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
+0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 
+0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
+0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
+0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 
+0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 
+0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
+0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 
+0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 
+0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
+0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
+0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 
+0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 
+0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 
+0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 
+0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 
+0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 
+0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 
+0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 
+0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 
+0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 
+0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 
+0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 
+0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x1b, 0x18, 0x18, 
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
+0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 
+0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, 
+0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c, 
+0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 
+};
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/chrp_pci.c linux/arch/ppc/kernel/chrp_pci.c
--- v2.4.9/linux/arch/ppc/kernel/chrp_pci.c	Mon Aug 27 12:41:39 2001
+++ linux/arch/ppc/kernel/chrp_pci.c	Sat Sep  8 12:38:41 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.chrp_pci.c 1.20 08/08/01 16:35:43 paulus
+ * BK Id: SCCS/s.chrp_pci.c 1.22 09/08/01 15:47:42 paulus
  */
 /*
  * CHRP pci routines.
@@ -21,7 +21,7 @@
 #include <asm/prom.h>
 #include <asm/gg2.h>
 #include <asm/machdep.h>
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <asm/pci-bridge.h>
 
 #include "open_pic.h"
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/chrp_setup.c linux/arch/ppc/kernel/chrp_setup.c
--- v2.4.9/linux/arch/ppc/kernel/chrp_setup.c	Wed Jul 25 17:10:18 2001
+++ linux/arch/ppc/kernel/chrp_setup.c	Sat Sep  8 12:38:41 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.chrp_setup.c 1.22 07/18/01 22:56:39 paulus
+ * BK Id: SCCS/s.chrp_setup.c 1.36 09/08/01 15:47:42 paulus
  */
 /*
  *  linux/arch/ppc/kernel/setup.c
@@ -51,8 +51,9 @@
 #include <asm/irq.h>
 #include <asm/hydra.h>
 #include <asm/keyboard.h>
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <asm/time.h>
+#include <asm/btext.h>
 
 #include "local_irq.h"
 #include "i8259.h"
@@ -68,7 +69,7 @@
 void chrp_event_scan(void);
 void rtas_display_progress(char *, unsigned short);
 void rtas_indicator_progress(char *, unsigned short);
-void bootx_text_progress(char *, unsigned short);
+void btext_progress(char *, unsigned short);
 
 extern unsigned long pmac_find_end_of_memory(void);
 extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
@@ -79,14 +80,7 @@
 extern void pckbd_leds(unsigned char leds);
 extern void pckbd_init_hw(void);
 extern unsigned char pckbd_sysrq_xlate[128];
-extern int mackbd_setkeycode(unsigned int scancode, unsigned int keycode);
-extern int mackbd_getkeycode(unsigned int scancode);
-extern int mackbd_translate(unsigned char scancode, unsigned char *keycode,
-			    char raw_mode);
-extern char mackbd_unexpected_up(unsigned char keycode);
-extern void mackbd_leds(unsigned char leds);
-extern void mackbd_init_hw(void);
-extern unsigned char mackbd_sysrq_xlate[128];
+extern void select_adb_keyboard(void);
 
 extern kdev_t boot_dev;
 
@@ -94,9 +88,13 @@
 extern unsigned long Hash_size, Hash_mask;
 extern int probingmem;
 extern unsigned long loops_per_jiffy;
-extern int bootx_text_mapped;
 static int max_width;
 
+#ifdef CONFIG_SMP
+extern struct smp_ops_t chrp_smp_ops;
+extern struct smp_ops_t xics_smp_ops;
+#endif
+
 static const char *gg2_memtypes[4] = {
 	"FPM", "SDRAM", "EDO", "BEDO"
 };
@@ -248,9 +246,6 @@
 	chrp_find_bridges();
 
 #ifndef CONFIG_PPC64BRIDGE
-	/* PCI bridge config space access area -
-	 * appears to be not in devtree on longtrail. */
-	ioremap(GG2_PCI_CONFIG_BASE, 0x80000);
 	/*
 	 *  Temporary fixes for PCI devices.
 	 *  -- Geert
@@ -259,7 +254,6 @@
 
 #endif /* CONFIG_PPC64BRIDGE */
 
-#ifndef CONFIG_POWER4
 	/* Some IBM machines don't have the hydra -- Cort */
 	if (!OpenPIC_Addr) {
 		struct device_node *root;
@@ -276,7 +270,6 @@
 			OpenPIC_Addr = ioremap(opprop[n-1], 0x40000);
 		}
 	}
-#endif
 
 	/*
 	 *  Fix the Super I/O configuration
@@ -401,9 +394,6 @@
 void __init
 chrp_init2(void)
 {
-#if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD)
-	struct device_node *kbd;
-#endif
 #ifdef CONFIG_NVRAM  
 	pmac_nvram_init();
 #endif
@@ -418,87 +408,35 @@
 	if (ppc_md.progress)
 		ppc_md.progress("  Have fun!    ", 0x7777);
 
-#if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD)
+#if defined(CONFIG_VT) && (defined(CONFIG_ADB_KEYBOARD) || defined(CONFIG_INPUT))
 	/* see if there is a keyboard in the device tree
 	   with a parent of type "adb" */
-	for (kbd = find_devices("keyboard"); kbd; kbd = kbd->next)
-		if (kbd->parent && kbd->parent->type
-		    && strcmp(kbd->parent->type, "adb") == 0)
-			break;
-	if (kbd) {
-		ppc_md.kbd_setkeycode    = mackbd_setkeycode;
-		ppc_md.kbd_getkeycode    = mackbd_getkeycode;
-		ppc_md.kbd_translate     = mackbd_translate;
-		ppc_md.kbd_unexpected_up = mackbd_unexpected_up;
-		ppc_md.kbd_leds          = mackbd_leds;
-		ppc_md.kbd_init_hw       = mackbd_init_hw;
-#ifdef CONFIG_MAGIC_SYSRQ
-		ppc_md.ppc_kbd_sysrq_xlate	 = mackbd_sysrq_xlate;
-		SYSRQ_KEY = 0x69;
-#endif /* CONFIG_MAGIC_SYSRQ */
+	{
+		struct device_node *kbd;
+
+		for (kbd = find_devices("keyboard"); kbd; kbd = kbd->next) {
+			if (kbd->parent && kbd->parent->type
+			    && strcmp(kbd->parent->type, "adb") == 0) {
+				select_adb_keyboard();
+				break;
+			}
+		}
 	}
-#endif /* CONFIG_VT && CONFIG_ADB_KEYBOARD */
+#endif /* CONFIG_VT && (CONFIG_ADB_KEYBOARD || CONFIG_INPUT) */
 }
 
 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
 /*
  * IDE stuff.
  */
-unsigned int chrp_ide_irq = 0;
-int chrp_ide_ports_known = 0;
-ide_ioreg_t chrp_ide_regbase[MAX_HWIFS];
-ide_ioreg_t chrp_idedma_regbase;
-
-void __chrp
-chrp_ide_probe(void)
-{
-        struct pci_dev *pdev = pci_find_device(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105, NULL);
-
-        chrp_ide_ports_known = 1;
-
-        if(pdev) {
-                chrp_ide_regbase[0]=pdev->resource[0].start;
-                chrp_ide_regbase[1]=pdev->resource[2].start;
-                chrp_idedma_regbase=pdev->resource[4].start;
-                chrp_ide_irq=pdev->irq;
-        }
-}
 
-void __chrp
-chrp_ide_insw(ide_ioreg_t port, void *buf, int ns)
-{
-	ide_insw(port+_IO_BASE, buf, ns);
-}
-
-void __chrp
-chrp_ide_outsw(ide_ioreg_t port, void *buf, int ns)
-{
-	ide_outsw(port+_IO_BASE, buf, ns);
-}
-
-int __chrp
-chrp_ide_default_irq(ide_ioreg_t base)
-{
-        if (chrp_ide_ports_known == 0)
-	        chrp_ide_probe();
-	return chrp_ide_irq;
-}
-
-ide_ioreg_t __chrp
-chrp_ide_default_io_base(int index)
-{
-        if (chrp_ide_ports_known == 0)
-	        chrp_ide_probe();
-	return chrp_ide_regbase[index];
-}
-
-int __chrp
+static int __chrp
 chrp_ide_check_region(ide_ioreg_t from, unsigned int extent)
 {
         return check_region(from, extent);
 }
 
-void __chrp
+static void __chrp
 chrp_ide_request_region(ide_ioreg_t from,
 			unsigned int extent,
 			const char *name)
@@ -506,14 +444,14 @@
         request_region(from, extent, name);
 }
 
-void __chrp
+static void __chrp
 chrp_ide_release_region(ide_ioreg_t from,
 			unsigned int extent)
 {
         release_region(from, extent);
 }
 
-void __chrp
+static void __chrp
 chrp_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;
@@ -523,20 +461,42 @@
 		hw->io_ports[i] = reg;
 		reg += 1;
 	}
-	if (ctrl_port) {
-		hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
+	hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
+}
+#endif
+
+/*
+ * One of the main thing these mappings are needed for is so that
+ * xmon can get to the serial port early on.  We probably should
+ * handle the machines with the mpc106 as well as the python (F50)
+ * and the GG2 (longtrail).  Actually we should look in the device
+ * tree and do the right thing.
+ */
+static void __init
+chrp_map_io(void)
+{
+	char *name;
+
+	/*
+	 * The code below tends to get removed, please don't take it out.
+	 * The F50 needs this mapping and it you take it out I'll track you
+	 * down and slap your hands.  If it causes problems please email me.
+	 *  -- Cort <cort@fsmlabs.com>
+	 */
+	name = get_property(find_path_device("/"), "name", NULL);
+	if (name && strncmp(name, "IBM-70", 6) == 0
+	    && strstr(name, "-F50")) {
+		io_block_mapping(0x80000000, 0x80000000, 0x10000000, _PAGE_IO);
+		io_block_mapping(0x90000000, 0x90000000, 0x10000000, _PAGE_IO);
+		return;
 	} else {
-		hw->io_ports[IDE_CONTROL_OFFSET] = 0;
+		io_block_mapping(0xf8000000, 0xf8000000, 0x04000000, _PAGE_IO);
 	}
-	if (irq != NULL)
-		hw->irq = chrp_ide_irq;
 }
 
-#endif
-
 void __init
-	   chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
-		     unsigned long r6, unsigned long r7)
+chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
+	  unsigned long r6, unsigned long r7)
 {
 #ifdef CONFIG_BLK_DEV_INITRD
 	/* take care of initrd if we have one */
@@ -576,6 +536,7 @@
 	ppc_md.calibrate_decr = chrp_calibrate_decr;
 
 	ppc_md.find_end_of_memory = pmac_find_end_of_memory;
+	ppc_md.setup_io_mappings = chrp_map_io;
 
 #ifdef CONFIG_VT
 	/* these are adjusted in chrp_init2 if we have an ADB keyboard */
@@ -608,22 +569,23 @@
 		}
 	}
 #ifdef CONFIG_BOOTX_TEXT
-	if (ppc_md.progress == NULL && bootx_text_mapped)
-		ppc_md.progress = bootx_text_progress;
+	if (ppc_md.progress == NULL && boot_text_mapped)
+		ppc_md.progress = btext_progress;
 #endif
 
+#ifdef CONFIG_SMP
+#ifndef CONFIG_POWER4
+	ppc_md.smp_ops = &chrp_smp_ops;
+#else
+	ppc_md.smp_ops = &xics_smp_ops;
+#endif /* CONFIG_POWER4 */
+#endif /* CONFIG_SMP */
+
 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
-        ppc_ide_md.insw = chrp_ide_insw;
-        ppc_ide_md.outsw = chrp_ide_outsw;
-        ppc_ide_md.default_irq = chrp_ide_default_irq;
-        ppc_ide_md.default_io_base = chrp_ide_default_io_base;
         ppc_ide_md.ide_check_region = chrp_ide_check_region;
         ppc_ide_md.ide_request_region = chrp_ide_request_region;
         ppc_ide_md.ide_release_region = chrp_ide_release_region;
-        ppc_ide_md.fix_driveid = ppc_generic_ide_fix_driveid;
         ppc_ide_md.ide_init_hwif = chrp_ide_init_hwif_ports;
-
-        ppc_ide_md.io_base = _IO_BASE;
 #endif
 
 	/*
@@ -668,7 +630,7 @@
 
 #ifdef CONFIG_BOOTX_TEXT
 void
-bootx_text_progress(char *s, unsigned short hex)
+btext_progress(char *s, unsigned short hex)
 {
 	prom_print(s);
 	prom_print("\n");
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/chrp_smp.c linux/arch/ppc/kernel/chrp_smp.c
--- v2.4.9/linux/arch/ppc/kernel/chrp_smp.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/kernel/chrp_smp.c	Sat Sep  8 12:38:41 2001
@@ -0,0 +1,149 @@
+/*
+ * BK Id: %F% %I% %G% %U% %#%
+ */
+/*
+ * Smp support for CHRP machines.
+ *
+ * Written by Cort Dougan (cort@cs.nmt.edu) borrowing a great
+ * deal of code from the sparc and intel versions.
+ *
+ * Copyright (C) 1999 Cort Dougan <cort@cs.nmt.edu>
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/delay.h>
+#define __KERNEL_SYSCALLS__
+#include <linux/unistd.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+
+#include <asm/ptrace.h>
+#include <asm/atomic.h>
+#include <asm/irq.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/hardirq.h>
+#include <asm/softirq.h>
+#include <asm/sections.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/smp.h>
+#include <asm/residual.h>
+#include <asm/feature.h>
+#include <asm/time.h>
+
+#include "open_pic.h"
+
+extern unsigned long smp_chrp_cpu_nr;
+
+static int __init
+smp_chrp_probe(void)
+{
+	if (smp_chrp_cpu_nr > 1)
+		openpic_request_IPIs();
+
+	return smp_chrp_cpu_nr;
+}
+
+static void __init
+smp_chrp_kick_cpu(int nr)
+{
+	*(unsigned long *)KERNELBASE = nr;
+	asm volatile("dcbf 0,%0"::"r"(KERNELBASE):"memory");
+}
+
+static void __init
+smp_chrp_setup_cpu(int cpu_nr)
+{
+	static atomic_t ready = ATOMIC_INIT(1);
+	static volatile int frozen = 0;
+
+	if (cpu_nr == 0) {
+		/* wait for all the others */
+		while (atomic_read(&ready) < smp_num_cpus)
+			barrier();
+		atomic_set(&ready, 1);
+		/* freeze the timebase */
+		call_rtas("freeze-time-base", 0, 1, NULL);
+		mb();
+		frozen = 1;
+		/* XXX assumes this is not a 601 */
+		set_tb(0, 0);
+		last_jiffy_stamp(0) = 0;
+		while (atomic_read(&ready) < smp_num_cpus)
+			barrier();
+		/* thaw the timebase again */
+		call_rtas("thaw-time-base", 0, 1, NULL);
+		mb();
+		frozen = 0;
+		smp_tb_synchronized = 1;
+	} else {
+		atomic_inc(&ready);
+		while (!frozen)
+			barrier();
+		set_tb(0, 0);
+		last_jiffy_stamp(0) = 0;
+		mb();
+		atomic_inc(&ready);
+		while (frozen)
+			barrier();
+	}
+
+	if (OpenPIC_Addr)
+		do_openpic_setup_cpu();
+}
+
+#ifdef CONFIG_POWER4
+static void __chrp
+smp_xics_message_pass(int target, int msg, unsigned long data, int wait)
+{
+	/* for now, only do reschedule messages
+	   since we only have one IPI */
+	if (msg != PPC_MSG_RESCHEDULE)
+		return;
+	for (i = 0; i < smp_num_cpus; ++i) {
+		if (target == MSG_ALL || target == i
+		    || (target == MSG_ALL_BUT_SELF
+			&& i != smp_processor_id()))
+			xics_cause_IPI(i);
+	}
+}
+
+static int __chrp
+smp_xics_probe(void)
+{
+	return smp_chrp_cpu_nr;
+}
+
+static void __chrp
+smp_xics_setup_cpu(int cpu_nr)
+{
+	if (cpu_nr > 0)
+		xics_setup_cpu();
+}
+#endif /* CONFIG_POWER4 */
+
+/* CHRP with openpic */
+struct smp_ops_t chrp_smp_ops __chrpdata = {
+	smp_openpic_message_pass,
+	smp_chrp_probe,
+	smp_chrp_kick_cpu,
+	smp_chrp_setup_cpu,
+};
+
+#ifdef CONFIG_POWER4
+/* CHRP with new XICS interrupt controller */
+struct smp_ops_t xics_smp_ops __chrpdata = {
+	smp_xics_message_pass,
+	smp_xics_probe,
+	smp_chrp_kick_cpu,
+	smp_xics_setup_cpu,
+};
+#endif /* CONFIG_POWER4 */
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/chrp_time.c linux/arch/ppc/kernel/chrp_time.c
--- v2.4.9/linux/arch/ppc/kernel/chrp_time.c	Mon May 21 17:04:46 2001
+++ linux/arch/ppc/kernel/chrp_time.c	Sat Sep  8 12:38:41 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.chrp_time.c 1.7 05/17/01 18:14:21 cort
+ * BK Id: SCCS/s.chrp_time.c 1.10 09/08/01 15:47:42 paulus
  */
 /*
  *  linux/arch/i386/kernel/time.c
@@ -29,7 +29,7 @@
 #include <asm/processor.h>
 #include <asm/nvram.h>
 #include <asm/prom.h>
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <asm/time.h>
 
 extern spinlock_t rtc_lock;
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/cputable.c linux/arch/ppc/kernel/cputable.c
--- v2.4.9/linux/arch/ppc/kernel/cputable.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/kernel/cputable.c	Tue Aug 28 06:58:33 2001
@@ -0,0 +1,283 @@
+/*
+ * BK Id: %F% %I% %G% %U% %#%
+ */
+/*
+ *  arch/ppc/kernel/cputable.c
+ *
+ *  Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.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/config.h>
+#include <linux/string.h>
+#include <linux/sched.h>
+#include <linux/threads.h>
+#include <linux/init.h>
+#include <asm/cputable.h>
+
+struct cpu_spec* cur_cpu_spec[NR_CPUS];
+
+extern void __setup_cpu_601(int cpu_nr);
+extern void __setup_cpu_603(int cpu_nr);
+extern void __setup_cpu_604(int cpu_nr);
+extern void __setup_cpu_750(int cpu_nr);
+extern void __setup_cpu_7400(int cpu_nr);
+extern void __setup_cpu_7450(int cpu_nr);
+extern void __setup_cpu_power3(int cpu_nr);
+extern void __setup_cpu_power4(int cpu_nr);
+extern void __setup_cpu_8xx(int cpu_nr);
+extern void __setup_cpu_generic(int cpu_nr);
+
+#define CLASSIC_PPC (!defined(CONFIG_8xx) && 	 \
+		     !defined(CONFIG_4xx) && !defined(CONFIG_POWER3) &&  \
+		     !defined(CONFIG_POWER4) && !defined(CONFIG_PPC_ISERIES))
+
+/* This table only contains "desktop" CPUs, it need to be filled with embedded
+ * ones as well...
+ */
+#define COMMON_PPC	(PPC_FEATURE_32 | PPC_FEATURE_HAS_FPU | \
+			 PPC_FEATURE_HAS_MMU)
+
+/* We only set the altivec features if the kernel was compiled with altivec
+ * support
+ */
+#ifdef CONFIG_ALTIVEC
+#define CPU_FTR_ALTIVEC_COMP	CPU_FTR_ALTIVEC
+#else
+#define CPU_FTR_ALTIVEC_COMP	0
+#endif
+
+struct cpu_spec	cpu_specs[] = {
+#if CLASSIC_PPC
+    { 	/* 601 */
+	0xffff0000, 0x00010000, "601",
+	CPU_FTR_601 | CPU_FTR_HPTE_TABLE,
+	COMMON_PPC | PPC_FEATURE_601_INSTR | PPC_FEATURE_UNIFIED_CACHE,
+	32, 32,
+	__setup_cpu_601
+    },
+    {	/* 603 */
+    	0xffff0000, 0x00030000, "603",
+    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB,
+	COMMON_PPC,
+    	32, 32,
+	__setup_cpu_603
+    },
+    {	/* 603e */
+    	0xffff0000, 0x00060000, "603e",
+    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB,
+	COMMON_PPC,
+	32, 32,
+	__setup_cpu_603
+    },
+    {	/* 603ev */
+    	0xffff0000, 0x00070000, "603ev",
+    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB,
+	COMMON_PPC,
+	32, 32,
+	__setup_cpu_603
+    },
+    {	/* 604 */
+    	0xffff0000, 0x00040000, "604",
+    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_604_PERF_MON |
+	CPU_FTR_HPTE_TABLE,
+	COMMON_PPC,
+	32, 32,
+	__setup_cpu_604
+    },
+    {	/* 604e */
+    	0xfffff000, 0x00090000, "604e",
+    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_604_PERF_MON |
+	CPU_FTR_HPTE_TABLE,
+	COMMON_PPC,
+	32, 32,
+	__setup_cpu_604
+    },
+    {	/* 604r */
+    	0xffff0000, 0x00090000, "604r",
+    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_604_PERF_MON |
+	CPU_FTR_HPTE_TABLE,
+	COMMON_PPC,
+	32, 32,
+	__setup_cpu_604
+    },
+    {	/* 604ev */
+    	0xffff0000, 0x000a0000, "604ev",
+    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_604_PERF_MON |
+	CPU_FTR_HPTE_TABLE,
+	COMMON_PPC,
+	32, 32,
+	__setup_cpu_604
+    },
+    {	/* 750 (0x4202, don't support TAU ?) */
+    	0xffffffff, 0x00084202, "750",
+    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
+	CPU_FTR_L2CR | CPU_FTR_HPTE_TABLE,
+	COMMON_PPC,
+	32, 32,
+	__setup_cpu_750
+    },
+    {	/* 750CX */
+    	0xffffff00, 0x00082200, "750CX",
+    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
+	CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE,
+	COMMON_PPC,
+	32, 32,
+	__setup_cpu_750
+    },
+    {	/* 740/750 (L2CR bit need fixup for 740) */
+    	0xffff0000, 0x00080000, "740/750",
+    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
+	CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE,
+	COMMON_PPC,
+	32, 32,
+	__setup_cpu_750
+    },
+    {	/* 7400 rev 1.1 ? (no TAU) */
+    	0xffffffff, 0x000c1101, "7400 (1.1)",
+    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
+	CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE,
+	COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC,
+	32, 32,
+	__setup_cpu_7400
+    },
+    {	/* 7400 */
+    	0xffff0000, 0x000c0000, "7400",
+    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
+	CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE,
+	COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC,
+	32, 32,
+	__setup_cpu_7400
+    },
+    {	/* 7410 */
+    	0xffff0000, 0x800c0000, "7410",
+    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
+	CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE,
+	COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC,
+	32, 32,
+	__setup_cpu_7400
+    },
+    {	/* 7450 */
+    	0xffff0000, 0x80000000, "7450",
+    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
+	CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP |
+	CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450,
+	COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC,
+	32, 32,
+	__setup_cpu_7450
+    },
+    {	/* 82xx (8240, 8245, 8260 are all 603e cores) */
+	0xffff0000, 0x00810000, "82xx",
+	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB,
+	COMMON_PPC,
+	32, 32,
+	__setup_cpu_603
+    },
+    {	/* default match, we assume split I/D cache & TB (non-601)... */
+    	0x00000000, 0x00000000, "(generic PPC)",
+    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE,
+	COMMON_PPC,
+	32, 32,
+	__setup_cpu_generic
+    },
+#endif /* CLASSIC_PPC */    
+#ifdef CONFIG_PPC64BRIDGE
+    {	/* Power3 */
+    	0xffff0000, 0x00400000, "Power3 (630)",
+    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE,
+    	COMMON_PPC | PPC_FEATURE_64,
+	128, 128,
+	__setup_cpu_power3
+    },
+    {	/* Power3+ */
+    	0xffff0000, 0x00410000, "Power3 (630+)",
+    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE,
+    	COMMON_PPC | PPC_FEATURE_64,
+	128, 128,
+	__setup_cpu_power3
+    },
+	{	/* I-star */
+		0xffff0000, 0x00360000, "I-star",
+		CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE,
+		COMMON_PPC | PPC_FEATURE_64,
+		128, 128,
+		__setup_cpu_power3
+	},
+	{	/* S-star */
+		0xffff0000, 0x00370000, "S-star",
+		CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE,
+		COMMON_PPC | PPC_FEATURE_64,
+		128, 128,
+		__setup_cpu_power3
+	},
+#endif /* CONFIG_PPC64BRIDGE */    
+#ifdef CONFIG_POWER4
+    {	/* Power4 */
+    	0xffff0000, 0x00350000, "Power4",
+    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE,
+    	COMMON_PPC | PPC_FEATURE_64,
+	128, 128,
+	__setup_cpu_power4
+    },
+#endif /* CONFIG_POWER4 */    
+#ifdef CONFIG_8xx
+    {	/* 8xx */
+    	0xffff0000, 0x00500000, "8xx",
+		/* CPU_FTR_CAN_DOZE is possible, if the 8xx code is there.... */
+    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB,
+    	PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
+ 	16, 16,
+	0, __setup_cpu_8xx
+    },
+#endif /* CONFIG_8xx */
+#ifdef CONFIG_4xx
+    {	/* 403GC */
+    	0xffffff00, 0x00200200, "403GC",
+    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB,
+    	PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
+	16, 16,
+	0, /*__setup_cpu_403 */
+    },
+    {	/* 403GCX */
+    	0xffffff00, 0x00201400, "403GCX",
+    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB,
+    	PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
+	16, 16,
+	0, /*__setup_cpu_403 */
+    },
+    {	/* 403G ?? */
+    	0xffff0000, 0x00200000, "403G ??",
+    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB,
+    	PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
+	16, 16,
+	0, /*__setup_cpu_403 */
+    },
+    {	/* 405GP */
+    	0xffff0000, 0x40110000, "405GP",
+    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB,
+    	PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+	32, 32,
+	0, /*__setup_cpu_405 */
+    },
+    {	/* STB 03xxx */
+    	0xffff0000, 0x40130000, "STB03xxx",
+    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB,
+    	PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+	32, 32,
+	0, /*__setup_cpu_405 */
+    },
+#endif /* CONFIG_4xx */
+#if !CLASSIC_PPC
+    {	/* default match */
+    	0x00000000, 0x00000000, "(generic PPC)",
+    	0,
+    	PPC_FEATURE_32,
+	32, 32,
+	0,
+    }
+#endif /* !CLASSIC_PPC */
+};
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/entry.S linux/arch/ppc/kernel/entry.S
--- v2.4.9/linux/arch/ppc/kernel/entry.S	Wed Jul 25 17:10:18 2001
+++ linux/arch/ppc/kernel/entry.S	Tue Aug 28 06:58:33 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.entry.S 1.20 07/19/01 23:02:48 paulus
+ * BK Id: SCCS/s.entry.S 1.22 08/15/01 22:43:06 paulus
  */
 /*
  *  PowerPC version 
@@ -23,12 +23,14 @@
  */
 
 #include "ppc_asm.h"
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sys.h>
+#include <linux/threads.h>
 #include <asm/processor.h>
 #include <asm/page.h>
 #include <asm/mmu.h>
-#include <linux/errno.h>
-#include <linux/sys.h>
-#include <linux/config.h>
+#include <asm/cputable.h>
 
 #undef SHOW_SYSCALLS
 #undef SHOW_SYSCALLS_TASK
@@ -217,7 +219,9 @@
 	mfmsr	r22
 	li	r0,MSR_FP	/* Disable floating-point */
 #ifdef CONFIG_ALTIVEC
-	oris	r0,r0,MSR_VEC@h
+BEGIN_FTR_SECTION
+	oris	r0,r0,MSR_VEC@h	/* Disable altivec */
+END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
 #endif /* CONFIG_ALTIVEC */
 	andc	r22,r22,r0
 	mtmsr	r22
@@ -238,21 +242,6 @@
 	tophys(r0,r4)
 	CLR_TOP32(r0)
 	mtspr	SPRG3,r0	/* Update current THREAD phys addr */
-#ifdef CONFIG_8xx
-	/* XXX it would be nice to find a SPRGx for this on 6xx,7xx too */
-	lwz	r9,PGDIR(r4)	/* cache the page table root */
-        tophys(r9,r9)		/* convert to phys addr */
-#ifdef CONFIG_8xx_CPU6
-	lis	r6, cpu6_errata_word@h
-	ori	r6, r6, cpu6_errata_word@l
-	li	r5, 0x3980
-	stw	r5, 8(r6)
-	lwz	r5, 8(r6)
-#endif
-        mtspr   M_TWB,r9	/* Update MMU base address */
-	tlbia
-	sync
-#endif /* CONFIG_8xx */
 	lwz	r1,KSP(r4)	/* Load new stack pointer */
 	/* save the old current 'last' for return value */
 	mr	r3,r2
@@ -328,19 +317,16 @@
 	andi.	r0,r0,MSR_PR
 	beq+	1f
 #ifdef CONFIG_ALTIVEC
-	mfpvr	r8			/* check if we are on a G4 */
-	srwi	r8,r8,16
-	cmpwi	r8,PVR_7400@h
-	bne	2f
+BEGIN_FTR_SECTION
 	lwz	r0,THREAD+THREAD_VRSAVE(r2)
-	mtspr	SPRN_VRSAVE,r0		/* if so, restore VRSAVE reg */
-2:
+	mtspr	SPRN_VRSAVE,r0		/* if G4, restore VRSAVE reg */
+END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
 #endif /* CONFIG_ALTIVEC */
 	addi	r0,r1,INT_FRAME_SIZE	/* size of frame */
 	stw	r0,THREAD+KSP(r2)	/* save kernel stack pointer */
 	tophys(r8,r1)
 	CLR_TOP32(r8)
-	mtspr	SPRG2,r8		/* phys exception stack pointer */	
+	mtspr	SPRG2,r8		/* phys exception stack pointer */
 1:
 	lwz	r3,_CTR(r1)
 	lwz	r0,_LINK(r1)
@@ -348,15 +334,32 @@
 	mtlr	r0
 	REST_4GPRS(3, r1)
 	REST_2GPRS(7, r1)
+
+	/* We have to "dummy" load from the context save area in case
+	 * these instructions cause an MMU fault.  If this happens
+	 * after we load SRR0/SRR1, our return context is hosed.  -- Dan
+	 */
+	lwz	r0,GPR0(r1)
+	lwz	r0,GPR2(r1)
+	lwz	r0,GPR1(r1)
+
+	/* We re-use r3,r4 here (the load above was to cause the MMU
+	 * fault if necessary).  Using r3,r4 removes the need to "dummy"
+	 * load the CCR and NIP.  Since we load them we may as well
+	 * use them.
+	 */
+	lwz	r3,_CCR(r1)
+	lwz	r4,_NIP(r1)
+
 	lwz	r0,_MSR(r1)
 	FIX_SRR1(r0,r2)
 	mtspr	SRR1,r0
-	lwz	r2,_CCR(r1)
-	mtcrf	0xFF,r2
-	lwz	r2,_NIP(r1)
-	mtspr	SRR0,r2
+	mtcrf	0xFF,r3
+	mtspr	SRR0,r4
 	lwz	r0,GPR0(r1)
 	lwz	r2,GPR2(r1)
+	lwz	r3,GPR3(r1)
+	lwz	r4,GPR4(r1)
 	lwz	r1,GPR1(r1)
 	SYNC
 	RFI
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/feature.c linux/arch/ppc/kernel/feature.c
--- v2.4.9/linux/arch/ppc/kernel/feature.c	Mon Aug 27 12:41:39 2001
+++ linux/arch/ppc/kernel/feature.c	Sat Sep  8 12:38:41 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.feature.c 1.16 07/06/01 14:42:47 trini
+ * BK Id: SCCS/s.feature.c 1.21 09/08/01 15:47:42 paulus
  */
 /*
  *  arch/ppc/kernel/feature.c
@@ -20,7 +20,7 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/spinlock.h>
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <asm/errno.h>
 #include <asm/ohare.h>
 #include <asm/heathrow.h>
@@ -38,11 +38,15 @@
 #define FREG(c,r)			(&(((c)->reg)[(r)>>2]))
 
 /* Keylargo reg. access. */
-#define KL_FCR(r)	(keylargo_base + ((r) >> 2))
-#define KL_IN(r)	(in_le32(KL_FCR(r)))
-#define KL_OUT(r,v)	(out_le32(KL_FCR(r), (v)))
-#define KL_BIS(r,v)	(KL_OUT((r), KL_IN(r) | (v)))
-#define KL_BIC(r,v)	(KL_OUT((r), KL_IN(r) & ~(v)))
+#define KL_FCR(r)		(keylargo_base + ((r) >> 2))
+#define KL_IN(r)		(in_le32(KL_FCR(r)))
+#define KL_OUT(r,v)		(out_le32(KL_FCR(r), (v)))
+#define KL_BIS(r,v)		(KL_OUT((r), KL_IN(r) | (v)))
+#define KL_BIC(r,v)		(KL_OUT((r), KL_IN(r) & ~(v)))
+#define KL_GPIO_IN(r)		(in_8(((volatile u8 *)keylargo_base)+(r)))
+#define KL_GPIO_OUT(r,v)	(out_8(((volatile u8 *)keylargo_base)+(r), (v)))
+#define KL_LOCK()		spin_lock_irqsave(&keylargo->lock, flags)
+#define KL_UNLOCK()		spin_unlock_irqrestore(&keylargo->lock, flags)
 
 /* Uni-N reg. access. Note that Uni-N regs are big endian */
 #define UN_REG(r)	(uninorth_base + ((r) >> 2))
@@ -259,15 +263,29 @@
 static int				uninorth_rev;
 static int				keylargo_rev;
 static u32				board_features;
-static u8				airport_pwr_regs[5];
 static int				airport_pwr_state;
 static struct device_node*		airport_dev;
+static struct device_node*		uninorth_fw;
 
+/* Feature bits for Apple motherboards */
 #define FTR_NEED_OPENPIC_TWEAK		0x00000001
 #define FTR_CAN_NAP			0x00000002
 #define FTR_HAS_FW_POWER		0x00000004
 #define FTR_CAN_SLEEP			0x00000008
 
+/* This table currently lacks most oldworld machines, but
+ * they currently don't need it so...
+ * 
+ * Todo: The whole feature_xxx mecanism need to be redone
+ * some way to be able to handle the new kind of features
+ * exposed by core99. At this point, the main "tables" will
+ * probably be in this table, which will have to be filled with
+ * all known machines
+ */
+/* Warning: Don't change ordering of entries as some machines
+ * adverstise beeing compatible with several models. In those
+ * case, the "highest" has to be first
+ */
 static struct board_features_t {
 	char*	compatible;
 	u32	features;
@@ -283,17 +301,21 @@
   {	"PowerMac3,1",		FTR_NEED_OPENPIC_TWEAK		}, /* Sawtooth (G4) */
   {	"PowerMac3,2",		0				}, /* G4/Dual G4 */
   {	"PowerMac3,3",		FTR_NEED_OPENPIC_TWEAK		}, /* G4/Dual G4 */
-  {	"PowerMac5,1",		0				}, /* Cube */
+  {	"PowerMac3,4",		0				}, /* QuickSilver G4 */
+  {	"PowerMac3,5",		0				}, /* QuickSilver G4 */
+  {	"PowerMac5,1",		FTR_CAN_NAP			}, /* Cube */
   {	"AAPL,3400/2400",	FTR_CAN_SLEEP			}, /* 2400/3400 PowerBook */
   {	"AAPL,3500",		FTR_CAN_SLEEP			}, /* 3500 PowerBook (G3) */
   {	"AAPL,PowerBook1998",	FTR_CAN_SLEEP			}, /* Wallstreet PowerBook */
   {	"PowerBook1,1",		FTR_CAN_SLEEP			}, /* 101 (Lombard) PowerBook */
+  {	"PowerBook4,1",		FTR_CAN_NAP|FTR_CAN_SLEEP|	   /* New polycarbonate iBook */
+  				0/*FTR_HAS_FW_POWER*/		}, 
   {	"PowerBook2,1",		FTR_CAN_SLEEP 			}, /* iBook */
-  {	"PowerBook4,1",		FTR_CAN_NAP|FTR_CAN_SLEEP	}, /* iBook Dual USB */
   {	"PowerBook2,2",		FTR_CAN_SLEEP /*| FTR_CAN_NAP*/	}, /* iBook FireWire */
   {	"PowerBook3,1",		FTR_CAN_SLEEP|FTR_CAN_NAP|	   /* PowerBook 2000 (Pismo) */
   				FTR_HAS_FW_POWER		}, 
-  {	"PowerBook3,2",		FTR_CAN_NAP|FTR_CAN_SLEEP	}, /* PowerBook Titanium */
+  {	"PowerBook3,2",		FTR_CAN_NAP|FTR_CAN_SLEEP|	   /* PowerBook Titanium */
+  				0/*FTR_HAS_FW_POWER*/		},
   {	NULL, 0 }
 };
 
@@ -305,15 +327,25 @@
 	struct device_node *np;
 	u32 *rev;
 	int i;
-
+	char* model;
+	
 	if (_machine != _MACH_Pmac)
 		return;
 
-	/* Figure out motherboard type & options */
-	for(i=0;board_features_datas[i].compatible;i++) {
-		if (machine_is_compatible(board_features_datas[i].compatible)) {
-			board_features = board_features_datas[i].features;
-			break;
+	np = find_path_device("/");
+	if (!np) {
+		printk(KERN_ERR "feature.c: Can't find device-tree root !\n");
+		return;
+	}
+	model = (char*)get_property(np, "model", NULL);
+	if (model) {
+		printk("PowerMac model: %s\n", model);
+		/* Figure out motherboard type & options */
+		for(i=0;board_features_datas[i].compatible;i++) {
+			if (!strcmp(board_features_datas[i].compatible, model)) {
+				board_features = board_features_datas[i].features;
+				break;
+			}
 		}
 	}
 
@@ -382,8 +414,9 @@
 		printk("Uninorth at 0x%08x\n", np->addrs[0].address);
 	}
 	if (uninorth_base && keylargo_base)
-		printk("Uni-N revision: %d, KeyLargo revision: %d\n",
-			uninorth_rev, keylargo_rev);
+		printk("Uni-N revision: %d, KeyLargo revision: %d %s\n",
+			uninorth_rev, keylargo_rev,
+			(keylargo_rev & KL_PANGEA_REV) ? "(Pangea chipset)" : "");
 
 	if (uninorth_base)
 		uninorth_init();
@@ -402,6 +435,25 @@
 		feature_clear(controllers[0].device, FEATURE_Sound_CLK_enable);
 	}
 #endif
+
+#ifdef CONFIG_PMAC_PBOOK
+	/* On PowerBooks, we disable the serial ports by default, they
+	 * will be re-enabled by the driver
+	 */
+#ifndef CONFIG_XMON
+	if (controller_count && find_devices("via-pmu") != NULL) {
+		feature_set_modem_power(NULL, 0);
+		feature_clear(controllers[0].device, FEATURE_Serial_IO_A);
+		feature_clear(controllers[0].device, FEATURE_Serial_IO_B);
+		feature_clear(controllers[0].device, FEATURE_Serial_enable);
+		if (controller_count > 1) {
+			feature_clear(controllers[1].device, FEATURE_Serial_IO_A);
+			feature_clear(controllers[1].device, FEATURE_Serial_IO_B);
+			feature_clear(controllers[1].device, FEATURE_Serial_enable);
+		}
+	}
+#endif
+#endif
 }
 
 static struct feature_controller __init *
@@ -588,12 +640,16 @@
 	/* TODO: Handle save/restore of PCI config space here
 	 */
 
-	spin_lock_irqsave(&keylargo->lock, flags);
+	/* XXX We use the keylargo spinlock, but we never
+	 * have uninorth without keylargo, so...
+	 */
+	KL_LOCK();
 	if (power)
 		UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC);
 	else
 		UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC);
-	spin_unlock_irqrestore(&keylargo->lock, flags);
+	(void)UN_IN(UNI_N_CLOCK_CNTL);
+	KL_UNLOCK();
 	udelay(20);
 }
 
@@ -605,17 +661,16 @@
 	if (!keylargo_base || !keylargo)
 		return;
 		
-	spin_lock_irqsave(&keylargo->lock, flags);
-	out_8((volatile u8 *)KL_FCR(KL_GPIO_ETH_PHY_RESET),
-		KEYLARGO_GPIO_OUTPUT_ENABLE);
-	(void)in_8((volatile u8 *)KL_FCR(KL_GPIO_ETH_PHY_RESET));
-	spin_unlock_irqrestore(&keylargo->lock, flags);
+	KL_LOCK();
+	KL_GPIO_OUT(KL_GPIO_ETH_PHY_RESET, KEYLARGO_GPIO_OUTPUT_ENABLE);
+	(void)KL_GPIO_IN(KL_GPIO_ETH_PHY_RESET);
+	KL_UNLOCK();
 	mdelay(10);
-	spin_lock_irqsave(&keylargo->lock, flags);
-	out_8((volatile u8 *)KL_FCR(KL_GPIO_ETH_PHY_RESET),
+	KL_LOCK();
+	KL_GPIO_OUT(KL_GPIO_ETH_PHY_RESET,
 		KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA);
-	(void)in_8((volatile u8 *)KL_FCR(KL_GPIO_ETH_PHY_RESET));
-	spin_unlock_irqrestore(&keylargo->lock, flags);
+	(void)KL_GPIO_IN(KL_GPIO_ETH_PHY_RESET);
+	KL_UNLOCK();
 	mdelay(10);
 }
 
@@ -642,17 +697,23 @@
 	else
 		return;
 
-	spin_lock_irqsave(&keylargo->lock, flags);
+	KL_LOCK();
 	if (power) {
 		/* Turn ON */
 			
 		if (number == 0) {
 			KL_BIC(KEYLARGO_FCR0, (KL0_USB0_PAD_SUSPEND0 | KL0_USB0_PAD_SUSPEND1));
+			(void)KL_IN(KEYLARGO_FCR0);
+			KL_UNLOCK();
 			mdelay(1);
+			KL_LOCK();
 			KL_BIS(KEYLARGO_FCR0, KL0_USB0_CELL_ENABLE);
 		} else {
 			KL_BIC(KEYLARGO_FCR0, (KL0_USB1_PAD_SUSPEND0 | KL0_USB1_PAD_SUSPEND1));
+			KL_UNLOCK();
+			(void)KL_IN(KEYLARGO_FCR0);
 			mdelay(1);
+			KL_LOCK();
 			KL_BIS(KEYLARGO_FCR0, KL0_USB1_CELL_ENABLE);
 		}
 		reg = KL_IN(KEYLARGO_FCR4);
@@ -689,7 +750,7 @@
 		}
 		udelay(1);
 	}
-	spin_unlock_irqrestore(&keylargo->lock, flags);
+	KL_UNLOCK();
 }
 
 void  __pmac
@@ -697,18 +758,25 @@
 {
 	unsigned long flags;
 
-	/* TODO: Handle save/restore of PCI config space here
+	/* TODO: should probably handle save/restore of PCI config space here
 	 */
 		
+	if (!uninorth_fw || (device && uninorth_fw != device))
+		return;
 	if (!uninorth_base)
 		return;
-	spin_lock_irqsave(&keylargo->lock, flags);
+
+	/* XXX We use the keylargo spinlock, but we never
+	 * have uninorth without keylargo, so...
+	 */
+	KL_LOCK();
 	if (power)
 		UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW);
 	else
 		UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW);
+	(void)UN_IN(UNI_N_CLOCK_CNTL);
+	KL_UNLOCK();
 	udelay(20);
-	spin_unlock_irqrestore(&keylargo->lock, flags);
 }
 
 /* Warning: will kill the PHY.. */
@@ -717,79 +785,159 @@
 {
 	unsigned long flags;
 	u8 gpioValue = power ? 0 : 4;
-	
+
+	if (!uninorth_fw || (device && uninorth_fw != device))
+		return;
 	if (!keylargo_base || !(board_features & FTR_HAS_FW_POWER))
 		return;
-	spin_lock_irqsave(&keylargo->lock, flags);
-	out_8((volatile u8 *)KL_FCR(KL_GPIO_FW_CABLE_POWER), gpioValue);
-	(void)in_8((volatile u8 *)KL_FCR(KL_GPIO_FW_CABLE_POWER));
-	spin_unlock_irqrestore(&keylargo->lock, flags);		
+	KL_LOCK();
+	KL_GPIO_OUT(KL_GPIO_FW_CABLE_POWER, gpioValue);
+	(void)KL_GPIO_IN(KL_GPIO_FW_CABLE_POWER);
+	KL_UNLOCK();		
+}
+
+void
+feature_set_modem_power(struct device_node* device, int power)
+{
+	unsigned long flags;
+
+	if (!device) {
+		device = find_devices("ch-a");
+		while(device && !device_is_compatible(device, "cobalt"))
+			device = device->next;
+		if (!device)
+			return;
+	}
+	if (keylargo && (keylargo_rev & KL_PANGEA_REV)) {
+		KL_LOCK();
+		if (power) {
+			/* Assert modem reset */
+			KL_GPIO_OUT(KL_GPIO_MODEM_RESET, KEYLARGO_GPIO_OUTPUT_ENABLE);
+			(void)KL_GPIO_IN(KL_GPIO_MODEM_RESET);
+			udelay(10);
+			/* Power up modem */
+			KL_GPIO_OUT(KL_GPIO_MODEM_POWER, KEYLARGO_GPIO_OUTPUT_ENABLE);
+			(void)KL_GPIO_IN(KL_GPIO_MODEM_POWER);
+			udelay(10);
+			/* Release modem reset */
+			KL_GPIO_OUT(KL_GPIO_MODEM_RESET,
+				KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA);
+			(void)KL_GPIO_IN(KL_GPIO_MODEM_RESET);
+		} else {
+			/* Power down modem */
+			KL_GPIO_OUT(KL_GPIO_MODEM_POWER,
+				KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA);
+			(void)KL_GPIO_IN(KL_GPIO_MODEM_POWER);
+		}
+		KL_UNLOCK();
+	} else {
+		if (power) {
+			mdelay(300);
+			feature_set(device, FEATURE_Modem_power);
+	   		mdelay(5);
+			feature_clear(device, FEATURE_Modem_power);
+	   		mdelay(10);
+			feature_set(device, FEATURE_Modem_power);
+		} else {
+			feature_clear(device, FEATURE_Modem_power);
+			mdelay(10);
+		}
+	}
 }
 
 #ifdef CONFIG_SMP
 void __pmac
 feature_core99_kick_cpu(int cpu_nr)
 {
-#if 1 /* New way */
 	const int reset_lines[] = {	KL_GPIO_RESET_CPU0,
 					KL_GPIO_RESET_CPU1,
 					KL_GPIO_RESET_CPU2,
 					KL_GPIO_RESET_CPU3 };
-	volatile u8* reset_io;
-
+	int reset_io;
+	unsigned long flags;
+	
 	if (!keylargo_base || cpu_nr > 3)
 		return;
-	reset_io = (volatile u8*)KL_FCR(reset_lines[cpu_nr]);
-	out_8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE);
-	udelay(1);
-	out_8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA);
-#else
-	out_8((volatile u8 *)KL_FCR(KL_GPIO_EXTINT_CPU1), KL_GPIO_EXTINT_CPU1_ASSERT);
+	reset_io = reset_lines[cpu_nr];
+	
+	KL_LOCK();
+	KL_GPIO_OUT(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE);
+	(void)KL_GPIO_IN(reset_io);
 	udelay(1);
-	out_8((volatile u8 *)KL_FCR(KL_GPIO_EXTINT_CPU1), KL_GPIO_EXTINT_CPU1_RELEASE);
-#endif	
+	KL_GPIO_OUT(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA);
+	(void)KL_GPIO_IN(reset_io);
+	KL_UNLOCK();
 }
 #endif /* CONFIG_SMP */
 
 void __pmac
 feature_set_airport_power(struct device_node* device, int power)
 {
+	unsigned long flags;
+	
 	if (!keylargo_base || !airport_dev || airport_dev != device)
 		return;
 	if (airport_pwr_state == power)
-		return;
+		return;	
 	if (power) {
-		/* Some if this is from Darwin code, some is from tracing of
-		 * MacOS driver with Macsbug. Some real bit definitions would
-		 * really help here...
+		/* This code is a reproduction of OF enable-cardslot
+		 * and init-wireless methods, slightly hacked until
+		 * I got it working.
 		 */
-		out_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_0), airport_pwr_regs[0]);
-		out_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_1), airport_pwr_regs[1]);
-		out_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_2), airport_pwr_regs[2]);
-		out_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_3), airport_pwr_regs[3]);
-		out_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_4), airport_pwr_regs[4]);
-		udelay(20);
-		out_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_4), 5);
-		udelay(20);
-		out_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_4), 4);
-		mdelay(20);
+		KL_LOCK();
+		KL_GPIO_OUT(KEYLARGO_GPIO_0+0xf, 5);
+		(void)KL_GPIO_IN(KEYLARGO_GPIO_0+0xf);
+		KL_UNLOCK();
+		mdelay(10);
+		KL_LOCK();
+		KL_GPIO_OUT(KEYLARGO_GPIO_0+0xf, 4);
+		(void)KL_GPIO_IN(KEYLARGO_GPIO_0+0xf);
+		KL_UNLOCK();
+
+		mdelay(10);
+
+		KL_LOCK();
 		KL_BIC(KEYLARGO_FCR2, KL2_AIRPORT_RESET_N);
+		(void)KL_IN(KEYLARGO_FCR2);
+		udelay(10);
+		KL_GPIO_OUT(KEYLARGO_GPIO_EXTINT_0+0xb, 0);
+		(void)KL_GPIO_IN(KEYLARGO_GPIO_EXTINT_0+0xb);
+		udelay(10);
+		KL_GPIO_OUT(KEYLARGO_GPIO_EXTINT_0+0xa, 0x28);
+		(void)KL_GPIO_IN(KEYLARGO_GPIO_EXTINT_0+0xa);
+		udelay(10);
+		KL_GPIO_OUT(KEYLARGO_GPIO_EXTINT_0+0xd, 0x28);
+		(void)KL_GPIO_IN(KEYLARGO_GPIO_EXTINT_0+0xd);
+		udelay(10);
+		KL_GPIO_OUT(KEYLARGO_GPIO_0+0xd, 0x28);
+		(void)KL_GPIO_IN(KEYLARGO_GPIO_0+0xd);
+		udelay(10);
+		KL_GPIO_OUT(KEYLARGO_GPIO_0+0xe, 0x28);
+		(void)KL_GPIO_IN(KEYLARGO_GPIO_0+0xe);
+		KL_UNLOCK();
 		udelay(10);
+		KL_OUT(0x1c000, 0);
+		
+		mdelay(1);
 		out_8((volatile u8*)KL_FCR(0x1a3e0), 0x41);
+		(void)in_8((volatile u8*)KL_FCR(0x1a3e0));
 		udelay(10);
+		KL_LOCK();
 		KL_BIS(KEYLARGO_FCR2, KL2_AIRPORT_RESET_N);
-		udelay(10);
+		(void)KL_IN(KEYLARGO_FCR2);
+		KL_UNLOCK();
+		mdelay(100);
 	} else {
-		airport_pwr_regs[0] = in_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_0));
-		airport_pwr_regs[1] = in_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_1));
-		airport_pwr_regs[2] = in_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_2));
-		airport_pwr_regs[3] = in_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_3));
-		airport_pwr_regs[4] = in_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_4));
-		out_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_0), 0);
-		out_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_1), 0);
-		out_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_2), 0);
-		out_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_3), 0);
-		out_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_4), 0);
+		KL_LOCK();
+		KL_BIC(KEYLARGO_FCR2, KL2_AIRPORT_RESET_N);
+		(void)KL_IN(KEYLARGO_FCR2);
+		KL_GPIO_OUT(KL_GPIO_AIRPORT_0, 0);
+		KL_GPIO_OUT(KL_GPIO_AIRPORT_1, 0);
+		KL_GPIO_OUT(KL_GPIO_AIRPORT_2, 0);
+		KL_GPIO_OUT(KL_GPIO_AIRPORT_3, 0);
+		KL_GPIO_OUT(KL_GPIO_AIRPORT_4, 0);
+		(void)KL_GPIO_IN(KL_GPIO_AIRPORT_4);
+		KL_UNLOCK();
 	}
 	airport_pwr_state = power;	
 }
@@ -826,8 +974,11 @@
 	/* Enable FW before PCI probe. Will be disabled later on
 	 */
 	fw = find_devices("firewire");
-	if (fw && device_is_compatible(fw, "pci106b,18"))
+	if (fw && (device_is_compatible(fw, "pci106b,18") || 
+			device_is_compatible(fw, "pci106b,30"))) {
+		uninorth_fw = fw;
 		feature_set_firewire_power(fw, 1);
+	}
 }
 
 /* Initialize the Core99 KeyLargo ASIC. 
@@ -864,7 +1015,7 @@
 		device_is_compatible(ctrler->device, "gatwick"))
 		ctrler = &controllers[1];
 
-	if (ctrler->bits == feature_bits_heathrow ||
+	if (ctrler->bits == feature_bits_wallstreet ||
 		ctrler->bits == feature_bits_paddington) {
 		heathrow_prepare_for_sleep(ctrler);
 		return;
@@ -884,7 +1035,7 @@
 		device_is_compatible(ctrler->device, "gatwick"))
 		ctrler = &controllers[1];
 	
-	if (ctrler->bits == feature_bits_heathrow ||
+	if (ctrler->bits == feature_bits_wallstreet ||
 		ctrler->bits == feature_bits_paddington) {
 		heathrow_wakeup(ctrler);
 		return;
@@ -929,15 +1080,10 @@
 {
 	u32 temp;
 
-	/* For now, suspending the USB ref cause the machine to die on
-	 * wakeup -- BenH
-	 */
-#if 0
 	mdelay(1);
 	KL_BIS(KEYLARGO_FCR0, KL0_USB_REF_SUSPEND);
 	(void)KL_IN(KEYLARGO_FCR0);
-	mdelay(1500);
-#endif
+	mdelay(100);
 
 	KL_BIC(KEYLARGO_FCR0,	KL0_SCCA_ENABLE | KL0_SCCB_ENABLE |
 				KL0_SCC_CELL_ENABLE |
@@ -1014,7 +1160,7 @@
 core99_prepare_for_sleep(struct feature_controller* ctrler)
 {
 	int i;
-	u8* base8;
+	volatile u8* base8;
 	
 	/*
 	 * Save various bits of KeyLargo
@@ -1026,15 +1172,19 @@
 	feature_set_airport_power(airport_dev, 0);
 
 	/* We power off the FW cable. Should be done by the driver... */
+	feature_set_firewire_power(NULL, 0);
 	feature_set_firewire_cable_power(NULL, 0);
+
+	/* We make sure int. modem is off (in case driver lost it) */
+	feature_set_modem_power(NULL, 0);
 	 
 	/* Save the state of the various GPIOs */
 	save_gpio_levels[0] = KL_IN(KEYLARGO_GPIO_LEVELS0);
 	save_gpio_levels[1] = KL_IN(KEYLARGO_GPIO_LEVELS1);
-	base8 = (u8 *)KL_FCR(KEYLARGO_GPIO_EXTINT_0);
+	base8 = ((volatile u8 *)keylargo_base) + KEYLARGO_GPIO_EXTINT_0;
 	for (i=0; i<KEYLARGO_GPIO_EXTINT_CNT; i++)
 		save_gpio_extint[i] = in_8(base8+i);
-	base8 = (u8 *)KL_FCR(KEYLARGO_GPIO_0);
+	base8 = ((volatile u8 *)keylargo_base) + KEYLARGO_GPIO_0;
 	for (i=0; i<KEYLARGO_GPIO_CNT; i++)
 		save_gpio_normal[i] = in_8(base8+i);
 
@@ -1089,7 +1239,7 @@
 core99_wake_up(struct feature_controller* ctrler)
 {
 	int i;
-	u8* base8;
+	volatile u8* base8;
 
 	/*
 	 * Wakeup the host bridge
@@ -1131,10 +1281,10 @@
 
 	KL_OUT(KEYLARGO_GPIO_LEVELS0, save_gpio_levels[0]);
 	KL_OUT(KEYLARGO_GPIO_LEVELS1, save_gpio_levels[1]);
-	base8 = (u8 *)KL_FCR(KEYLARGO_GPIO_EXTINT_0);
+	base8 = ((volatile u8 *)keylargo_base) + KEYLARGO_GPIO_EXTINT_0;
 	for (i=0; i<KEYLARGO_GPIO_EXTINT_CNT; i++)
 		out_8(base8+i, save_gpio_extint[i]);
-	base8 = (u8 *)KL_FCR(KEYLARGO_GPIO_0);
+	base8 = ((volatile u8 *)keylargo_base) + KEYLARGO_GPIO_0;
 	for (i=0; i<KEYLARGO_GPIO_CNT; i++)
 		out_8(base8+i, save_gpio_normal[i]);
 
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/gemini_setup.c linux/arch/ppc/kernel/gemini_setup.c
--- v2.4.9/linux/arch/ppc/kernel/gemini_setup.c	Mon May 21 17:04:47 2001
+++ linux/arch/ppc/kernel/gemini_setup.c	Tue Aug 28 06:58:33 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.gemini_setup.c 1.7 05/17/01 18:14:21 cort
+ * BK Id: SCCS/s.gemini_setup.c 1.11 08/20/01 14:34:41 paulus
  */
 /*
  *  linux/arch/ppc/kernel/setup.c
@@ -54,17 +54,6 @@
 	0, 0, 14, 0, 0, 13, 5, 9, 6, 11, 8, 10, 0, 12, 7, 0
 };
 
-int chrp_get_irq(struct pt_regs *);
-void chrp_post_irq(struct pt_regs* regs, int);
-
-static inline unsigned long _get_HID1(void)
-{
-	unsigned long val;
-
-	__asm__ __volatile__("mfspr %0,1009" : "=r" (val));
-	return val;
-}
-
 /*
  * prom_init is the Gemini version of prom.c:prom_init.  We only need
  * the BSS clearing code, so I copied that out of prom.c.  This is a
@@ -208,10 +197,11 @@
 int
 gemini_get_clock_speed(void)
 {
-	unsigned long hid1, pvr = _get_PVR();
+	unsigned long hid1, pvr;
 	int clock;
 
-	hid1 = (_get_HID1() >> 28) & 0xf;
+	pvr = mfspr(PVR);
+	hid1 = (mfspr(HID1) >> 28) & 0xf;
 	if (PVR_VER(pvr) == 8 ||
 	    PVR_VER(pvr) == 12)
 		hid1 = cpu_7xx[hid1];
@@ -241,11 +231,12 @@
 {
         unsigned char reg, brev, fam, creg;
         unsigned long cache;
-        unsigned long pvr = _get_PVR();
+        unsigned long pvr;
 
         reg = readb(GEMINI_L2CFG);
         brev = readb(GEMINI_BREV);
         fam = readb(GEMINI_FEAT);
+        pvr = mfspr(PVR);
 
         switch(PVR_VER(pvr)) {
 
@@ -486,11 +477,60 @@
 	return total;
 }
 
-void __init gemini_init(unsigned long r3, unsigned long r4, unsigned long r5,
-			unsigned long r6, unsigned long r7)
+static void __init
+gemini_map_io(void)
+{
+	io_block_mapping(0xf0000000, 0xf0000000, 0x10000000, _PAGE_IO);
+	io_block_mapping(0x80000000, 0x80000000, 0x10000000, _PAGE_IO);
+}
+
+#ifdef CONFIG_SMP
+static int
+smp_gemini_probe(void)
+{
+	int i, nr;
+
+        nr = (readb(GEMINI_CPUSTAT) & GEMINI_CPU_COUNT_MASK) >> 2;
+	if (nr == 0)
+		nr = 4;
+
+	if (nr > 1) {
+		openpic_request_IPIs();
+		for (i = 1; i < nr; ++i)
+			smp_hw_index[i] = i;
+	}
+
+	return nr;
+}
+
+static void
+smp_gemini_kick_cpu(int nr)
+{
+	openpic_init_processor( 1<<nr );
+	openpic_init_processor( 0 );
+}
+
+static void
+smp_gemini_setup_cpu(int cpu_nr)
+{
+	if (OpenPIC_Addr)
+		do_openpic_setup_cpu();
+	if (cpu_nr > 0)
+		gemini_init_l2();
+}
+
+static struct smp_ops_t gemini_smp_ops = {
+	smp_openpic_message_pass,
+	smp_gemini_probe,
+	smp_gemini_kick_cpu,
+	smp_gemini_setup_cpu,
+};
+#endif /* CONFIG_SMP */
+
+void __init platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
+			  unsigned long r6, unsigned long r7)
 {
 	int i;
-	int chrp_get_irq( struct pt_regs * );
 
 	for(i = 0; i < GEMINI_LEDS; i++)
 		gemini_led_off(i);
@@ -525,6 +565,7 @@
 	ppc_md.calibrate_decr = gemini_calibrate_decr;
 
 	ppc_md.find_end_of_memory = gemini_find_end_of_memory;
+	ppc_md.setup_io_mappings = gemini_map_io;
 
 	/* no keyboard/mouse/video stuff yet.. */
 	ppc_md.kbd_setkeycode = NULL;
@@ -537,4 +578,8 @@
 	ppc_md.ppc_kbd_sysrq_xlate = NULL;
 #endif
 	ppc_md.pcibios_fixup_bus = gemini_pcibios_fixup;
+
+#ifdef CONFIG_SMP
+	ppc_md.smp_ops = &gemini_smp_ops;
+#endif /* CONFIG_SMP */
 }
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/head.S linux/arch/ppc/kernel/head.S
--- v2.4.9/linux/arch/ppc/kernel/head.S	Wed Jul 25 17:10:18 2001
+++ linux/arch/ppc/kernel/head.S	Tue Aug 28 06:58:33 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.head.S 1.25 07/07/01 17:08:44 paulus
+ * BK Id: SCCS/s.head.S 1.29 08/19/01 22:43:23 paulus
  */
 /*
  *  PowerPC version 
@@ -31,6 +31,7 @@
 #include <asm/page.h>
 #include <asm/mmu.h>
 #include <asm/pgtable.h>
+#include <asm/cputable.h>
 
 #ifdef CONFIG_APUS
 #include <asm/amigappc.h>
@@ -153,7 +154,7 @@
 
 #ifndef CONFIG_GEMINI
 /* Switch MMU off, clear BATs and flush TLB. At this point, r3 contains
- * the physical address we are running at, returned by prom_init()
+ * the physical address we are running at, returned by early_init()
  */
  	bl	mmu_off
 __after_mmu_off:
@@ -761,12 +762,10 @@
 	addi	r24,r1,STACK_FRAME_OVERHEAD
 	stw	r24,PT_REGS(r23)
 #ifdef CONFIG_ALTIVEC
-	mfpvr	r24			/* check if we are on a G4 */
-	srwi	r24,r24,16
-	cmpwi	r24,PVR_7400@h
-	bne	2f
-	mfspr	r22,SPRN_VRSAVE		/* if so, save vrsave register value */
+BEGIN_FTR_SECTION
+	mfspr	r22,SPRN_VRSAVE		/* if G4, save vrsave register value */
 	stw	r22,THREAD_VRSAVE(r23)
+END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
 #endif /* CONFIG_ALTIVEC */
 2:	addi	r2,r23,-THREAD		/* set r2 to current */
 	tovirt(r2,r2)
@@ -1280,10 +1279,13 @@
 	SYNC
 	MTMSRD(r0)
 	isync
-#else
-	bl	enable_caches
 #endif
 
+	lis	r3,-KERNELBASE@h
+	mr	r4,r24
+	bl	identify_cpu
+	bl	call_setup_cpu		/* Call setup_cpu for this CPU */
+
 	/* get current */
 	lis	r2,current_set@h
 	ori	r2,r2,current_set@l
@@ -1322,54 +1324,87 @@
 /*
  * Enable caches and 604-specific features if necessary.
  */
-enable_caches:
-	mfspr	r9,PVR
-	rlwinm	r9,r9,16,16,31
-	cmpi	0,r9,1
-	beq	6f			/* not needed for 601 */
+_GLOBAL(__setup_cpu_601)
+	blr
+_GLOBAL(__setup_cpu_603)
+	b	setup_common_caches
+_GLOBAL(__setup_cpu_604)
+	mflr	r4
+	bl	setup_common_caches
+	bl	setup_604_hid0
+	mtlr	r4
+	blr
+_GLOBAL(__setup_cpu_750)
+	mflr	r4
+	bl	setup_common_caches
+	bl	setup_750_7400_hid0
+	mtlr	r4
+	blr
+_GLOBAL(__setup_cpu_7400)
+	mflr	r4
+	bl	setup_common_caches
+	bl	setup_750_7400_hid0
+	mtlr	r4
+	blr
+_GLOBAL(__setup_cpu_7450)
+	blr
+_GLOBAL(__setup_cpu_power3)
+	blr
+_GLOBAL(__setup_cpu_power4)
+	blr
+_GLOBAL(__setup_cpu_generic)
+	blr
+
+/* Enable caches for 603's, 604, 750 & 7400 */
+setup_common_caches:
 	mfspr	r11,HID0
 	andi.	r0,r11,HID0_DCE
 	ori	r11,r11,HID0_ICE|HID0_DCE
 	ori	r8,r11,HID0_ICFI
-	bne	3f			/* don't invalidate the D-cache */
+	bne	1f			/* don't invalidate the D-cache */
 	ori	r8,r8,HID0_DCI		/* unless it wasn't enabled */
-3:
-	sync
+1:	sync
 	mtspr	HID0,r8			/* enable and invalidate caches */
 	sync
 	mtspr	HID0,r11		/* enable caches */
 	sync
 	isync
-	cmpi	0,r9,4			/* check for 604 */
-	cmpi	1,r9,9			/* or 604e */
-	cmpi	2,r9,10			/* or mach5 / 604r */
-	cmpi	3,r9,8			/* check for 750 (G3) */
-	cmpi	4,r9,12			/* or 7400 (G4) */
-	cror	2,2,6
-	cror	2,2,10
-	bne	4f
-	ori	r11,r11,HID0_SIED|HID0_BHTE /* for 604[e|r], enable */
-	bne	2,5f
-	ori	r11,r11,HID0_BTCD	/* superscalar exec & br history tbl */
-	b	5f
-4:
-	cror	14,14,18
-	bne	3,6f
-	/* for G3/G4:
-	 * enable Store Gathering (SGE), Address Brodcast (ABE),
-	 * Branch History Table (BHTE), Branch Target ICache (BTIC)
-	 */
+	blr
+
+/* 604, 604e, 604ev, ...
+ * Enable superscalar execution & branch history table
+ */
+setup_604_hid0:
+	mfspr	r11,HID0
+	ori	r11,r11,HID0_SIED|HID0_BHTE
+	ori	r8,r11,HID0_BTCD
+	sync
+	mtspr	HID0,r8		/* flush branch target address cache */
+	sync			/* on 604e/604r */
+	mtspr	HID0,r11
+	sync
+	isync
+	blr
+
+/* 740/750/7400/7410
+ * Enable Store Gathering (SGE), Address Brodcast (ABE),
+ * Branch History Table (BHTE), Branch Target ICache (BTIC)
+ * Dynamic Power Management (DPM), Speculative (SPD)
+ * Clear Instruction cache throttling (ICTC)
+ */
+setup_750_7400_hid0:
+	mfspr	r11,HID0
 	ori	r11,r11,HID0_SGE | HID0_ABE | HID0_BHTE | HID0_BTIC
 	oris	r11,r11,HID0_DPM@h	/* enable dynamic power mgmt */
 	li	r3,HID0_SPD
 	andc	r11,r11,r3		/* clear SPD: enable speculative */
  	li	r3,0
  	mtspr	ICTC,r3			/* Instruction Cache Throttling off */
-5:	isync
+	isync
 	mtspr	HID0,r11
 	sync
 	isync
-6:	blr
+	blr
 
 /*
  * Load stuff into the MMU.  Intended to be called with
@@ -1414,9 +1449,10 @@
  * This is where the main kernel code starts.
  */
 start_here:
-#ifndef CONFIG_PPC64BRIDGE
-	bl	enable_caches
-#endif
+	/* Call setup_cpu for CPU 0 */
+	li	r3,0		/* data offset */
+	li	r24,0		/* cpu# */
+	bl	call_setup_cpu
 
 	/* ptr to current */
 	lis	r2,init_task_union@h
@@ -1435,14 +1471,15 @@
 	li	r0,0
 	stwu	r0,-STACK_FRAME_OVERHEAD(r1)
 /*
- * Decide what sort of machine this is and initialize the MMU.
+ * Do early bootinfo parsing, platform-specific initialization,
+ * and set up the MMU.
  */
 	mr	r3,r31
 	mr	r4,r30
 	mr	r5,r29
 	mr	r6,r28
 	mr	r7,r27
-	bl	identify_machine
+	bl	machine_init
 	bl	MMU_init
 
 #ifdef CONFIG_APUS
@@ -1475,12 +1512,10 @@
 /* Load up the kernel context */
 2:
 	sync			/* Force all PTE updates to finish */
+	ISYNC_601
 	tlbia			/* Clear all TLB entries */
 	sync			/* wait for tlbia/tlbie to finish */
-#ifdef CONFIG_SMP
-	tlbsync			/* ... on all CPUs */
-	sync
-#endif
+	TLBSYNC			/* ... on all CPUs */
 
 	bl	load_up_mmu
 /* Now turn on the MMU for real! */
@@ -1500,7 +1535,7 @@
 	mulli	r3,r3,897	/* multiply context by skew factor */
 	rlwinm	r3,r3,4,8,27	/* VSID = (context & 0xfffff) << 4 */
 	addis	r3,r3,0x6000	/* Set Ks, Ku bits */
-	li	r0,12		/* TASK_SIZE / SEGMENT_SIZE */
+	li	r0,NUM_USER_SEGMENTS
 	mtctr	r0
 	li	r4,0
 3:
@@ -1512,7 +1547,8 @@
 	rlwinm	r3,r3,0,8,3	/* clear out any overflow from VSID field */
 	addis	r4,r4,0x1000	/* address of next segment */
 	bdnz	3b
-	SYNC
+	SYNC_601
+	isync
 	blr
 
 /* 
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/head_8xx.S linux/arch/ppc/kernel/head_8xx.S
--- v2.4.9/linux/arch/ppc/kernel/head_8xx.S	Tue Jul  3 17:08:18 2001
+++ linux/arch/ppc/kernel/head_8xx.S	Wed Aug 29 20:49:36 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.head_8xx.S 1.14 06/28/01 15:50:16 paulus
+ * BK Id: SCCS/s.head_8xx.S 1.21 08/28/01 16:27:27 trini
  */
 /*
  *  arch/ppc/kernel/except_8xx.S
@@ -31,6 +31,7 @@
 #include <asm/mmu.h>
 #include <asm/cache.h>
 #include <asm/pgtable.h>
+#include <asm/cputable.h>
 
 	.text
 	.globl	_stext
@@ -87,70 +88,10 @@
 	mr	r27,r7
 	li	r24,0			/* cpu # */
 
-	tlbia			/* Invalidate all TLB entries */
-	li	r8, 0
-	mtspr	MI_CTR, r8	/* Set instruction control to zero */
-	lis	r8, MD_RESETVAL@h
-#ifndef CONFIG_8xx_COPYBACK
-	oris	r8, r8, MD_WTDEF@h
-#endif
-	mtspr	MD_CTR, r8	/* Set data TLB control */
-
-	/* Now map the lower 8 Meg into the TLBs.  For this quick hack,
-	 * we can load the instruction and data TLB registers with the
-	 * same values.
-	 */
-	lis	r8, KERNELBASE@h	/* Create vaddr for TLB */
-	ori	r8, r8, MI_EVALID	/* Mark it valid */
-	mtspr	MI_EPN, r8
-	mtspr	MD_EPN, r8
-	li	r8, MI_PS8MEG		/* Set 8M byte page */
-	ori	r8, r8, MI_SVALID	/* Make it valid */
-	mtspr	MI_TWC, r8
-	mtspr	MD_TWC, r8
-	li	r8, MI_BOOTINIT		/* Create RPN for address 0 */
-	mtspr	MI_RPN, r8		/* Store TLB entry */
-	mtspr	MD_RPN, r8
-	lis	r8, MI_Kp@h		/* Set the protection mode */
-	mtspr	MI_AP, r8
-	mtspr	MD_AP, r8
-
-	/* Map another 8 MByte at the IMMR to get the processor
-	 * internal registers (among other things).
+	/* We have to turn on the MMU right away so we get cache modes
+	 * set correctly.
 	 */
-	mfspr	r9, 638			/* Get current IMMR */
-	andis.	r9, r9, 0xff80		/* Get 8Mbyte boundary */
-
-	mr	r8, r9			/* Create vaddr for TLB */
-	ori	r8, r8, MD_EVALID	/* Mark it valid */
-	mtspr	MD_EPN, r8
-	li	r8, MD_PS8MEG		/* Set 8M byte page */
-	ori	r8, r8, MD_SVALID	/* Make it valid */
-	mtspr	MD_TWC, r8
-	mr	r8, r9			/* Create paddr for TLB */
-	ori	r8, r8, MI_BOOTINIT|0x2 /* Inhibit cache -- Cort */
-	mtspr	MD_RPN, r8
-
-	/* Since the cache is enabled according to the information we
-	 * just loaded into the TLB, invalidate and enable the caches here.
-	 * We should probably check/set other modes....later.
-	 */
-	lis	r8, IDC_INVALL@h
-	mtspr	IC_CST, r8
-	mtspr	DC_CST, r8
-	lis	r8, IDC_ENABLE@h
-	mtspr	IC_CST, r8
-#ifdef CONFIG_8xx_COPYBACK
-	mtspr	DC_CST, r8
-#else
-	/* For a debug option, I left this here to easily enable
-	 * the write through cache mode
-	 */
-	lis	r8, DC_SFWT@h
-	mtspr	DC_CST, r8
-	lis	r8, IDC_ENABLE@h
-	mtspr	DC_CST, r8
-#endif
+	bl	initial_mmu
 
 /* We now have the lower 8 Meg mapped into TLB entries, and the caches
  * ready to work.
@@ -513,6 +454,7 @@
 #else
 	li	r21, 0x00f0
 	rlwimi	r20, r21, 0, 24, 28
+
 #endif
 #ifdef CONFIG_8xx_CPU6
 	li	r3, 0x3d80
@@ -721,131 +663,34 @@
 giveup_fpu:
 	blr
 
-/*
- * This code is jumped to from the startup code to copy
- * the kernel image to physical address 0.
- */
-relocate_kernel:
-	lis	r9,0x426f		/* if booted from BootX, don't */
-	addi	r9,r9,0x6f58		/* translate source addr */
-	cmpw	r31,r9			/* (we have to on chrp) */
-	beq	7f
-	rlwinm	r4,r4,0,8,31		/* translate source address */
-	add	r4,r4,r3		/* to region mapped with BATs */
-7:	addis	r9,r26,klimit@ha	/* fetch klimit */
-	lwz	r25,klimit@l(r9)
-	addis	r25,r25,-KERNELBASE@h
-	li	r6,0			/* Destination offset */
-	li	r5,0x4000		/* # bytes of memory to copy */
-	bl	copy_and_flush		/* copy the first 0x4000 bytes */
-	addi	r0,r3,4f@l		/* jump to the address of 4f */
-	mtctr	r0			/* in copy and do the rest. */
-	bctr				/* jump to the copy */
-4:	mr	r5,r25
-	bl	copy_and_flush		/* copy the rest */
-	b	turn_on_mmu
-
-/*
- * Copy routine used to copy the kernel to start at physical address 0
- * and flush and invalidate the caches as needed.
- * r3 = dest addr, r4 = source addr, r5 = copy limit, r6 = start offset
- * on exit, r3, r4, r5 are unchanged, r6 is updated to be >= r5.
- */
-copy_and_flush:
-	addi	r5,r5,-4
-	addi	r6,r6,-4
-4:	li	r0,CACHE_LINE_SIZE/4
-	mtctr	r0
-3:	addi	r6,r6,4			/* copy a cache line */
-	lwzx	r0,r6,r4
-	stwx	r0,r6,r3
-	bdnz	3b
-	dcbst	r6,r3			/* write it to memory */
-	sync
-	icbi	r6,r3			/* flush the icache line */
-	cmplw	0,r6,r5
-	blt	4b
-	isync
-	addi	r5,r5,4
-	addi	r6,r6,4
+/* Maybe someday.......
+*/
+_GLOBAL(__setup_cpu_8xx)
 	blr
 
-#ifdef CONFIG_SMP
-	.globl	__secondary_start_psurge
-__secondary_start_psurge:
-	li	r24,1			/* cpu # */
-	b	__secondary_start
-
-	.globl	__secondary_hold
-__secondary_hold:
-	/* tell the master we're here */
-	lis	r5,0x4@h
-	ori	r5,r5,0x4@l
-	stw	r3,0(r5)
-	dcbf	0,r5
-100:
-	lis	r5,0
-	dcbi	0,r5
-	lwz	r4,0(r5)
-	/* wait until we're told to start */
-	cmp	0,r4,r3
-	bne	100b
-	/* our cpu # was at addr 0 - go */
-	lis	r5,__secondary_start@h
-	ori	r5,r5,__secondary_start@l
-	tophys(r5,r5)
-	mtlr	r5
-	mr	r24,r3			/* cpu # */
-	blr
-#endif /* CONFIG_SMP */
-	
 /*
  * This is where the main kernel code starts.
  */
 start_here:
-#ifdef CONFIG_SMP
-	/* if we're the second cpu stack and r2 are different
-	* and we want to not clear the bss -- Cort */
-	lis	r5,first_cpu_booted@h
-	ori	r5,r5,first_cpu_booted@l
-	lwz	r5,0(r5)
-	cmpi	0,r5,0
-	beq	99f
-
-	/* get current */
-	lis	r2,current_set@h
-	ori	r2,r2,current_set@l
-	slwi	r24,r24,2			/* cpu # to current_set[cpu#] */
-	add	r2,r2,r24
-	lwz	r2,0(r2)
-	b	10f
-99:	
-#endif /* CONFIG_SMP */
+
 	/* ptr to current */
 	lis	r2,init_task_union@h
 	ori	r2,r2,init_task_union@l
-	/* Clear out the BSS */
-	lis	r11,_end@ha
-	addi	r11,r11,_end@l
-	lis	r8,__bss_start@ha
-	addi	r8,r8,__bss_start@l
-	subf	r11,r8,r11
-	addi	r11,r11,3
-	rlwinm.	r11,r11,30,2,31
-	beq	2f
-	addi	r8,r8,-4
-	mtctr	r11
-	li	r0,0
-3:	stwu	r0,4(r8)
-	bdnz	3b
-2:
-#ifdef CONFIG_SMP	
-10:
-#endif /* CONFIG_SMP */
+
+	/* ptr to phys current thread */
+	tophys(r4,r2)
+	addi	r4,r4,THREAD	/* init task's THREAD */
+	mtspr	SPRG3,r4
+	li	r3,0
+	mtspr	SPRG2,r3	/* 0 => r1 has kernel sp */
+
 	/* stack */
 	addi	r1,r2,TASK_UNION_SIZE
 	li	r0,0
 	stwu	r0,-STACK_FRAME_OVERHEAD(r1)
+
+	bl	early_init	/* We have to do this with MMU on */
+
 /*
  * Decide what sort of machine this is and initialize the MMU.
  */
@@ -854,12 +699,11 @@
 	mr	r5,r29
 	mr	r6,r28
 	mr	r7,r27
-	bl	identify_machine
+	bl	machine_init
 	bl	MMU_init
 
 /*
  * Go back to running unmapped so we can load up new values
- * for SDR1 (hash table pointer) and the segment registers
  * and change to using our exception vectors.
  * On the 8xx, all we have to do is invalidate the TLB to clear
  * the old 8M byte TLB mappings and load the page table base register.
@@ -869,8 +713,8 @@
 	 * easier......until someone changes init's static structures.
 	 */
 	lis	r6, swapper_pg_dir@h
-	tophys(r6,r6)
 	ori	r6, r6, swapper_pg_dir@l
+	tophys(r6,r6)
 #ifdef CONFIG_8xx_CPU6
 	lis	r4, cpu6_errata_word@h
 	ori	r4, r4, cpu6_errata_word@l
@@ -891,65 +735,117 @@
 	SYNC			/* Force all PTE updates to finish */
 	tlbia			/* Clear all TLB entries */
 	sync			/* wait for tlbia/tlbie to finish */
-#ifdef CONFIG_SMP
-	tlbsync			/* ... on all CPUs */
-	sync
-#endif
-/* Set up for using our exception vectors */
-	/* ptr to phys current thread */
-	tophys(r4,r2)
-	addi	r4,r4,THREAD	/* init task's THREAD */
-	mtspr	SPRG3,r4
-	li	r3,0
-	mtspr	SPRG2,r3	/* 0 => r1 has kernel sp */
+	TLBSYNC			/* ... on all CPUs */
+
+	/* set up the PTE pointers for the Abatron bdiGDB.
+	*/
+	tovirt(r6,r6)
+	lis	r5, abatron_pteptrs@h
+	ori	r5, r5, abatron_pteptrs@l
+	stw	r5, 0xf0(r0)	/* Must match your Abatron config file */
+	tophys(r5,r5)
+	stw	r6, 0(r5)
+
 /* Now turn on the MMU for real! */
 	li	r4,MSR_KERNEL
 	lis	r3,start_kernel@h
 	ori	r3,r3,start_kernel@l
-#ifdef CONFIG_SMP
-	/* the second time through here we go to
-	 * start_secondary(). -- Cort
-	 */
-	lis	r5,first_cpu_booted@h
-	ori	r5,r5,first_cpu_booted@l
-	tophys(r5,r5)
-	lwz	r5,0(r5)
-	cmpi	0,r5,0
-	beq	10f
-	lis	r3,start_secondary@h
-	ori	r3,r3,start_secondary@l
-10:	
-#endif /* CONFIG_SMP */
 	mtspr	SRR0,r3
 	mtspr	SRR1,r4
 	rfi			/* enable MMU and jump to start_kernel */
 
+/* Set up the initial MMU state so we can do the first level of
+ * kernel initialization.  This maps the first 8 MBytes of memory 1:1
+ * virtual to physical.  Also, set the cache mode since that is defined
+ * by TLB entries and perform any additional mapping (like of the IMMR).
+ */
+initial_mmu:
+	tlbia			/* Invalidate all TLB entries */
+	li	r8, 0
+	mtspr	MI_CTR, r8	/* Set instruction control to zero */
+	lis	r8, MD_RESETVAL@h
+#ifndef CONFIG_8xx_COPYBACK
+	oris	r8, r8, MD_WTDEF@h
+#endif
+	mtspr	MD_CTR, r8	/* Set data TLB control */
+
+	/* Now map the lower 8 Meg into the TLBs.  For this quick hack,
+	 * we can load the instruction and data TLB registers with the
+	 * same values.
+	 */
+	lis	r8, KERNELBASE@h	/* Create vaddr for TLB */
+	ori	r8, r8, MI_EVALID	/* Mark it valid */
+	mtspr	MI_EPN, r8
+	mtspr	MD_EPN, r8
+	li	r8, MI_PS8MEG		/* Set 8M byte page */
+	ori	r8, r8, MI_SVALID	/* Make it valid */
+	mtspr	MI_TWC, r8
+	mtspr	MD_TWC, r8
+	li	r8, MI_BOOTINIT		/* Create RPN for address 0 */
+	mtspr	MI_RPN, r8		/* Store TLB entry */
+	mtspr	MD_RPN, r8
+	lis	r8, MI_Kp@h		/* Set the protection mode */
+	mtspr	MI_AP, r8
+	mtspr	MD_AP, r8
+
+	/* Map another 8 MByte at the IMMR to get the processor
+	 * internal registers (among other things).
+	 */
+	mfspr	r9, 638			/* Get current IMMR */
+	andis.	r9, r9, 0xff80		/* Get 8Mbyte boundary */
+
+	mr	r8, r9			/* Create vaddr for TLB */
+	ori	r8, r8, MD_EVALID	/* Mark it valid */
+	mtspr	MD_EPN, r8
+	li	r8, MD_PS8MEG		/* Set 8M byte page */
+	ori	r8, r8, MD_SVALID	/* Make it valid */
+	mtspr	MD_TWC, r8
+	mr	r8, r9			/* Create paddr for TLB */
+	ori	r8, r8, MI_BOOTINIT|0x2 /* Inhibit cache -- Cort */
+	mtspr	MD_RPN, r8
+
+	/* Since the cache is enabled according to the information we
+	 * just loaded into the TLB, invalidate and enable the caches here.
+	 * We should probably check/set other modes....later.
+	 */
+	lis	r8, IDC_INVALL@h
+	mtspr	IC_CST, r8
+	mtspr	DC_CST, r8
+	lis	r8, IDC_ENABLE@h
+	mtspr	IC_CST, r8
+#ifdef CONFIG_8xx_COPYBACK
+	mtspr	DC_CST, r8
+#else
+	/* For a debug option, I left this here to easily enable
+	 * the write through cache mode
+	 */
+	lis	r8, DC_SFWT@h
+	mtspr	DC_CST, r8
+	lis	r8, IDC_ENABLE@h
+	mtspr	DC_CST, r8
+#endif
+	blr
+
+
 /*
  * Set up to use a given MMU context.
+ * r3 is context number, r4 is PGD pointer.
  *
- * The MPC8xx has something that currently happens "automagically."
- * Unshared user space address translations are subject to ASID (context)
- * match.  During each task switch, the ASID is incremented.  We can
- * guarantee (I hope :-) that no entries currently match this ASID
- * because every task will cause at least a TLB entry to be loaded for
- * the first instruction and data access, plus the kernel running will
- * have displaced several more TLBs.  The MMU contains 32 entries for
- * each TLB, and there are 16 contexts, so we just need to make sure
- * two pages get replaced for every context switch, which currently
- * happens.  There are other TLB management techniques that I will
- * eventually implement, but this is the easiest for now.  -- Dan
- *
- * On the MPC8xx, we place the physical address of the new task
- * page directory loaded into the MMU base register, and set the
- * ASID compare register with the new "context".
+ * We place the physical address of the new task page directory loaded
+ * into the MMU base register, and set the ASID compare register with
+ * the new "context."
  */
 _GLOBAL(set_context)
-	/* fetch the pgd from the context_mm array */
-	lis	r5, context_mm@ha
-	slwi	r6, r3, 2
-	add	r5, r5, r6
-	lwz	r5, context_mm@l(r5)	/* get the mm */
-	lwz	r4, MM_PGD(r5)		/* get the pgd from the mm */
+
+#ifdef CONFIG_BDI_SWITCH
+	/* Context switch the PTE pointer for the Abatron BDI2000.
+	 * The PGDIR is passed as second argument.
+	 */
+	lis	r5, KERNELBASE@h
+	lwz	r5, 0xf0(r5)
+	stw	r4, 0x4(r5)
+#endif
+
 #ifdef CONFIG_8xx_CPU6
 	lis	r6, cpu6_errata_word@h
 	ori	r6, r6, cpu6_errata_word@l
@@ -967,7 +863,6 @@
 	tophys	(r4, r4)
 	mtspr	M_TWB, r4		/* and pgd */
 #endif
-        tlbia
 	SYNC
 	blr
 
@@ -1012,6 +907,12 @@
 	.globl	cmd_line
 cmd_line:
 	.space	512
+
+/* Room for two PTE table poiners, usually the kernel and current user
+ * pointer to their respective root page table (pgdir).
+ */
+abatron_pteptrs:
+	.space	8
 
 #ifdef CONFIG_8xx_CPU6
 	.globl	cpu6_errata_word
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/idle.c linux/arch/ppc/kernel/idle.c
--- v2.4.9/linux/arch/ppc/kernel/idle.c	Mon May 21 17:04:47 2001
+++ linux/arch/ppc/kernel/idle.c	Tue Aug 28 06:58:33 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.idle.c 1.11 05/17/01 18:14:21 cort
+ * BK Id: SCCS/s.idle.c 1.14 08/15/01 22:43:06 paulus
  */
 /*
  * Idle daemon for PowerPC.  Idle daemon will handle any action
@@ -31,12 +31,11 @@
 #include <asm/processor.h>
 #include <asm/mmu.h>
 #include <asm/cache.h>
+#include <asm/cputable.h>
 
 void zero_paged(void);
 void power_save(void);
-void inline htab_reclaim(void);
 
-unsigned long htab_reclaim_on = 0;
 unsigned long zero_paged_on = 0;
 unsigned long powersave_nap = 0;
 
@@ -50,27 +49,30 @@
 {
 	int do_power_save = 0;
 
-	/* only sleep on the 603-family/750 processors */
-	switch (_get_PVR() >> 16) {
-	case 3:			/* 603 */
-	case 6:			/* 603e */
-	case 7:			/* 603ev */
-	case 8:			/* 750 */
-	case 12:		/* 7400 */
-	case 0x800c:		/* 7410 */
+	if (cur_cpu_spec[smp_processor_id()]->cpu_features & CPU_FTR_CAN_DOZE)
 		do_power_save = 1;
-	}
 
 	/* endless loop with no priority at all */
 	current->nice = 20;
 	current->counter = -100;
-	init_idle();	
-	for (;;)
-	{
-		/*if ( !current->need_resched && zero_paged_on )
-			zero_paged();*/
-		if (!current->need_resched && htab_reclaim_on)
-			htab_reclaim();
+	init_idle();
+	for (;;) {
+#ifdef CONFIG_SMP
+		int oldval;
+
+		if (!do_power_save) {
+			/*
+			 * Deal with another CPU just having chosen a thread to
+			 * run here:
+			 */
+			oldval = xchg(&current->need_resched, -1);
+
+			if (!oldval) {
+				while(current->need_resched == -1)
+					; /* Do Nothing */
+			}
+		}
+#endif
 		if (do_power_save && !current->need_resched)
 			power_save();
 
@@ -92,68 +94,6 @@
 	return 0; 
 }
 
-/*
- * Mark 'zombie' pte's in the hash table as invalid.
- * This improves performance for the hash table reload code
- * a bit since we don't consider unused pages as valid.
- *  -- Cort
- */
-PTE *reclaim_ptr = 0;
-void inline htab_reclaim(void)
-{
-#ifndef CONFIG_8xx		
-#if 0	
-	PTE *ptr, *start;
-	static int dir = 1;
-#endif	
-	struct task_struct *p;
-	unsigned long valid = 0;
-	extern PTE *Hash, *Hash_end;
-	extern unsigned long Hash_size;
-
-	/* if we don't have a htab */
-	if ( Hash_size == 0 )
-		return;
-#if 0	
-	/* find a random place in the htab to start each time */
-	start = &Hash[jiffies%(Hash_size/sizeof(PTE))];
-	/* go a different direction each time */
-	dir *= -1;
-        for ( ptr = start;
-	      !current->need_resched && (ptr != Hash_end) && (ptr != Hash);
-	      ptr += dir)
-	{
-#else
-	if ( !reclaim_ptr ) reclaim_ptr = Hash;
-	while ( !current->need_resched )
-	{
-		reclaim_ptr++;
-		if ( reclaim_ptr == Hash_end ) reclaim_ptr = Hash;
-#endif	  
-		if (!reclaim_ptr->v)
-			continue;
-		valid = 0;
-		for_each_task(p)
-		{
-			if ( current->need_resched )
-				goto out;
-			/* if this vsid/context is in use */
-			if ( (reclaim_ptr->vsid >> 4) == p->mm->context )
-			{
-				valid = 1;
-				break;
-			}
-		}
-		if ( valid )
-			continue;
-		/* this pte isn't used */
-		reclaim_ptr->v = 0;
-	}
-out:
-	if ( current->need_resched ) printk("need_resched: %lx\n", current->need_resched);
-#endif /* CONFIG_8xx */
-}
-
 #if 0
 /*
  * Returns a pre-zero'd page from the list otherwise returns
@@ -287,7 +227,7 @@
 		atomic_inc((atomic_t *)&zero_cache_total);
 	}
 }
-#endif
+#endif /* 0 */
 
 void power_save(void)
 {
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/indirect_pci.c linux/arch/ppc/kernel/indirect_pci.c
--- v2.4.9/linux/arch/ppc/kernel/indirect_pci.c	Mon May 21 17:04:47 2001
+++ linux/arch/ppc/kernel/indirect_pci.c	Sat Sep  8 12:38:41 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.indirect_pci.c 1.7 05/17/01 18:14:21 cort
+ * BK Id: SCCS/s.indirect_pci.c 1.10 09/08/01 15:47:42 paulus
  */
 /*
  * Support for indirect PCI bridges.
@@ -19,7 +19,6 @@
 #include <linux/init.h>
 #include <linux/bootmem.h>
 
-#include <asm/init.h>
 #include <asm/io.h>
 #include <asm/prom.h>
 #include <asm/pci-bridge.h>
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/irq.c linux/arch/ppc/kernel/irq.c
--- v2.4.9/linux/arch/ppc/kernel/irq.c	Wed Jul 25 17:10:18 2001
+++ linux/arch/ppc/kernel/irq.c	Tue Aug 28 06:58:33 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.irq.c 1.30 07/19/01 16:51:32 paulus
+ * BK Id: SCCS/s.irq.c 1.32 08/24/01 20:07:37 paulus
  */
 /*
  *  arch/ppc/kernel/irq.c
@@ -93,6 +93,11 @@
 static struct irqaction malloc_cache[IRQ_KMALLOC_ENTRIES];
 extern int mem_init_done;
 
+#if defined(CONFIG_TAU_INT)
+extern int tau_interrupts(unsigned long cpu);
+extern int tau_initialized;
+#endif
+
 void *irq_kmalloc(size_t size, int pri)
 {
 	unsigned int i;
@@ -402,12 +407,14 @@
 		}
 		len += sprintf(buf+len, "\n");
 	}
-#ifdef CONFIG_TAU
-	len += sprintf(buf+len, "TAU: ");
-	for (j = 0; j < smp_num_cpus; j++)
-		len += sprintf(buf+len, "%10u ",
-				tau_interrupts(j));
-	len += sprintf(buf+len, "\n");
+#ifdef CONFIG_TAU_INT
+	if (tau_initialized){
+		len += sprintf(buf+len, "TAU: ");
+		for (j = 0; j < smp_num_cpus; j++)
+			len += sprintf(buf+len, "%10u ",
+					tau_interrupts(j));
+		len += sprintf(buf+len, "  PowerPC             Thermal Assist (cpu temp)\n");
+	}
 #endif
 #ifdef CONFIG_SMP
 	/* should this be per processor send/receive? */
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/l2cr.S linux/arch/ppc/kernel/l2cr.S
--- v2.4.9/linux/arch/ppc/kernel/l2cr.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/kernel/l2cr.S	Tue Aug 28 06:58:33 2001
@@ -0,0 +1,201 @@
+/*
+	L2CR functions
+	Copyright © 1997-1998 by PowerLogix R & D, Inc.
+	
+	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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+/*
+	Thur, Dec. 12, 1998.
+	- First public release, contributed by PowerLogix.
+	***********
+	Sat, Aug. 7, 1999.
+	- Terry: Made sure code disabled interrupts before running. (Previously
+			it was assumed interrupts were already disabled).
+	- Terry: Updated for tentative G4 support.  4MB of memory is now flushed
+			instead of 2MB.  (Prob. only 3 is necessary).
+	- Terry: Updated for workaround to HID0[DPM] processor bug
+			during global invalidates.
+	***********
+	Thu, July 13, 2000.
+	- Terry: Added isync to correct for an errata.
+	
+	Author:	Terry Greeniaus (tgree@phys.ualberta.ca)
+	Please e-mail updates to this file to me, thanks!
+*/
+#include <asm/processor.h>
+#include <asm/cputable.h>
+#include "ppc_asm.h"
+
+/* Usage:
+	
+	When setting the L2CR register, you must do a few special
+	things.  If you are enabling the cache, you must perform a
+	global invalidate.  If you are disabling the cache, you must
+	flush the cache contents first.  This routine takes care of
+	doing these things.  When first enabling the cache, make sure
+	you pass in the L2CR you want, as well as passing in the
+	global invalidate bit set.  A global invalidate will only be
+	performed if the L2I bit is set in applyThis.  When enabling
+	the cache, you should also set the L2E bit in applyThis.  If
+	you want to modify the L2CR contents after the cache has been
+	enabled, the recommended procedure is to first call
+	__setL2CR(0) to disable the cache and then call it again with
+	the new values for L2CR.  Examples:
+
+	_setL2CR(0)		- disables the cache
+	_setL2CR(0xB3A04000)	- enables my G3 upgrade card:
+				- L2E set to turn on the cache
+				- L2SIZ set to 1MB
+				- L2CLK set to 1:1
+				- L2RAM set to pipelined synchronous late-write
+				- L2I set to perform a global invalidation
+				- L2OH set to 0.5 nS
+				- L2DF set because this upgrade card
+				  requires it
+
+	A similar call should work for your card.  You need to know
+	the correct setting for your card and then place them in the
+	fields I have outlined above.  Other fields support optional
+	features, such as L2DO which caches only data, or L2TS which
+	causes cache pushes from the L1 cache to go to the L2 cache
+	instead of to main memory.
+*/
+/*
+ * Summary: this procedure ignores the L2I bit in the value passed in,
+ * flushes the cache if it was already enabled, always invalidates the
+ * cache, then enables the cache if the L2E bit is set in the value
+ * passed in.
+ *   -- paulus.
+ */
+_GLOBAL(_set_L2CR)
+	/* Make sure this is a 750 or 7400 chip */
+BEGIN_FTR_SECTION
+	li	r3,-1
+	blr
+END_FTR_SECTION_IFCLR(CPU_FTR_L2CR)
+
+	/* Turn off interrupts and data relocation. */
+	mfmsr	r7		/* Save MSR in r7 */
+	rlwinm	r4,r7,0,17,15
+	rlwinm	r4,r4,0,28,26	/* Turn off DR bit */
+	sync
+	mtmsr	r4
+	isync
+
+	/* Get the current enable bit of the L2CR into r4 */
+	mfspr	r4,L2CR
+	
+	/* Tweak some bits */
+	rlwinm	r5,r3,0,0,0		/* r5 contains the new enable bit */
+	rlwinm	r3,r3,0,11,9		/* Turn off the invalidate bit */
+	rlwinm	r3,r3,0,1,31		/* Turn off the enable bit */
+
+	/* Check to see if we need to flush */
+	rlwinm.	r4,r4,0,0,0
+	beq	2f
+
+	/* Flush the cache. First, read the first 4MB of memory (physical) to
+	 * put new data in the cache.  (Actually we only need
+	 * the size of the L2 cache plus the size of the L1 cache, but 4MB will
+	 * cover everything just to be safe).
+	 */
+		
+	 /**** Might be a good idea to set L2DO here - to prevent instructions
+	       from getting into the cache.  But since we invalidate
+	       the next time we enable the cache it doesn't really matter.
+	  ****/
+
+	lis	r4,0x0002
+	mtctr	r4
+	li	r4,0
+1:
+	lwzx	r0,r0,r4
+	addi	r4,r4,32		/* Go to start of next cache line */
+	bdnz	1b
+	
+	/* Now, flush the first 4MB of memory */
+	lis	r4,0x0002
+	mtctr	r4
+	li	r4,0
+	sync
+1:
+	dcbf	r0,r4
+	addi	r4,r4,32		/* Go to start of next cache line */
+	bdnz	1b
+
+2:
+	/* Set up the L2CR configuration bits (and switch L2 off) */
+	sync
+	mtspr	L2CR,r3
+	sync
+
+	/* Before we perform the global invalidation, we must disable dynamic
+	 * power management via HID0[DPM] to work around a processor bug where
+	 * DPM can possibly interfere with the state machine in the processor
+	 * that invalidates the L2 cache tags.
+	 */
+	mfspr	r8,HID0			/* Save HID0 in r8 */
+	rlwinm	r4,r8,0,12,10		/* Turn off HID0[DPM] */
+	sync
+	mtspr	HID0,r4			/* Disable DPM */
+	sync
+
+	/* Perform a global invalidation */
+	oris	r3,r3,0x0020
+	sync
+	mtspr	L2CR,r3
+	sync
+	isync				/* For errata */
+
+	/* Wait for the invalidation to complete */
+3:	mfspr	r3,L2CR
+	rlwinm.	r4,r3,0,31,31
+	bne	3b
+	
+	rlwinm	r3,r3,0,11,9		/* Turn off the L2I bit */
+	sync
+	mtspr	L2CR,r3
+	sync
+	
+	/* Restore HID0[DPM] to whatever it was before */
+	sync
+	mtspr	1008,r8
+	sync
+
+	/* See if we need to enable the cache */
+	cmplwi	r5,0
+	beq	4f
+
+	/* Enable the cache */
+	oris	r3,r3,0x8000
+	mtspr	L2CR,r3
+	sync
+
+	/* Restore MSR (restores EE and DR bits to original state) */
+4:	SYNC
+	mtmsr	r7
+	isync
+	blr
+
+_GLOBAL(_get_L2CR)
+	/* Return the L2CR contents */
+	li	r3,0
+BEGIN_FTR_SECTION
+	mfspr	r3,L2CR
+END_FTR_SECTION_IFSET(CPU_FTR_L2CR)
+	blr
+
+/* --- End of PowerLogix code ---
+ */
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/m8260_setup.c linux/arch/ppc/kernel/m8260_setup.c
--- v2.4.9/linux/arch/ppc/kernel/m8260_setup.c	Wed Jul 25 17:10:18 2001
+++ linux/arch/ppc/kernel/m8260_setup.c	Tue Aug 28 06:58:33 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.m8260_setup.c 1.20 07/18/01 22:56:39 paulus
+ * BK Id: SCCS/s.m8260_setup.c 1.24 08/20/01 15:25:16 paulus
  */
 /*
  *  linux/arch/ppc/kernel/setup.c
@@ -52,17 +52,6 @@
 unsigned long m8260_get_rtc_time(void);
 void m8260_calibrate_decr(void);
 
-#if 0
-extern int mackbd_setkeycode(unsigned int scancode, unsigned int keycode);
-extern int mackbd_getkeycode(unsigned int scancode);
-extern int mackbd_pretranslate(unsigned char scancode, char raw_mode);
-extern int mackbd_translate(unsigned char scancode, unsigned char *keycode,
-			   char raw_mode);
-extern char mackbd_unexpected_up(unsigned char keycode);
-extern void mackbd_leds(unsigned char leds);
-extern void mackbd_init_hw(void);
-#endif
-
 extern unsigned long loops_per_jiffy;
 
 unsigned char __res[sizeof(bd_t)];
@@ -72,10 +61,6 @@
 extern unsigned long find_available_memory(void);
 extern void m8260_cpm_reset(void);
 
-void __init adbdev_init(void)
-{
-}
-
 void __init
 m8260_setup_arch(void)
 {
@@ -102,7 +87,7 @@
 	bd_t	*binfo = (bd_t *)__res;
 	int freq, divisor;
 
-	freq = (binfo->bi_busfreq * 1000000);
+	freq = binfo->bi_busfreq;
         divisor = 4;
         tb_ticks_per_jiffy = freq / HZ / divisor;
 	tb_to_us = mulhwu_scale_factor(freq / divisor, 1000000);
@@ -111,7 +96,8 @@
 /* The 8260 has an internal 1-second timer update register that
  * we should use for this purpose.
  */
-static uint	rtc_time;
+static uint rtc_time;
+
 static int
 m8260_set_rtc_time(unsigned long time)
 {
@@ -145,7 +131,7 @@
 			startaddr = simple_strtoul(&cmd[10], NULL, 0);
 	}
 
-	m8260_gorom((uint)__pa(__res), startaddr);
+	m8260_gorom((unsigned int)__pa(__res), startaddr);
 }
 
 void
@@ -171,9 +157,9 @@
 	len += sprintf(len+buffer,"core clock\t: %d MHz\n"
 		       "CPM  clock\t: %d MHz\n"
 		       "bus  clock\t: %d MHz\n",
-		       bp->bi_intfreq /*/ 1000000*/,
-		       bp->bi_cpmfreq /*/ 1000000*/,
-		       bp->bi_busfreq /*/ 1000000*/);
+		       bp->bi_intfreq / 1000000,
+		       bp->bi_cpmfreq / 1000000,
+		       bp->bi_busfreq / 1000000);
 
 	return len;
 }
@@ -219,9 +205,21 @@
 	return binfo->bi_memsize;
 }
 
+/* Map the IMMR, plus anything else we can cover
+ * in that upper space according to the memory controller
+ * chip select mapping.  Grab another bunch of space
+ * below that for stuff we can't cover in the upper.
+ */
+static void __init
+m8260_map_io(void)
+{
+	io_block_mapping(0xf0000000, 0xf0000000, 0x10000000, _PAGE_IO);
+	io_block_mapping(0xe0000000, 0xe0000000, 0x10000000, _PAGE_IO);
+}
+
 void __init
-m8260_init(unsigned long r3, unsigned long r4, unsigned long r5,
-	 unsigned long r6, unsigned long r7)
+platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
+	      unsigned long r6, unsigned long r7)
 {
 
 	if ( r3 )
@@ -261,6 +259,7 @@
 	ppc_md.calibrate_decr = m8260_calibrate_decr;
 
 	ppc_md.find_end_of_memory = m8260_find_end_of_memory;
+	ppc_md.setup_io_mappings = m8260_map_io;
 
 	ppc_md.kbd_setkeycode    = NULL;
 	ppc_md.kbd_getkeycode    = NULL;
@@ -273,51 +272,11 @@
 #endif
 
 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
-        ppc_ide_md.insw = m8xx_ide_insw;
-        ppc_ide_md.outsw = m8xx_ide_outsw;
         ppc_ide_md.default_irq = m8xx_ide_default_irq;
         ppc_ide_md.default_io_base = m8xx_ide_default_io_base;
-        ppc_ide_md.fix_driveid = ppc_generic_ide_fix_driveid;
         ppc_ide_md.ide_init_hwif = m8xx_ide_init_hwif_ports;
         ppc_ide_md.ide_request_irq = m8xx_ide_request_irq;
-
-        ppc_ide_md.io_base = _IO_BASE;
 #endif		
-}
-
-/*
- * Copied from prom.c so I don't have include all of that crap.
- *				-- Dan
- *
- * prom_init() is called very early on, before the kernel text
- * and data have been mapped to KERNELBASE.  At this point the code
- * is running at whatever address it has been loaded at, so
- * references to extern and static variables must be relocated
- * explicitly.  The procedure reloc_offset() returns the address
- * we're currently running at minus the address we were linked at.
- * (Note that strings count as static variables.)
- */
-extern unsigned long reloc_offset(void);
-#define PTRRELOC(x)	((typeof(x))((unsigned long)(x) + offset))
-
-__init
-unsigned long
-prom_init(uint r3, uint r4, uint r5, uint r6)
-{
-	unsigned long offset = reloc_offset();
- 	unsigned long phys;
-	extern char __bss_start, _end;
-
-	/* First zero the BSS -- use memset, some arches don't have
-	 * caches on yet */
-	memset_io(PTRRELOC(&__bss_start),0 , &_end - &__bss_start);
-
- 	/* Default */
- 	phys = offset + KERNELBASE;
-
-	/* We are done.
-	*/
-	return phys;
 }
 
 /* Mainly for ksyms.
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/m8xx_setup.c linux/arch/ppc/kernel/m8xx_setup.c
--- v2.4.9/linux/arch/ppc/kernel/m8xx_setup.c	Wed Jul 25 17:10:18 2001
+++ linux/arch/ppc/kernel/m8xx_setup.c	Sat Sep  8 12:39:33 2001
@@ -1,7 +1,6 @@
 /*
- * BK Id: SCCS/s.m8xx_setup.c 1.23 07/18/01 22:56:39 paulus
- */
-/*
+ * BK Id: SCCS/s.m8xx_setup.c 1.29 08/30/01 09:01:04 trini
+ *
  *  linux/arch/ppc/kernel/setup.c
  *
  *  Copyright (C) 1995  Linus Torvalds
@@ -172,8 +171,7 @@
 	machine_restart(NULL);
 }
 
-/* A place holder for time base interrupts, if they are ever enabled.
-*/
+/* A place holder for time base interrupts, if they are ever enabled. */
 void timebase_interrupt(int irq, void * dev, struct pt_regs * regs)
 {
 	printk ("timebase_interrupt()\n");
@@ -188,13 +186,11 @@
 	bd_t	*binfo = (bd_t *)__res;
 	int freq, fp, divisor;
 
-	/* Unlock the SCCR.
-	*/
+	/* Unlock the SCCR. */
 	((volatile immap_t *)IMAP_ADDR)->im_clkrstk.cark_sccrk = ~KAPWR_KEY;
 	((volatile immap_t *)IMAP_ADDR)->im_clkrstk.cark_sccrk = KAPWR_KEY;
 
-	/* Force all 8xx processors to use divide by 16 processor clock.
-	*/
+	/* Force all 8xx processors to use divide by 16 processor clock. */
 	((volatile immap_t *)IMAP_ADDR)->im_clkrst.car_sccr |= 0x02000000;
 
 	/* Processor frequency is MHz.
@@ -224,15 +220,17 @@
 	 */
 	((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbscrk = ~KAPWR_KEY;
 	((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_rtcsck = ~KAPWR_KEY;
-	((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk = ~KAPWR_KEY;
+	((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk    = ~KAPWR_KEY;
 	((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbscrk = KAPWR_KEY;
 	((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_rtcsck = KAPWR_KEY;
-	((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk = KAPWR_KEY;
+	((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk    = KAPWR_KEY;
 
-	/* Disable the RTC one second and alarm interrupts.
-	*/
+	/* Disable the RTC one second and alarm interrupts. */
 	((volatile immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc &=
 						~(RTCSC_SIE | RTCSC_ALE);
+	/* Enable the RTC */
+	((volatile immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc |=
+						(RTCSC_RTF | RTCSC_RTE);
 
 	/* Enabling the decrementer also enables the timebase interrupts
 	 * (or from the other point of view, to get decrementer interrupts
@@ -260,15 +258,14 @@
 	return(0);
 }
 
-unsigned long
+static unsigned long
 m8xx_get_rtc_time(void)
 {
-	/* Get time from the RTC.
-	*/
+	/* Get time from the RTC. */
 	return((unsigned long)(((immap_t *)IMAP_ADDR)->im_sit.sit_rtc));
 }
 
-void
+static void
 m8xx_restart(char *cmd)
 {
 	__volatile__ unsigned char dummy;
@@ -288,20 +285,21 @@
 	while(1);
 }
 
-void
+static void
 m8xx_power_off(void)
 {
    m8xx_restart(NULL);
 }
 
-void
+static void
 m8xx_halt(void)
 {
    m8xx_restart(NULL);
 }
 
 
-int m8xx_setup_residual(char *buffer)
+static int
+m8xx_setup_residual(char *buffer)
 {
         int     len = 0;
 	bd_t	*bp;
@@ -322,7 +320,7 @@
  * External interrupts can be either edge or level triggered, and
  * need to be initialized by the appropriate driver.
  */
-void __init
+static void __init
 m8xx_init_IRQ(void)
 {
 	int i;
@@ -353,32 +351,12 @@
  * IDE stuff.
  */
 #ifdef CONFIG_BLK_DEV_MPC8xx_IDE
-void ide_interrupt_handler (void *dev)
+static void ide_interrupt_handler (void *dev)
 {
 }
 #endif
 
-void
-m8xx_ide_insw(ide_ioreg_t port, void *buf, int ns)
-{
-#ifdef CONFIG_BLK_DEV_MPC8xx_IDE
-	ide_insw(port, buf, ns);
-#else
-	_insw_ns((unsigned short *)(port+_IO_BASE), buf, ns);
-#endif
-}
-
-void
-m8xx_ide_outsw(ide_ioreg_t port, void *buf, int ns)
-{
-#ifdef CONFIG_BLK_DEV_MPC8xx_IDE
-	ide_outsw(port, buf, ns);
-#else
-	_outsw_ns((unsigned short *)(port+_IO_BASE), buf, ns);
-#endif
-}
-
-int
+static int
 m8xx_ide_default_irq(ide_ioreg_t base)
 {
 #ifdef CONFIG_BLK_DEV_MPC8xx_IDE
@@ -391,13 +369,13 @@
 #endif
 }
 
-ide_ioreg_t
+static ide_ioreg_t
 m8xx_ide_default_io_base(int index)
 {
         return index;
 }
 
-int
+static int
 m8xx_ide_request_irq(unsigned int irq,
 		       void (*handler)(int, void *, struct pt_regs *),
 		       unsigned long flags, 
@@ -412,8 +390,9 @@
  *
  * See include/linux/ide.h for definition of hw_regs_t (p, base)
  */
-void m8xx_ide_init_hwif_ports(hw_regs_t *hw,
-	ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq)
+static void
+m8xx_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, 
+		ide_ioreg_t ctrl_port, int *irq)
 {
 	int i;
 #ifdef CONFIG_BLK_DEV_MPC8xx_IDE
@@ -479,7 +458,7 @@
 # endif	/* CONFIG_SPD823TS, CONFIG_IVMS8 */
 
 	for (i = 0; i < IDE_NR_PORTS; ++i) {
-	 	*p++ = base + ioport_dsc[data_port].reg_off[i];
+		*p++ = base + ioport_dsc[data_port].reg_off[i] - _IO_BASE;
 	}
 
 	if (irq) {
@@ -585,7 +564,8 @@
  * functions in the image just to get prom_init, all we really need right
  * now is the initialization of the physical memory region.
  */
-unsigned long __init m8xx_find_end_of_memory(void)
+static unsigned long __init
+m8xx_find_end_of_memory(void)
 {
 	bd_t	*binfo;
 	extern unsigned char __res[];
@@ -595,11 +575,47 @@
 	return binfo->bi_memsize;
 }
 
-void __init
-m8xx_init(unsigned long r3, unsigned long r4, unsigned long r5,
-	 unsigned long r6, unsigned long r7)
+/*
+ * Now map in some of the I/O space that is generically needed
+ * or shared with multiple devices.
+ * All of this fits into the same 4Mbyte region, so it only
+ * requires one page table page.  (or at least it used to  -- paulus)
+ */
+static void __init
+m8xx_map_io(void)
 {
+        io_block_mapping(IMAP_ADDR, IMAP_ADDR, IMAP_SIZE, _PAGE_IO);
+#ifdef CONFIG_MBX
+        io_block_mapping(NVRAM_ADDR, NVRAM_ADDR, NVRAM_SIZE, _PAGE_IO);
+        io_block_mapping(MBX_CSR_ADDR, MBX_CSR_ADDR, MBX_CSR_SIZE, _PAGE_IO);
+        io_block_mapping(PCI_CSR_ADDR, PCI_CSR_ADDR, PCI_CSR_SIZE, _PAGE_IO);
+
+	/* Map some of the PCI/ISA I/O space to get the IDE interface.
+	*/
+        io_block_mapping(PCI_ISA_IO_ADDR, PCI_ISA_IO_ADDR, 0x4000, _PAGE_IO);
+        io_block_mapping(PCI_IDE_ADDR, PCI_IDE_ADDR, 0x4000, _PAGE_IO);
+#endif
+#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC)
+	io_block_mapping(RPX_CSR_ADDR, RPX_CSR_ADDR, RPX_CSR_SIZE, _PAGE_IO);
+#if !defined(CONFIG_PCI)
+	io_block_mapping(_IO_BASE,_IO_BASE,_IO_BASE_SIZE, _PAGE_IO);
+#endif
+#endif
+#ifdef CONFIG_HTDMSOUND
+	io_block_mapping(HIOX_CSR_ADDR, HIOX_CSR_ADDR, HIOX_CSR_SIZE, _PAGE_IO);
+#endif
+#ifdef CONFIG_FADS
+	io_block_mapping(BCSR_ADDR, BCSR_ADDR, BCSR_SIZE, _PAGE_IO);
+#endif
+#ifdef CONFIG_PCI
+        io_block_mapping(PCI_CSR_ADDR, PCI_CSR_ADDR, PCI_CSR_SIZE, _PAGE_IO);
+#endif
+}
 
+void __init
+platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
+		unsigned long r6, unsigned long r7)
+{
 	if ( r3 )
 		memcpy( (void *)__res,(void *)(r3+KERNELBASE), sizeof(bd_t) );
 	
@@ -617,8 +633,7 @@
 #endif /* CONFIG_BLK_DEV_INITRD */
 	/* take care of cmd line */
 	if ( r6 )
-	{
-		
+	{	
 		*(char *)(r7+KERNELBASE) = 0;
 		strcpy(cmd_line, (char *)(r6+KERNELBASE));
 	}
@@ -641,6 +656,7 @@
 	ppc_md.calibrate_decr = m8xx_calibrate_decr;
 
 	ppc_md.find_end_of_memory = m8xx_find_end_of_memory;
+	ppc_md.setup_io_mappings = m8xx_map_io;
 
 	ppc_md.kbd_setkeycode    = NULL;
 	ppc_md.kbd_getkeycode    = NULL;
@@ -653,13 +669,8 @@
 #endif
 
 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
-        ppc_ide_md.insw = m8xx_ide_insw;
-        ppc_ide_md.outsw = m8xx_ide_outsw;
         ppc_ide_md.default_irq = m8xx_ide_default_irq;
         ppc_ide_md.default_io_base = m8xx_ide_default_io_base;
-        ppc_ide_md.fix_driveid = ppc_generic_ide_fix_driveid;
         ppc_ide_md.ide_init_hwif = m8xx_ide_init_hwif_ports;
-
-        ppc_ide_md.io_base = _IO_BASE;
 #endif		
 }
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/misc.S linux/arch/ppc/kernel/misc.S
--- v2.4.9/linux/arch/ppc/kernel/misc.S	Sun Aug 12 13:27:58 2001
+++ linux/arch/ppc/kernel/misc.S	Tue Aug 28 06:58:33 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.misc.S 1.21 07/07/01 17:00:08 paulus
+ * BK Id: SCCS/s.misc.S 1.28 08/24/01 20:07:37 paulus
  */
 /*
  * This file contains miscellaneous low-level functions.
@@ -22,6 +22,7 @@
 #include <asm/processor.h>
 #include <asm/page.h>
 #include <asm/cache.h>
+#include <asm/cputable.h>
 #include "ppc_asm.h"
 
 	.text
@@ -49,6 +50,97 @@
 	mtlr	r0
 	blr
 
+/*
+ * identify_cpu,
+ * called with r3 = data offset and r4 = CPU number
+ * doesn't change r3
+ */
+_GLOBAL(identify_cpu)
+	addis	r8,r3,cpu_specs@ha
+	addi	r8,r8,cpu_specs@l
+	mfpvr	r7
+1:
+	lwz	r5,CPU_SPEC_PVR_MASK(r8)
+	and	r5,r5,r7
+	lwz	r6,CPU_SPEC_PVR_VALUE(r8)
+	cmplw	0,r6,r5
+	beq	1f
+	addi	r8,r8,CPU_SPEC_ENTRY_SIZE
+	b	1b
+1:
+	addis	r6,r3,cur_cpu_spec@ha
+	addi	r6,r6,cur_cpu_spec@l
+	slwi	r4,r4,2
+	sub	r8,r8,r3
+	stwx	r8,r4,r6
+	blr
+
+/*
+ * do_cpu_ftr_fixups - goes through the list of CPU feature fixups
+ * and writes nop's over sections of code that don't apply for this cpu.
+ * r3 = data offset (not changed)
+ */
+_GLOBAL(do_cpu_ftr_fixups)
+	/* Get CPU 0 features */
+	addis	r6,r3,cur_cpu_spec@ha
+	addi	r6,r6,cur_cpu_spec@l
+	lwz	r4,0(r6)
+	add	r4,r4,r3
+	lwz	r4,CPU_SPEC_FEATURES(r4)
+
+	/* Get the fixup table */
+	addis	r6,r3,__start___ftr_fixup@ha
+	addi	r6,r6,__start___ftr_fixup@l
+	addis	r7,r3,__stop___ftr_fixup@ha
+	addi	r7,r7,__stop___ftr_fixup@l
+
+	/* Do the fixup */
+1:	cmplw	0,r6,r7
+	bgelr
+	addi	r6,r6,16
+	lwz	r8,-16(r6)	/* mask */
+	and	r8,r8,r4
+	lwz	r9,-12(r6)	/* value */
+	cmplw	0,r8,r9
+	beq	1b
+	lwz	r8,-8(r6)	/* section begin */
+	lwz	r9,-4(r6)	/* section end */
+	subf.	r9,r8,r9
+	beq	1b
+	/* write nops over the section of code */
+	/* todo: if large section, add a branch at the start of it */
+	srwi	r9,r9,2
+	mtctr	r9
+	add	r8,r8,r3
+	lis	r0,0x60000000@h	/* nop */
+3:	stw	r0,0(r8)
+	andi.	r10,r4,CPU_FTR_SPLIT_ID_CACHE@l
+	beq	2f
+	dcbst	0,r8		/* suboptimal, but simpler */
+	sync
+	icbi	0,r8
+2:	addi	r8,r8,4
+	bdnz	3b
+	sync			/* additional sync needed on g4 */
+	isync
+	b	1b
+
+/*
+ * call_setup_cpu - call the setup_cpu function for this cpu
+ * r3 = data offset, r24 = cpu number
+ */
+_GLOBAL(call_setup_cpu)
+	addis	r5,r3,cur_cpu_spec@ha
+	addi	r5,r5,cur_cpu_spec@l
+	slwi	r4,r24,2
+	lwzx	r5,r4,r5
+	add	r5,r5,r3
+	lwz	r6,CPU_SPEC_SETUP(r5)
+	add	r6,r6,r3
+	mtctr	r6
+	mr	r3,r24
+	bctr
+
 /* void __save_flags_ptr(unsigned long *flags) */
 _GLOBAL(__save_flags_ptr)
 	mfmsr	r4
@@ -185,7 +277,7 @@
 _GLOBAL(_nmask_and_or_msr)
 	mfmsr	r0		/* Get current msr */
 	andc	r0,r0,r3	/* And off the bits set in r3 (first parm) */
-	or	r0,r0,r4		/* Or on the bits in r4 (second parm) */
+	or	r0,r0,r4	/* Or on the bits in r4 (second parm) */
 	SYNC			/* Some chip revs have problems here... */
 	mtmsr	r0		/* Update machine state */
 	isync
@@ -216,8 +308,7 @@
 	tlbia
 	sync
 #ifdef CONFIG_SMP
-	tlbsync
-	sync
+	TLBSYNC
 	li	r0,0
 	stw	r0,0(r9)		/* clear hash_table_lock */
 	mtmsr	r10
@@ -249,8 +340,7 @@
 	tlbie	r3
 	sync
 #ifdef CONFIG_SMP
-	tlbsync
-	sync
+	TLBSYNC
 	li	r0,0
 	stw	r0,0(r9)		/* clear hash_table_lock */
 	mtmsr	r10
@@ -314,26 +404,70 @@
 	sync				/* additional sync needed on g4 */
 	isync
 	blr
+/*
+ * Write any modified data cache blocks out to memory.
+ * Does not invalidate the corresponding cache lines (especially for
+ * any corresponding instruction cache).
+ *
+ * clean_dcache_range(unsigned long start, unsigned long stop)
+ */
+_GLOBAL(clean_dcache_range)
+	li	r5,CACHE_LINE_SIZE-1
+	andc	r3,r3,r5
+	subf	r4,r3,r4
+	add	r4,r4,r5
+	srwi.	r4,r4,LG_CACHE_LINE_SIZE
+	beqlr
+	mtctr	r4
+
+1:	dcbst	0,r3
+	addi	r3,r3,CACHE_LINE_SIZE
+	bdnz	1b
+	sync				/* wait for dcbst's to get to ram */
+	blr
 
 /*
- * Like above, but only do the D-cache.
+ * Write any modified data cache blocks out to memory
+ * and invalidate the corresponding instruction cache blocks.
  *
  * flush_dcache_range(unsigned long start, unsigned long stop)
  */
 _GLOBAL(flush_dcache_range)
-       li      r5,CACHE_LINE_SIZE-1
-       andc    r3,r3,r5
-       subf    r4,r3,r4
-       add     r4,r4,r5
-       srwi.   r4,r4,LG_CACHE_LINE_SIZE
-       beqlr
-       mtctr   r4
-
-1:     dcbst   0,r3
-       addi    r3,r3,CACHE_LINE_SIZE
-       bdnz    1b
-       sync                            /* wait for dcbst's to get to ram */
-       blr
+	li	r5,CACHE_LINE_SIZE-1
+	andc	r3,r3,r5
+	subf	r4,r3,r4
+	add	r4,r4,r5
+	srwi.	r4,r4,LG_CACHE_LINE_SIZE
+	beqlr
+	mtctr	r4
+
+1:	dcbf	0,r3
+	addi	r3,r3,CACHE_LINE_SIZE
+	bdnz	1b
+	sync				/* wait for dcbst's to get to ram */
+	blr
+
+/*
+ * Like above, but invalidate the D-cache.  This is used by the 8xx
+ * to invalidate the cache so the PPC core doesn't get stale data
+ * from the CPM (no cache snooping here :-).
+ *
+ * invalidate_dcache_range(unsigned long start, unsigned long stop)
+ */
+_GLOBAL(invalidate_dcache_range)
+	li	r5,CACHE_LINE_SIZE-1
+	andc	r3,r3,r5
+	subf	r4,r3,r4
+	add	r4,r4,r5
+	srwi.	r4,r4,LG_CACHE_LINE_SIZE
+	beqlr
+	mtctr	r4
+
+1:	dcbi	0,r3
+	addi	r3,r3,CACHE_LINE_SIZE
+	bdnz	1b
+	sync				/* wait for dcbi's to get to ram */
+	blr
 
 /*
  * Flush a particular page from the data cache to RAM.
@@ -481,94 +615,9 @@
 	blr
 
 /*
- * Try to acquire a spinlock.
- * Only does the stwcx. if the load returned 0 - the Programming
- * Environments Manual suggests not doing unnecessary stcwx.'s
- * since they may inhibit forward progress by other CPUs in getting
- * a lock.
- */
-_GLOBAL(__spin_trylock)
-	mr	r4,r3
-	eieio			/* prevent reordering of stores */
-	li	r5,-1
-	lwarx	r3,0,r4		/* fetch old value, establish reservation */
-	cmpwi	0,r3,0		/* is it 0? */
-	bnelr-			/* return failure if not */
-	stwcx.	r5,0,r4		/* try to update with new value */
-	bne-	1f		/* if we failed */
-	eieio			/* prevent reordering of stores */
-	blr
-1:	li	r3,1		/* return non-zero for failure */
-	blr
-
-/*
- * Atomic add/sub/inc/dec operations
- *
- * void atomic_add(int c, int *v)
- * void atomic_sub(int c, int *v)
- * void atomic_inc(int *v)
- * void atomic_dec(int *v)
- * int atomic_dec_and_test(int *v)
- * int atomic_inc_return(int *v)
- * int atomic_dec_return(int *v)
  * void atomic_clear_mask(atomic_t mask, atomic_t *addr)
  * void atomic_set_mask(atomic_t mask, atomic_t *addr);
  */
-#if 0 /* now inline - paulus */
-_GLOBAL(atomic_add)
-10:	lwarx	r5,0,r4		/* Fetch old value & reserve */
-	add	r5,r5,r3	/* Perform 'add' operation */
-	stwcx.	r5,0,r4		/* Update with new value */
-	bne-	10b		/* Retry if "reservation" (i.e. lock) lost */
-	blr
-_GLOBAL(atomic_add_return)
-10:	lwarx	r5,0,r4		/* Fetch old value & reserve */
-	add	r5,r5,r3	/* Perform 'add' operation */
-	stwcx.	r5,0,r4		/* Update with new value */
-	bne-	10b		/* Retry if "reservation" (i.e. lock) lost */
-	mr	r3,r5
-	blr
-_GLOBAL(atomic_sub)
-10:	lwarx	r5,0,r4		/* Fetch old value & reserve */
-	sub	r5,r5,r3	/* Perform 'add' operation */
-	stwcx.	r5,0,r4		/* Update with new value */
-	bne-	10b		/* Retry if "reservation" (i.e. lock) lost */
-	blr
-_GLOBAL(atomic_inc)
-10:	lwarx	r5,0,r3		/* Fetch old value & reserve */
-	addi	r5,r5,1		/* Perform 'add' operation */
-	stwcx.	r5,0,r3		/* Update with new value */
-	bne-	10b		/* Retry if "reservation" (i.e. lock) lost */
-	blr
-_GLOBAL(atomic_inc_return)
-10:	lwarx	r5,0,r3		/* Fetch old value & reserve */
-	addi	r5,r5,1		/* Perform 'add' operation */
-	stwcx.	r5,0,r3		/* Update with new value */
-	bne-	10b		/* Retry if "reservation" (i.e. lock) lost */
-	mr	r3,r5		/* Return new value */
-	blr
-_GLOBAL(atomic_dec)
-10:	lwarx	r5,0,r3		/* Fetch old value & reserve */
-	subi	r5,r5,1		/* Perform 'add' operation */
-	stwcx.	r5,0,r3		/* Update with new value */
-	bne-	10b		/* Retry if "reservation" (i.e. lock) lost */
-	blr
-_GLOBAL(atomic_dec_return)
-10:	lwarx	r5,0,r3		/* Fetch old value & reserve */
-	subi	r5,r5,1		/* Perform 'add' operation */
-	stwcx.	r5,0,r3		/* Update with new value */
-	bne-	10b		/* Retry if "reservation" (i.e. lock) lost */
-	mr	r3,r5		/* Return new value */
-	blr
-_GLOBAL(atomic_dec_and_test)
-10:	lwarx	r5,0,r3		/* Fetch old value & reserve */
-	subi	r5,r5,1		/* Perform 'add' operation */
-	stwcx.	r5,0,r3		/* Update with new value */
-	bne-	10b		/* Retry if "reservation" (i.e. lock) lost */
-	cntlzw	r3,r5
-	srwi	r3,r3,5
-	blr
-#endif /* 0 */
 _GLOBAL(atomic_clear_mask)
 10:	lwarx	r5,0,r4
 	andc	r5,r5,r3
@@ -768,281 +817,7 @@
 _GLOBAL(_get_SP)
 	mr	r3,r1		/* Close enough */
 	blr
-
-#if 0
-/* isn't it just easier to use the mtspr/mfspr inline macros?? --Troy */
-_GLOBAL(_get_THRM1)
-	mfspr	r3,THRM1
-	blr
-
-_GLOBAL(_get_THRM2)
-	mfspr	r3,THRM2
-	blr
-
-_GLOBAL(_get_THRM3)
-	mfspr	r3,THRM3
-	blr
-		
-_GLOBAL(_set_THRM1)
-	mtspr	THRM1,r3
-	blr
-
-_GLOBAL(_set_THRM2)
-	mtspr	THRM2,r3
-	blr
-
-_GLOBAL(_set_THRM3)
-	mtspr	THRM3,r3
-	blr
-#endif
-	
-_GLOBAL(_get_PVR)
-	mfspr	r3,PVR
-	blr
-
-#ifdef CONFIG_8xx
-_GLOBAL(_get_IMMR)
-	mfspr	r3, 638
-	blr
-#endif
 	
-_GLOBAL(_get_HID0)
-	mfspr	r3,HID0
-	blr
-
-_GLOBAL(_set_HID0)
-	sync
-	mtspr	HID0, r3
-	SYNC		/* Handle errata in some cases */
-	blr
-
-_GLOBAL(_get_ICTC)
-	mfspr	r3,ICTC
-	blr
-
-_GLOBAL(_set_ICTC)
-	mtspr	ICTC,r3
-	blr
-
-/*
-	L2CR functions
-	Copyright © 1997-1998 by PowerLogix R & D, Inc.
-	
-	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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-/*
-	Thur, Dec. 12, 1998.
-	- First public release, contributed by PowerLogix.
-	***********
-	Sat, Aug. 7, 1999.
-	- Terry: Made sure code disabled interrupts before running. (Previously
-			it was assumed interrupts were already disabled).
-	- Terry: Updated for tentative G4 support.  4MB of memory is now flushed
-			instead of 2MB.  (Prob. only 3 is necessary).
-	- Terry: Updated for workaround to HID0[DPM] processor bug
-			during global invalidates.
-	***********
-	Thu, July 13, 2000.
-	- Terry: Added isync to correct for an errata.
-	
-	Author:	Terry Greeniaus (tgree@phys.ualberta.ca)
-	Please e-mail updates to this file to me, thanks!
-*/
-/* Usage:
-	
-	When setting the L2CR register, you must do a few special
-	things.  If you are enabling the cache, you must perform a
-	global invalidate.  If you are disabling the cache, you must
-	flush the cache contents first.  This routine takes care of
-	doing these things.  When first enabling the cache, make sure
-	you pass in the L2CR you want, as well as passing in the
-	global invalidate bit set.  A global invalidate will only be
-	performed if the L2I bit is set in applyThis.  When enabling
-	the cache, you should also set the L2E bit in applyThis.  If
-	you want to modify the L2CR contents after the cache has been
-	enabled, the recommended procedure is to first call
-	__setL2CR(0) to disable the cache and then call it again with
-	the new values for L2CR.  Examples:
-
-	_setL2CR(0)		- disables the cache
-	_setL2CR(0xB3A04000)	- enables my G3 upgrade card:
-				- L2E set to turn on the cache
-				- L2SIZ set to 1MB
-				- L2CLK set to 1:1
-				- L2RAM set to pipelined synchronous late-write
-				- L2I set to perform a global invalidation
-				- L2OH set to 0.5 nS
-				- L2DF set because this upgrade card
-				  requires it
-
-	A similar call should work for your card.  You need to know
-	the correct setting for your card and then place them in the
-	fields I have outlined above.  Other fields support optional
-	features, such as L2DO which caches only data, or L2TS which
-	causes cache pushes from the L1 cache to go to the L2 cache
-	instead of to main memory.
-*/
-/*
- * Summary: this procedure ignores the L2I bit in the value passed in,
- * flushes the cache if it was already enabled, always invalidates the
- * cache, then enables the cache if the L2E bit is set in the value
- * passed in.
- *   -- paulus.
- */
-_GLOBAL(_set_L2CR)
-	/* Make sure this is a 750 or 7400 chip */
-	mfspr	r4,PVR
-	rlwinm	r4,r4,16,16,31
-	cmpwi	r4,0x0008
-	cmpwi	cr1,r4,0x000c
-	cror	2,2,4*cr1+2
-	bne	99f
-
-	/* Turn off interrupts and data relocation. */
-	mfmsr	r7		/* Save MSR in r7 */
-	rlwinm	r4,r7,0,17,15
-	rlwinm	r4,r4,0,28,26	/* Turn off DR bit */
-	sync
-	mtmsr	r4
-	isync
-
-	/* Get the current enable bit of the L2CR into r4 */
-	mfspr	r4,L2CR
-	
-	/* Tweak some bits */
-	rlwinm	r5,r3,0,0,0		/* r5 contains the new enable bit */
-	rlwinm	r3,r3,0,11,9		/* Turn off the invalidate bit */
-	rlwinm	r3,r3,0,1,31		/* Turn off the enable bit */
-
-	/* Check to see if we need to flush */
-	rlwinm.	r4,r4,0,0,0
-	beq	2f
-
-	/* Flush the cache. First, read the first 4MB of memory (physical) to
-	 * put new data in the cache.  (Actually we only need
-	 * the size of the L2 cache plus the size of the L1 cache, but 4MB will
-	 * cover everything just to be safe).
-	 */
-		
-	 /**** Might be a good idea to set L2DO here - to prevent instructions
-	       from getting into the cache.  But since we invalidate
-	       the next time we enable the cache it doesn't really matter.
-	  ****/
-
-	lis	r4,0x0002
-	mtctr	r4
-	li	r4,0
-1:
-	lwzx	r0,r0,r4
-	addi	r4,r4,32		/* Go to start of next cache line */
-	bdnz	1b
-	
-	/* Now, flush the first 4MB of memory */
-	lis	r4,0x0002
-	mtctr	r4
-	li	r4,0
-	sync
-1:
-	dcbf	r0,r4
-	addi	r4,r4,32		/* Go to start of next cache line */
-	bdnz	1b
-
-2:
-	/* Set up the L2CR configuration bits (and switch L2 off) */
-	sync
-	mtspr	L2CR,r3
-	sync
-
-	/* Before we perform the global invalidation, we must disable dynamic
-	 * power management via HID0[DPM] to work around a processor bug where
-	 * DPM can possibly interfere with the state machine in the processor
-	 * that invalidates the L2 cache tags.
-	 */
-	mfspr	r8,HID0			/* Save HID0 in r8 */
-	rlwinm	r4,r8,0,12,10		/* Turn off HID0[DPM] */
-	sync
-	mtspr	HID0,r4			/* Disable DPM */
-	sync
-
-	/* Perform a global invalidation */
-	oris	r3,r3,0x0020
-	sync
-	mtspr	L2CR,r3
-	sync
-	isync				/* For errata */
-
-	/* Wait for the invalidation to complete */
-3:	mfspr	r3,L2CR
-	rlwinm.	r4,r3,0,31,31
-	bne	3b
-	
-	rlwinm	r3,r3,0,11,9		/* Turn off the L2I bit */
-	sync
-	mtspr	L2CR,r3
-	sync
-	
-	/* Restore HID0[DPM] to whatever it was before */
-	sync
-	mtspr	1008,r8
-	sync
-
-	/* See if we need to enable the cache */
-	cmplwi	r5,0
-	beq	4f
-
-	/* Enable the cache */
-	oris	r3,r3,0x8000
-	mtspr	L2CR,r3
-	sync
-
-	/* Restore MSR (restores EE and DR bits to original state) */
-4:	SYNC
-	mtmsr	r7
-	isync
-	blr
-
-99:	li	r3,-1
-	blr
-
-_GLOBAL(_get_L2CR)
-	/* Make sure this is a 750 chip */
-	mfspr	r3,PVR
-	srwi	r3,r3,16
-	cmpwi	r3,0x0008
-	cmpwi	cr1,r3,0x000c
-	li	r3,0
-	cror	2,2,4*cr1+2
-	bnelr
-	/* Return the L2CR contents */
-	mfspr	r3,L2CR
-	blr
-
-/* --- End of PowerLogix code ---
- */
-
-/*
-_GLOBAL(_get_L2CR)
-	mfspr	r3,L2CR
-	blr
-
-_GLOBAL(_set_L2CR)
-	mtspr	L2CR,r3
-	blr
-		
-*/
-
 /*
  * These are used in the alignment trap handler when emulating
  * single-precision loads and stores.
@@ -1099,7 +874,7 @@
 	mr	r3,r4	        /* load arg and call fn */
 	blrl
 	li	r0,__NR_exit	/* exit after child exits */
-        li	r3,0
+	li	r3,0
 	sc
 
 /*
@@ -1279,7 +1054,7 @@
 	.long sys_setfsuid
 	.long sys_setfsgid
 	.long sys_llseek	/* 140 */
-        .long sys_getdents
+	.long sys_getdents
 	.long ppc_select
 	.long sys_flock
 	.long sys_msync
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/mk_defs.c linux/arch/ppc/kernel/mk_defs.c
--- v2.4.9/linux/arch/ppc/kernel/mk_defs.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/ppc/kernel/mk_defs.c	Tue Aug 28 06:58:33 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.mk_defs.c 1.8 06/28/01 15:50:16 paulus
+ * BK Id: SCCS/s.mk_defs.c 1.11 08/19/01 22:43:23 paulus
  */
 /*
  * This program is used to generate definitions needed by
@@ -26,6 +26,7 @@
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/processor.h>
+#include <asm/cputable.h>
 
 #define DEFINE(sym, val) \
 	asm volatile("\n#define\t" #sym "\t%0" : : "i" (val))
@@ -118,5 +119,14 @@
 	DEFINE(TRAP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, trap));
 	DEFINE(CLONE_VM, CLONE_VM);
 	DEFINE(MM_PGD, offsetof(struct mm_struct, pgd));
+
+	/* About the CPU features table */
+	DEFINE(CPU_SPEC_ENTRY_SIZE, sizeof(struct cpu_spec));
+	DEFINE(CPU_SPEC_PVR_MASK, offsetof(struct cpu_spec, pvr_mask));
+	DEFINE(CPU_SPEC_PVR_VALUE, offsetof(struct cpu_spec, pvr_value));
+	DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features));
+	DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup));
+
+	DEFINE(NUM_USER_SEGMENTS, TASK_SIZE>>28);
 	return 0;
 }
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/oak_setup.c linux/arch/ppc/kernel/oak_setup.c
--- v2.4.9/linux/arch/ppc/kernel/oak_setup.c	Mon May 21 17:04:47 2001
+++ linux/arch/ppc/kernel/oak_setup.c	Tue Aug 28 06:58:33 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.oak_setup.c 1.5 05/17/01 18:14:21 cort
+ * BK Id: SCCS/s.oak_setup.c 1.8 08/15/01 21:48:38 paulus
  */
 /*
  *
@@ -74,8 +74,8 @@
  *
  */
 void __init
-oak_init(unsigned long r3, unsigned long r4, unsigned long r5, 
-	 unsigned long r6, unsigned long r7)
+platform_init(unsigned long r3, unsigned long r4, unsigned long r5, 
+	      unsigned long r6, unsigned long r7)
 {
 	/*
 	 * If we were passed in a board information, copy it into the
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/open_pic.c linux/arch/ppc/kernel/open_pic.c
--- v2.4.9/linux/arch/ppc/kernel/open_pic.c	Mon May 21 17:04:47 2001
+++ linux/arch/ppc/kernel/open_pic.c	Sat Sep  8 12:38:41 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.open_pic.c 1.20 05/17/01 18:14:21 cort
+ * BK Id: SCCS/s.open_pic.c 1.28 09/08/01 15:47:42 paulus
  */
 /*
  *  arch/ppc/kernel/open_pic.c -- OpenPIC Interrupt Handling
@@ -17,11 +17,13 @@
 #include <linux/sched.h>
 #include <linux/init.h>
 #include <linux/irq.h>
+#include <linux/init.h>
 #include <asm/ptrace.h>
 #include <asm/signal.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/prom.h>
+#include <asm/sections.h>
 
 #include "local_irq.h"
 #include "open_pic.h"
@@ -47,8 +49,6 @@
 
 /* Global Operations */
 static void openpic_disable_8259_pass_through(void);
-static u_int openpic_irq(void);
-static void openpic_eoi(void);
 static void openpic_set_priority(u_int pri);
 static void openpic_set_spurious(u_int vector);
 
@@ -73,8 +73,8 @@
  * These functions are not used but the code is kept here
  * for completeness and future reference.
  */
-#ifdef notused
 static void openpic_reset(void);
+#ifdef notused
 static void openpic_enable_8259_pass_through(void);
 static u_int openpic_get_priority(void);
 static u_int openpic_get_spurious(void);
@@ -412,13 +412,16 @@
 #endif
 }
 
-#ifdef notused
 static void openpic_reset(void)
 {
 	openpic_setfield(&OpenPIC->Global.Global_Configuration0,
 			 OPENPIC_CONFIG_RESET);
+	while (openpic_readfield(&OpenPIC->Global.Global_Configuration0,
+				 OPENPIC_CONFIG_RESET))
+		mb();
 }
 
+#ifdef notused
 static void openpic_enable_8259_pass_through(void)
 {
 	openpic_clearfield(&OpenPIC->Global.Global_Configuration0,
@@ -435,7 +438,7 @@
 /*
  *  Find out the current interrupt
  */
-static u_int openpic_irq(void)
+u_int openpic_irq(void)
 {
 	u_int vec;
 	DECL_THIS_CPU;
@@ -446,7 +449,7 @@
 	return vec;
 }
 
-static void openpic_eoi(void)
+void openpic_eoi(void)
 {
 	DECL_THIS_CPU;
 
@@ -518,6 +521,8 @@
 		      physmask(cpumask));
 }
 
+static spinlock_t openpic_setup_lock = SPIN_LOCK_UNLOCKED;
+
 #ifdef CONFIG_SMP
 /*
  *  Initialize an interprocessor interrupt (and disable it)
@@ -583,7 +588,6 @@
  * Get IPI's working and start taking interrupts.
  *   -- Cort
  */
-static spinlock_t openpic_setup_lock __initdata = SPIN_LOCK_UNLOCKED;
 
 void __init do_openpic_setup_cpu(void)
 {
@@ -802,11 +806,87 @@
 #endif
 		openpic_eoi();
         }
-	if (irq == OPENPIC_VEC_SPURIOUS + open_pic_irq_offset) {
+	if (irq == OPENPIC_VEC_SPURIOUS + open_pic_irq_offset)
 		irq = -1;
-		/* That's not SMP safe ... but who cares ? */
-		ppc_spurious_interrupts++;
-	}
 	return irq;
 }
 
+#ifdef CONFIG_SMP
+void
+smp_openpic_message_pass(int target, int msg, unsigned long data, int wait)
+{
+	/* make sure we're sending something that translates to an IPI */
+	if (msg > 0x3) {
+		printk("SMP %d: smp_message_pass: unknown msg %d\n",
+		       smp_processor_id(), msg);
+		return;
+	}
+	switch (target) {
+	case MSG_ALL:
+		openpic_cause_IPI(msg, 0xffffffff);
+		break;
+	case MSG_ALL_BUT_SELF:
+		openpic_cause_IPI(msg,
+				  0xffffffff & ~(1 << smp_processor_id()));
+		break;
+	default:
+		openpic_cause_IPI(msg, 1<<target);
+		break;
+	}
+}
+#endif /* CONFIG_SMP */
+
+#ifdef CONFIG_PMAC_PBOOK
+static u32 save_ipi_vp[OPENPIC_NUM_IPI];
+static u32 save_irq_src_vp[OPENPIC_MAX_SOURCES];
+static u32 save_irq_src_dest[OPENPIC_MAX_SOURCES];
+static u32 save_cpu_task_pri[OPENPIC_MAX_PROCESSORS];
+
+void __pmac
+openpic_sleep_save_intrs(void)
+{
+	int	i;
+	unsigned long flags;
+	
+	spin_lock_irqsave(&openpic_setup_lock, flags);
+
+	for (i=0; i<NumProcessors; i++) {
+		save_cpu_task_pri[i] = openpic_read(&OpenPIC->Processor[i].Current_Task_Priority);
+		openpic_writefield(&OpenPIC->Processor[i].Current_Task_Priority,
+				   OPENPIC_CURRENT_TASK_PRIORITY_MASK, 0xf);
+	}
+
+	for (i=0; i<OPENPIC_NUM_IPI; i++)
+		save_ipi_vp[i] = openpic_read(&OpenPIC->Global.IPI_Vector_Priority(i));
+	for (i=0; i<NumSources; i++) {
+		save_irq_src_vp[i] = openpic_read(&OpenPIC->Source[i].Vector_Priority)
+			& ~OPENPIC_ACTIVITY;
+		save_irq_src_dest[i] = openpic_read(&OpenPIC->Source[i].Destination);
+	}
+	spin_unlock_irqrestore(&openpic_setup_lock, flags);
+}
+
+void __pmac
+openpic_sleep_restore_intrs(void)
+{
+	int		i;
+	unsigned long	flags;
+
+	spin_lock_irqsave(&openpic_setup_lock, flags);
+	
+	openpic_reset();
+
+	for (i=0; i<OPENPIC_NUM_IPI; i++)
+		openpic_write(&OpenPIC->Global.IPI_Vector_Priority(i), save_ipi_vp[i]);
+	for (i=0; i<NumSources; i++) {
+		openpic_write(&OpenPIC->Source[i].Vector_Priority, save_irq_src_vp[i]);
+		openpic_write(&OpenPIC->Source[i].Destination, save_irq_src_dest[i]);
+	}
+	openpic_set_spurious(OPENPIC_VEC_SPURIOUS+open_pic_irq_offset);
+	openpic_disable_8259_pass_through();
+	for (i=0; i<NumProcessors; i++)
+		openpic_write(&OpenPIC->Processor[i].Current_Task_Priority, save_cpu_task_pri[i]);
+
+	spin_unlock_irqrestore(&openpic_setup_lock, flags);
+}
+#endif /* CONFIG_PMAC_PBOOK */
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/open_pic.h linux/arch/ppc/kernel/open_pic.h
--- v2.4.9/linux/arch/ppc/kernel/open_pic.h	Mon May 21 17:04:47 2001
+++ linux/arch/ppc/kernel/open_pic.h	Tue Aug 28 06:58:33 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.open_pic.h 1.8 05/17/01 18:14:21 cort
+ * BK Id: SCCS/s.open_pic.h 1.12 08/20/01 22:33:28 paulus
  */
 /*
  *  arch/ppc/kernel/open_pic.h -- OpenPIC Interrupt Handling
@@ -19,6 +19,14 @@
 
 #define OPENPIC_SIZE	0x40000
 
+/*
+ *  Non-offset'ed vector numbers
+ */
+
+#define OPENPIC_VEC_TIMER	64	/* and up */
+#define OPENPIC_VEC_IPI		72	/* and up */
+#define OPENPIC_VEC_SPURIOUS	127
+
 /* OpenPIC IRQ controller structure */
 extern struct hw_interrupt_type open_pic;
 
@@ -33,16 +41,28 @@
 
 /* Exported functions */
 extern void openpic_init(int, int, unsigned char *, int);
+extern u_int openpic_irq(void);
+extern void openpic_eoi(void);
 extern void openpic_request_IPIs(void);
 extern void do_openpic_setup_cpu(void);
 extern int openpic_get_irq(struct pt_regs *regs);
 extern void openpic_init_processor(u_int cpumask);
 extern void openpic_setup_ISU(int isu_num, unsigned long addr);
 extern void openpic_cause_IPI(u_int ipi, u_int cpumask);
+extern void smp_openpic_message_pass(int target, int msg, unsigned long data,
+				     int wait);
 
 extern inline int openpic_to_irq(int irq)
 {
-	return irq += NUM_8259_INTERRUPTS;
+	/* IRQ 0 usually means 'disabled'.. don't mess with it 
+	 * exceptions to this (sandpoint maybe?) 
+	 * shouldn't use openpic_to_irq 
+	 */
+	if (irq != 0){
+		return irq += NUM_8259_INTERRUPTS;
+	} else {
+		return 0;
+	}
 }
 /*extern int open_pic_irq_offset;*/
 #endif /* _PPC_KERNEL_OPEN_PIC_H */
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/open_pic_defs.h linux/arch/ppc/kernel/open_pic_defs.h
--- v2.4.9/linux/arch/ppc/kernel/open_pic_defs.h	Mon May 21 17:04:47 2001
+++ linux/arch/ppc/kernel/open_pic_defs.h	Tue Aug 28 06:58:33 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.open_pic_defs.h 1.7 05/17/01 18:14:21 cort
+ * BK Id: SCCS/s.open_pic_defs.h 1.8 08/20/01 22:33:28 paulus
  */
 /*
  *  linux/openpic.h -- OpenPIC definitions
@@ -44,14 +44,6 @@
 #define OPENPIC_NUM_PRI		16
 #define OPENPIC_NUM_VECTORS	256
 
-
-    /*
-     *  Non-offset'ed vector numbers
-     */
-
-#define OPENPIC_VEC_TIMER       64    /* and up */
-#define OPENPIC_VEC_IPI         72    /* and up */
-#define OPENPIC_VEC_SPURIOUS    127
 
 
     /*
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/pmac_backlight.c linux/arch/ppc/kernel/pmac_backlight.c
--- v2.4.9/linux/arch/ppc/kernel/pmac_backlight.c	Mon May 21 17:04:47 2001
+++ linux/arch/ppc/kernel/pmac_backlight.c	Sat Sep  8 12:38:41 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.pmac_backlight.c 1.5 05/17/01 18:14:21 cort
+ * BK Id: SCCS/s.pmac_backlight.c 1.8 09/08/01 15:47:42 paulus
  */
 /*
  * Miscellaneous procedures for dealing with the PowerMac hardware.
@@ -14,7 +14,7 @@
 #include <linux/stddef.h>
 #include <linux/reboot.h>
 #include <linux/nvram.h>
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <asm/ptrace.h>
 #include <asm/io.h>
 #include <asm/pgtable.h>
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/pmac_nvram.c linux/arch/ppc/kernel/pmac_nvram.c
--- v2.4.9/linux/arch/ppc/kernel/pmac_nvram.c	Mon Aug 27 12:41:39 2001
+++ linux/arch/ppc/kernel/pmac_nvram.c	Sat Sep  8 12:38:41 2001
@@ -1,17 +1,18 @@
 /*
- * BK Id: SCCS/s.pmac_nvram.c 1.10 08/08/01 16:23:35 paulus
+ * BK Id: SCCS/s.pmac_nvram.c 1.15 09/08/01 15:47:42 paulus
  */
 /*
  * Miscellaneous procedures for dealing with the PowerMac hardware.
  */
 #include <linux/config.h>
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/stddef.h>
 #include <linux/nvram.h>
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <asm/io.h>
 #include <asm/system.h>
 #include <asm/prom.h>
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/pmac_pci.c linux/arch/ppc/kernel/pmac_pci.c
--- v2.4.9/linux/arch/ppc/kernel/pmac_pci.c	Mon Aug 27 12:41:39 2001
+++ linux/arch/ppc/kernel/pmac_pci.c	Sat Sep  8 12:38:41 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.pmac_pci.c 1.22 08/08/01 16:35:43 paulus
+ * BK Id: SCCS/s.pmac_pci.c 1.27 09/08/01 15:47:42 paulus
  */
 /*
  * Support for PCI bridges found on Power Macintoshes.
@@ -22,7 +22,7 @@
 #include <linux/init.h>
 #include <linux/bootmem.h>
 
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <asm/io.h>
 #include <asm/prom.h>
 #include <asm/pci-bridge.h>
@@ -528,6 +528,7 @@
 pmac_pci_enable_device_hook(struct pci_dev *dev, int initial)
 {
 	struct device_node* node;
+	int updatecfg = 0;
 
 	node = pci_device_to_OF_node(dev);
 
@@ -538,14 +539,40 @@
 	    && dev->device == PCI_DEVICE_ID_APPLE_KL_USB && !node)
 		return -EINVAL;
 		
-	/* Firewire was disabled after PCI probe, the driver is claiming it,
-	 * so we must re-enable it now, at least until the driver can do it
-	 * itself.
+	/* Firewire & GMAC were disabled after PCI probe, the driver is
+	 * claiming them, we must re-enable them now.
 	 */
 	if (node && !strcmp(node->name, "firewire") && 
-	    device_is_compatible(node, "pci106b,18")) {
+	    (device_is_compatible(node, "pci106b,18") || 
+	     device_is_compatible(node, "pci106b,30"))) {
 		feature_set_firewire_cable_power(node, 1);
 		feature_set_firewire_power(node, 1);
+		updatecfg = 1;
+	}
+	if (node && !strcmp(node->name, "ethernet") && 
+	    device_is_compatible(node, "gmac")) {
+		feature_set_gmac_power(node, 1);
+		updatecfg = 1;
+	}
+
+	if (updatecfg) {
+		u16 cmd;
+		
+		/*
+		 * Make sure PCI is correctly configured
+		 *
+		 * We use old pci_bios versions of the function since, by
+		 * default, gmac is not powered up, and so will be absent
+		 * from the kernel initial PCI lookup. 
+		 * 
+		 * Should be replaced by 2.4 new PCI mecanisms and really
+		 * regiser the device.
+		 */
+		pci_read_config_word(dev, PCI_COMMAND, &cmd);
+		cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE;
+    		pci_write_config_word(dev, PCI_COMMAND, cmd);
+    		pci_write_config_byte(dev, PCI_LATENCY_TIMER, 16);
+    		pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 8);
 	}
 	
 	return 0;
@@ -580,7 +607,8 @@
 
 	nd = find_devices("firewire");
 	while (nd) {
-		if (nd->parent && device_is_compatible(nd, "pci106b,18")
+		if (nd->parent && (device_is_compatible(nd, "pci106b,18") ||
+					device_is_compatible(nd, "pci106b,30"))
 		    && device_is_compatible(nd->parent, "uni-north")) {
 			feature_set_firewire_power(nd, 0);
 			feature_set_firewire_cable_power(nd, 0);
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/pmac_pic.c linux/arch/ppc/kernel/pmac_pic.c
--- v2.4.9/linux/arch/ppc/kernel/pmac_pic.c	Mon May 21 17:04:47 2001
+++ linux/arch/ppc/kernel/pmac_pic.c	Sat Sep  8 12:38:42 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.pmac_pic.c 1.14 05/17/01 18:14:21 cort
+ * BK Id: SCCS/s.pmac_pic.c 1.20 09/08/01 15:47:42 paulus
  */
 #include <linux/config.h>
 #include <linux/stddef.h>
@@ -8,7 +8,7 @@
 #include <linux/signal.h>
 #include <linux/pci.h>
 
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <asm/io.h>
 #include <asm/smp.h>
 #include <asm/prom.h>
@@ -35,7 +35,6 @@
 
 static int max_irqs;
 static int max_real_irqs;
-static int pmac_has_openpic;
 
 spinlock_t pmac_pic_lock = SPIN_LOCK_UNLOCKED;
 
@@ -291,17 +290,16 @@
  * controller.  If we find this second ohare, set it up and fix the
  * interrupt value in the device tree for the ethernet chip.
  */
-static void __init enable_second_ohare(void)
+static int __init enable_second_ohare(void)
 {
 	unsigned char bus, devfn;
 	unsigned short cmd;
         unsigned long addr;
-	int second_irq;
 	struct device_node *irqctrler = find_devices("pci106b,7");
 	struct device_node *ether;
 
 	if (irqctrler == NULL || irqctrler->n_addrs <= 0)
-		return;
+		return -1;
 	addr = (unsigned long) ioremap(irqctrler->addrs[0].address, 0x40);
 	pmac_irq_hw[1] = (volatile struct pmac_irq_hw *)(addr + 0x20);
 	max_irqs = 64;
@@ -317,11 +315,6 @@
 		}
 	}
 
-	second_irq = irqctrler->intrs[0].line;
-	printk(KERN_INFO "irq: secondary controller on irq %d\n", second_irq);
-	request_irq(second_irq, gatwick_action, SA_INTERRUPT,
-		    "interrupt cascade", 0 );
-
 	/* Fix interrupt for the modem/ethernet combo controller. The number
 	   in the device tree (27) is bogus (correct for the ethernet-only
 	   board but not the combo ethernet/modem board).
@@ -333,6 +326,9 @@
 		printk(KERN_INFO "irq: Fixed ethernet IRQ to %d\n",
 		       ether->intrs[0].line);
 	}
+
+	/* Return the interrupt number of the cascade */
+	return irqctrler->intrs[0].line;
 }
 
 void __init
@@ -341,8 +337,8 @@
         int i;
         struct device_node *irqctrler;
         unsigned long addr;
-	int second_irq = -999;
-
+	int irq_cascade = -1;
+	
 	/* We first try to detect Apple's new Core99 chipset, since mac-io
 	 * is quite different on those machines and contains an IBM MPIC2.
 	 */
@@ -368,7 +364,6 @@
 			OpenPIC_Addr = ioremap(irqctrler->addrs[0].address,
 					       irqctrler->addrs[0].size);
 			openpic_init(1, 0, 0, nmi_irq);
-			pmac_has_openpic = 1;
 #ifdef CONFIG_XMON
 			if (nmi_irq >= 0)
 				request_irq(nmi_irq, xmon_irq, 0,
@@ -418,6 +413,9 @@
 			for (i = 2; i < 4; ++i)
 				pmac_irq_hw[i] = (volatile struct pmac_irq_hw*)
 					(addr + (4 - i) * 0x10);
+			irq_cascade = irqctrler->intrs[0].line;
+			if (device_is_compatible(irqctrler, "gatwick"))
+				pmac_fix_gatwick_interrupts(irqctrler, max_real_irqs);
 		}
 	} else {
 		/* older powermacs have a GC (grand central) or ohare at
@@ -430,23 +428,20 @@
 	   ohare chip, on the combo ethernet/modem card */
 	if (machine_is_compatible("AAPL,3400/2400")
 	     || machine_is_compatible("AAPL,3500"))
-		enable_second_ohare();
+		irq_cascade = enable_second_ohare();
 
 	/* disable all interrupts in all controllers */
 	for (i = 0; i * 32 < max_irqs; ++i)
 		out_le32(&pmac_irq_hw[i]->enable, 0);
 	
 	/* get interrupt line of secondary interrupt controller */
-	if (irqctrler) {
-		second_irq = irqctrler->intrs[0].line;
+	if (irq_cascade >= 0) {
 		printk(KERN_INFO "irq: secondary controller on irq %d\n",
-			(int)second_irq);
-		if (device_is_compatible(irqctrler, "gatwick"))
-			pmac_fix_gatwick_interrupts(irqctrler, max_real_irqs);
+			(int)irq_cascade);
 		for ( i = max_real_irqs ; i < max_irqs ; i++ )
 			irq_desc[i].handler = &gatwick_pic;
-		request_irq( second_irq, gatwick_action, SA_INTERRUPT,
-			     "gatwick cascade", 0 );
+		request_irq( irq_cascade, gatwick_action, SA_INTERRUPT,
+			     "cascade", 0 );
 	}
 	printk("System has %d possible interrupts\n", max_irqs);
 	if (max_irqs != max_real_irqs)
@@ -467,14 +462,15 @@
  */
 unsigned int sleep_save_mask[2];
 
-void
-sleep_save_intrs(int viaint)
+void __pmac
+pmac_sleep_save_intrs(int viaint)
 {
 	sleep_save_mask[0] = ppc_cached_irq_mask[0];
 	sleep_save_mask[1] = ppc_cached_irq_mask[1];
 	ppc_cached_irq_mask[0] = 0;
 	ppc_cached_irq_mask[1] = 0;
-	set_bit(viaint, ppc_cached_irq_mask);
+	if (viaint > 0)
+		set_bit(viaint, ppc_cached_irq_mask);
 	out_le32(&pmac_irq_hw[0]->enable, ppc_cached_irq_mask[0]);
 	if (max_real_irqs > 32)
 		out_le32(&pmac_irq_hw[1]->enable, ppc_cached_irq_mask[1]);
@@ -484,8 +480,8 @@
         (void)in_le32(&pmac_irq_hw[0]->enable);
 }
 
-void
-sleep_restore_intrs(void)
+void __pmac
+pmac_sleep_restore_intrs(void)
 {
 	int i;
 
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/pmac_pic.h linux/arch/ppc/kernel/pmac_pic.h
--- v2.4.9/linux/arch/ppc/kernel/pmac_pic.h	Mon May 21 17:04:47 2001
+++ linux/arch/ppc/kernel/pmac_pic.h	Tue Aug 28 06:58:33 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.pmac_pic.h 1.5 05/17/01 18:14:21 cort
+ * BK Id: SCCS/s.pmac_pic.h 1.9 08/19/01 22:23:04 paulus
  */
 #ifndef _PPC_KERNEL_PMAC_PIC_H
 #define _PPC_KERNEL_PMAC_PIC_H
@@ -10,6 +10,5 @@
 
 void pmac_pic_init(void);
 int pmac_get_irq(struct pt_regs *regs);
-void pmac_post_irq(int);
 
 #endif /* _PPC_KERNEL_PMAC_PIC_H */
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/pmac_setup.c linux/arch/ppc/kernel/pmac_setup.c
--- v2.4.9/linux/arch/ppc/kernel/pmac_setup.c	Mon Aug 27 12:41:39 2001
+++ linux/arch/ppc/kernel/pmac_setup.c	Sat Sep  8 12:38:42 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.pmac_setup.c 1.24 07/06/01 14:49:51 trini
+ * BK Id: SCCS/s.pmac_setup.c 1.39 09/08/01 15:47:42 paulus
  */
 /*
  *  linux/arch/ppc/kernel/setup.c
@@ -51,7 +51,7 @@
 #include <linux/pmu.h>
 
 #include <asm/processor.h>
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <asm/prom.h>
 #include <asm/system.h>
 #include <asm/pgtable.h>
@@ -65,6 +65,8 @@
 #include <asm/keyboard.h>
 #include <asm/dma.h>
 #include <asm/bootx.h>
+#include <asm/cputable.h>
+#include <asm/btext.h>
 
 #include <asm/time.h>
 #include "local_irq.h"
@@ -133,13 +135,16 @@
 sys_ctrler_t sys_ctrler = SYS_CTRLER_UNKNOWN;
 
 #ifdef CONFIG_SMP
+extern struct smp_ops_t psurge_smp_ops;
+extern struct smp_ops_t core99_smp_ops;
+
 volatile static long int core99_l2_cache;
-void __pmac
+void __init
 core99_init_l2(void)
 {
 	int cpu = smp_processor_id();
 
-	if ( (_get_PVR() >> 16) != 8 && (_get_PVR() >> 16) != 12 )
+	if (!(cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR))
 		return;
 
 	if (cpu == 0){
@@ -277,6 +282,9 @@
 {
 	struct device_node *cpu;
 	int *fp;
+	unsigned long pvr;
+	
+	pvr = PVR_VER(mfspr(PVR));
 
 	/* Set loops_per_jiffy to a half-way reasonable value,
 	   for use until calibrate_delay gets called. */
@@ -284,18 +292,12 @@
 	if (cpu != 0) {
 		fp = (int *) get_property(cpu, "clock-frequency", NULL);
 		if (fp != 0) {
-			switch (_get_PVR() >> 16) {
-			case 4:		/* 604 */
-			case 8:		/* G3 */
-			case 9:		/* 604e */
-			case 10:	/* mach V (604ev5) */
-			case 12:	/* G4 */
-			case 20:	/* 620 */
+			if (pvr == 4 || pvr >= 8)
+				/* 604, G3, G4 etc. */
 				loops_per_jiffy = *fp / HZ;
-				break;
-			default:	/* 601, 603, etc. */
+			else
+				/* 601, 603, etc. */
 				loops_per_jiffy = *fp / (2*HZ);
-			}
 		} else
 			loops_per_jiffy = 50000000 / HZ;
 	}
@@ -303,14 +305,13 @@
 	/* this area has the CPU identification register
 	   and some registers used by smp boards */
 	sysctrl_regs = (volatile u32 *) ioremap(0xf8000000, 0x1000);
-	__ioremap(0xffc00000, 0x400000, pgprot_val(PAGE_READONLY));
 	ohare_init();
 
 	/* Lookup PCI hosts */
 	pmac_find_bridges();
 	
 	/* Checks "l2cr-value" property in the registry */
-	if ( (_get_PVR() >> 16) == 8 || (_get_PVR() >> 16) == 12 ) {
+	if (cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR) {
 		struct device_node *np = find_devices("cpus");		
 		if (np == 0)
 			np = find_type_devices("cpu");		
@@ -342,9 +343,19 @@
 
 #ifdef CONFIG_ADB_CUDA
 	find_via_cuda();
+#else
+	if (find_devices("via-cuda")) {
+		printk("WARNING ! Your machine is Cuda based but your kernel\n");
+		printk("          wasn't compiled with CONFIG_ADB_CUDA option !\n");
+	}
 #endif	
 #ifdef CONFIG_ADB_PMU
 	find_via_pmu();
+#else
+	if (find_devices("via-pmu")) {
+		printk("WARNING ! Your machine is PMU based but your kernel\n");
+		printk("          wasn't compiled with CONFIG_ADB_PMU option !\n");
+	}
 #endif	
 #ifdef CONFIG_NVRAM
 	pmac_nvram_init();
@@ -361,6 +372,14 @@
 	else
 #endif
 		ROOT_DEV = to_kdev_t(DEFAULT_ROOT_DEVICE);
+
+#ifdef CONFIG_SMP
+	/* Check for Core99 */
+	if (find_devices("uni-n"))
+		ppc_md.smp_ops = &core99_smp_ops;
+	else
+		ppc_md.smp_ops = &psurge_smp_ops;
+#endif /* CONFIG_SMP */
 }
 
 static void __init ohare_init(void)
@@ -475,9 +494,11 @@
 	static int found_boot = 0;
 	char *p;
 
-	/* Do nothing if the root has been set already. */
+	/* Do nothing if the root has been mounted already. */
+	if (init_task.fs->rootmnt != NULL)
+		return;
 	if ((goodness <= current_root_goodness) &&
-		(ROOT_DEV != to_kdev_t(DEFAULT_ROOT_DEVICE)))
+	    (ROOT_DEV != to_kdev_t(DEFAULT_ROOT_DEVICE)))
 		return;
 	p = strstr(saved_command_line, "root=");
 	if (p != NULL && (p == saved_command_line || p[-1] == ' '))
@@ -563,41 +584,7 @@
 /*
  * IDE stuff.
  */
-void __pmac
-pmac_ide_insw(ide_ioreg_t port, void *buf, int ns)
-{
-	_insw_ns((unsigned short *)(port+_IO_BASE), buf, ns);
-}
-
-void __pmac
-pmac_ide_outsw(ide_ioreg_t port, void *buf, int ns)
-{
-	_outsw_ns((unsigned short *)(port+_IO_BASE), buf, ns);
-}
-
-int __pmac
-pmac_ide_default_irq(ide_ioreg_t base)
-{
-#if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC)
-	extern int pmac_ide_get_irq(ide_ioreg_t base);
-        return pmac_ide_get_irq(base);
-#else
-	return 0;
-#endif
-}
-
-ide_ioreg_t __pmac
-pmac_ide_default_io_base(int index)
-{
-#if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC)
-	extern ide_ioreg_t pmac_ide_get_base(int index);
-        return pmac_ide_get_base(index);
-#else
-	return 0;
-#endif
-}
-
-int __pmac
+static int __pmac
 pmac_ide_check_region(ide_ioreg_t from, unsigned int extent)
 {
 	/*
@@ -606,11 +593,11 @@
 	 * register, it should be OK.
 	 */
 	if (from < ~_IO_BASE)
-		return 0;
-	return check_region(from, extent);
+		return check_region(from, extent);
+	return 0;
 }
 
-void __pmac
+static void __pmac
 pmac_ide_request_region(ide_ioreg_t from,
 			unsigned int extent,
 			const char *name)
@@ -619,7 +606,7 @@
 		request_region(from, extent, name);
 }
 
-void __pmac
+static void __pmac
 pmac_ide_release_region(ide_ioreg_t from,
 			unsigned int extent)
 {
@@ -627,21 +614,24 @@
 		release_region(from, extent);
 }
 
-#if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC)
-/* This is declared in drivers/block/ide-pmac.c */
-void __pmac
-pmac_ide_init_hwif_ports (hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq);
-#else
 /*
- * This registers the standard ports for this architecture with the IDE
- * driver.
+ * This is only used if we have a PCI IDE controller, not
+ * for the IDE controller in the ohare/paddington/heathrow/keylargo.
  */
-void __pmac
-pmac_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq)
+static void __pmac
+pmac_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;
+	}
+	hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
 }
 #endif
-#endif
 
 /*
  * Read in a property describing some pieces of memory.
@@ -728,39 +718,8 @@
 }
 
 void __init
-pmac_init(unsigned long r3, unsigned long r4, unsigned long r5,
-	  unsigned long r6, unsigned long r7)
+select_adb_keyboard(void)
 {
-	/* isa_io_base gets set in pmac_find_bridges */
-	isa_mem_base = PMAC_ISA_MEM_BASE;
-	pci_dram_offset = PMAC_PCI_DRAM_OFFSET;
-	ISA_DMA_THRESHOLD = ~0L;
-	DMA_MODE_READ = 1;
-	DMA_MODE_WRITE = 2;
-
-	ppc_md.setup_arch     = pmac_setup_arch;
-	ppc_md.setup_residual = NULL;
-	ppc_md.get_cpuinfo    = pmac_get_cpuinfo;
-	ppc_md.irq_cannonicalize = NULL;
-	ppc_md.init_IRQ       = pmac_pic_init;
-	ppc_md.get_irq        = pmac_get_irq; /* Changed later on ... */
-	ppc_md.init           = pmac_init2;
-	
-	ppc_md.pcibios_fixup  = pmac_pcibios_fixup;
-	ppc_md.pcibios_enable_device_hook = pmac_pci_enable_device_hook;
-	ppc_md.pcibios_after_init = pmac_pcibios_after_init;
-
-	ppc_md.restart        = pmac_restart;
-	ppc_md.power_off      = pmac_power_off;
-	ppc_md.halt           = pmac_halt;
-
-	ppc_md.time_init      = pmac_time_init;
-	ppc_md.set_rtc_time   = pmac_set_rtc_time;
-	ppc_md.get_rtc_time   = pmac_get_rtc_time;
-	ppc_md.calibrate_decr = pmac_calibrate_decr;
-
-	ppc_md.find_end_of_memory = pmac_find_end_of_memory;
-
 #ifdef CONFIG_VT
 #ifdef CONFIG_INPUT
 	ppc_md.kbd_init_hw       = mac_hid_init_hw;
@@ -768,6 +727,7 @@
 	ppc_md.kbd_unexpected_up = mac_hid_kbd_unexpected_up;
 	ppc_md.kbd_setkeycode    = 0;
 	ppc_md.kbd_getkeycode    = 0;
+	ppc_md.kbd_leds		 = 0;
 #ifdef CONFIG_MAGIC_SYSRQ
 #ifdef CONFIG_MAC_ADBKEYCODES
 	if (!keyboard_sends_linux_keycodes) {
@@ -793,21 +753,55 @@
 #endif /* CONFIG_MAGIC_SYSRQ */
 #endif /* CONFIG_INPUT_ADBHID/CONFIG_ADB_KEYBOARD */
 #endif /* CONFIG_VT */
+}
+
+void __init
+pmac_init(unsigned long r3, unsigned long r4, unsigned long r5,
+	  unsigned long r6, unsigned long r7)
+{
+	/* isa_io_base gets set in pmac_find_bridges */
+	isa_mem_base = PMAC_ISA_MEM_BASE;
+	pci_dram_offset = PMAC_PCI_DRAM_OFFSET;
+	ISA_DMA_THRESHOLD = ~0L;
+	DMA_MODE_READ = 1;
+	DMA_MODE_WRITE = 2;
+
+	ppc_md.setup_arch     = pmac_setup_arch;
+	ppc_md.setup_residual = NULL;
+	ppc_md.get_cpuinfo    = pmac_get_cpuinfo;
+	ppc_md.irq_cannonicalize = NULL;
+	ppc_md.init_IRQ       = pmac_pic_init;
+	ppc_md.get_irq        = pmac_get_irq; /* Changed later on ... */
+	ppc_md.init           = pmac_init2;
+	
+	ppc_md.pcibios_fixup  = pmac_pcibios_fixup;
+	ppc_md.pcibios_enable_device_hook = pmac_pci_enable_device_hook;
+	ppc_md.pcibios_after_init = pmac_pcibios_after_init;
+
+	ppc_md.restart        = pmac_restart;
+	ppc_md.power_off      = pmac_power_off;
+	ppc_md.halt           = pmac_halt;
+
+	ppc_md.time_init      = pmac_time_init;
+	ppc_md.set_rtc_time   = pmac_set_rtc_time;
+	ppc_md.get_rtc_time   = pmac_get_rtc_time;
+	ppc_md.calibrate_decr = pmac_calibrate_decr;
+
+	ppc_md.find_end_of_memory = pmac_find_end_of_memory;
+
+	select_adb_keyboard();
 
 #if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC)
-        ppc_ide_md.insw			= pmac_ide_insw;
-        ppc_ide_md.outsw		= pmac_ide_outsw;
-        ppc_ide_md.default_irq		= pmac_ide_default_irq;
-        ppc_ide_md.default_io_base	= pmac_ide_default_io_base;
         ppc_ide_md.ide_check_region	= pmac_ide_check_region;
         ppc_ide_md.ide_request_region	= pmac_ide_request_region;
         ppc_ide_md.ide_release_region	= pmac_ide_release_region;
-        ppc_ide_md.fix_driveid		= ppc_generic_ide_fix_driveid;
         ppc_ide_md.ide_init_hwif	= pmac_ide_init_hwif_ports;
 #endif /* CONFIG_BLK_DEV_IDE && CONFIG_BLK_DEV_IDE_PMAC */
+
 #ifdef CONFIG_BOOTX_TEXT
 	ppc_md.progress = pmac_progress;
 #endif /* CONFIG_BOOTX_TEXT */
+
 	if (ppc_md.progress) ppc_md.progress("pmac_init(): exit", 0);
 	
 }
@@ -821,7 +815,7 @@
 {
 	if (disp_bi == 0)
 		return;
-	prom_drawstring(s);
-	prom_drawchar('\n');
+	btext_drawstring(s);
+	btext_drawchar('\n');
 }
 #endif /* CONFIG_BOOTX_TEXT */
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/pmac_smp.c linux/arch/ppc/kernel/pmac_smp.c
--- v2.4.9/linux/arch/ppc/kernel/pmac_smp.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/kernel/pmac_smp.c	Sat Sep  8 12:38:42 2001
@@ -0,0 +1,489 @@
+/*
+ * BK Id: %F% %I% %G% %U% %#%
+ */
+/*
+ * SMP support for power macintosh.
+ *
+ * We support both the old "powersurge" SMP architecture
+ * and the current Core99 (G4 PowerMac) machines.
+ *
+ * Support Macintosh G4 SMP by Troy Benjegerdes (hozer@drgw.net)
+ * and Ben Herrenschmidt <benh@kernel.crashing.org>.
+ *
+ * Support for DayStar quad CPU cards
+ * Copyright (C) XLR8, Inc. 1994-2000
+ *
+ *  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/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/delay.h>
+#define __KERNEL_SYSCALLS__
+#include <linux/unistd.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+
+#include <asm/ptrace.h>
+#include <asm/atomic.h>
+#include <asm/irq.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/hardirq.h>
+#include <asm/softirq.h>
+#include <asm/sections.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/smp.h>
+#include <asm/residual.h>
+#include <asm/feature.h>
+#include <asm/time.h>
+#include <asm/gemini.h>
+
+#include "open_pic.h"
+
+/*
+ * Powersurge (old powermac SMP) support.
+ */
+
+extern void __secondary_start_psurge(void);
+extern void __secondary_start_psurge2(void);	/* Temporary horrible hack */
+extern void __secondary_start_psurge3(void);	/* Temporary horrible hack */
+
+/* Addresses for powersurge registers */
+#define HAMMERHEAD_BASE		0xf8000000
+#define HHEAD_CONFIG		0x90
+#define HHEAD_SEC_INTR		0xc0
+
+/* register for interrupting the primary processor on the powersurge */
+/* N.B. this is actually the ethernet ROM! */
+#define PSURGE_PRI_INTR		0xf3019000
+
+/* register for storing the start address for the secondary processor */
+/* N.B. this is the PCI config space address register for the 1st bridge */
+#define PSURGE_START		0xf2800000
+
+/* Daystar/XLR8 4-CPU card */
+#define PSURGE_QUAD_REG_ADDR	0xf8800000
+
+#define PSURGE_QUAD_IRQ_SET	0
+#define PSURGE_QUAD_IRQ_CLR	1
+#define PSURGE_QUAD_IRQ_PRIMARY	2
+#define PSURGE_QUAD_CKSTOP_CTL	3
+#define PSURGE_QUAD_PRIMARY_ARB	4
+#define PSURGE_QUAD_BOARD_ID	6
+#define PSURGE_QUAD_WHICH_CPU	7
+#define PSURGE_QUAD_CKSTOP_RDBK	8
+#define PSURGE_QUAD_RESET_CTL	11
+
+#define PSURGE_QUAD_OUT(r, v)	(out_8(quad_base + ((r) << 4) + 4, (v)))
+#define PSURGE_QUAD_IN(r)	(in_8(quad_base + ((r) << 4) + 4) & 0x0f)
+#define PSURGE_QUAD_BIS(r, v)	(PSURGE_QUAD_OUT((r), PSURGE_QUAD_IN(r) | (v)))
+#define PSURGE_QUAD_BIC(r, v)	(PSURGE_QUAD_OUT((r), PSURGE_QUAD_IN(r) & ~(v)))
+
+/* virtual addresses for the above */
+static volatile u8 *hhead_base;
+static volatile u8 *quad_base;
+static volatile u32 *psurge_pri_intr;
+static volatile u8 *psurge_sec_intr;
+static volatile u32 *psurge_start;
+
+/* what sort of powersurge board we have */
+static int psurge_type;
+
+/* values for psurge_type */
+#define PSURGE_DUAL		0
+#define PSURGE_QUAD_OKEE	1
+#define PSURGE_QUAD_COTTON	2
+#define PSURGE_QUAD_ICEGRASS	3
+
+/* l2 cache stuff for dual G4 macs */
+extern void core99_init_l2(void);
+
+/*
+ * Set and clear IPIs for powersurge.
+ */
+static inline void psurge_set_ipi(int cpu)
+{
+	if (cpu == 0)
+		in_be32(psurge_pri_intr);
+	else if (psurge_type == PSURGE_DUAL)
+		out_8(psurge_sec_intr, 0);
+	else
+		PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_SET, 1 << cpu);
+}
+
+static inline void psurge_clr_ipi(int cpu)
+{
+	if (cpu > 0) {
+		if (psurge_type == PSURGE_DUAL)
+			out_8(psurge_sec_intr, ~0);
+		else
+			PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_CLR, 1 << cpu);
+	}
+}
+
+/*
+ * On powersurge (old SMP powermac architecture) we don't have
+ * separate IPIs for separate messages like openpic does.  Instead
+ * we have a bitmap for each processor, where a 1 bit means that
+ * the corresponding message is pending for that processor.
+ * Ideally each cpu's entry would be in a different cache line.
+ *  -- paulus.
+ */
+static unsigned long psurge_smp_message[NR_CPUS];
+
+void __pmac
+psurge_smp_message_recv(struct pt_regs *regs)
+{
+	int cpu = smp_processor_id();
+	int msg;
+
+	/* clear interrupt */
+	psurge_clr_ipi(cpu);
+
+	if (smp_num_cpus < 2)
+		return;
+
+	/* make sure there is a message there */
+	for (msg = 0; msg < 4; msg++)
+		if (test_and_clear_bit(msg, &psurge_smp_message[cpu]))
+			smp_message_recv(msg, regs);
+}
+
+void __pmac
+psurge_primary_intr(int irq, void *d, struct pt_regs *regs)
+{
+	psurge_smp_message_recv(regs);
+}
+
+static void __pmac
+smp_psurge_message_pass(int target, int msg, unsigned long data, int wait)
+{
+	int i;
+
+	if (smp_num_cpus < 2)
+		return;
+
+	for (i = 0; i < smp_num_cpus; i++) {
+		if (target == MSG_ALL
+		    || (target == MSG_ALL_BUT_SELF && i != smp_processor_id())
+		    || target == i) {
+			set_bit(msg, &psurge_smp_message[i]);
+			psurge_set_ipi(i);
+		}
+	}
+}
+
+/*
+ * Determine a quad card presence. We read the board ID register, we
+ * force the data bus to change to something else, and we read it again.
+ * It it's stable, then the register probably exist (ugh !)
+ */
+static int __init psurge_quad_probe(void)
+{
+	int type;
+	unsigned int i;
+
+	type = PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID);
+	if (type < PSURGE_QUAD_OKEE || type > PSURGE_QUAD_ICEGRASS
+	    || type != PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID))
+		return PSURGE_DUAL;
+
+	/* looks OK, try a slightly more rigorous test */
+	/* bogus is not necessarily cacheline-aligned,
+	   though I don't suppose that really matters.  -- paulus */
+	for (i = 0; i < 100; i++) {
+		volatile u32 bogus[8];
+		bogus[(0+i)%8] = 0x00000000;
+		bogus[(1+i)%8] = 0x55555555;
+		bogus[(2+i)%8] = 0xFFFFFFFF;
+		bogus[(3+i)%8] = 0xAAAAAAAA;
+		bogus[(4+i)%8] = 0x33333333;
+		bogus[(5+i)%8] = 0xCCCCCCCC;
+		bogus[(6+i)%8] = 0xCCCCCCCC;
+		bogus[(7+i)%8] = 0x33333333;
+		wmb();
+		asm volatile("dcbf 0,%0" : : "r" (bogus) : "memory");
+		mb();
+		if (type != PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID))
+			return PSURGE_DUAL;
+	}
+	return type;
+}
+
+static void __init psurge_quad_init(void)
+{
+	int procbits;
+
+	if (ppc_md.progress) ppc_md.progress("psurge_quad_init", 0x351);
+	procbits = ~PSURGE_QUAD_IN(PSURGE_QUAD_WHICH_CPU);
+	if (psurge_type == PSURGE_QUAD_ICEGRASS)
+		PSURGE_QUAD_BIS(PSURGE_QUAD_RESET_CTL, procbits);
+	else
+		PSURGE_QUAD_BIC(PSURGE_QUAD_CKSTOP_CTL, procbits);
+	mdelay(33);
+	out_8(psurge_sec_intr, ~0);
+	PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_CLR, procbits);
+	PSURGE_QUAD_BIS(PSURGE_QUAD_RESET_CTL, procbits);
+	if (psurge_type != PSURGE_QUAD_ICEGRASS)
+		PSURGE_QUAD_BIS(PSURGE_QUAD_CKSTOP_CTL, procbits);
+	PSURGE_QUAD_BIC(PSURGE_QUAD_PRIMARY_ARB, procbits);
+	mdelay(33);
+	PSURGE_QUAD_BIC(PSURGE_QUAD_RESET_CTL, procbits);
+	mdelay(33);
+	PSURGE_QUAD_BIS(PSURGE_QUAD_PRIMARY_ARB, procbits);
+	mdelay(33);
+}
+
+static int __init smp_psurge_probe(void)
+{
+	int i, ncpus;
+
+	/* We don't do SMP on the PPC601 -- paulus */
+	if (PVR_VER(mfspr(PVR)) == 1)
+		return 1;
+
+	/*
+	 * The powersurge cpu board can be used in the generation
+	 * of powermacs that have a socket for an upgradeable cpu card,
+	 * including the 7500, 8500, 9500, 9600.
+	 * The device tree doesn't tell you if you have 2 cpus because
+	 * OF doesn't know anything about the 2nd processor.
+	 * Instead we look for magic bits in magic registers,
+	 * in the hammerhead memory controller in the case of the
+	 * dual-cpu powersurge board.  -- paulus.
+	 */
+	if (find_devices("hammerhead") == NULL)
+		return 1;
+
+	hhead_base = ioremap(HAMMERHEAD_BASE, 0x800);
+	quad_base = ioremap(PSURGE_QUAD_REG_ADDR, 1024);
+	psurge_sec_intr = hhead_base + HHEAD_SEC_INTR;
+
+	psurge_type = psurge_quad_probe();
+	if (psurge_type != PSURGE_DUAL) {
+		psurge_quad_init();
+		/* All released cards using this HW design have 4 CPUs */
+		ncpus = 4;
+	} else {
+		iounmap((void *) quad_base);
+		if ((in_8(hhead_base + HHEAD_CONFIG) & 0x02) == 0) {
+			/* not a dual-cpu card */
+			iounmap((void *) hhead_base);
+			return 1;
+		}
+		ncpus = 2;
+	}
+
+	psurge_start = ioremap(PSURGE_START, 4);
+	psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4);
+
+	/* this is not actually strictly necessary -- paulus. */
+	for (i = 1; i < ncpus; ++i)
+		smp_hw_index[i] = i;
+
+	if (ppc_md.progress) ppc_md.progress("smp_psurge_probe - done", 0x352);
+
+	return ncpus;
+}
+
+static void __init smp_psurge_kick_cpu(int nr)
+{
+	void (*start)(void) = __secondary_start_psurge;
+	unsigned long a;
+
+	/* may need to flush here if secondary bats aren't setup */
+	for (a = KERNELBASE; a < KERNELBASE + 0x800000; a += 32)
+		asm volatile("dcbf 0,%0" : : "r" (a) : "memory");
+	asm volatile("sync");
+
+	if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu", 0x353);
+
+	/* setup entry point of secondary processor */
+	switch (nr) {
+	case 2:
+		start = __secondary_start_psurge2;
+		break;
+	case 3:
+		start = __secondary_start_psurge3;
+		break;
+	}
+
+	out_be32(psurge_start, __pa(start));
+	mb();
+
+	psurge_set_ipi(nr);
+	udelay(10);
+	psurge_clr_ipi(nr);
+
+	if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu - done", 0x354);
+}
+
+/*
+ * With the dual-cpu powersurge board, the decrementers and timebases
+ * of both cpus are frozen after the secondary cpu is started up,
+ * until we give the secondary cpu another interrupt.  This routine
+ * uses this to get the timebases synchronized.
+ *  -- paulus.
+ */
+static void __init psurge_dual_sync_tb(int cpu_nr)
+{
+	static volatile int sec_tb_reset = 0;
+	int t;
+
+	set_dec(tb_ticks_per_jiffy);
+	set_tb(0, 0);
+	last_jiffy_stamp(cpu_nr) = 0;
+
+	if (cpu_nr > 0) {
+		mb();
+		sec_tb_reset = 1;
+		return;
+	}
+
+	/* wait for the secondary to have reset its TB before proceeding */
+	for (t = 10000000; t > 0 && !sec_tb_reset; --t)
+		;
+
+	/* now interrupt the secondary, starting both TBs */
+	psurge_set_ipi(1);
+
+	smp_tb_synchronized = 1;
+}
+
+static void __init
+smp_psurge_setup_cpu(int cpu_nr)
+{
+
+	if (cpu_nr == 0) {
+		if (smp_num_cpus < 2)
+			return;
+		/* reset the entry point so if we get another intr we won't
+		 * try to startup again */
+		out_be32(psurge_start, 0x100);
+		if (request_irq(30, psurge_primary_intr, 0, "primary IPI", 0))
+			printk(KERN_ERR "Couldn't get primary IPI interrupt");
+	}
+
+	if (psurge_type == PSURGE_DUAL)
+		psurge_dual_sync_tb(cpu_nr);
+}
+
+static int __init
+smp_core99_probe(void)
+{
+	struct device_node *cpus;
+	int i, ncpus = 1;
+
+	if (ppc_md.progress) ppc_md.progress("smp_core99_probe", 0x345);
+	cpus = find_type_devices("cpu");
+	if (cpus)
+		while ((cpus = cpus->next) != NULL)
+			++ncpus;
+	printk("smp_core99_probe: found %d cpus\n", ncpus);
+	if (ncpus > 1) {
+		openpic_request_IPIs();
+		for (i = 1; i < ncpus; ++i)
+			smp_hw_index[i] = i;
+	}
+
+	return ncpus;
+}
+
+static void __init
+smp_core99_kick_cpu(int nr)
+{
+	unsigned long save_vector, new_vector;
+	unsigned long flags;
+#if 1 /* New way... */
+	volatile unsigned long *vector
+		 = ((volatile unsigned long *)(KERNELBASE+0x100));
+	if (nr < 1 || nr > 3)
+		return;
+#else
+	volatile unsigned long *vector
+		 = ((volatile unsigned long *)(KERNELBASE+0x500));
+	if (nr != 1)
+		return;
+#endif
+	if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu", 0x346);
+
+	local_irq_save(flags);
+	local_irq_disable();
+	
+	/* Save reset vector */
+	save_vector = *vector;
+	
+	/* Setup fake reset vector that does	  
+	 *   b __secondary_start_psurge - KERNELBASE
+	 */  
+	switch(nr) {
+		case 1:
+			new_vector = (unsigned long)__secondary_start_psurge;
+			break;
+		case 2:
+			new_vector = (unsigned long)__secondary_start_psurge2;
+			break;
+		case 3:
+			new_vector = (unsigned long)__secondary_start_psurge3;
+			break;
+	}
+	*vector = 0x48000002 + new_vector - KERNELBASE;
+	
+	/* flush data cache and inval instruction cache */
+	flush_icache_range((unsigned long) vector, (unsigned long) vector + 4);
+	
+	/* Put some life in our friend */
+	feature_core99_kick_cpu(nr);
+	
+	/* FIXME: We wait a bit for the CPU to take the exception, I should
+	 * instead wait for the entry code to set something for me. Well,
+	 * ideally, all that crap will be done in prom.c and the CPU left
+	 * in a RAM-based wait loop like CHRP.
+	 */
+	mdelay(1);
+	
+	/* Restore our exception vector */
+	*vector = save_vector;
+	flush_icache_range((unsigned long) vector, (unsigned long) vector + 4);
+	
+	local_irq_restore(flags);
+	if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu done", 0x347);
+}
+
+static void __init
+smp_core99_setup_cpu(int cpu_nr)
+{
+	/* Setup openpic */
+	do_openpic_setup_cpu();
+
+	/* Setup L2 */
+	if (cpu_nr != 0)
+		core99_init_l2();
+	else
+		if (ppc_md.progress) ppc_md.progress("core99_setup_cpu 0 done", 0x349);
+}
+
+/* PowerSurge-style Macs */
+struct smp_ops_t psurge_smp_ops __pmacdata = {
+	smp_psurge_message_pass,
+	smp_psurge_probe,
+	smp_psurge_kick_cpu,
+	smp_psurge_setup_cpu,
+};
+
+/* Core99 Macs (dual G4s) */
+struct smp_ops_t core99_smp_ops __pmacdata = {
+	smp_openpic_message_pass,
+	smp_core99_probe,
+	smp_core99_kick_cpu,
+	smp_core99_setup_cpu,
+};
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/pmac_time.c linux/arch/ppc/kernel/pmac_time.c
--- v2.4.9/linux/arch/ppc/kernel/pmac_time.c	Mon Aug 27 12:41:39 2001
+++ linux/arch/ppc/kernel/pmac_time.c	Sat Sep  8 12:38:42 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.pmac_time.c 1.11 07/06/01 15:46:39 trini
+ * BK Id: SCCS/s.pmac_time.c 1.16 09/08/01 15:47:42 paulus
  */
 /*
  * Support for periodic interrupts (100 per second) and for getting
@@ -22,7 +22,7 @@
 #include <linux/cuda.h>
 #include <linux/pmu.h>
 
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <asm/prom.h>
 #include <asm/system.h>
 #include <asm/io.h>
@@ -260,8 +260,13 @@
 	pmu_register_sleep_notifier(&time_sleep_notifier);
 #endif /* CONFIG_PMAC_PBOOK */
 
-	if (via_calibrate_decr())
-		return;
+	/* We assume MacRISC2 machines have correct device-tree
+	 * calibration. That's better since the VIA itself seems
+	 * to be slightly off. --BenH
+	 */
+	if (!machine_is_compatible("MacRISC2"))
+		if (via_calibrate_decr())
+			return;
 
 	/*
 	 * The cpu node should have a timebase-frequency property
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/ppc_asm.h linux/arch/ppc/kernel/ppc_asm.h
--- v2.4.9/linux/arch/ppc/kernel/ppc_asm.h	Wed Jul 25 17:10:18 2001
+++ linux/arch/ppc/kernel/ppc_asm.h	Tue Aug 28 06:58:33 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.ppc_asm.h 1.14 07/02/01 22:08:05 paulus
+ * BK Id: SCCS/s.ppc_asm.h 1.16 08/15/01 22:43:06 paulus
  */
 /*
  * arch/ppc/kernel/ppc_asm.h
@@ -70,20 +70,35 @@
 #define REST_32VR(n,b,base)	REST_16VR(n,b,base); REST_16VR(n+16,b,base)
 
 #ifdef CONFIG_PPC601_SYNC_FIX
-#define SYNC \
-	sync; \
-	isync
+#define SYNC				\
+BEGIN_FTR_SECTION			\
+	sync;				\
+	isync;				\
+END_FTR_SECTION_IFSET(CPU_FTR_601)
+#define SYNC_601			\
+BEGIN_FTR_SECTION			\
+	sync;				\
+END_FTR_SECTION_IFSET(CPU_FTR_601)
+#define ISYNC_601			\
+BEGIN_FTR_SECTION			\
+	isync;				\
+END_FTR_SECTION_IFSET(CPU_FTR_601)
 #else
 #define	SYNC
+#define SYNC_601
+#define ISYNC_601
 #endif
 
 #ifndef CONFIG_SMP
 #define TLBSYNC
 #else /* CONFIG_SMP */
+/* tlbsync is not implemented on 601 */
 #define TLBSYNC				\
+BEGIN_FTR_SECTION			\
 	tlbsync;			\
-	sync
-#endif /* CONFIG_SMP */
+	sync;				\
+END_FTR_SECTION_IFCLR(CPU_FTR_601)
+#endif
 
 /*
  * This instruction is not implemented on the PPC 603 or 601; however, on
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/ppc_htab.c linux/arch/ppc/kernel/ppc_htab.c
--- v2.4.9/linux/arch/ppc/kernel/ppc_htab.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/ppc/kernel/ppc_htab.c	Tue Aug 28 06:58:33 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.ppc_htab.c 1.11 06/28/01 15:50:16 paulus
+ * BK Id: SCCS/s.ppc_htab.c 1.17 08/20/01 22:59:41 paulus
  */
 /*
  * PowerPC hash table management proc entry.  Will show information
@@ -20,6 +20,7 @@
 #include <linux/stat.h>
 #include <linux/sysctl.h>
 #include <linux/ctype.h>
+#include <linux/threads.h>
 
 #include <asm/uaccess.h>
 #include <asm/bitops.h>
@@ -28,6 +29,8 @@
 #include <asm/residual.h>
 #include <asm/io.h>
 #include <asm/pgtable.h>
+#include <asm/cputable.h>
+#include <asm/system.h>
 
 static ssize_t ppc_htab_read(struct file * file, char * buf,
 			     size_t count, loff_t *ppos);
@@ -67,7 +70,7 @@
         write:          ppc_htab_write,
 };
 
-char *pmc1_lookup(unsigned long mmcr0)
+static char *pmc1_lookup(unsigned long mmcr0)
 {
 	switch ( mmcr0 & (0x7f<<7) )
 	{
@@ -84,7 +87,7 @@
 	}
 }	
 
-char *pmc2_lookup(unsigned long mmcr0)
+static char *pmc2_lookup(unsigned long mmcr0)
 {
 	switch ( mmcr0 & 0x3f )
 	{
@@ -121,11 +124,7 @@
 	if (count < 0)
 		return -EINVAL;
 
-	switch ( _get_PVR()>>16 )
-	{
-	case 4:  /* 604 */
-	case 9:  /* 604e */
-	case 10: /* 604ev5 */
+	if (cur_cpu_spec[0]->cpu_features & CPU_FTR_604_PERF_MON) {
 		asm volatile ("mfspr %0,952 \n\t"
 		    "mfspr %1,953 \n\t"
 		    "mfspr %2,954 \n\t"
@@ -141,12 +140,9 @@
 			      "PMC2\t\t: %08lx (%s)\n",
 			      pmc1, pmc1_lookup(mmcr0),
 			      pmc2, pmc2_lookup(mmcr0));
-		break;
-	default:
-		break;
 	}
 
-	
+#ifdef CONFIG_PPC_STD_MMU
 	/* if we don't have a htab */
 	if ( Hash_size == 0 )
 	{
@@ -154,7 +150,6 @@
 		goto return_string;
 	}
 
-#if !defined(CONFIG_8xx) && !defined(CONFIG_4xx)
 	for ( ptr = Hash ; ptr < Hash_end ; ptr++)
 	{
 		unsigned int ctx, mctx, vsid;
@@ -211,7 +206,7 @@
 		      "Evicts\t\t: %lu\n",
 		      htab_reloads, htab_preloads, htab_hash_searches,
 		      primary_pteg_full, htab_evicts);
-#endif /* !8xx && !4xx */
+#endif /* CONFIG_PPC_STD_MMU */
 	
 return_string:
 	n += sprintf( buffer + n,
@@ -235,7 +230,7 @@
 static ssize_t ppc_htab_write(struct file * file, const char * buffer,
 			      size_t count, loff_t *ppos)
 {
-#ifndef CONFIG_8xx
+#ifdef CONFIG_PPC_STD_MMU
 	unsigned long tmp;
 	if ( current->uid != 0 )
 		return -EACCES;
@@ -246,37 +241,22 @@
 	/* turn off performance monitoring */
 	if ( !strncmp( buffer, "off", 3) )
 	{
-		switch ( _get_PVR()>>16 )
-		{
-		case 4:  /* 604 */
-		case 9:  /* 604e */
-		case 10: /* 604ev5 */
+		if (cur_cpu_spec[0]->cpu_features & CPU_FTR_604_PERF_MON) {
 			asm volatile ("mtspr %0, %3 \n\t"
 			    "mtspr %1, %3 \n\t"
 			    "mtspr %2, %3 \n\t"			    
 			    :: "i" (MMCR0), "i" (PMC1), "i" (PMC2), "r" (0));
-			break;
-		default:
-			break;
 		}
-			
 	}
 
 	if ( !strncmp( buffer, "reset", 5) )
 	{
-		switch ( _get_PVR()>>16 )
-		{
-		case 4:  /* 604 */
-		case 9:  /* 604e */
-		case 10: /* 604ev5 */
+		if (cur_cpu_spec[0]->cpu_features & CPU_FTR_604_PERF_MON) {
 			/* reset PMC1 and PMC2 */
 			asm volatile (
 				"mtspr 953, %0 \n\t"
 				"mtspr 954, %0 \n\t"
 				:: "r" (0));
-			break;
-		default:
-			break;
 		}
 		htab_reloads = 0;
 		htab_evicts = 0;
@@ -286,11 +266,7 @@
 
 	if ( !strncmp( buffer, "user", 4) )
 	{
-		switch ( _get_PVR()>>16 )
-		{
-		case 4:  /* 604 */
-		case 9:  /* 604e */
-		case 10: /* 604ev5 */
+		if (cur_cpu_spec[0]->cpu_features & CPU_FTR_604_PERF_MON) {
 			/* setup mmcr0 and clear the correct pmc */
 			asm("mfspr %0,%1\n\t"  : "=r" (tmp) : "i" (MMCR0));
 			tmp &= ~(0x60000000);
@@ -301,19 +277,12 @@
 				"mtspr %5,%4 \n\t"    /* reset the pmc2 */
 				:: "r" (tmp), "i" (MMCR0), "i" (0),
 				"i" (PMC1),  "r" (0), "i"(PMC2) );
-			break;
-		default:
-			break;
 		}
 	}
 
 	if ( !strncmp( buffer, "kernel", 6) )
 	{
-		switch ( _get_PVR()>>16 )
-		{
-		case 4:  /* 604 */
-		case 9:  /* 604e */
-		case 10: /* 604ev5 */
+		if (cur_cpu_spec[0]->cpu_features & CPU_FTR_604_PERF_MON) {
 			/* setup mmcr0 and clear the correct pmc */
 			asm("mfspr %0,%1\n\t"  : "=r" (tmp) : "i" (MMCR0));
 			tmp &= ~(0x60000000);
@@ -324,20 +293,13 @@
 				"mtspr %5,%4 \n\t"    /* reset the pmc2 */
 				:: "r" (tmp), "i" (MMCR0), "i" (0),
 				"i" (PMC1),  "r" (0), "i"(PMC2) );
-			break;
-		default:
-			break;
 		}
 	}
 	
 	/* PMC1 values */
 	if ( !strncmp( buffer, "dtlb", 4) )
 	{
-		switch ( _get_PVR()>>16 )
-		{
-		case 4:  /* 604 */
-		case 9:  /* 604e */
-		case 10: /* 604ev5 */
+		if (cur_cpu_spec[0]->cpu_features & CPU_FTR_604_PERF_MON) {
 			/* setup mmcr0 and clear the correct pmc */
 			asm("mfspr %0,%1\n\t"  : "=r" (tmp) : "i" (MMCR0));
 			tmp &= ~(0x7f<<7);
@@ -352,11 +314,7 @@
 
 	if ( !strncmp( buffer, "ic miss", 7) )
 	{
-		switch ( _get_PVR()>>16 )
-		{
-		case 4:  /* 604 */
-		case 9:  /* 604e */
-		case 10: /* 604ev5 */
+		if (cur_cpu_spec[0]->cpu_features & CPU_FTR_604_PERF_MON) {
 			/* setup mmcr0 and clear the correct pmc */
 			asm("mfspr %0,%1\n\t"  : "=r" (tmp) : "i" (MMCR0));
 			tmp &= ~(0x7f<<7);
@@ -372,11 +330,7 @@
 	/* PMC2 values */
 	if ( !strncmp( buffer, "load miss time", 14) )
 	{
-		switch ( _get_PVR()>>16 )
-		{
-		case 4:  /* 604 */
-		case 9:  /* 604e */
-		case 10: /* 604ev5 */
+		if (cur_cpu_spec[0]->cpu_features & CPU_FTR_604_PERF_MON) {
 			/* setup mmcr0 and clear the correct pmc */
 		       asm volatile(
 			       "mfspr %0,%1\n\t"     /* get current mccr0 */
@@ -392,11 +346,7 @@
 	
 	if ( !strncmp( buffer, "itlb", 4) )
 	{
-		switch ( _get_PVR()>>16 )
-		{
-		case 4:  /* 604 */
-		case 9:  /* 604e */
-		case 10: /* 604ev5 */
+		if (cur_cpu_spec[0]->cpu_features & CPU_FTR_604_PERF_MON) {
 			/* setup mmcr0 and clear the correct pmc */
 		       asm volatile(
 			       "mfspr %0,%1\n\t"     /* get current mccr0 */
@@ -412,11 +362,7 @@
 
 	if ( !strncmp( buffer, "dc miss", 7) )
 	{
-		switch ( _get_PVR()>>16 )
-		{
-		case 4:  /* 604 */
-		case 9:  /* 604e */
-		case 10: /* 604ev5 */
+		if (cur_cpu_spec[0]->cpu_features & CPU_FTR_604_PERF_MON) {
 			/* setup mmcr0 and clear the correct pmc */
 		       asm volatile(
 			       "mfspr %0,%1\n\t"     /* get current mccr0 */
@@ -472,9 +418,9 @@
 	reset_SDR1();
 #endif	
 	return count;
-#else /* CONFIG_8xx */
+#else /* CONFIG_PPC_STD_MMU */
 	return 0;
-#endif /* CONFIG_8xx */
+#endif /* CONFIG_PPC_STD_MMU */
 }
 
 
@@ -516,7 +462,7 @@
 		"0.5", "1.0", "(reserved2)", "(reserved3)"
 	};
 
-	if ( ((_get_PVR() >> 16) != 8) && ((_get_PVR() >> 16) != 12))
+	if (!(cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR))
 		return -EFAULT;
 	
 	if ( /*!table->maxlen ||*/ (filp->f_pos && !write)) {
@@ -526,7 +472,7 @@
 	
 	vleft = table->maxlen / sizeof(int);
 	left = *lenp;
-	
+
 	for (; left /*&& vleft--*/; first=0) {
 		if (write) {
 			while (left) {
@@ -556,7 +502,6 @@
 			buffer += len;
 			left -= len;
 			_set_L2CR(val);
-			  
 		} else {
 			p = buf;
 			if (!first)
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/ppc_ksyms.c linux/arch/ppc/kernel/ppc_ksyms.c
--- v2.4.9/linux/arch/ppc/kernel/ppc_ksyms.c	Mon Aug 27 12:41:39 2001
+++ linux/arch/ppc/kernel/ppc_ksyms.c	Tue Aug 28 06:58:33 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.ppc_ksyms.c 1.38 07/23/01 15:35:53 trini
+ * BK Id: SCCS/s.ppc_ksyms.c 1.51 08/24/01 17:05:47 paulus
  */
 #include <linux/config.h>
 #include <linux/module.h>
@@ -48,6 +48,8 @@
 #include <asm/smp.h>
 #endif /* CONFIG_SMP */
 #include <asm/time.h>
+#include <asm/cputable.h>
+#include <asm/btext.h>
 
 #ifdef  CONFIG_8xx
 #include "../8xx_io/commproc.h"
@@ -73,6 +75,8 @@
 int abs(int);
 extern unsigned long ret_to_user_hook;
 
+extern unsigned long mm_ptov (unsigned long paddr);
+
 EXPORT_SYMBOL(clear_page);
 EXPORT_SYMBOL(do_signal);
 EXPORT_SYMBOL(syscall_trace);
@@ -157,16 +161,10 @@
 EXPORT_SYMBOL(ioremap);
 EXPORT_SYMBOL(__ioremap);
 EXPORT_SYMBOL(iounmap);
+EXPORT_SYMBOL(iopa);
+EXPORT_SYMBOL(mm_ptov);
 
-EXPORT_SYMBOL(ide_insw);
-EXPORT_SYMBOL(ide_outsw);
 EXPORT_SYMBOL(ppc_ide_md);
-#ifdef CONFIG_BLK_DEV_IDE_MODULE
-EXPORT_SYMBOL(chrp_ide_irq);
-EXPORT_SYMBOL(chrp_ide_ports_known);
-EXPORT_SYMBOL(chrp_ide_regbase);
-EXPORT_SYMBOL(chrp_ide_probe);
-#endif
 
 #ifdef CONFIG_PCI
 EXPORT_SYMBOL_NOVERS(isa_io_base);
@@ -183,10 +181,10 @@
 /*EXPORT_SYMBOL(_disable_interrupts);
   EXPORT_SYMBOL(_enable_interrupts);*/
 EXPORT_SYMBOL(flush_instruction_cache);
-EXPORT_SYMBOL(_get_PVR);
 EXPORT_SYMBOL(giveup_fpu);
 EXPORT_SYMBOL(enable_kernel_fp);
 EXPORT_SYMBOL(flush_icache_range);
+EXPORT_SYMBOL(flush_dcache_range);
 EXPORT_SYMBOL(xchg_u32);
 #ifdef CONFIG_ALTIVEC
 EXPORT_SYMBOL(last_task_used_altivec);
@@ -200,6 +198,7 @@
 EXPORT_SYMBOL(__global_sti);
 EXPORT_SYMBOL(__global_save_flags);
 EXPORT_SYMBOL(__global_restore_flags);
+#ifdef SPINLOCK_DEBUG
 EXPORT_SYMBOL(_spin_lock);
 EXPORT_SYMBOL(_spin_unlock);
 EXPORT_SYMBOL(spin_trylock);
@@ -207,6 +206,7 @@
 EXPORT_SYMBOL(_read_unlock);
 EXPORT_SYMBOL(_write_lock);
 EXPORT_SYMBOL(_write_unlock);
+#endif
 EXPORT_SYMBOL(smp_call_function);
 EXPORT_SYMBOL(smp_hw_index);
 EXPORT_SYMBOL(smp_num_cpus);
@@ -226,17 +226,6 @@
 EXPORT_SYMBOL(cuda_request);
 EXPORT_SYMBOL(cuda_poll);
 #endif /* CONFIG_ADB_CUDA */
-#ifdef CONFIG_ADB_PMU
-EXPORT_SYMBOL(pmu_request);
-EXPORT_SYMBOL(pmu_poll);
-EXPORT_SYMBOL(pmu_suspend);
-EXPORT_SYMBOL(pmu_resume);
-#endif /* CONFIG_ADB_PMU */
-#ifdef CONFIG_PMAC_PBOOK
-EXPORT_SYMBOL(pmu_register_sleep_notifier);
-EXPORT_SYMBOL(pmu_unregister_sleep_notifier);
-EXPORT_SYMBOL(pmu_enable_irled);
-#endif /* CONFIG_PMAC_PBOOK */
 #ifdef CONFIG_PMAC_BACKLIGHT
 EXPORT_SYMBOL(get_backlight_level);
 EXPORT_SYMBOL(set_backlight_level);
@@ -245,7 +234,6 @@
 #endif /* CONFIG_PMAC_BACKLIGHT */
 #if defined(CONFIG_ALL_PPC)
 EXPORT_SYMBOL(_machine);
-EXPORT_SYMBOL_NOVERS(have_of);
 EXPORT_SYMBOL_NOVERS(sys_ctrler);
 EXPORT_SYMBOL(find_devices);
 EXPORT_SYMBOL(find_type_devices);
@@ -273,10 +261,11 @@
 EXPORT_SYMBOL(feature_set_usb_power);
 EXPORT_SYMBOL(feature_set_firewire_power);
 EXPORT_SYMBOL(feature_set_firewire_cable_power);
+EXPORT_SYMBOL(feature_set_modem_power);
 EXPORT_SYMBOL(feature_set_airport_power);
 #endif /* defined(CONFIG_ALL_PPC) */
 #if defined(CONFIG_BOOTX_TEXT)
-EXPORT_SYMBOL(bootx_update_display);
+EXPORT_SYMBOL(btext_update_display);
 #endif
 #if defined(CONFIG_SCSI) && defined(CONFIG_ALL_PPC)
 EXPORT_SYMBOL(note_scsi_host);
@@ -303,7 +292,7 @@
 
 EXPORT_SYMBOL(abs);
 
-#ifdef CONFIG_VT
+#ifdef CONFIG_VGA_CONSOLE
 EXPORT_SYMBOL(screen_info);
 #endif
 
@@ -367,3 +356,4 @@
 #endif
 extern long *ret_from_intercept;
 EXPORT_SYMBOL(ret_from_intercept);
+EXPORT_SYMBOL(cur_cpu_spec);
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/prep_nvram.c linux/arch/ppc/kernel/prep_nvram.c
--- v2.4.9/linux/arch/ppc/kernel/prep_nvram.c	Mon May 21 17:04:47 2001
+++ linux/arch/ppc/kernel/prep_nvram.c	Sat Sep  8 12:38:42 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.prep_nvram.c 1.9 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.prep_nvram.c 1.12 09/08/01 15:47:42 paulus
  */
 /*
  *  linux/arch/ppc/kernel/prep_nvram.c
@@ -12,7 +12,7 @@
 #include <linux/slab.h>
 #include <linux/ioport.h>
 
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <asm/segment.h>
 #include <asm/io.h>
 #include <asm/processor.h>
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/prep_pci.c linux/arch/ppc/kernel/prep_pci.c
--- v2.4.9/linux/arch/ppc/kernel/prep_pci.c	Mon Aug 27 12:41:39 2001
+++ linux/arch/ppc/kernel/prep_pci.c	Sat Sep  8 12:38:42 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.prep_pci.c 1.22 08/05/01 16:18:54 trini
+ * BK Id: SCCS/s.prep_pci.c 1.26 09/08/01 15:47:42 paulus
  */
 /*
  * PReP pci functions.
@@ -15,7 +15,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <asm/byteorder.h>
 #include <asm/io.h>
 #include <asm/ptrace.h>
@@ -172,7 +172,7 @@
 	0,	/* Slot 7  - unused */
 	0,	/* Slot 8  - unused */
 	0,	/* Slot 9  - unused */
-	0,	/* Slot 10 - unxued */
+	0,	/* Slot 10 - unused */
 	0,	/* Slot 11 - unused */
 	0,	/* Slot 12 - unused */
 	0,	/* Slot 13 - unused */
@@ -200,7 +200,7 @@
 	0,      /* Slot 7  - unused */
 	0,      /* Slot 8  - unused */
 	0,      /* Slot 9  - unused */
-	0,      /* Slot 10 - unxued */
+	0,      /* Slot 10 - unused */
 	0,      /* Slot 11 - unused */
 	0,      /* Slot 12 - unused */
 	0,      /* Slot 13 - unused */
@@ -322,8 +322,8 @@
 	3,	/* Slot 12 - unused */
 	0,	/* Slot 13 - unused */
 	2,	/* Slot 14 - SCSI */
-	0,	/* Slot 15 - graphics on 3600 */
-	9,	/* Slot 16 - PMC */
+	0,	/* Slot 15 - unused */
+	9,	/* Slot 16 - PMC 1 */
 	12,	/* Slot 17 - pci */
 	11,	/* Slot 18 - pci */
 	10,	/* Slot 19 - pci */
@@ -511,6 +511,44 @@
         13      /* Line 4 */
 };
 
+/*
+ * IBM RS/6000 43p/140  -- paulus
+ * XXX we should get all this from the residual data
+ */
+static char ibm43p_pci_IRQ_map[23] __prepdata = {
+        0, /* Slot 0  - unused */
+        0, /* Slot 1  - unused */
+        0, /* Slot 2  - unused */
+        0, /* Slot 3  - unused */
+        0, /* Slot 4  - unused */
+        0, /* Slot 5  - unused */
+        0, /* Slot 6  - unused */
+        0, /* Slot 7  - unused */
+        0, /* Slot 8  - unused */
+        0, /* Slot 9  - unused */
+        0, /* Slot 10 - unused */
+        0, /* Slot 11 - FireCoral ISA bridge */
+        6, /* Slot 12 - Ethernet  */
+        0, /* Slot 13 - openpic */
+        0, /* Slot 14 - unused */
+        0, /* Slot 15 - unused */
+        7, /* Slot 16 - NCR58C825a onboard scsi */
+        0, /* Slot 17 - unused */
+        2, /* Slot 18 - PCI Slot 2 PCIINTx# (See below) */
+        0, /* Slot 19 - unused */
+        0, /* Slot 20 - unused */
+        0, /* Slot 21 - unused */
+        1, /* Slot 22 - PCI slot 1 PCIINTx# (See below) */
+};
+
+static char ibm43p_pci_IRQ_routes[] __prepdata = {
+        0,      /* Line 0 - unused */
+        15,     /* Line 1 */
+        15,     /* Line 2 */
+        15,     /* Line 3 */
+        15,     /* Line 4 */
+};
+
 /* Motorola PowerPlus architecture PCI IRQ tables */
 /* Interrupt line values for INTA-D on primary/secondary MPIC inputs */
 
@@ -767,7 +805,52 @@
 	{0x000, 0x00, 0x00, "",					NULL,			NULL, NULL, NULL, 0x00}
 };
 
-unsigned long __init prep_route_pci_interrupts(void)
+void ibm_prep_init(void)
+{
+	u32 addr;
+#ifdef CONFIG_PREP_RESIDUAL
+	PPC_DEVICE *mpic;
+#endif
+
+	if (inb(0x0852) == 0xd5) {
+		/* This is for the 43p-140 */
+		early_read_config_dword(0, 0, PCI_DEVFN(13, 0),
+					PCI_BASE_ADDRESS_0, &addr);
+		if (addr != 0xffffffff
+		    && !(addr & PCI_BASE_ADDRESS_SPACE_IO)
+		    && (addr &= PCI_BASE_ADDRESS_MEM_MASK) != 0) {
+			addr += PREP_ISA_MEM_BASE;
+			OpenPIC_Addr = ioremap(addr, 0x40000);
+			ppc_md.get_irq = openpic_get_irq;
+		}
+	}
+
+#ifdef CONFIG_PREP_RESIDUAL
+	mpic = residual_find_device(-1, NULL, SystemPeripheral,
+				    ProgrammableInterruptController, MPIC, 0);
+	if (mpic != NULL) {
+		printk("mpic = %p\n", mpic);
+	}
+#endif
+}
+
+void
+ibm43p_pci_map_non0(struct pci_dev *dev)
+{
+	unsigned char intpin;
+	static unsigned char bridge_intrs[4] = { 3, 4, 5, 8 };
+
+	if (dev == NULL)
+		return;
+	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &intpin);
+	if (intpin < 1 || intpin > 4)
+		return;
+	intpin = (PCI_SLOT(dev->devfn) + intpin - 1) & 3;
+	dev->irq = openpic_to_irq(bridge_intrs[intpin]);
+	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+}
+
+void __init prep_route_pci_interrupts(void)
 {
 	unsigned char *ibc_pirq = (unsigned char *)0x80800860;
 	unsigned char *ibc_pcicon = (unsigned char *)0x80800840;
@@ -856,7 +939,13 @@
 			Motherboard_map_name = "IBM 6015";
 			Motherboard_map = ibm6015_pci_IRQ_map;
 			Motherboard_routes = ibm6015_pci_IRQ_routes;
-			break;			
+			break;
+		case 0xd5:
+			Motherboard_map_name = "IBM 43p/140";
+			Motherboard_map = ibm43p_pci_IRQ_map;
+			Motherboard_routes = ibm43p_pci_IRQ_routes;
+			Motherboard_non0 = ibm43p_pci_map_non0;
+			break;
 		default:
 			Motherboard_map_name = "IBM 8xx (Carolina)";
 			Motherboard_map = ibm8xx_pci_IRQ_map;
@@ -878,7 +967,7 @@
 	else
 	{
 		printk("No known machine pci routing!\n");
-		return -1;
+		return;
 	}
 	
 	/* Set up mapping from slots */
@@ -888,16 +977,15 @@
 	}
 	/* Enable PCI interrupts */
 	*ibc_pcicon |= 0x20;
-	return 0;
 }
 
 void __init
 prep_pib_init(void)
 {
-unsigned char   reg;
-unsigned short  short_reg;
+	unsigned char   reg;
+	unsigned short  short_reg;
 
-struct pci_dev *dev = NULL;
+	struct pci_dev *dev = NULL;
 
 	if (( _prep_type == _PREP_Motorola) && (OpenPIC_Addr)) {
 		/*
@@ -910,43 +998,47 @@
 			 * PPCBUG does not set the enable bits
 			 * for the IDE device. Force them on here.
 			 */
-			pcibios_read_config_byte(dev->bus->number, 
-					dev->devfn, 0x40, &reg);
+			pci_read_config_byte(dev, 0x40, &reg);
 
 			reg |= 0x03; /* IDE: Chip Enable Bits */
-			pcibios_write_config_byte(dev->bus->number, 
-					dev->devfn, 0x40, reg);
-
-			/* Force correct IDE function interrupt */
-			dev->irq = 14;
-			pcibios_write_config_byte(dev->bus->number,
-					dev->devfn,
+			pci_write_config_byte(dev, 0x40, reg);
+		}
+		if ((dev = pci_find_device(PCI_VENDOR_ID_VIA,
+						PCI_DEVICE_ID_VIA_82C586_2,
+						dev)) && (dev->devfn = 0x5a)) {
+			/* Force correct USB interrupt */
+			dev->irq = 11;
+			pci_write_config_byte(dev,
 					PCI_INTERRUPT_LINE,
 					dev->irq);
-
-		} else if ((dev = pci_find_device(PCI_VENDOR_ID_WINBOND, 
+		}
+		if ((dev = pci_find_device(PCI_VENDOR_ID_WINBOND,
 					PCI_DEVICE_ID_WINBOND_83C553, dev))) {
-			/*
-			 * Clear the PCI Interrupt Routing Control Register.
-			 */
+			 /* Clear PCI Interrupt Routing Control Register. */
 			short_reg = 0x0000;
 			pci_write_config_word(dev, 0x44, short_reg);
 			if (OpenPIC_Addr){
-				/*
-				 * Route both IDE interrupts to IRQ 14
-				 */
+				/* Route IDE interrupts to IRQ 14 */
 				reg = 0xEE;
-				pci_write_config_byte(dev, 0x44, reg);
+				pci_write_config_byte(dev, 0x43, reg);
 			}
 		}
 	}
+
 	if ((dev = pci_find_device(PCI_VENDOR_ID_WINBOND,
 				   PCI_DEVICE_ID_WINBOND_82C105, dev))){
 		if (OpenPIC_Addr){
-			/* Disable LEGIRQ mode so PCI INTs are routed to
-			   the 8259 */
-			printk("Set winbond IDE to native mode\n");
-			pci_write_config_dword(dev, 0x40, 0x10ff00a1);
+			/*
+			 * Disable LEGIRQ mode so PCI INTS are routed
+			 * directly to the 8259 and enable both channels
+			 */
+			pci_write_config_dword(dev, 0x40, 0x10ff0033);
+
+			/* Force correct IDE interrupt */
+			dev->irq = 14;
+			pci_write_config_byte(dev,
+					PCI_INTERRUPT_LINE,
+					dev->irq);
 		}else{
 			/* Enable LEGIRQ for PCI INT -> 8259 IRQ routing */
 			pci_write_config_dword(dev, 0x40, 0x10ff08a1);
@@ -1106,6 +1198,19 @@
 	}
 }
 
+static void __init
+prep_init_resource(struct resource *res, unsigned long start,
+		   unsigned long end, int flags)
+{
+	res->flags = flags;
+	res->start = start;
+	res->end = end;
+	res->name = "PCI host bridge";
+	res->parent = NULL;
+	res->sibling = NULL;
+	res->child = NULL;
+}
+
 void __init
 prep_find_bridges(void)
 {
@@ -1119,6 +1224,9 @@
 	hose->last_busno = 0xff;
 	hose->pci_mem_offset = PREP_ISA_MEM_BASE;
 	hose->io_base_virt = (void *)PREP_ISA_IO_BASE;
+	prep_init_resource(&hose->io_resource, 0, 0x0fffffff, IORESOURCE_IO);
+	prep_init_resource(&hose->mem_resources[0], 0xc0000000, 0xfeffffff,
+			   IORESOURCE_MEM);
 	
 	printk("PReP architecture\n");
 	{
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/prep_setup.c linux/arch/ppc/kernel/prep_setup.c
--- v2.4.9/linux/arch/ppc/kernel/prep_setup.c	Mon Aug 27 12:41:39 2001
+++ linux/arch/ppc/kernel/prep_setup.c	Sat Sep  8 12:38:42 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.prep_setup.c 1.26 08/05/01 16:18:54 trini
+ * BK Id: SCCS/s.prep_setup.c 1.36 09/08/01 15:47:42 paulus
  */
 /*
  *  linux/arch/ppc/kernel/setup.c
@@ -7,6 +7,9 @@
  *  Copyright (C) 1995  Linus Torvalds
  *  Adapted from 'alpha' version by Gary Thomas
  *  Modified by Cort Dougan (cort@cs.nmt.edu)
+ *
+ * Support for PReP (Motorola MTX/MVME)
+ * by Troy Benjegerdes (hozer@drgw.net)
  */
 
 /*
@@ -38,7 +41,7 @@
 #include <linux/pci.h>
 #include <linux/ide.h>
 
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <asm/mmu.h>
 #include <asm/processor.h>
 #include <asm/residual.h>
@@ -78,6 +81,7 @@
 extern unsigned char rs_nvram_read_val(int addr);
 extern void rs_nvram_write_val(int addr,
 				 unsigned char val);
+extern void ibm_prep_init(void);
 
 extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
 extern int pckbd_getkeycode(unsigned int scancode);
@@ -329,13 +333,20 @@
 
 	/*print_residual_device_info();*/
 
-	raven_init();
+	switch (_prep_type) {
+	case _PREP_Motorola:
+		raven_init();
+		break;
+	case _PREP_IBM:
+		ibm_prep_init();
+		break;
+	}
 
 #ifdef CONFIG_VGA_CONSOLE
 	/* remap the VGA memory */
 	vgacon_remap_base = 0xf0000000;
 	/*vgacon_remap_base = ioremap(0xc0000000, 0xba000);*/
-        conswitchp = &vga_con;
+	conswitchp = &vga_con;
 #elif defined(CONFIG_DUMMY_CONSOLE)
 	conswitchp = &dummy_con;
 #endif
@@ -662,23 +673,6 @@
 	}
 }
 
-#if 0
-void __prep
-prep_do_IRQ(struct pt_regs *regs, int cpu)
-{
-        int irq;
-
-	if ( (irq = i8259_irq(0)) < 0 )
-	{
-		printk(KERN_DEBUG "Bogus interrupt from PC = %lx\n",
-		       regs->nip);
-		ppc_spurious_interrupts++;
-		return;
-	}
-        ppc_irq_dispatch_handler( regs, irq );
-}
-#endif
-
 int __prep
 prep_get_irq(struct pt_regs *regs)
 {
@@ -701,18 +695,6 @@
 /*
  * IDE stuff.
  */
-void __prep
-prep_ide_insw(ide_ioreg_t port, void *buf, int ns)
-{
-	_insw((unsigned short *)((port)+_IO_BASE), buf, ns);
-}
-
-void __prep
-prep_ide_outsw(ide_ioreg_t port, void *buf, int ns)
-{
-	_outsw((unsigned short *)((port)+_IO_BASE), buf, ns);
-}
-
 int __prep
 prep_ide_default_irq(ide_ioreg_t base)
 {
@@ -721,8 +703,9 @@
 		case 0x170: return 13;
 		case 0x1e8: return 11;
 		case 0x168: return 10;
-		default:
-                        return 0;
+		case 0xfff0: return 14;		/* MCP(N)750 ide0 */
+		case 0xffe0: return 15;		/* MCP(N)750 ide1 */
+		default: return 0;
 	}
 }
 
@@ -780,6 +763,45 @@
 }
 #endif
 
+#ifdef CONFIG_SMP
+/* PReP (MTX) support */
+static int
+smp_prep_probe(void)
+{
+	extern int mot_multi;
+
+	if (mot_multi) {
+		openpic_request_IPIs();
+		smp_hw_index[1] = 1;
+		return 2;
+	}
+
+	return 1;
+}
+
+static void
+smp_prep_kick_cpu(int nr)
+{
+	*(unsigned long *)KERNELBASE = nr;
+	asm volatile("dcbf 0,%0"::"r"(KERNELBASE):"memory");
+	printk("CPU1 reset, waiting\n");
+}
+
+static void
+smp_prep_setup_cpu(int cpu_nr)
+{
+	if (OpenPIC_Addr)
+		do_openpic_setup_cpu();
+}
+
+static struct smp_ops_t prep_smp_ops = {
+	smp_openpic_message_pass,
+	smp_prep_probe,
+	smp_prep_kick_cpu,
+	smp_prep_setup_cpu,
+};
+#endif /* CONFIG_SMP */
+
 /*
  * This finds the amount of physical ram and does necessary
  * setup for prep.  This is pretty architecture specific so
@@ -788,29 +810,39 @@
  */
 unsigned long __init prep_find_end_of_memory(void)
 {
-	unsigned long total;
+	unsigned long total = 0;
+	extern unsigned int boot_mem_size;
+
 #ifdef CONFIG_PREP_RESIDUAL	
 	total = res->TotalMemory;
-#else
-	total = 0;
 #endif	
 
-	if (total == 0 )
-	{
+	if (total == 0 && boot_mem_size != 0)
+		total = boot_mem_size;
+
+	if (total == 0) {
 		/*
 		 * I need a way to probe the amount of memory if the residual
 		 * data doesn't contain it. -- Cort
 		 */
-		printk("Ramsize from residual data was 0 -- Probing for value\n");
 		total = 0x02000000;
-		printk("Ramsize default to be %ldM\n", total>>20);
+		printk(KERN_INFO "Ramsize from residual data was 0"
+		       " -- defaulting to %ldM\n", total>>20);
 	}
 
 	return (total);
 }
 
-unsigned long *MotSave_SmpIar;
-unsigned char *MotSave_CpusState[2];
+/*
+ * Setup the bat mappings we're going to load that cover
+ * the io areas.  RAM was mapped by mapin_ram().
+ * -- Cort
+ */
+void __init prep_map_io(void)
+{
+	io_block_mapping(0x80000000, 0x80000000, 0x10000000, _PAGE_IO);
+	io_block_mapping(0xf0000000, 0xc0000000, 0x08000000, _PAGE_IO);
+}
 
 void __init
 prep_init2(void)
@@ -838,13 +870,6 @@
 	{
 		memcpy((void *)res,(void *)(r3+KERNELBASE),
 		       sizeof(RESIDUAL));
-
-		/* These need to be saved for the Motorola Prep 
-		 * MVME4600 and Dual MTX boards.
-		 */
-		MotSave_SmpIar = &old_res->VitalProductData.SmpIar;
-		MotSave_CpusState[0] = &old_res->Cpus[0].CpuState;
-		MotSave_CpusState[1] = &old_res->Cpus[1].CpuState;
 	}
 #endif
 
@@ -912,19 +937,16 @@
 	}
 
 	ppc_md.find_end_of_memory = prep_find_end_of_memory;
+	ppc_md.setup_io_mappings = prep_map_io;
 
 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
-        ppc_ide_md.insw = prep_ide_insw;
-        ppc_ide_md.outsw = prep_ide_outsw;
         ppc_ide_md.default_irq = prep_ide_default_irq;
         ppc_ide_md.default_io_base = prep_ide_default_io_base;
         ppc_ide_md.ide_check_region = prep_ide_check_region;
         ppc_ide_md.ide_request_region = prep_ide_request_region;
         ppc_ide_md.ide_release_region = prep_ide_release_region;
-        ppc_ide_md.fix_driveid = NULL;
         ppc_ide_md.ide_init_hwif = prep_ide_init_hwif_ports;
-#endif		
-        ppc_ide_md.io_base = _IO_BASE;
+#endif
 
 #ifdef CONFIG_VT
 	ppc_md.kbd_setkeycode    = pckbd_setkeycode;
@@ -938,4 +960,8 @@
 	SYSRQ_KEY = 0x54;
 #endif
 #endif
+
+#ifdef CONFIG_SMP
+	ppc_md.smp_ops		 = &prep_smp_ops;
+#endif /* CONFIG_SMP */
 }
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/prep_time.c linux/arch/ppc/kernel/prep_time.c
--- v2.4.9/linux/arch/ppc/kernel/prep_time.c	Mon May 21 17:04:47 2001
+++ linux/arch/ppc/kernel/prep_time.c	Sat Sep  8 12:38:42 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.prep_time.c 1.7 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.prep_time.c 1.10 09/08/01 15:47:42 paulus
  */
 /*
  *  linux/arch/i386/kernel/time.c
@@ -23,7 +23,7 @@
 #include <linux/kernel_stat.h>
 #include <linux/init.h>
 
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <asm/segment.h>
 #include <asm/io.h>
 #include <asm/processor.h>
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/process.c linux/arch/ppc/kernel/process.c
--- v2.4.9/linux/arch/ppc/kernel/process.c	Wed Jul 25 17:10:18 2001
+++ linux/arch/ppc/kernel/process.c	Tue Aug 28 06:58:33 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.process.c 1.23 07/19/01 23:02:48 paulus
+ * BK Id: SCCS/s.process.c 1.27 08/28/01 22:01:21 paulus
  */
 /*
  *  linux/arch/ppc/kernel/process.c
@@ -59,8 +59,6 @@
 };
 /* only used to get secondary processor up */
 struct task_struct *current_set[NR_CPUS] = {&init_task, };
-char *sysmap = NULL; 
-unsigned long sysmap_size = 0;
 
 #undef SHOW_TASK_SWITCHES
 #undef CHECK_STACK
@@ -324,7 +322,6 @@
 	    unsigned long unused,
 	    struct task_struct *p, struct pt_regs *regs)
 {
-	unsigned long msr;
 	struct pt_regs *childregs, *kregs;
 	extern void ret_from_fork(void);
 	unsigned long sp = (unsigned long)p + sizeof(union task_union);
@@ -362,11 +359,12 @@
 	 * copy fpu info - assume lazy fpu switch now always
 	 *  -- Cort
 	 */
-	if (regs->msr & MSR_FP)
+	if (regs->msr & MSR_FP) {
 		giveup_fpu(current);
+		childregs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1);
+	}
 	memcpy(&p->thread.fpr, &current->thread.fpr, sizeof(p->thread.fpr));
 	p->thread.fpscr = current->thread.fpscr;
-	childregs->msr &= ~MSR_FP;
 
 #ifdef CONFIG_ALTIVEC
 	/*
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/prom.c linux/arch/ppc/kernel/prom.c
--- v2.4.9/linux/arch/ppc/kernel/prom.c	Mon Aug 27 12:41:39 2001
+++ linux/arch/ppc/kernel/prom.c	Sat Sep  8 12:38:42 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.prom.c 1.35 07/25/01 14:11:37 trini
+ * BK Id: SCCS/s.prom.c 1.42 09/08/01 15:47:42 paulus
  */
 /*
  * Procedures for interfacing to the Open Firmware PROM on
@@ -20,7 +20,7 @@
 #include <linux/threads.h>
 #include <linux/spinlock.h>
 
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <asm/prom.h>
 #include <asm/page.h>
 #include <asm/processor.h>
@@ -33,6 +33,7 @@
 #include <asm/pgtable.h>
 #include <asm/bitops.h>
 #include <asm/bootinfo.h>
+#include <asm/btext.h>
 #include "open_pic.h"
 
 #ifdef CONFIG_FB
@@ -99,6 +100,7 @@
 #define FB_MAX	8
 #endif
 char *prom_display_paths[FB_MAX] __initdata = { 0, };
+phandle prom_display_nodes[FB_MAX] __initdata;
 unsigned int prom_num_displays __initdata = 0;
 char *of_stdout_device __initdata = 0;
 ihandle prom_disp_node __initdata = 0;
@@ -125,40 +127,6 @@
 
 static struct device_node *allnodes;
 
-#ifdef CONFIG_BOOTX_TEXT
-
-#define NO_SCROLL
-
-static void clearscreen(void);
-static void flushscreen(void);
-
-#ifndef NO_SCROLL
-static void scrollscreen(void);
-#endif
-
-static void prepare_disp_BAT(void);
-
-static void draw_byte(unsigned char c, long locX, long locY);
-static void draw_byte_32(unsigned char *bits, unsigned long *base, int rb);
-static void draw_byte_16(unsigned char *bits, unsigned long *base, int rb);
-static void draw_byte_8(unsigned char *bits, unsigned long *base, int rb);
-
-static int g_loc_X;
-static int g_loc_Y;
-static int g_max_loc_X;
-static int g_max_loc_Y;
-
-unsigned long disp_BAT[2] __initdata = {0, 0};
-
-#define cmapsz	(16*256)
-
-static unsigned char vga_font[cmapsz];
-
-int bootx_text_mapped = 1;
-
-#endif /* CONFIG_BOOTX_TEXT */
-
-
 static void *call_prom(const char *service, int nargs, int nret, ...);
 static void prom_exit(void);
 static unsigned long copy_device_tree(unsigned long, unsigned long);
@@ -174,7 +142,6 @@
 
 #ifdef CONFIG_BOOTX_TEXT
 static void setup_disp_fake_bi(ihandle dp);
-static void prom_welcome(boot_infos_t* bi, unsigned long phys);
 #endif
 
 extern void enter_rtas(void *);
@@ -182,10 +149,6 @@
 
 extern char cmd_line[512];	/* XXX */
 boot_infos_t *boot_infos;
-#ifdef CONFIG_BOOTX_TEXT
-boot_infos_t *disp_bi;
-boot_infos_t fake_bi;
-#endif
 unsigned long dev_tree_size;
 
 #define ALIGN(x) (((x) + sizeof(unsigned long)-1) & -sizeof(unsigned long))
@@ -257,13 +220,7 @@
 	unsigned long offset = reloc_offset();
 
 	if (RELOC(prom_stdout) == 0)
-	{
-#ifdef CONFIG_BOOTX_TEXT
-		if (RELOC(disp_bi) != 0)
-			prom_drawstring(msg);
-#endif
 		return;
-	}
 
 	for (p = msg; *p != 0; p = q) {
 		for (q = p; *q != 0 && *q != '\n'; ++q)
@@ -399,26 +356,21 @@
 		bi->logicalDisplayBase = 0;
 
 #ifdef CONFIG_BOOTX_TEXT
-	RELOC(g_loc_X) = 0;
-	RELOC(g_loc_Y) = 0;
-	RELOC(g_max_loc_X) = (bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) / 8;
-	RELOC(g_max_loc_Y) = (bi->dispDeviceRect[3] - bi->dispDeviceRect[1]) / 16;
-	RELOC(disp_bi) = PTRUNRELOC(bi);
-		
-	clearscreen();
+	btext_init(bi);
 
-	/* Test if boot-info is compatible. Done only in config CONFIG_BOOTX_TEXT since
-	   there is nothing much we can do with an incompatible version, except display
-	   a message and eventually hang the processor...
-		   
-	   I'll try to keep enough of boot-info compatible in the future to always allow
-	   display of this message;
-	*/
-	if (!BOOT_INFO_IS_COMPATIBLE(bi))
-		prom_print(RELOC(" !!! WARNING - Incompatible version of BootX !!!\n\n\n"));
-		
-	prom_welcome(bi, phys);
-	flushscreen();
+	/*
+	 * Test if boot-info is compatible.  Done only in config
+	 * CONFIG_BOOTX_TEXT since there is nothing much we can do
+	 * with an incompatible version, except display a message
+	 * and eventually hang the processor...
+	 *
+	 * I'll try to keep enough of boot-info compatible in the
+	 * future to always allow display of this message;
+	 */
+	if (!BOOT_INFO_IS_COMPATIBLE(bi)) {
+		btext_drawstring(RELOC(" !!! WARNING - Incompatible version of BootX !!!\n\n\n"));
+		btext_flushscreen();
+	}
 #endif	/* CONFIG_BOOTX_TEXT */	
 		
 	/* New BootX enters kernel with MMU off, i/os are not allowed
@@ -461,10 +413,13 @@
 	}
 		
 #ifdef CONFIG_BOOTX_TEXT
-	prepare_disp_BAT();
-	prom_drawstring(RELOC("booting...\n"));
-	flushscreen();
-	RELOC(bootx_text_mapped) = 1;
+	/*
+	 * Note that after we call prepare_disp_BAT, we can't do
+	 * prom_draw*, flushscreen or clearscreen until we turn the MMU
+	 * on, since prepare_disp_BAT sets disp_bi->logicalDisplayBase
+	 * to a virtual address.
+	 */
+	btext_prepare_BAT();
 #endif
 }
 
@@ -591,13 +546,11 @@
 unsigned long __init
 prom_init(int r3, int r4, prom_entry pp)
 {
-	int chrp = 0;
 	unsigned long mem;
-	ihandle prom_mmu, prom_op;
+	ihandle prom_mmu;
 	unsigned long offset = reloc_offset();
 	int l;
 	char *p, *d;
-	int prom_version = 0;
  	unsigned long phys;
 
  	/* Default */
@@ -622,31 +575,6 @@
 	RELOC(of_stdout_device) = PTRUNRELOC(p);
 	mem += strlen(p) + 1;
 
-	/* Find the OF version */
-	prom_op = call_prom(RELOC("finddevice"), 1, 1, RELOC("/openprom"));
-	prom_version = 0;
-	if (prom_op != (void*)-1) {
-		char model[64];
-		int sz;
-		sz = (int)call_prom(RELOC("getprop"), 4, 1, prom_op,
-				    RELOC("model"), model, 64);
-		if (sz > 0) {
-			char *c;
-			/* hack to skip the ibm chrp firmware # */
-			if ( strncmp(model,RELOC("IBM"),3) ) {
-				for (c = model; *c; c++)
-					if (*c >= '0' && *c <= '9') {
-						prom_version = *c - '0';
-						break;
-					}
-			}
-			else
-				chrp = 1;
-		}
-	}
-	if (prom_version >= 3)
-		prom_print(RELOC("OF Version 3 detected.\n"));
-
 	/* Get the boot device and translate it to a full OF pathname. */
 	p = (char *) mem;
 	l = (int) call_prom(RELOC("getprop"), 4, 1, RELOC(prom_chosen),
@@ -725,22 +653,14 @@
 	call_prom(RELOC("quiesce"), 0, 0);
 
 #ifdef CONFIG_BOOTX_TEXT
-	if (!chrp && RELOC(disp_bi)) {
-		RELOC(prom_stdout) = 0; /* stop OF output */
-		clearscreen();
-		prepare_disp_BAT();
-		prom_welcome(PTRRELOC(RELOC(disp_bi)), phys);
-		prom_drawstring(RELOC("booting...\n"));
-		RELOC(bootx_text_mapped) = 1;
-	} else {
-		RELOC(bootx_text_mapped) = 0;
-	}
+	btext_prepare_BAT();
 #endif
 
 	prom_print(RELOC("returning "));
 	prom_print_hex(phys);
 	prom_print(RELOC(" from prom_init\n"));
 	RELOC(prom_stdout) = 0;
+
 	return phys;
 }
 
@@ -767,82 +687,6 @@
 	rtas(&u, RELOC(rtas_data));
 }
 
-#ifdef CONFIG_BOOTX_TEXT
-static void __init
-prom_welcome(boot_infos_t* bi, unsigned long phys)
-{
-	unsigned long offset = reloc_offset();
-	unsigned long flags;
-	unsigned long pvr;
-	
-	prom_drawstring(RELOC("Welcome to Linux, kernel " UTS_RELEASE "\n"));
-	prom_drawstring(RELOC("\nstarted at       : 0x"));
-	prom_drawhex(phys);
-	prom_drawstring(RELOC("\nlinked at        : 0x"));
-	prom_drawhex(KERNELBASE);
-	prom_drawstring(RELOC("\nframe buffer at  : 0x"));
-	prom_drawhex((unsigned long)bi->dispDeviceBase);
-	prom_drawstring(RELOC(" (phys), 0x"));
-	prom_drawhex((unsigned long)bi->logicalDisplayBase);
-	prom_drawstring(RELOC(" (log)"));
-	prom_drawstring(RELOC("\nklimit           : 0x"));
-	prom_drawhex((unsigned long)RELOC(klimit));
-	prom_drawstring(RELOC("\nMSR              : 0x"));
-	__asm__ __volatile__ ("mfmsr %0" : "=r" (flags));
-	prom_drawhex(flags);
-	__asm__ __volatile__ ("mfspr %0, 287" : "=r" (pvr));
-	pvr >>= 16;
-	if (pvr > 1) {
-	    prom_drawstring(RELOC("\nHID0             : 0x"));
-	    __asm__ __volatile__ ("mfspr %0, 1008" : "=r" (flags));
-	    prom_drawhex(flags);
-	}
-	if (pvr == 8 || pvr == 12 || pvr == 0x800c) {
-	    prom_drawstring(RELOC("\nICTC             : 0x"));
-	    __asm__ __volatile__ ("mfspr %0, 1019" : "=r" (flags));
-	    prom_drawhex(flags);
-	}
-	prom_drawstring(RELOC("\n\n"));
-}
-
-/* Calc BAT values for mapping the display and store them
- * in disp_BAT.  Those values are then used from head.S to map
- * the display during identify_machine() and MMU_Init()
- * 
- * For now, the display is mapped in place (1:1). This should
- * be changed if the display physical address overlaps
- * KERNELBASE, which is fortunately not the case on any machine
- * I know of. This mapping is temporary and will disappear as
- * soon as the setup done by MMU_Init() is applied
- * 
- * For now, we align the BAT and then map 8Mb on 601 and 16Mb
- * on other PPCs. This may cause trouble if the framebuffer
- * is really badly aligned, but I didn't encounter this case
- * yet.
- */
-static void __init
-prepare_disp_BAT(void)
-{
-	unsigned long offset = reloc_offset();
-	boot_infos_t* bi = PTRRELOC(RELOC(disp_bi));
-	unsigned long addr = (unsigned long)bi->dispDeviceBase;
-	
-	if ((_get_PVR() >> 16) != 1) {
-		/* 603, 604, G3, G4, ... */
-		addr &= 0xFF000000UL;
-		RELOC(disp_BAT[0]) = addr | (BL_16M<<2) | 2;
-		RELOC(disp_BAT[1]) = addr | (_PAGE_NO_CACHE | _PAGE_GUARDED | BPP_RW);		
-	} else {
-		/* 601 */
-		addr &= 0xFF800000UL;
-		RELOC(disp_BAT[0]) = addr | (_PAGE_NO_CACHE | PP_RWXX) | 4;
-		RELOC(disp_BAT[1]) = addr | BL_8M | 0x40;
-	}
-	bi->logicalDisplayBase = bi->dispDeviceBase;
-}
-
-#endif
-
 static int __init
 prom_set_color(ihandle ih, int i, int r, int g, int b)
 {
@@ -920,17 +764,22 @@
 		i = RELOC(prom_num_displays)++;
 		if (RELOC(of_stdout_device) != 0 && i > 0
 		    && strcmp(PTRRELOC(RELOC(of_stdout_device)), path) == 0) {
-			for (; i > 0; --i)
+			for (; i > 0; --i) {
 				RELOC(prom_display_paths[i])
 					= RELOC(prom_display_paths[i-1]);
+				RELOC(prom_display_nodes[i])
+					= RELOC(prom_display_nodes[i-1]);
+			}
 		}
 		RELOC(prom_display_paths[i]) = PTRUNRELOC(path);
+		RELOC(prom_display_nodes[i]) = node;
 		if (i == 0)
 			RELOC(prom_disp_node) = node;
 		if (RELOC(prom_num_displays) >= FB_MAX)
 			break;
 	}
 
+try_again:
 	/*
 	 * Open the first display and set its colormap.
 	 */
@@ -941,6 +790,15 @@
 		ih = call_prom(RELOC("open"), 1, 1, path);
 		if (ih == 0 || ih == (ihandle) -1) {
 			prom_print(RELOC("... failed\n"));
+			for (i=1; i<RELOC(prom_num_displays); i++) {
+				RELOC(prom_display_paths[i-1]) = RELOC(prom_display_paths[i]);
+				RELOC(prom_display_nodes[i-1]) = RELOC(prom_display_nodes[i]);
+			}	
+			if (--RELOC(prom_num_displays) > 0)
+				RELOC(prom_disp_node) = RELOC(prom_display_nodes[0]);
+			else
+				RELOC(prom_disp_node) = NULL;
+			goto try_again;
 		} else {
 			prom_print(RELOC("... ok\n"));
 			/*
@@ -977,7 +835,6 @@
 {
 	int width = 640, height = 480, depth = 8, pitch;
 	unsigned address;
-	boot_infos_t* bi;
 	unsigned long offset = reloc_offset();
 	struct pci_reg_property addrs[8];
 	int i, naddrs;
@@ -1025,20 +882,8 @@
 	/* kludge for valkyrie */
 	if (strcmp(name, RELOC("valkyrie")) == 0) 
 		address += 0x1000;
- 
-	RELOC(disp_bi) = &fake_bi;
-	bi = PTRRELOC((&fake_bi));
-	RELOC(g_loc_X) = 0;
-	RELOC(g_loc_Y) = 0;
-	RELOC(g_max_loc_X) = width / 8;
-	RELOC(g_max_loc_Y) = height / 16;
-	bi->logicalDisplayBase = (unsigned char *)address;
-	bi->dispDeviceBase = (unsigned char *)address;
-	bi->dispDeviceRowBytes = pitch;
-	bi->dispDeviceDepth = depth;
-	bi->dispDeviceRect[0] = bi->dispDeviceRect[1] = 0;
-	bi->dispDeviceRect[2] = width;
-	bi->dispDeviceRect[3] = height;
+
+	btext_setup_display(width, height, depth, pitch, address);
 }
 #endif
 
@@ -1147,8 +992,7 @@
 		prev_propp = &pp->next;
 		namep = (char *) (pp + 1);
 		pp->name = PTRUNRELOC(namep);
-		/* Work around a GCC3 bug */
-		memcpy(namep, RELOC("linux,phandle"), sizeof("linux,phandle"));
+		strcpy(namep, RELOC("linux,phandle"));
 		mem_start = ALIGN((unsigned long)namep + strlen(namep) + 1);
 		pp->value = (unsigned char *) PTRUNRELOC(&np->node);
 		pp->length = sizeof(np->node);
@@ -1213,15 +1057,21 @@
 		 * np->name has not been set yet.  -- paulus
 		 */
 		int n = 0;
-		char *name;
+		char *name, *ic;
+		int iclen;
 
 		for (np = allnodes; np != NULL; np = np->allnext) {
-			if ((name = get_property(np, "name", NULL)) == NULL
-			    || strcmp(name, "interrupt-controller") != 0)
-				continue;
-			if (n == 0)
-				dflt_interrupt_controller = np;
-			++n;
+			ic = get_property(np, "interrupt-controller", &iclen);
+			name = get_property(np, "name", NULL);
+			/* checking iclen makes sure we don't get a false
+			   match on /chosen.interrupt_controller */
+			if ((name != NULL
+			     && strcmp(name, "interrupt-controller") == 0)
+			    || (ic != NULL && iclen == 0)) {
+				if (n == 0)
+					dflt_interrupt_controller = np;
+				++n;
+			}
 		}
 		num_interrupt_controllers = n;
 	}
@@ -1559,7 +1409,7 @@
 	}
 }
 
-int __init
+int
 prom_n_addr_cells(struct device_node* np)
 {
 	int* ip;
@@ -1574,7 +1424,7 @@
 	return 1;
 }
 
-int __init
+int
 prom_n_size_cells(struct device_node* np)
 {
 	int* ip;
@@ -1890,7 +1740,7 @@
 /*
  * Returns all nodes linked together
  */
-struct device_node __openfirmware *
+struct device_node * __openfirmware
 find_all_nodes(void)
 {
 	struct device_node *head, **prevp, *np;
@@ -1983,7 +1833,7 @@
 /*
  * Find the device_node with a given phandle.
  */
-static struct device_node __init *
+static struct device_node * __init
 find_phandle(phandle ph)
 {
 	struct device_node *np;
@@ -2111,6 +1961,12 @@
 		u.words[i+3] = va_arg(list, unsigned long);
 	va_end(list);
 
+	/* Shouldn't we enable kernel FP here ? enter_rtas will play
+	 * with MSR_FE0|MSR_FE1|MSR_FP so I assume rtas might use
+	 * floating points. If that's the case, then we need to make
+	 * sure any lazy FP context is backed up
+	 * --BenH
+	 */
 	spin_lock_irqsave(&rtas_lock, s);
 	enter_rtas((void *)__pa(&u));
 	spin_unlock_irqrestore(&rtas_lock, s);
@@ -2130,694 +1986,3 @@
 	for (;;)
 		prom_exit();
 }
-
-#ifdef CONFIG_BOOTX_TEXT
-
-/* Here's a small text engine to use during early boot or for debugging purposes
- * 
- * todo:
- * 
- *  - build some kind of vgacon with it to enable early printk
- *  - move to a separate file
- *  - add a few video driver hooks to keep in sync with display
- *    changes.
- */
-
-void
-map_bootx_text(void)
-{
-	unsigned long base, offset, size;
-	if (disp_bi == 0)
-		return;
-	base = ((unsigned long) disp_bi->dispDeviceBase) & 0xFFFFF000UL;
-	offset = ((unsigned long) disp_bi->dispDeviceBase) - base;
-	size = disp_bi->dispDeviceRowBytes * disp_bi->dispDeviceRect[3] + offset
-		+ disp_bi->dispDeviceRect[0];
-	disp_bi->logicalDisplayBase = ioremap(base, size);
-	if (disp_bi->logicalDisplayBase == 0)
-		return;
-	disp_bi->logicalDisplayBase += offset;
-	bootx_text_mapped = 1;
-}
-
-/* Calc the base address of a given point (x,y) */
-static unsigned char * __pmac
-calc_base(boot_infos_t *bi, int x, int y)
-{
-	unsigned char *base;
-
-	base = bi->logicalDisplayBase;
-	if (base == 0)
-		base = bi->dispDeviceBase;
-	base += (x + bi->dispDeviceRect[0]) * (bi->dispDeviceDepth >> 3);
-	base += (y + bi->dispDeviceRect[1]) * bi->dispDeviceRowBytes;
-	return base;
-}
-
-/* Adjust the display to a new resolution */
-void __openfirmware
-bootx_update_display(unsigned long phys, int width, int height,
-		     int depth, int pitch)
-{
-	if (disp_bi == 0)
-		return;
-	/* check it's the same frame buffer (within 64MB) */
-	if ((phys ^ (unsigned long)disp_bi->dispDeviceBase) & 0xfc000000) {
-		return;
-	}
-
-	disp_bi->dispDeviceBase = (__u8 *) phys;
-	disp_bi->dispDeviceRect[0] = 0;
-	disp_bi->dispDeviceRect[1] = 0;
-	disp_bi->dispDeviceRect[2] = width;
-	disp_bi->dispDeviceRect[3] = height;
-	disp_bi->dispDeviceDepth = depth;
-	disp_bi->dispDeviceRowBytes = pitch;
-	if (bootx_text_mapped) {
-		iounmap(disp_bi->logicalDisplayBase);
-		bootx_text_mapped = 0;
-	}
-	map_bootx_text();
-	g_loc_X = 0;
-	g_loc_Y = 0;
-	g_max_loc_X = width / 8;
-	g_max_loc_Y = height / 16;
-}
-
-static void __pmac
-clearscreen(void)
-{
-	unsigned long offset	= reloc_offset();
-	boot_infos_t* bi	= PTRRELOC(RELOC(disp_bi));
-	unsigned long *base	= (unsigned long *)calc_base(bi, 0, 0);
-	unsigned long width 	= ((bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) *
-					(bi->dispDeviceDepth >> 3)) >> 2;
-	int i,j;
-	
-	for (i=0; i<(bi->dispDeviceRect[3] - bi->dispDeviceRect[1]); i++)
-	{
-		unsigned long *ptr = base;
-		for(j=width; j; --j)
-			*(ptr++) = 0;
-		base += (bi->dispDeviceRowBytes >> 2);
-	}
-}
-
-__inline__ void dcbst(const void* addr)
-{
-	__asm__ __volatile__ ("dcbst 0,%0" :: "r" (addr));
-}
-
-static void __pmac
-flushscreen(void)
-{
-	unsigned long offset	= reloc_offset();
-	boot_infos_t* bi	= PTRRELOC(RELOC(disp_bi));
-	unsigned long *base	= (unsigned long *)calc_base(bi, 0, 0);
-	unsigned long width 	= ((bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) *
-					(bi->dispDeviceDepth >> 3)) >> 2;
-	int i,j;
-	
-	for (i=0; i<(bi->dispDeviceRect[3] - bi->dispDeviceRect[1]); i++)
-	{
-		unsigned long *ptr = base;
-		for(j=width; j>0; j-=8) {
-			dcbst(ptr);
-			ptr += 8;
-		}
-		base += (bi->dispDeviceRowBytes >> 2);
-	}
-}
-
-#ifndef NO_SCROLL
-static void __pmac
-scrollscreen(void)
-{
-	unsigned long offset		= reloc_offset();
-	boot_infos_t* bi		= PTRRELOC(RELOC(disp_bi));
-	unsigned long *src		= (unsigned long *)calc_base(bi,0,16);
-	unsigned long *dst		= (unsigned long *)calc_base(bi,0,0);
-	unsigned long width		= ((bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) *
-						(bi->dispDeviceDepth >> 3)) >> 2;
-	int i,j;
-	
-#ifdef CONFIG_ADB_PMU
-	pmu_suspend();	/* PMU will not shut us down ! */
-#endif
-	for (i=0; i<(bi->dispDeviceRect[3] - bi->dispDeviceRect[1] - 16); i++)
-	{
-		unsigned long *src_ptr = src;
-		unsigned long *dst_ptr = dst;
-		for(j=width; j; --j)
-			*(dst_ptr++) = *(src_ptr++);
-		src += (bi->dispDeviceRowBytes >> 2);
-		dst += (bi->dispDeviceRowBytes >> 2);
-	}
-	for (i=0; i<16; i++)
-	{
-		unsigned long *dst_ptr = dst;
-		for(j=width; j; --j)
-			*(dst_ptr++) = 0;
-		dst += (bi->dispDeviceRowBytes >> 2);
-	}
-#ifdef CONFIG_ADB_PMU
-	pmu_resume();	/* PMU will not shut us down ! */
-#endif
-}
-#endif /* ndef NO_SCROLL */
-
-void __pmac
-prom_drawchar(char c)
-{
-	unsigned long offset = reloc_offset();
-	int cline = 0, x;
-
-	if (!RELOC(bootx_text_mapped))
-		return;
-
-	switch (c) {
-	case '\b':
-		if (RELOC(g_loc_X) > 0)
-			--RELOC(g_loc_X);
-		break;
-	case '\t':
-		RELOC(g_loc_X) = (RELOC(g_loc_X) & -8) + 8;
-		break;
-	case '\r':
-		RELOC(g_loc_X) = 0;
-		break;
-	case '\n':
-		RELOC(g_loc_X) = 0;
-		RELOC(g_loc_Y)++;
-		cline = 1;
-		break;
-	default:
-		draw_byte(c, RELOC(g_loc_X)++, RELOC(g_loc_Y));
-	}
-	if (RELOC(g_loc_X) >= RELOC(g_max_loc_X)) {
-		RELOC(g_loc_X) = 0;
-		RELOC(g_loc_Y)++;
-		cline = 1;
-	}
-#ifndef NO_SCROLL
-	while (RELOC(g_loc_Y) >= RELOC(g_max_loc_Y)) {
-		scrollscreen();
-		RELOC(g_loc_Y)--;
-	}
-#else
-	/* wrap around from bottom to top of screen so we don't
-	   waste time scrolling each line.  -- paulus. */
-	if (RELOC(g_loc_Y) >= RELOC(g_max_loc_Y))
-		RELOC(g_loc_Y) = 0;
-	if (cline) {
-		for (x = 0; x < RELOC(g_max_loc_X); ++x)
-			draw_byte(' ', x, RELOC(g_loc_Y));
-	}
-#endif
-}
-
-void __pmac
-prom_drawstring(const char *c)
-{
-	unsigned long offset	= reloc_offset();
-
-	if (!RELOC(bootx_text_mapped))
-		return;
-	while (*c)
-		prom_drawchar(*c++);
-}
-
-void __pmac
-prom_drawhex(unsigned long v)
-{
-	static char hex_table[] = "0123456789abcdef";
-	unsigned long offset	= reloc_offset();
-	
-	if (!RELOC(bootx_text_mapped))
-		return;
-	prom_drawchar(RELOC(hex_table)[(v >> 28) & 0x0000000FUL]);
-	prom_drawchar(RELOC(hex_table)[(v >> 24) & 0x0000000FUL]);
-	prom_drawchar(RELOC(hex_table)[(v >> 20) & 0x0000000FUL]);
-	prom_drawchar(RELOC(hex_table)[(v >> 16) & 0x0000000FUL]);
-	prom_drawchar(RELOC(hex_table)[(v >> 12) & 0x0000000FUL]);
-	prom_drawchar(RELOC(hex_table)[(v >>  8) & 0x0000000FUL]);
-	prom_drawchar(RELOC(hex_table)[(v >>  4) & 0x0000000FUL]);
-	prom_drawchar(RELOC(hex_table)[(v >>  0) & 0x0000000FUL]);
-}
-
-static void __pmac
-draw_byte(unsigned char c, long locX, long locY)
-{
-	unsigned long offset	= reloc_offset();
-	boot_infos_t* bi	= PTRRELOC(RELOC(disp_bi));
-	unsigned char *base	= calc_base(bi, locX << 3, locY << 4);
-	unsigned char *font	= &RELOC(vga_font)[((unsigned long)c) * 16];
-	int rb			= bi->dispDeviceRowBytes;
-	
-	switch(bi->dispDeviceDepth) {
-		case 32:
-			draw_byte_32(font, (unsigned long *)base, rb);
-			break;
-		case 16:
-			draw_byte_16(font, (unsigned long *)base, rb);
-			break;
-		case 8:
-			draw_byte_8(font, (unsigned long *)base, rb);
-			break;
-		default:
-			break;
-	}
-}
-
-static unsigned long expand_bits_8[16] __pmacdata  = {
-	0x00000000,
-	0x000000ff,
-	0x0000ff00,
-	0x0000ffff,
-	0x00ff0000,
-	0x00ff00ff,
-	0x00ffff00,
-	0x00ffffff,
-	0xff000000,
-	0xff0000ff,
-	0xff00ff00,
-	0xff00ffff,
-	0xffff0000,
-	0xffff00ff,
-	0xffffff00,
-	0xffffffff
-};
-
-static unsigned long expand_bits_16[4] __pmacdata = {
-	0x00000000,
-	0x0000ffff,
-	0xffff0000,
-	0xffffffff
-};
-
-static void __pmac
-draw_byte_32(unsigned char *font, unsigned long *base, int rb)
-{
-	int l, bits;	
-	int fg = 0xFFFFFFFFUL;
-	int bg = 0x00000000UL;
-	
-	for (l = 0; l < 16; ++l)
-	{
-		bits = *font++;
-		base[0] = (-(bits >> 7) & fg) ^ bg;
-		base[1] = (-((bits >> 6) & 1) & fg) ^ bg;
-		base[2] = (-((bits >> 5) & 1) & fg) ^ bg;
-		base[3] = (-((bits >> 4) & 1) & fg) ^ bg;
-		base[4] = (-((bits >> 3) & 1) & fg) ^ bg;
-		base[5] = (-((bits >> 2) & 1) & fg) ^ bg;
-		base[6] = (-((bits >> 1) & 1) & fg) ^ bg;
-		base[7] = (-(bits & 1) & fg) ^ bg;
-		base = (unsigned long *) ((char *)base + rb);
-	}
-}
-
-static void __pmac
-draw_byte_16(unsigned char *font, unsigned long *base, int rb)
-{
-	int l, bits;	
-	int fg = 0xFFFFFFFFUL;
-	int bg = 0x00000000UL;
-	unsigned long offset = reloc_offset();
-	unsigned long *eb = RELOC(expand_bits_16);
-
-	for (l = 0; l < 16; ++l)
-	{
-		bits = *font++;
-		base[0] = (eb[bits >> 6] & fg) ^ bg;
-		base[1] = (eb[(bits >> 4) & 3] & fg) ^ bg;
-		base[2] = (eb[(bits >> 2) & 3] & fg) ^ bg;
-		base[3] = (eb[bits & 3] & fg) ^ bg;
-		base = (unsigned long *) ((char *)base + rb);
-	}
-}
-
-static void __pmac
-draw_byte_8(unsigned char *font, unsigned long *base, int rb)
-{
-	int l, bits;	
-	int fg = 0x0F0F0F0FUL;
-	int bg = 0x00000000UL;
-	unsigned long offset = reloc_offset();
-	unsigned long *eb = RELOC(expand_bits_8);
-
-	for (l = 0; l < 16; ++l)
-	{
-		bits = *font++;
-		base[0] = (eb[bits >> 4] & fg) ^ bg;
-		base[1] = (eb[bits & 0xf] & fg) ^ bg;
-		base = (unsigned long *) ((char *)base + rb);
-	}
-}
-
-static unsigned char vga_font[cmapsz] __pmacdata = {
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 
-0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff, 
-0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 
-0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 
-0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 
-0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 
-0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 
-0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1e, 0x0e, 
-0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 
-0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x63, 
-0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 
-0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0e, 
-0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 
-0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdb, 
-0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 
-0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 
-0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 
-0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 
-0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 
-0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 
-0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 
-0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 
-0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 
-0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 
-0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, 
-0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 
-0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 
-0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 
-0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 
-0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 
-0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 
-0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 
-0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 
-0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 
-0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xde, 0xde, 
-0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 
-0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 
-0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x6c, 
-0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 
-0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 
-0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c, 
-0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 
-0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xe7, 
-0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 
-0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 
-0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 
-0x0c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 
-0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 
-0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 
-0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 
-0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 
-0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 
-0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 
-0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 
-0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 
-0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 
-0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 
-0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x60, 
-0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 
-0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 
-0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, 0x00, 0x00, 0xe0, 0x60, 
-0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 
-0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0xe0, 0x60, 
-0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb, 
-0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 
-0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 
-0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30, 
-0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 
-0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 
-0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 
-0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18, 
-0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 
-0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 
-0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00, 
-0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 
-0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 
-0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 
-0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 
-0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, 
-0x3c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 
-0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 
-0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66, 
-0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 
-0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00, 
-0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 
-0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b, 
-0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x6c, 
-0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 
-0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 
-0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 
-0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 
-0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, 
-0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 
-0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 
-0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18, 
-0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 
-0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 
-0xd8, 0x70, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 
-0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 
-0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 
-0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 
-0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 
-0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, 
-0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 
-0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06, 
-0x0c, 0x1f, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 
-0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 
-0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 
-0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x44, 0x11, 0x44, 
-0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 
-0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 
-0x55, 0xaa, 0x55, 0xaa, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 
-0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 
-0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 
-0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 
-0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
-0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
-0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 
-0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
-0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 
-0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
-0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 
-0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
-0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 
-0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 
-0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
-0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 
-0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 
-0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
-0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
-0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
-0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 
-0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 
-0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 
-0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 
-0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 
-0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 
-0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 
-0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 
-0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 
-0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 
-0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 
-0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 
-0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 
-0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x1b, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 
-0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, 
-0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c, 
-0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 
-};
-
-#endif /* CONFIG_BOOTX_TEXT */
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/residual.c linux/arch/ppc/kernel/residual.c
--- v2.4.9/linux/arch/ppc/kernel/residual.c	Mon May 21 17:04:47 2001
+++ linux/arch/ppc/kernel/residual.c	Sat Sep  8 12:38:42 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.residual.c 1.7 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.residual.c 1.11 09/08/01 15:47:42 paulus
  */
 /*
  * Code to deal with the PReP residual data.
@@ -44,7 +44,7 @@
 #include <linux/pci.h>
 #include <linux/ide.h>
 
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <asm/mmu.h>
 #include <asm/processor.h>
 #include <asm/io.h>
@@ -55,7 +55,7 @@
 unsigned char __res[sizeof(RESIDUAL)] __prepdata = {0,};
 RESIDUAL *res = (RESIDUAL *)&__res;
 
-const char * PnP_BASE_TYPES[] __initdata = {
+char * PnP_BASE_TYPES[] __initdata = {
   "Reserved",
   "MassStorageDevice",
   "NetworkInterfaceController",
@@ -71,7 +71,7 @@
 
 /* Device Sub Type Codes */
 
-const unsigned char * PnP_SUB_TYPES[] __initdata = {
+unsigned char * PnP_SUB_TYPES[] __initdata = {
   "\001\000SCSIController",
   "\001\001IDEController",
   "\001\002FloppyController",
@@ -128,7 +128,7 @@
 
 /* Device Interface Type Codes */
 
-const  unsigned char * PnP_INTERFACES[] __initdata = {
+unsigned char * PnP_INTERFACES[] __initdata = {
   "\000\000\000General",
   "\001\000\000GeneralSCSI",
   "\001\001\000GeneralIDE",
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/setup.c linux/arch/ppc/kernel/setup.c
--- v2.4.9/linux/arch/ppc/kernel/setup.c	Mon Aug 27 12:41:39 2001
+++ linux/arch/ppc/kernel/setup.c	Sat Sep  8 12:38:42 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.setup.c 1.46 07/26/01 14:18:18 trini
+ * BK Id: SCCS/s.setup.c 1.57 09/08/01 15:47:42 paulus
  */
 /*
  * Common prep/pmac/chrp boot and setup code.
@@ -17,7 +17,6 @@
 #include <linux/tty.h>
 #include <linux/bootmem.h>
 
-#include <asm/init.h>
 #include <asm/residual.h>
 #include <asm/io.h>
 #include <asm/prom.h>
@@ -28,6 +27,7 @@
 #include <asm/amigappc.h>
 #include <asm/smp.h>
 #include <asm/elf.h>
+#include <asm/cputable.h>
 #ifdef CONFIG_8xx
 #include <asm/mpc8xx.h>
 #include <asm/8xx_immap.h>
@@ -40,55 +40,18 @@
 #include <asm/ppc4xx.h>
 #endif
 #include <asm/bootx.h>
+#include <asm/btext.h>
 #include <asm/machdep.h>
 #include <asm/feature.h>
 #include <asm/uaccess.h>
+#include <asm/system.h>
 
-
-extern void apus_init(unsigned long r3,
-                      unsigned long r4,
-                      unsigned long r5,
-                      unsigned long r6,
-                      unsigned long r7);
-
-extern void chrp_init(unsigned long r3,
-                      unsigned long r4,
-                      unsigned long r5,
-                      unsigned long r6,
-                      unsigned long r7);
-
-extern void gemini_init(unsigned long r3,
-                      unsigned long r4,
-                      unsigned long r5,
-                      unsigned long r6,
-                      unsigned long r7);
-
-extern void m8xx_init(unsigned long r3,
-		     unsigned long r4,
-		     unsigned long r5,
-		     unsigned long r6,
-		     unsigned long r7);
-
-extern void m8260_init(unsigned long r3,
-		     unsigned long r4,
-		     unsigned long r5,
-		     unsigned long r6,
-		     unsigned long r7);
-
-extern void pmac_init(unsigned long r3,
-                      unsigned long r4,
-                      unsigned long r5,
-                      unsigned long r6,
-                      unsigned long r7);
-
-extern void prep_init(unsigned long r3,
-                      unsigned long r4,
-                      unsigned long r5,
-                      unsigned long r6,
-                      unsigned long r7);
-
+extern void platform_init(unsigned long r3, unsigned long r4,
+		unsigned long r5, unsigned long r6, unsigned long r7);
 extern void bootx_init(unsigned long r4, unsigned long phys);
 extern unsigned long reloc_offset(void);
+extern void identify_cpu(unsigned long offset, unsigned long cpu);
+extern void do_cpu_ftr_fixups(unsigned long offset);
 
 #ifdef CONFIG_XMON
 extern void xmon_map_scc(void);
@@ -98,6 +61,13 @@
 char saved_command_line[256];
 unsigned char aux_device_present;
 struct ide_machdep_calls ppc_ide_md;
+char *sysmap;
+unsigned long sysmap_size;
+
+/* Used with the BI_MEMSIZE bootinfo parameter to store the memory
+   size value reported by the boot loader. */ 
+unsigned int boot_mem_size;
+
 int parse_bootinfo(void);
 
 unsigned long ISA_DMA_THRESHOLD;
@@ -105,7 +75,13 @@
 
 #ifdef CONFIG_ALL_PPC
 int _machine = 0;
-int have_of = 0;
+
+extern void prep_init(unsigned long r3, unsigned long r4,
+		unsigned long r5, unsigned long r6, unsigned long r7);
+extern void pmac_init(unsigned long r3, unsigned long r4,
+		unsigned long r5, unsigned long r6, unsigned long r7);
+extern void chrp_init(unsigned long r3, unsigned long r4,
+		unsigned long r5, unsigned long r6, unsigned long r7);
 #endif /* CONFIG_ALL_PPC */
 
 #ifdef CONFIG_MAGIC_SYSRQ
@@ -126,15 +102,7 @@
 int icache_bsize;
 int ucache_bsize;
 
-/*
- * Perhaps we can put the pmac screen_info[] here
- * on pmac as well so we don't need the ifdef's.
- * Until we get multiple-console support in here
- * that is.  -- Cort
- * Maybe tie it to serial consoles, since this is really what
- * these processors use on existing boards.  -- Dan
- */ 
-#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx) && !defined(CONFIG_8260)
+#ifdef CONFIG_VGA_CONSOLE
 struct screen_info screen_info = {
 	0, 25,			/* orig-x, orig-y */
 	0,			/* unused */
@@ -146,35 +114,7 @@
 	1,			/* orig-video-isVGA */
 	16			/* orig-video-points */
 };
-
-/*
- * I really need to add multiple-console support... -- Cort
- */
-int __init pmac_display_supported(char *name)
-{
-	return 0;
-}
-void __init pmac_find_display(void)
-{
-}
-
-#else /* CONFIG_4xx || CONFIG_8xx */
-
-/* We need this to satisfy some external references until we can
- * strip the kernel down.
- */
-struct screen_info screen_info = {
-	0, 25,			/* orig-x, orig-y */
-	0,			/* unused */
-	0,			/* orig-video-page */
-	0,			/* orig-video-mode */
-	80,			/* orig-video-cols */
-	0,0,0,			/* ega_ax, ega_bx, ega_cx */
-	25,			/* orig-video-lines */
-	0,			/* orig-video-isVGA */
-	16			/* orig-video-points */
-};
-#endif /* !CONFIG_4xx && !CONFIG_8xx */
+#endif /* CONFIG_VGA_CONSOLE */
 
 void machine_restart(char *cmd)
 {
@@ -190,35 +130,11 @@
 {
 	ppc_md.halt();
 }
-  
-unsigned long cpu_temp(void)
-{
-	unsigned char thres = 0;
-	
-#if 0
-	/* disable thrm2 */
-	_set_THRM2( 0 );
-	/* threshold 0 C, tid: exceeding threshold, tie: don't generate interrupt */
-	_set_THRM1( THRM1_V );
-
-	/* we need 20us to do the compare - assume 300MHz processor clock */
-	_set_THRM3(0);
-	_set_THRM3(THRM3_E | (300*30)<<18 );
-
-	udelay(100);
-	/* wait for the compare to complete */
-	/*while ( !(_get_THRM1() & THRM1_TIV) ) ;*/
-	if ( !(_get_THRM1() & THRM1_TIV) )
-		printk("no tiv\n");
-	if ( _get_THRM1() & THRM1_TIN )
-		printk("crossed\n");
-	/* turn everything off */
-	_set_THRM3(0);
-	_set_THRM1(0);
-#endif
-		
-	return thres;
-}
+
+#ifdef CONFIG_TAU
+extern u32 cpu_temp(unsigned long cpu);
+extern u32 cpu_temp_both(unsigned long cpu);
+#endif /* CONFIG_TAU */
 
 int get_cpuinfo(char *buffer)
 {
@@ -227,7 +143,7 @@
 	unsigned long i;
 	unsigned int pvr;
 	unsigned short maj, min;
-	
+
 #ifdef CONFIG_SMP
 #define CPU_PRESENT(x) (cpu_callin_map[(x)])
 #define GET_PVR ((long int)(cpu_data[i].pvr))
@@ -235,7 +151,7 @@
 #else
 #define CPU_PRESENT(x) ((x)==0)
 #define smp_num_cpus 1
-#define GET_PVR ((long int)_get_PVR())
+#define GET_PVR (mfspr(PVR))
 #define CD(x) (x)
 #endif	
 
@@ -249,90 +165,31 @@
 		len += sprintf(len+buffer,"cpu\t\t: ");
 
 		pvr = GET_PVR;
-	
-		switch (PVR_VER(pvr))
-		{
-		case 0x0001:
-			len += sprintf(len+buffer, "601\n");
-			break;
-		case 0x0003:
-			len += sprintf(len+buffer, "603\n");
-			break;
-		case 0x0004:
-			len += sprintf(len+buffer, "604\n");
-			break;
-		case 0x0006:
-			len += sprintf(len+buffer, "603e\n");
-			break;
-		case 0x0007:
-			len += sprintf(len+buffer, "603");
-			if (((pvr >> 12) & 0xF) == 1) {
-				pvr ^= 0x00001000;	/* revision fix-up */
-				len += sprintf(len+buffer, "r\n");
-			} else {
-				len += sprintf(len+buffer, "ev\n");
-			}
-			break;
-		case 0x0008:		/* 740/750(P) */
-		case 0x1008:
-			len += sprintf(len+buffer, "750%s\n",
-				       PVR_VER(pvr) == 0x1008 ? "P" : "");
-			len += sprintf(len+buffer, "temperature \t: %lu C\n",
-				       cpu_temp());
-			break;
-		case 0x0009:		/* 604e/604r */
-		case 0x000A:
-			len += sprintf(len+buffer, "604");
-
-			if (PVR_VER(pvr) == 0x000A ||
-			    ((pvr >> 12) & 0xF) != 0) {
-				pvr &= ~0x00003000;	/* revision fix-up */
-				len += sprintf(len+buffer, "r\n");
-			} else {
-				len += sprintf(len+buffer, "e\n");
-			}
-			break;
-		case 0x000C:
-			len += sprintf(len+buffer, "7400 (G4");
+
+		if (cur_cpu_spec[i]->pvr_mask)
+			len += sprintf(len+buffer, "%s", cur_cpu_spec[i]->cpu_name);
+		else
+			len += sprintf(len+buffer, "unknown (%08x)", pvr);
 #ifdef CONFIG_ALTIVEC
+		if (cur_cpu_spec[i]->cpu_features & CPU_FTR_ALTIVEC)
 			len += sprintf(len+buffer, ", altivec supported");
-#endif /* CONFIG_ALTIVEC */
-			len += sprintf(len+buffer, ")\n");
-			break;
-		case 0x0020:
-			len += sprintf(len+buffer, "403G");
-			switch ((pvr >> 8) & 0xFF) {
-			case 0x02:
-				len += sprintf(len+buffer, "C\n");    
-				break;				      
-			case 0x14:
-				len += sprintf(len+buffer, "CX\n");
-				break;
-			}
-			break;
-		case 0x0035:
-			len += sprintf(len+buffer, "POWER4\n");
-			break;
-		case 0x0040:
-			len += sprintf(len+buffer, "POWER3 (630)\n");
-			break;
-		case 0x0041:
-			len += sprintf(len+buffer, "POWER3 (630+)\n");
-			break;
-		case 0x0050:
-			len += sprintf(len+buffer, "8xx\n");
-			break;
-		case 0x0081:
-			len += sprintf(len+buffer, "82xx\n");
-			break;
-		case 0x4011:
-			len += sprintf(len+buffer, "405GP\n");
-			break;
-		default:
-			len += sprintf(len+buffer, "unknown (%08x)\n", pvr);
-			break;
+#endif		
+		len += sprintf(len+buffer, "\n");
+#ifdef CONFIG_TAU
+		if (cur_cpu_spec[i]->cpu_features & CPU_FTR_TAU) {
+#ifdef CONFIG_TAU_AVERAGE	/* more straightforward, but potentially misleading */
+			len += sprintf(len+buffer, "temperature \t: %u C (uncalibrated)\n",
+				       cpu_temp(i));
+#else
+			/* show the actual temp sensor range */
+			u32 temp;
+			temp = cpu_temp_both(i);
+			len += sprintf(len+buffer, "temperature \t: %u-%u C (uncalibrated)\n",
+					temp & 0xff, temp >> 16);
+#endif
 		}
-		
+#endif
+
 		/*
 		 * Assume here that all clock rates are the same in a
 		 * smp system.  -- Cort
@@ -394,7 +251,7 @@
 	}
 
 #ifdef CONFIG_SMP
-	if ( i )
+	if ( i && smp_num_cpus > 1)
 		len += sprintf(buffer+len, "\n");
 	len += sprintf(buffer+len,"total bogomips\t: %lu.%02lu\n",
 		       bogosum/(500000/HZ),
@@ -423,31 +280,6 @@
 	return len;
 }
 
-#ifdef CONFIG_ALL_PPC
-void __init
-intuit_machine_type(void)
-{
-	char *model;
-	struct device_node *root;
-			
-	/* ask the OF info if we're a chrp or pmac */
-	root = find_path_device("/");
-	if (root != 0) {
-		/* assume pmac unless proven to be chrp -- Cort */
-		_machine = _MACH_Pmac;
-		model = get_property(root, "device_type", NULL);
-		if (model && !strncmp("chrp", model, 4))
-			_machine = _MACH_chrp;
-		else {
-			model = get_property(root, "model", NULL);
-			if (model && !strncmp(model, "IBM", 3))
-				_machine = _MACH_chrp;
-		}
-	}
-}
-#endif /* CONFIG_ALL_PPC */
-
-#if defined(CONFIG_6xx) || defined(CONFIG_PPC64BRIDGE)
 /*
  * We're called here very early in the boot.  We determine the machine
  * type and call the appropriate low-level setup functions.
@@ -472,6 +304,13 @@
 	 * caches on yet */
 	memset_io(PTRRELOC(&__bss_start), 0, &_end - &__bss_start);
 
+	/*
+	 * Identify the CPU type and fix up code sections
+	 * that depend on which cpu we have.
+	 */
+	identify_cpu(offset, 0);
+	do_cpu_ftr_fixups(offset);
+
 #if defined(CONFIG_ALL_PPC)
 	/* If we came here from BootX, clear the screen,
 	 * set up some pointers and return. */
@@ -493,78 +332,105 @@
 
 	return phys;
 }
-#endif /* CONFIG_6xx || CONFIG_PPC64BRIDGE */
+
+#ifdef CONFIG_ALL_PPC
+void __init
+intuit_machine_type(void)
+{
+	char *model;
+	struct device_node *root;
+			
+	/* ask the OF info if we're a chrp or pmac */
+	root = find_path_device("/");
+	if (root != 0) {
+		/* assume pmac unless proven to be chrp -- Cort */
+		_machine = _MACH_Pmac;
+		model = get_property(root, "device_type", NULL);
+		if (model && !strncmp("chrp", model, 4))
+			_machine = _MACH_chrp;
+		else {
+			model = get_property(root, "model", NULL);
+			if (model && !strncmp(model, "IBM", 3))
+				_machine = _MACH_chrp;
+		}
+	}
+}
 
 /*
- * Find out what kind of machine we're on and save any data we need
- * from the early boot process (devtree is copied on pmac by prom_init() )
+ * The ALL_PPC version of platform_init...
  */
-unsigned long __init
-identify_machine(unsigned long r3, unsigned long r4, unsigned long r5,
-		 unsigned long r6, unsigned long r7)
+void __init
+platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
+	      unsigned long r6, unsigned long r7)
 {
-#ifdef CONFIG_CMDLINE
-	strcpy(cmd_line, CONFIG_CMDLINE);
-#endif /* CONFIG_CMDLINE */
+#ifdef CONFIG_BOOTX_TEXT
+	extern boot_infos_t *disp_bi;
 
-	parse_bootinfo();
+	if (disp_bi) {
+		btext_clearscreen();
+		btext_welcome(disp_bi);
+	}
+#endif	
 
-	if ( ppc_md.progress ) ppc_md.progress("id mach(): start", 0x100);
-	
-#ifdef CONFIG_ALL_PPC
 	/* if we didn't get any bootinfo telling us what we are... */
-	if ( _machine == 0 )
-	{
+	if (_machine == 0) {
 		/* prep boot loader tells us if we're prep or not */
 		if ( *(unsigned long *)(KERNELBASE) == (0xdeadc0de) )
-		{
 			_machine = _MACH_prep;
-		} else
-			have_of = 1;
 	}
 
-	if ( have_of )
-	{
-		/* prom_init has already been called from __start */
-		if (boot_infos)
-			relocate_nodes();
-		/* we need to set _machine before calling finish_device_tree */
-		if (_machine == 0)
-			intuit_machine_type();
-		finish_device_tree();
-		/*
-		 * If we were booted via quik, r3 points to the physical
-		 * address of the command-line parameters.
-		 * If we were booted from an xcoff image (i.e. netbooted or
-		 * booted from floppy), we get the command line from the
-		 * bootargs property of the /chosen node.
-		 * If an initial ramdisk is present, r3 and r4
-		 * are used for initrd_start and initrd_size,
-		 * otherwise they contain 0xdeadbeef.  
-		 */
-		if (r3 >= 0x4000 && r3 < 0x800000 && r4 == 0) {
-			strncpy(cmd_line, (char *)r3 + KERNELBASE,
+	/* not much more to do here, if prep */
+	if (_machine == _MACH_prep) {
+		prep_init(r3, r4, r5, r6, r7);
+		return;
+	}
+
+	/* prom_init has already been called from __start */
+	if (boot_infos)
+		relocate_nodes();
+
+	/* If we aren't PReP, we can find out if we're Pmac
+	 * or CHRP with this. */
+	if (_machine == 0)
+		intuit_machine_type();
+
+	/* finish_device_tree may need _machine defined. */
+	finish_device_tree();
+
+	/*
+	 * If we were booted via quik, r3 points to the physical
+	 * address of the command-line parameters.
+	 * If we were booted from an xcoff image (i.e. netbooted or
+	 * booted from floppy), we get the command line from the
+	 * bootargs property of the /chosen node.
+	 * If an initial ramdisk is present, r3 and r4
+	 * are used for initrd_start and initrd_size,
+	 * otherwise they contain 0xdeadbeef.  
+	 */
+	if (r3 >= 0x4000 && r3 < 0x800000 && r4 == 0) {
+		cmd_line[0] = 0;
+		strncpy(cmd_line, (char *)r3 + KERNELBASE,
+			sizeof(cmd_line));
+	} else if (boot_infos != 0) {
+		/* booted by BootX - check for ramdisk */
+		if (boot_infos->kernelParamsOffset != 0)
+			strncpy(cmd_line, (char *) boot_infos
+				+ boot_infos->kernelParamsOffset,
 				sizeof(cmd_line));
-		} else if (boot_infos != 0) {
-			/* booted by BootX - check for ramdisk */
- 			if (boot_infos->kernelParamsOffset != 0)
-				strncpy(cmd_line, (char *) boot_infos
-					+ boot_infos->kernelParamsOffset,
-					sizeof(cmd_line));
 #ifdef CONFIG_BLK_DEV_INITRD
-			if (boot_infos->ramDisk) {
-				initrd_start = (unsigned long) boot_infos
-					+ boot_infos->ramDisk;
-				initrd_end = initrd_start + boot_infos->ramDiskSize;
-				initrd_below_start_ok = 1;
-			}
+		if (boot_infos->ramDisk) {
+			initrd_start = (unsigned long) boot_infos
+				+ boot_infos->ramDisk;
+			initrd_end = initrd_start + boot_infos->ramDiskSize;
+			initrd_below_start_ok = 1;
+		}
 #endif
-		} else {
-			struct device_node *chosen;
-			char *p;
+	} else {
+		struct device_node *chosen;
+		char *p;
 			
 #ifdef CONFIG_BLK_DEV_INITRD
-			if (r3 && r4 && r4 != 0xdeadbeef)
+		if (r3 && r4 && r4 != 0xdeadbeef)
 			{
 				if (r3 < KERNELBASE)
 					r3 += KERNELBASE;
@@ -574,92 +440,32 @@
 				initrd_below_start_ok = 1;
 			}
 #endif
-			chosen = find_devices("chosen");
-			if (chosen != NULL) {
-				p = get_property(chosen, "bootargs", NULL);
-				if (p && *p) {
-					cmd_line[0] = 0;
-					strncpy(cmd_line, p, sizeof(cmd_line));
-				}
+		chosen = find_devices("chosen");
+		if (chosen != NULL) {
+			p = get_property(chosen, "bootargs", NULL);
+			if (p && *p) {
+				cmd_line[0] = 0;
+				strncpy(cmd_line, p, sizeof(cmd_line));
 			}
 		}
-		cmd_line[sizeof(cmd_line) - 1] = 0;
 	}
-#endif /* CONFIG_ALL_PPC */
+	cmd_line[sizeof(cmd_line) - 1] = 0;
 
-#if defined(CONFIG_ALL_PPC)
-	switch (_machine)
-	{
+	switch (_machine) {
 	case _MACH_Pmac:
-                pmac_init(r3, r4, r5, r6, r7);
-		break;
-	case _MACH_prep:
-                prep_init(r3, r4, r5, r6, r7);
+		pmac_init(r3, r4, r5, r6, r7);
 		break;
 	case _MACH_chrp:
-                chrp_init(r3, r4, r5, r6, r7);
+		chrp_init(r3, r4, r5, r6, r7);
 		break;
-	default:
-		printk("Unknown machine type in identify_machine!\n");
-	}
-#elif defined(CONFIG_APUS)
-	apus_init(r3, r4, r5, r6, r7);
-#elif defined(CONFIG_GEMINI)
-	gemini_init(r3, r4, r5, r6, r7);
-#elif defined(CONFIG_4xx)
-	oak_init(r3, r4, r5, r6, r7);
-#elif defined(CONFIG_8xx)
-        m8xx_init(r3, r4, r5, r6, r7);
-#elif defined(CONFIG_8260)
-        m8260_init(r3, r4, r5, r6, r7);
-#else
-#error "No board type has been defined for identify_machine()!"
-#endif
-
-#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx) && !defined(CONFIG_8260)
-	/* Check for nobats option (used in mapin_ram). */
-	if (strstr(cmd_line, "nobats")) {
-		extern int __map_without_bats;
-		__map_without_bats = 1;
-	}
-#endif /* !CONFIG_4xx && !CONFIG_8xx && !CONFIG_8260 */
-
-	/* Look for mem= option on command line */
-	if (strstr(cmd_line, "mem=")) {
-		char *p, *q;
-		unsigned long maxmem = 0;
-		extern unsigned long __max_memory;
-
-		for (q = cmd_line; (p = strstr(q, "mem=")) != 0; ) {
-			q = p + 4;
-			if (p > cmd_line && p[-1] != ' ')
-				continue;
-			maxmem = simple_strtoul(q, &q, 0);
-			if (*q == 'k' || *q == 'K') {
-				maxmem <<= 10;
-				++q;
-			} else if (*q == 'm' || *q == 'M') {
-				maxmem <<= 20;
-				++q;
-			}
-		}
-		__max_memory = maxmem;
 	}
-
-	/* this is for modules since _machine can be a define -- Cort */
-	ppc_md.ppc_machine = _machine;
-
-	if ( ppc_md.progress ) ppc_md.progress("id mach(): done", 0x200);
-
-	return 0;
 }
+#endif /* CONFIG_ALL_PPC */
 
 int parse_bootinfo(void)
 {
 	struct bi_record *rec;
 	extern char __bss_start[];
-	extern char *sysmap;
-	extern unsigned long sysmap_size;
 
 	rec = (struct bi_record *)_ALIGN((ulong)__bss_start+(1<<20)-1,(1<<20));
 	if ( rec->tag != BI_FIRST )
@@ -696,20 +502,43 @@
 #ifdef CONFIG_ALL_PPC
 		case BI_MACHTYPE:
 			_machine = data[0];
-			have_of = data[1];
 			break;
 #endif /* CONFIG_ALL_PPC */
+		case BI_MEMSIZE:
+			boot_mem_size = data[0];
+			break;
 		}
 	}
 
 	return 0;
 }
 
+/*
+ * Find out what kind of machine we're on and save any data we need
+ * from the early boot process (devtree is copied on pmac by prom_init()).
+ * This is called very early on the boot process, after a minimal
+ * MMU environment has been set up but before MMU_init is called.
+ */
+void __init
+machine_init(unsigned long r3, unsigned long r4, unsigned long r5,
+	     unsigned long r6, unsigned long r7)
+{
+#ifdef CONFIG_CMDLINE
+	strcpy(cmd_line, CONFIG_CMDLINE);
+#endif /* CONFIG_CMDLINE */
+
+	parse_bootinfo();
+
+	platform_init(r3, r4, r5, r6, r7);
+
+	if (ppc_md.progress)
+		ppc_md.progress("id mach(): done", 0x200);
+}
+
 /* Checks "l2cr=xxxx" command-line option */
-int ppc_setup_l2cr(char *str)
+int __init ppc_setup_l2cr(char *str)
 {
-	if ( ((_get_PVR() >> 16) == 8) || ((_get_PVR() >> 16) == 12) )
-	{
+	if (cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR) {
 		unsigned long val = simple_strtoul(str, NULL, 0);
 		printk(KERN_INFO "l2cr set to %lx\n", val);
                 _set_L2CR(0);           /* force invalidate by disable cache */
@@ -761,18 +590,13 @@
 	 * Systems with OF can look in the properties on the cpu node(s)
 	 * for a possibly more accurate value.
 	 */
-	dcache_bsize = icache_bsize = 32;	/* most common value */
-	switch (_get_PVR() >> 16) {
-	case 1:		/* 601, with unified cache */
-		ucache_bsize = 32;
-		break;
-	/* XXX need definitions in here for 8xx etc. */
-	case 0x40:
-	case 0x41:
-	case 0x35:	/* 64-bit POWER3, POWER3+, POWER4 */
-		dcache_bsize = icache_bsize = 128;
-		break;
-	}
+	if (cur_cpu_spec[0]->cpu_features & CPU_FTR_SPLIT_ID_CACHE) {
+		dcache_bsize = cur_cpu_spec[0]->dcache_bsize;
+		icache_bsize = cur_cpu_spec[0]->icache_bsize;
+		ucache_bsize = 0;
+	} else
+		ucache_bsize = dcache_bsize = icache_bsize
+			= cur_cpu_spec[0]->dcache_bsize;
 
 	/* reboot on panic */
 	panic_timeout = 180;
@@ -813,6 +637,9 @@
 
 	paging_init();
 	sort_exception_table();
+
+	/* this is for modules since _machine can be a define -- Cort */
+	ppc_md.ppc_machine = _machine;
 }
 
 /* Convert the shorts/longs in hd_driveid from little to big endian;
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/sleep.S linux/arch/ppc/kernel/sleep.S
--- v2.4.9/linux/arch/ppc/kernel/sleep.S	Tue Jul  3 17:08:18 2001
+++ linux/arch/ppc/kernel/sleep.S	Tue Aug 28 06:58:33 2001
@@ -1,10 +1,10 @@
 /*
- * BK Id: SCCS/s.sleep.S 1.10 06/28/01 15:50:17 paulus
+ * BK Id: SCCS/s.sleep.S 1.13 08/19/01 22:23:04 paulus
  */
 /*
  * This file contains sleep low-level functions for PowerBook G3.
  *    Copyright (C) 1999 Benjamin Herrenschmidt (benh@kernel.crashing.org)
- *    and Paul Mackerras (paulus@cs.anu.edu.au).
+ *    and Paul Mackerras (paulus@samba.org).
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -45,7 +45,13 @@
 #define tovirt(rd,rs)	addis	rd,rs,KERNELBASE@h
 
 	.text
+	.align	5
 
+/* This gets called by via-pmu.c late during the sleep process.
+ * The PMU was already send the sleep command and will shut us down
+ * soon. We need to save all that is needed and setup the wakeup
+ * vector that will be called by the ROM on wakeup
+ */
 _GLOBAL(low_sleep_handler)
 	mflr	r0
 	stw	r0,4(r1)
@@ -53,13 +59,14 @@
 	stw	r2,SL_R2(r1)
 	stmw	r12,SL_R12(r1)
 
-	/* Save MSR, SDR1, TB  */
+	/* Save MSR & SDR1 */
 	mfmsr	r4
 	stw	r4,SL_MSR(r1)
 	mfsdr1	r4
 	stw	r4,SL_SDR1(r1)
-1:	
-	mftbu	r4
+
+	/* Get a stable timebase and save it */
+1:	mftbu	r4
 	stw	r4,SL_TB(r1)
 	mftb	r5
 	stw	r5,SL_TB+4(r1)
@@ -114,10 +121,19 @@
 	/* Save HID0 */
 	mfspr	r4,HID0
 	stw	r4,SL_HID0(r1)
-
-	/* Set up stuff at address 0 */
-	lis	r5,wake_up@ha
-	addi	r5,r5,wake_up@l
+	
+	/* The ROM can wake us up via 2 different vectors:
+	 *  - On wallstreet & lombard, we must write a magic
+	 *    value 'Lars' at address 4 and a pointer to a
+	 *    memory location containing the PC to resume from
+	 *    at address 0.
+	 *  - On Core99, we must store the wakeup vector at
+	 *    address 0x80 and eventually it's parameters
+	 *    at address 0x84. I've have some trouble with those
+	 *    parameters however and I no longer use them.
+	 */
+	lis	r5,grackle_wake_up@ha
+	addi	r5,r5,grackle_wake_up@l
 	tophys(r5,r5)
 	stw	r5,SL_PC(r1)
 	lis	r4,KERNELBASE@h
@@ -127,22 +143,35 @@
 	addi	r6,r6,MAGIC@l
 	stw	r5,0(r4)
 	stw	r6,4(r4)
+	/* Setup stuffs at 0x80-0x84 for Core99 */
+	lis	r3,core99_wake_up@ha
+	addi	r3,r3,core99_wake_up@l
+	tophys(r3,r3)
+	stw	r3,0x80(r4)
+	stw	r5,0x84(r4)
+	/* Store a pointer to our backup storage into
+	 * a kernel global
+	 */
+	lis r3,sleep_storage@ha
+	addi r3,r3,sleep_storage@l
+	stw r5,0(r3)
+
 
 /*
- * Flush the L1 data cache by reading the first 64kB of RAM
+ * Flush the L1 data cache by reading the first 128kB of RAM
  * and then flushing the same area with the dcbf instruction.
  * The L2 cache has already been disabled.
  */
-	li	r4,0x0800	/* 64kB / 32B */
+	li	r4,0x1000	/* 128kB / 32B */
 	mtctr	r4
 	lis	r4,KERNELBASE@h
 1:
 	lwz	r0,0(r4)
-	addi	r4,r4,0x0020		/* Go to start of next cache line */
+	addi	r4,r4,0x0020	/* Go to start of next cache line */
 	bdnz	1b
 	sync
 	
-	li	r4,0x0800	/* 64k */
+	li	r4,0x1000	/* 128kB / 32B */
 	mtctr	r4
 	lis	r4,KERNELBASE@h
 1:
@@ -160,7 +189,13 @@
 	sync
 	mtspr	HID0,r2
 	sync
-	
+
+/* This loop puts us back to sleep in case we have a spurrious
+ * wakeup so that the host bridge properly stays asleep. The
+ * CPU will be turned off, either after a known time (about 1
+ * second) on wallstreet & lombard, or as soon as the CPU enters
+ * SLEEP mode on core99
+ */
 	mfmsr	r2
 	oris	r2,r2,MSR_POW@h
 1:	sync
@@ -170,22 +205,66 @@
 
 /* 
  * Here is the resume code.
+ */
+
+
+/*
+ * Core99 machines resume here
+ * r4 has the physical address of SL_PC(sp) (unused)
+ */
+_GLOBAL(core99_wake_up)
+	/* Make sure HID0 no longer contains any sleep bit */
+	mfspr	r3,HID0
+	rlwinm	r3,r3,0,11,7		/* clear SLEEP, NAP, DOZE bits */
+	mtspr	HID0,r3
+	sync
+	isync
+
+	/* Won't that cause problems on CPU that doesn't support it ? */
+	lis	r3, 0
+	mtspr	SPRN_MMCR0, r3
+	
+	/* sanitize MSR */
+	mfmsr	r3
+	ori	r3,r3,MSR_EE|MSR_IP
+	xori	r3,r3,MSR_EE|MSR_IP
+	sync
+	isync
+	mtmsr	r3
+	sync
+	isync
+
+	/* Recover sleep storage */
+	lis	r3,sleep_storage@ha
+	addi	r3,r3,sleep_storage@l
+	tophys(r3,r3)
+	lwz	r1,0(r3)
+
+	/* Pass thru to older resume code ... */
+/* 
+ * Here is the resume code for older machines.
  * r1 has the physical address of SL_PC(sp).
  */
 	
-wake_up:
-	/* Flash inval the instruction cache */
+grackle_wake_up:
+	/* Enable and then Flash inval the instruction & data cache */
 	mfspr	r3,HID0
-	ori	r3,r3, HID0_ICFI
-	mtspr	HID0,r3
+	ori	r3,r3, HID0_ICE|HID0_ICFI|HID0_DCE|HID0_DCI
+	sync
 	isync
-	/* Restore the HID0 register.  This turns on the L1 caches. */
+	mtspr	HID0,r3
+	xori	r3,r3, HID0_ICFI|HID0_DCI
+	mtspr	HID0,r3
+	sync
+	
+	/* Restore the remaining bits of the HID0 register. */
 	subi	r1,r1,SL_PC
 	lwz	r3,SL_HID0(r1)
 	sync
 	isync
 	mtspr	HID0,r3
 	sync
+	isync
 
 	/* Restore the kernel's segment registers, the
 	   BATs, and SDR1.  Then we can turn on the MMU. */
@@ -242,6 +321,13 @@
 	lwz	r4,SL_IBAT3+4(r1)
 	mtibatl	3,r4
 
+	/* Flush all TLBs */
+	lis	r4,0x1000
+1:	addic.	r4,r4,-0x1000
+	tlbie	r4
+	blt	1b
+	sync
+
 	/* restore the MSR and turn on the MMU */
 	lwz	r3,SL_MSR(r1)
 	bl	turn_on_mmu	
@@ -250,6 +336,8 @@
 	tovirt(r1,r1)
 
 	/* Restore TB */
+	li	r3,0
+	mttbl	r3
 	lwz	r3,SL_TB(r1)
 	lwz	r4,SL_TB+4(r1)
 	mttbu	r3
@@ -269,4 +357,10 @@
 	mtsrr0	r4
 	mtsrr1	r3
 	sync
+	isync
 	rfi
+
+	.data
+	.globl sleep_storage
+sleep_storage:
+	.long 0
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/smp.c linux/arch/ppc/kernel/smp.c
--- v2.4.9/linux/arch/ppc/kernel/smp.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/ppc/kernel/smp.c	Sat Sep  8 12:38:42 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.smp.c 1.25 05/23/01 00:38:42 cort
+ * BK Id: SCCS/s.smp.c 1.31 09/08/01 15:47:42 paulus
  */
 /*
  * Smp support for ppc.
@@ -9,11 +9,6 @@
  *
  * Copyright (C) 1999 Cort Dougan <cort@cs.nmt.edu>
  *
- * Support for PReP (Motorola MTX/MVME) and Macintosh G4 SMP 
- * by Troy Benjegerdes (hozer@drgw.net)
- *
- * Support for DayStar quad CPU cards
- * Copyright (C) XLR8, Inc. 1994-2000
  */
 
 #include <linux/config.h>
@@ -36,16 +31,15 @@
 #include <asm/pgtable.h>
 #include <asm/hardirq.h>
 #include <asm/softirq.h>
-#include <asm/init.h>
 #include <asm/io.h>
 #include <asm/prom.h>
 #include <asm/smp.h>
 #include <asm/residual.h>
 #include <asm/feature.h>
 #include <asm/time.h>
-#include <asm/gemini.h>
 
 #include "open_pic.h"
+
 int smp_threads_ready;
 volatile int smp_commenced;
 int smp_num_cpus = 1;
@@ -54,13 +48,14 @@
 struct klock_info_struct klock_info = { KLOCK_CLEAR, 0 };
 atomic_t ipi_recv;
 atomic_t ipi_sent;
-spinlock_t kernel_flag = SPIN_LOCK_UNLOCKED;
+spinlock_t kernel_flag __cacheline_aligned = SPIN_LOCK_UNLOCKED;
 unsigned int prof_multiplier[NR_CPUS];
 unsigned int prof_counter[NR_CPUS];
 cycles_t cacheflush_time;
 static int max_cpus __initdata = NR_CPUS;
 unsigned long cpu_online_map;
 int smp_hw_index[NR_CPUS];
+static struct smp_ops_t *smp_ops;
 
 /* all cpu mappings are 1-1 -- Cort */
 volatile unsigned long cpu_callin_map[NR_CPUS];
@@ -74,60 +69,6 @@
 void smp_call_function_interrupt(void);
 void smp_message_pass(int target, int msg, unsigned long data, int wait);
 
-extern void __secondary_start_psurge(void);
-extern void __secondary_start_psurge2(void);	/* Temporary horrible hack */
-extern void __secondary_start_psurge3(void);	/* Temporary horrible hack */
-
-/* Addresses for powersurge registers */
-#define HAMMERHEAD_BASE		0xf8000000
-#define HHEAD_CONFIG		0x90
-#define HHEAD_SEC_INTR		0xc0
-
-/* register for interrupting the primary processor on the powersurge */
-/* N.B. this is actually the ethernet ROM! */
-#define PSURGE_PRI_INTR		0xf3019000
-
-/* register for storing the start address for the secondary processor */
-/* N.B. this is the PCI config space address register for the 1st bridge */
-#define PSURGE_START		0xf2800000
-
-/* Daystar/XLR8 4-CPU card */
-#define PSURGE_QUAD_REG_ADDR	0xf8800000
-
-#define PSURGE_QUAD_IRQ_SET	0
-#define PSURGE_QUAD_IRQ_CLR	1
-#define PSURGE_QUAD_IRQ_PRIMARY	2
-#define PSURGE_QUAD_CKSTOP_CTL	3
-#define PSURGE_QUAD_PRIMARY_ARB	4
-#define PSURGE_QUAD_BOARD_ID	6
-#define PSURGE_QUAD_WHICH_CPU	7
-#define PSURGE_QUAD_CKSTOP_RDBK	8
-#define PSURGE_QUAD_RESET_CTL	11
-
-#define PSURGE_QUAD_OUT(r, v)	(out_8(quad_base + ((r) << 4) + 4, (v)))
-#define PSURGE_QUAD_IN(r)	(in_8(quad_base + ((r) << 4) + 4) & 0x0f)
-#define PSURGE_QUAD_BIS(r, v)	(PSURGE_QUAD_OUT((r), PSURGE_QUAD_IN(r) | (v)))
-#define PSURGE_QUAD_BIC(r, v)	(PSURGE_QUAD_OUT((r), PSURGE_QUAD_IN(r) & ~(v)))
-
-/* virtual addresses for the above */
-static volatile u8 *hhead_base;
-static volatile u8 *quad_base;
-static volatile u32 *psurge_pri_intr;
-static volatile u8 *psurge_sec_intr;
-static volatile u32 *psurge_start;
-
-/* what sort of powersurge board we have */
-static int psurge_type;
-
-/* values for psurge_type */
-#define PSURGE_DUAL		0
-#define PSURGE_QUAD_OKEE	1
-#define PSURGE_QUAD_COTTON	2
-#define PSURGE_QUAD_ICEGRASS	3
-
-/* l2 cache stuff for dual G4 macs */
-extern void core99_init_l2(void);
-
 /* Since OpenPIC has only 4 IPIs, we use slightly different message numbers.
  * 
  * Make sure this matches openpic_request_IPIs in open_pic.c, or what shows up
@@ -137,621 +78,12 @@
 #define PPC_MSG_INVALIDATE_TLB	2
 #define PPC_MSG_XMON_BREAK	3
 
-static inline void set_tb(unsigned int upper, unsigned int lower)
-{
-	mtspr(SPRN_TBWL, 0);
-	mtspr(SPRN_TBWU, upper);
-	mtspr(SPRN_TBWL, lower);
-}
-
-/*
- * Set and clear IPIs for powersurge.
- */
-static inline void psurge_set_ipi(int cpu)
-{
-	if (cpu == 0)
-		in_be32(psurge_pri_intr);
-	else if (psurge_type == PSURGE_DUAL)
-		out_8(psurge_sec_intr, 0);
-	else
-		PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_SET, 1 << cpu);
-}
-
-static inline void psurge_clr_ipi(int cpu)
-{
-	if (cpu > 0) {
-		if (psurge_type == PSURGE_DUAL)
-			out_8(psurge_sec_intr, ~0);
-		else
-			PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_CLR, 1 << cpu);
-	}
-}
-
-/*
- * On powersurge (old SMP powermac architecture) we don't have
- * separate IPIs for separate messages like openpic does.  Instead
- * we have a bitmap for each processor, where a 1 bit means that
- * the corresponding message is pending for that processor.
- * Ideally each cpu's entry would be in a different cache line.
- *  -- paulus.
- */
-static unsigned long psurge_smp_message[NR_CPUS];
-
-void psurge_smp_message_recv(struct pt_regs *regs)
-{
-	int cpu = smp_processor_id();
-	int msg;
-
-	/* clear interrupt */
-	psurge_clr_ipi(cpu);
-
-	if (smp_num_cpus < 2)
-		return;
-
-	/* make sure there is a message there */
-	for (msg = 0; msg < 4; msg++)
-		if (test_and_clear_bit(msg, &psurge_smp_message[cpu]))
-			smp_message_recv(msg, regs);
-}
-
-void
-psurge_primary_intr(int irq, void *d, struct pt_regs *regs)
-{
-	psurge_smp_message_recv(regs);
-}
-
-static void
-smp_psurge_message_pass(int target, int msg, unsigned long data, int wait)
-{
-	int i;
-
-	if (smp_num_cpus < 2)
-		return;
-
-	for (i = 0; i < smp_num_cpus; i++) {
-		if (target == MSG_ALL
-		    || (target == MSG_ALL_BUT_SELF && i != smp_processor_id())
-		    || target == i) {
-			set_bit(msg, &psurge_smp_message[i]);
-			psurge_set_ipi(i);
-		}
-	}
-}
-
-/*
- * Determine a quad card presence. We read the board ID register, we
- * force the data bus to change to something else, and we read it again.
- * It it's stable, then the register probably exist (ugh !)
- */
-static int __init psurge_quad_probe(void)
-{
-	int type;
-	unsigned int i;
-
-	type = PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID);
-	if (type < PSURGE_QUAD_OKEE || type > PSURGE_QUAD_ICEGRASS
-	    || type != PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID))
-		return PSURGE_DUAL;
-
-	/* looks OK, try a slightly more rigorous test */
-	/* bogus is not necessarily cacheline-aligned,
-	   though I don't suppose that really matters.  -- paulus */
-	for (i = 0; i < 100; i++) {
-		volatile u32 bogus[8];
-		bogus[(0+i)%8] = 0x00000000;
-		bogus[(1+i)%8] = 0x55555555;
-		bogus[(2+i)%8] = 0xFFFFFFFF;
-		bogus[(3+i)%8] = 0xAAAAAAAA;
-		bogus[(4+i)%8] = 0x33333333;
-		bogus[(5+i)%8] = 0xCCCCCCCC;
-		bogus[(6+i)%8] = 0xCCCCCCCC;
-		bogus[(7+i)%8] = 0x33333333;
-		wmb();
-		asm volatile("dcbf 0,%0" : : "r" (bogus) : "memory");
-		mb();
-		if (type != PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID))
-			return PSURGE_DUAL;
-	}
-	return type;
-}
-
-static void __init psurge_quad_init(void)
-{
-	int procbits;
-
-	if (ppc_md.progress) ppc_md.progress("psurge_quad_init", 0x351);
-	procbits = ~PSURGE_QUAD_IN(PSURGE_QUAD_WHICH_CPU);
-	if (psurge_type == PSURGE_QUAD_ICEGRASS)
-		PSURGE_QUAD_BIS(PSURGE_QUAD_RESET_CTL, procbits);
-	else
-		PSURGE_QUAD_BIC(PSURGE_QUAD_CKSTOP_CTL, procbits);
-	mdelay(33);
-	out_8(psurge_sec_intr, ~0);
-	PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_CLR, procbits);
-	PSURGE_QUAD_BIS(PSURGE_QUAD_RESET_CTL, procbits);
-	if (psurge_type != PSURGE_QUAD_ICEGRASS)
-		PSURGE_QUAD_BIS(PSURGE_QUAD_CKSTOP_CTL, procbits);
-	PSURGE_QUAD_BIC(PSURGE_QUAD_PRIMARY_ARB, procbits);
-	mdelay(33);
-	PSURGE_QUAD_BIC(PSURGE_QUAD_RESET_CTL, procbits);
-	mdelay(33);
-	PSURGE_QUAD_BIS(PSURGE_QUAD_PRIMARY_ARB, procbits);
-	mdelay(33);
-}
-
-static int __init smp_psurge_probe(void)
-{
-	int i, ncpus;
-
-	/* We don't do SMP on the PPC601 -- paulus */
-	if ((_get_PVR() >> 16) == 1)
-		return 1;
-
-	/*
-	 * The powersurge cpu board can be used in the generation
-	 * of powermacs that have a socket for an upgradeable cpu card,
-	 * including the 7500, 8500, 9500, 9600.
-	 * The device tree doesn't tell you if you have 2 cpus because
-	 * OF doesn't know anything about the 2nd processor.
-	 * Instead we look for magic bits in magic registers,
-	 * in the hammerhead memory controller in the case of the
-	 * dual-cpu powersurge board.  -- paulus.
-	 */
-	if (find_devices("hammerhead") == NULL)
-		return 1;
-
-	hhead_base = ioremap(HAMMERHEAD_BASE, 0x800);
-	quad_base = ioremap(PSURGE_QUAD_REG_ADDR, 1024);
-	psurge_sec_intr = hhead_base + HHEAD_SEC_INTR;
-
-	psurge_type = psurge_quad_probe();
-	if (psurge_type != PSURGE_DUAL) {
-		psurge_quad_init();
-		/* All released cards using this HW design have 4 CPUs */
-		ncpus = 4;
-	} else {
-		iounmap((void *) quad_base);
-		if ((in_8(hhead_base + HHEAD_CONFIG) & 0x02) == 0) {
-			/* not a dual-cpu card */
-			iounmap((void *) hhead_base);
-			return 1;
-		}
-		ncpus = 2;
-	}
-
-	psurge_start = ioremap(PSURGE_START, 4);
-	psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4);
-
-	/* this is not actually strictly necessary -- paulus. */
-	for (i = 1; i < ncpus; ++i)
-		smp_hw_index[i] = i;
-
-	if (ppc_md.progress) ppc_md.progress("smp_psurge_probe - done", 0x352);
-
-	return ncpus;
-}
-
-static void __init smp_psurge_kick_cpu(int nr)
-{
-	void (*start)(void) = __secondary_start_psurge;
-
-	if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu", 0x353);
-
-	/* setup entry point of secondary processor */
-	switch (nr) {
-	case 2:
-		start = __secondary_start_psurge2;
-		break;
-	case 3:
-		start = __secondary_start_psurge3;
-		break;
-	}
-
-	out_be32(psurge_start, __pa(start));
-	mb();
-
-	psurge_set_ipi(nr);
-	udelay(10);
-	psurge_clr_ipi(nr);
-
-	if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu - done", 0x354);
-}
-
-/*
- * With the dual-cpu powersurge board, the decrementers and timebases
- * of both cpus are frozen after the secondary cpu is started up,
- * until we give the secondary cpu another interrupt.  This routine
- * uses this to get the timebases synchronized.
- *  -- paulus.
- */
-static void __init psurge_dual_sync_tb(int cpu_nr)
-{
-	static volatile int sec_tb_reset = 0;
-	int t;
-
-	set_dec(tb_ticks_per_jiffy);
-	set_tb(0, 0);
-	last_jiffy_stamp(cpu_nr) = 0;
-
-	if (cpu_nr > 0) {
-		mb();
-		sec_tb_reset = 1;
-		return;
-	}
-
-	/* wait for the secondary to have reset its TB before proceeding */
-	for (t = 10000000; t > 0 && !sec_tb_reset; --t)
-		;
-
-	/* now interrupt the secondary, starting both TBs */
-	psurge_set_ipi(1);
-
-	smp_tb_synchronized = 1;
-}
-
-static void
-smp_psurge_setup_cpu(int cpu_nr)
-{
-
-	if (cpu_nr == 0) {
-		if (smp_num_cpus < 2)
-			return;
-		/* reset the entry point so if we get another intr we won't
-		 * try to startup again */
-		out_be32(psurge_start, 0x100);
-		if (request_irq(30, psurge_primary_intr, 0, "primary IPI", 0))
-			printk(KERN_ERR "Couldn't get primary IPI interrupt");
-	}
-
-	if (psurge_type == PSURGE_DUAL)
-		psurge_dual_sync_tb(cpu_nr);
-}
-
-
-static void
-smp_openpic_message_pass(int target, int msg, unsigned long data, int wait)
-{
-	/* make sure we're sending something that translates to an IPI */
-	if ( msg > 0x3 ){
-		printk("SMP %d: smp_message_pass: unknown msg %d\n",
-		       smp_processor_id(), msg);
-		return;
-	}
-	switch ( target )
-	{
-	case MSG_ALL:
-		openpic_cause_IPI(msg, 0xffffffff);
-		break;
-	case MSG_ALL_BUT_SELF:
-		openpic_cause_IPI(msg,
-				  0xffffffff & ~(1 << smp_processor_id()));
-		break;
-	default:
-		openpic_cause_IPI(msg, 1<<target);
-		break;
-	}
-}
-
-static int
-smp_core99_probe(void)
-{
-	struct device_node *cpus;
-	int i, ncpus = 1;
-
-	if (ppc_md.progress) ppc_md.progress("smp_core99_probe", 0x345);
-	cpus = find_type_devices("cpu");
-	if (cpus)
-		while ((cpus = cpus->next) != NULL)
-			++ncpus;
-	printk("smp_core99_probe: found %d cpus\n", ncpus);
-	if (ncpus > 1) {
-		openpic_request_IPIs();
-		for (i = 1; i < ncpus; ++i)
-			smp_hw_index[i] = i;
-	}
-
-	return ncpus;
-}
-
-static void
-smp_core99_kick_cpu(int nr)
-{
-	unsigned long save_vector, new_vector;
-	unsigned long flags;
-#if 1 /* New way... */
-	volatile unsigned long *vector
-		 = ((volatile unsigned long *)(KERNELBASE+0x100));
-	if (nr < 1 || nr > 3)
-		return;
-#else
-	volatile unsigned long *vector
-		 = ((volatile unsigned long *)(KERNELBASE+0x500));
-	if (nr != 1)
-		return;
-#endif
-	if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu", 0x346);
-
-	local_irq_save(flags);
-	local_irq_disable();
-	
-	/* Save reset vector */
-	save_vector = *vector;
-	
-	/* Setup fake reset vector that does	  
-	 *   b __secondary_start_psurge - KERNELBASE
-	 */  
-	switch(nr) {
-		case 1:
-			new_vector = (unsigned long)__secondary_start_psurge;
-			break;
-		case 2:
-			new_vector = (unsigned long)__secondary_start_psurge2;
-			break;
-		case 3:
-			new_vector = (unsigned long)__secondary_start_psurge3;
-			break;
-	}
-	*vector = 0x48000002 + new_vector - KERNELBASE;
-	
-	/* flush data cache and inval instruction cache */
-	flush_icache_range((unsigned long) vector, (unsigned long) vector + 4);
-	
-	/* Put some life in our friend */
-	feature_core99_kick_cpu(nr);
-	
-	/* FIXME: We wait a bit for the CPU to take the exception, I should
-	 * instead wait for the entry code to set something for me. Well,
-	 * ideally, all that crap will be done in prom.c and the CPU left
-	 * in a RAM-based wait loop like CHRP.
-	 */
-	mdelay(1);
-	
-	/* Restore our exception vector */
-	*vector = save_vector;
-	flush_icache_range((unsigned long) vector, (unsigned long) vector + 4);
-	
-	local_irq_restore(flags);
-	if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu done", 0x347);
-}
-
-static void
-smp_core99_setup_cpu(int cpu_nr)
-{
-	/* Setup openpic */
-	do_openpic_setup_cpu();
-
-	/* Setup L2 */
-	if (cpu_nr != 0)
-		core99_init_l2();
-	else
-		if (ppc_md.progress) ppc_md.progress("core99_setup_cpu 0 done", 0x349);
-}
-
-static int
-smp_chrp_probe(void)
-{
-	extern unsigned long smp_chrp_cpu_nr;
-
-	if (smp_chrp_cpu_nr > 1)
-		openpic_request_IPIs();
-
-	return smp_chrp_cpu_nr;
-}
-
-static void
-smp_chrp_kick_cpu(int nr)
-{
-	*(unsigned long *)KERNELBASE = nr;
-	asm volatile("dcbf 0,%0"::"r"(KERNELBASE):"memory");
-}
-
-static void
-smp_chrp_setup_cpu(int cpu_nr)
-{
-	static atomic_t ready = ATOMIC_INIT(1);
-	static volatile int frozen = 0;
-
-	if (cpu_nr == 0) {
-		/* wait for all the others */
-		while (atomic_read(&ready) < smp_num_cpus)
-			barrier();
-		atomic_set(&ready, 1);
-		/* freeze the timebase */
-		call_rtas("freeze-time-base", 0, 1, NULL);
-		mb();
-		frozen = 1;
-		/* XXX assumes this is not a 601 */
-		set_tb(0, 0);
-		last_jiffy_stamp(0) = 0;
-		while (atomic_read(&ready) < smp_num_cpus)
-			barrier();
-		/* thaw the timebase again */
-		call_rtas("thaw-time-base", 0, 1, NULL);
-		mb();
-		frozen = 0;
-		smp_tb_synchronized = 1;
-	} else {
-		atomic_inc(&ready);
-		while (!frozen)
-			barrier();
-		set_tb(0, 0);
-		last_jiffy_stamp(0) = 0;
-		mb();
-		atomic_inc(&ready);
-		while (frozen)
-			barrier();
-	}
-
-	if (OpenPIC_Addr)
-		do_openpic_setup_cpu();
-}
-
-#ifdef CONFIG_POWER4
-static void
-smp_xics_message_pass(int target, int msg, unsigned long data, int wait)
-{
-	/* for now, only do reschedule messages
-	   since we only have one IPI */
-	if (msg != PPC_MSG_RESCHEDULE)
-		return;
-	for (i = 0; i < smp_num_cpus; ++i) {
-		if (target == MSG_ALL || target == i
-		    || (target == MSG_ALL_BUT_SELF
-			&& i != smp_processor_id()))
-			xics_cause_IPI(i);
-	}
-}
-
-static int
-smp_xics_probe(void)
-{
-	return smp_chrp_cpu_nr;
-}
-
-static void
-smp_xics_setup_cpu(int cpu_nr)
-{
-	if (cpu_nr > 0)
-		xics_setup_cpu();
-}
-#endif /* CONFIG_POWER4 */
-
-static int
-smp_prep_probe(void)
-{
-	extern int mot_multi;
-
-	if (mot_multi) {
-		openpic_request_IPIs();
-		smp_hw_index[1] = 1;
-		return 2;
-	}
-
-	return 1;
-}
-
-static void
-smp_prep_kick_cpu(int nr)
-{
-	extern unsigned long *MotSave_SmpIar;
-	extern unsigned char *MotSave_CpusState[2];
-
-	*MotSave_SmpIar = (unsigned long)__secondary_start_psurge - KERNELBASE;
-	*MotSave_CpusState[1] = CPU_GOOD;
-	printk("CPU1 reset, waiting\n");
-}
-
-static void
-smp_prep_setup_cpu(int cpu_nr)
-{
-	if (OpenPIC_Addr)
-		do_openpic_setup_cpu();
-}
-
-#ifdef CONFIG_GEMINI	
-static int
-smp_gemini_probe(void)
-{
-	int i, nr;
-
-        nr = (readb(GEMINI_CPUSTAT) & GEMINI_CPU_COUNT_MASK) >> 2;
-	if (nr == 0)
-		nr = 4;
-
-	if (nr > 1) {
-		openpic_request_IPIs();
-		for (i = 1; i < nr; ++i)
-			smp_hw_index[i] = i;
-	}
-
-	return nr;
-}
-
-static void
-smp_gemini_kick_cpu(int nr)
-{
-	openpic_init_processor( 1<<nr );
-	openpic_init_processor( 0 );
-}
-
-static void
-smp_gemini_setup_cpu(int cpu_nr)
-{
-	if (OpenPIC_Addr)
-		do_openpic_setup_cpu();
-	if (cpu_nr > 0)
-		gemini_init_l2();
-}
-#endif /* CONFIG_GEMINI */
-
-
-static struct smp_ops_t {
-	void  (*message_pass)(int target, int msg, unsigned long data, int wait);
-	int   (*probe)(void);
-	void  (*kick_cpu)(int nr);
-	void  (*setup_cpu)(int nr);
-
-} *smp_ops;
-
 #define smp_message_pass(t,m,d,w) \
     do { if (smp_ops) \
 	     atomic_inc(&ipi_sent); \
 	     smp_ops->message_pass((t),(m),(d),(w)); \
        } while(0)
 
-
-/* PowerSurge-style Macs */
-static struct smp_ops_t psurge_smp_ops = {
-	smp_psurge_message_pass,
-	smp_psurge_probe,
-	smp_psurge_kick_cpu,
-	smp_psurge_setup_cpu,
-};
-
-/* Core99 Macs (dual G4s) */
-static struct smp_ops_t core99_smp_ops = {
-	smp_openpic_message_pass,
-	smp_core99_probe,
-	smp_core99_kick_cpu,
-	smp_core99_setup_cpu,
-};
-
-/* CHRP with openpic */
-static struct smp_ops_t chrp_smp_ops = {
-	smp_openpic_message_pass,
-	smp_chrp_probe,
-	smp_chrp_kick_cpu,
-	smp_chrp_setup_cpu,
-};
-
-#ifdef CONFIG_POWER4
-/* CHRP with new XICS interrupt controller */
-static struct smp_ops_t xics_smp_ops = {
-	smp_xics_message_pass,
-	smp_xics_probe,
-	smp_chrp_kick_cpu,
-	smp_xics_setup_cpu,
-};
-#endif /* CONFIG_POWER4 */
-
-/* PReP (MTX) */
-static struct smp_ops_t prep_smp_ops = {
-	smp_openpic_message_pass,
-	smp_prep_probe,
-	smp_prep_kick_cpu,
-	smp_prep_setup_cpu,
-};
-
-#ifdef CONFIG_GEMINI	
-/* Gemini */
-static struct smp_ops_t gemini_smp_ops = {
-	smp_openpic_message_pass,
-	smp_gemini_probe,
-	smp_gemini_kick_cpu,
-	smp_gemini_setup_cpu,
-};
-#endif /* CONFIG_GEMINI	*/
-
 /* 
  * Common functions
  */
@@ -798,7 +130,7 @@
  */
 void smp_send_tlb_invalidate(int cpu)
 {
-	if ( (_get_PVR()>>16) == 8 )
+	if ( PVR_VER(mfspr(PVR)) == 8 )
 		smp_message_pass(MSG_ALL_BUT_SELF, PPC_MSG_INVALIDATE_TLB, 0, 0);
 }
 
@@ -947,7 +279,6 @@
 	extern struct task_struct *current_set[NR_CPUS];
 	int i, cpu_nr;
 	struct task_struct *p;
-	unsigned long a;
 
 	printk("Entering SMP Mode...\n");
 	smp_num_cpus = 1;
@@ -973,35 +304,12 @@
 	 */
 	cacheflush_time = 5 * 1024;
 
-	/* To be later replaced by some arch-specific routine */
-	switch(_machine) {
-	case _MACH_Pmac:
-		/* Check for Core99 */
-		if (find_devices("uni-n"))
-			smp_ops = &core99_smp_ops;
-		else
-			smp_ops = &psurge_smp_ops;
-		break;
-	case _MACH_chrp:
-#ifndef CONFIG_POWER4
-		smp_ops = &chrp_smp_ops;
-#else
-		smp_ops = &xics_smp_ops;
-#endif /* CONFIG_POWER4 */
-		break;
-	case _MACH_prep:
-		smp_ops = &prep_smp_ops;
-		break;
-#ifdef CONFIG_GEMINI		
-	case _MACH_gemini:
-		smp_ops = &gemini_smp_ops;
-		break;
-#endif /* CONFIG_GEMINI	*/
-	default:
+	smp_ops = ppc_md.smp_ops;
+	if (smp_ops == NULL) {
 		printk("SMP not supported on this machine.\n");
 		return;
 	}
-	
+
 	/* Probe arch for CPUs */
 	cpu_nr = smp_ops->probe();
 
@@ -1044,10 +352,12 @@
 		p->has_cpu = 1;
 		current_set[i] = p;
 
-		/* need to flush here since secondary bats aren't setup */
-		for (a = KERNELBASE; a < KERNELBASE + 0x800000; a += 32)
-			asm volatile("dcbf 0,%0" : : "r" (a) : "memory");
-		asm volatile("sync");
+		/*
+		 * There was a cache flush loop here to flush the cache
+		 * to memory for the first 8MB of RAM.  The cache flush
+		 * has been pushed into the kick_cpu function for those
+		 * platforms that need it.
+		 */
 
 		/* wake up cpus */
 		smp_ops->kick_cpu(i);
@@ -1155,7 +465,6 @@
 	/* so time.c doesn't get confused */
 	set_dec(tb_ticks_per_jiffy);
 	last_jiffy_stamp(cpu) = 0;
-	cpu_callin_map[cpu] = 1;
 }
 
 void __init smp_commence(void)
@@ -1247,7 +556,7 @@
 
 	/* assume bogomips are same for everything */
         c->loops_per_jiffy = loops_per_jiffy;
-        c->pvr = _get_PVR();
+        c->pvr = mfspr(PVR);
 }
 
 static int __init maxcpus(char *str)
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/temp.c linux/arch/ppc/kernel/temp.c
--- v2.4.9/linux/arch/ppc/kernel/temp.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/kernel/temp.c	Tue Aug 28 06:58:33 2001
@@ -0,0 +1,278 @@
+/*
+ * temp.c	Thermal management for cpu's with Thermal Assist Units
+ *
+ * Written by Troy Benjegerdes <hozer@drgw.net>
+ *
+ * TODO:
+ * dynamic power management to limit peak CPU temp (using ICTC)
+ * calibration???
+ * 
+ * Silly, crazy ideas: use cpu load (from scheduler) and ICTC to extend battery
+ * life in portables, and add a 'performance/watt' metric somewhere in /proc
+ */
+
+#include <linux/config.h>
+#include <linux/errno.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/init.h>
+
+#include <asm/segment.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/nvram.h>
+#include <asm/cache.h>
+#include <asm/8xx_immap.h>
+#include <asm/machdep.h>
+
+static struct tau_temp
+{
+	int interrupts;
+	unsigned char low;
+	unsigned char high;
+	unsigned char grew;
+} tau[NR_CPUS];
+
+struct timer_list tau_timer;
+
+#undef DEBUG
+
+/* TODO: put these in a /proc interface, with some sanity checks, and maybe
+ * dynamic adjustment to minimize # of interrupts */
+/* configurable values for step size and how much to expand the window when
+ * we get an interrupt. These are based on the limit that was out of range */
+#define step_size		2	/* step size when temp goes out of range */
+#define window_expand		1	/* expand the window by this much */
+/* configurable values for shrinking the window */
+#define shrink_timer	2*HZ	/* period between shrinking the window */
+#define min_window	2	/* minimum window size, degrees C */
+
+void set_thresholds(unsigned long cpu)
+{
+#ifdef CONFIG_TAU_INT
+	/*
+	 * setup THRM1,
+	 * threshold, valid bit, enable interrupts, interrupt when below threshold
+	 */
+	mtspr(SPRN_THRM1, THRM1_THRES(tau[cpu].low) | THRM1_V | THRM1_TIE | THRM1_TID);
+
+	/* setup THRM2,
+	 * threshold, valid bit, enable interrupts, interrupt when above threshhold
+	 */
+	mtspr (SPRN_THRM2, THRM1_THRES(tau[cpu].high) | THRM1_V | THRM1_TIE);
+#else
+	/* same thing but don't enable interrupts */
+	mtspr(SPRN_THRM1, THRM1_THRES(tau[cpu].low) | THRM1_V | THRM1_TID);
+	mtspr(SPRN_THRM2, THRM1_THRES(tau[cpu].high) | THRM1_V);
+#endif
+}
+
+void TAUupdate(int cpu)
+{
+	unsigned thrm;
+
+#ifdef DEBUG
+	printk("TAUupdate ");
+#endif
+
+	/* if both thresholds are crossed, the step_sizes cancel out
+	 * and the window winds up getting expanded twice. */
+	if((thrm = mfspr(SPRN_THRM1)) & THRM1_TIV){ /* is valid? */
+		if(thrm & THRM1_TIN){ /* crossed low threshold */
+			if (tau[cpu].low >= step_size){
+				tau[cpu].low -= step_size;
+				tau[cpu].high -= (step_size - window_expand);
+			}
+			tau[cpu].grew = 1;
+#ifdef DEBUG
+			printk("low threshold crossed ");
+#endif
+		}
+	}
+	if((thrm = mfspr(SPRN_THRM2)) & THRM1_TIV){ /* is valid? */
+		if(thrm & THRM1_TIN){ /* crossed high threshold */
+			if (tau[cpu].high <= 127-step_size){
+				tau[cpu].low += (step_size - window_expand);
+				tau[cpu].high += step_size;
+			}
+			tau[cpu].grew = 1;
+#ifdef DEBUG
+			printk("high threshold crossed ");
+#endif
+		}
+	}
+
+#ifdef DEBUG
+	printk("grew = %d\n", tau[cpu].grew);
+#endif
+
+#ifndef CONFIG_TAU_INT /* tau_timeout will do this if not using interrupts */
+	set_thresholds(cpu);	
+#endif
+
+}
+
+#ifdef CONFIG_TAU_INT
+/*
+ * TAU interrupts - called when we have a thermal assist unit interrupt
+ * with interrupts disabled
+ */
+
+void TAUException(struct pt_regs * regs)
+{
+	unsigned long cpu = smp_processor_id();
+
+	hardirq_enter(cpu);
+	tau[cpu].interrupts++;
+	
+	TAUupdate(cpu);
+
+	hardirq_exit(cpu);
+	return;
+}
+#endif /* CONFIG_TAU_INT */
+
+static void tau_timeout(void * info)
+{
+	unsigned long cpu = smp_processor_id();
+	unsigned long flags;
+	int size;
+	int shrink;
+ 
+	/* disabling interrupts *should* be okay */
+	save_flags(flags); cli();
+
+#ifndef CONFIG_TAU_INT
+	TAUupdate(cpu);
+#endif
+	
+	size = tau[cpu].high - tau[cpu].low;
+	if (size > min_window && ! tau[cpu].grew) {
+		/* do an exponential shrink of half the amount currently over size */
+		shrink = (2 + size - min_window) / 4;
+		if (shrink) {
+			tau[cpu].low += shrink;
+			tau[cpu].high -= shrink;
+		} else { /* size must have been min_window + 1 */
+			tau[cpu].low += 1;
+#if 1 /* debug */
+			if ((tau[cpu].high - tau[cpu].low) != min_window){
+				printk(KERN_ERR "temp.c: line %d, logic error\n", __LINE__);
+			}
+#endif
+		}
+	}
+
+	tau[cpu].grew = 0;
+	
+	set_thresholds(cpu);
+
+	/*
+	 * Do the enable every time, since otherwise a bunch of (relatively)
+	 * complex sleep code needs to be added. One mtspr every time
+	 * tau_timeout is called is probably not a big deal.
+	 * 
+	 * Enable thermal sensor and set up sample interval timer
+	 * need 20 us to do the compare.. until a nice 'cpu_speed' function
+	 * call is implemented, just assume a 500 mhz clock. It doesn't really
+	 * matter if we take too long for a compare since it's all interrupt 
+	 * driven anyway. 
+	 *
+	 * use a extra long time.. (60 us @ 500 mhz)
+	 */
+	mtspr(SPRN_THRM3, THRM3_SITV(500*60) | THRM3_E);
+
+	restore_flags(flags);
+}
+
+static void tau_timeout_smp(unsigned long unused)
+{
+
+	/* schedule ourselves to be run again */
+	mod_timer(&tau_timer, jiffies + shrink_timer) ;
+#ifdef CONFIG_SMP
+	smp_call_function(tau_timeout, NULL, 1, 0);
+#endif
+	tau_timeout(NULL);
+}
+
+/*
+ * setup the TAU
+ * 
+ * Set things up to use THRM1 as a temperature lower bound, and THRM2 as an upper bound.
+ * Start off at zero
+ */
+
+int tau_initialized = 0;
+
+void __init TAU_init_smp(void * info)
+{
+	unsigned long cpu = smp_processor_id();
+	
+	/* set these to a reasonable value and let the timer shrink the
+	 * window */
+	tau[cpu].low = 5;
+	tau[cpu].high = 120;
+
+	set_thresholds(cpu);
+}
+
+int __init TAU_init(void)
+{
+	/* We assume in SMP that if one CPU has TAU support, they
+	 * all have it --BenH
+	 */
+	if (!(cur_cpu_spec[0]->cpu_features & CPU_FTR_TAU)) {
+		printk("Thermal assist unit not available\n");
+		tau_initialized = 0;
+		return 1;
+	}
+
+
+	/* first, set up the window shrinking timer */
+	init_timer(&tau_timer);
+	tau_timer.function = tau_timeout_smp;
+	tau_timer.expires = jiffies + shrink_timer;
+	add_timer(&tau_timer);
+	
+#ifdef CONFIG_SMP
+	smp_call_function(TAU_init_smp, NULL, 1, 0);
+#endif
+	TAU_init_smp(NULL);
+	
+	printk("Thermal assist unit ");
+#ifdef CONFIG_TAU_INT
+	printk("using interrupts, ");
+#else
+	printk("using timers, ");
+#endif
+	printk("shrink_timer: %d jiffies\n", shrink_timer); 
+	tau_initialized = 1;
+
+	return 0;
+}
+
+__initcall(TAU_init);
+
+/*
+ * return current temp
+ */
+
+u32 cpu_temp_both(unsigned long cpu)
+{
+	return ((tau[cpu].high << 16) | tau[cpu].low);
+}
+
+int cpu_temp(unsigned long cpu)
+{
+	return ((tau[cpu].high + tau[cpu].low) / 2);
+}
+
+int tau_interrupts(unsigned long cpu)
+{
+	return (tau[cpu].interrupts);
+}
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/time.c linux/arch/ppc/kernel/time.c
--- v2.4.9/linux/arch/ppc/kernel/time.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/ppc/kernel/time.c	Tue Aug 28 06:58:33 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.time.c 1.18 06/06/01 22:33:09 paulus
+ * BK Id: SCCS/s.time.c 1.21 08/20/01 22:08:08 paulus
  */
 /*
  * Common time routines among all ppc machines.
@@ -72,11 +72,6 @@
 
 unsigned long disarm_decr[NR_CPUS];
 
-#ifdef CONFIG_SMP
-extern void smp_local_timer_interrupt(struct pt_regs *);
-extern int smp_tb_synchronized;
-#endif /* CONFIG_SMP */
-
 extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz);
 
 /* keep track of when we need to update the rtc */
@@ -321,27 +316,30 @@
 	 * makes things more complex. Repeatedly read the RTC until the
 	 * next second boundary to try to achieve some precision...
 	 */
-	stamp = get_native_tbl();
-	sec = ppc_md.get_rtc_time();
-	elapsed = 0;
-	do {
-		old_stamp = stamp; 
-		old_sec = sec;
+	if (ppc_md.get_rtc_time) {
 		stamp = get_native_tbl();
-		if (__USE_RTC() && stamp < old_stamp) old_stamp -= 1000000000;
-		elapsed += stamp - old_stamp;
 		sec = ppc_md.get_rtc_time();
-	} while ( sec == old_sec && elapsed < 2*HZ*tb_ticks_per_jiffy);
-	if (sec==old_sec) {
-		printk("Warning: real time clock seems stuck!\n");
+		elapsed = 0;
+		do {
+			old_stamp = stamp; 
+			old_sec = sec;
+			stamp = get_native_tbl();
+			if (__USE_RTC() && stamp < old_stamp) old_stamp -= 1000000000;
+			elapsed += stamp - old_stamp;
+			sec = ppc_md.get_rtc_time();
+		} while ( sec == old_sec && elapsed < 2*HZ*tb_ticks_per_jiffy);
+		if (sec==old_sec) {
+			printk("Warning: real time clock seems stuck!\n");
+		}
+		write_lock_irqsave(&xtime_lock, flags);
+		xtime.tv_sec = sec;
+		last_jiffy_stamp(0) = tb_last_stamp = stamp;
+		xtime.tv_usec = 0;
+		/* No update now, we just read the time from the RTC ! */
+		last_rtc_update = xtime.tv_sec;
+		write_unlock_irqrestore(&xtime_lock, flags);
 	}
-	write_lock_irqsave(&xtime_lock, flags);
-	xtime.tv_sec = sec;
-	last_jiffy_stamp(0) = tb_last_stamp = stamp;
-	xtime.tv_usec = 0;
-	/* No update now, we just read the time from the RTC ! */
-	last_rtc_update = xtime.tv_sec;
-	write_unlock_irqrestore(&xtime_lock, flags);
+
 	/* Not exact, but the timer interrupt takes care of this */
 	set_dec(tb_ticks_per_jiffy);
 
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/kernel/traps.c linux/arch/ppc/kernel/traps.c
--- v2.4.9/linux/arch/ppc/kernel/traps.c	Mon Aug 27 12:41:39 2001
+++ linux/arch/ppc/kernel/traps.c	Tue Aug 28 06:58:33 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.traps.c 1.16 07/31/01 10:53:34 trini
+ * BK Id: SCCS/s.traps.c 1.19 08/24/01 20:07:37 paulus
  */
 /*
  *  linux/arch/ppc/kernel/traps.c
@@ -244,7 +244,7 @@
 	 */
 	if ((instword & INST_MFSPR_PVR_MASK) == INST_MFSPR_PVR) {
 		rd = (instword >> 21) & 0x1f;
-		regs->gpr[rd] = _get_PVR();
+		regs->gpr[rd] = mfspr(PVR);
 		retval = 0;
 	}
 	if (retval == 0)
@@ -372,12 +372,14 @@
 }
 #endif
 
+#if !defined(CONFIG_TAU_INT)
 void
 TAUException(struct pt_regs *regs)
 {
 	printk("TAU trap at PC: %lx, SR: %lx, vector=%lx\n",
 	       regs->nip, regs->msr, regs->trap);
 }
+#endif /* CONFIG_INT_TAU */
 
 void __init trap_init(void)
 {
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/lib/checksum.S linux/arch/ppc/lib/checksum.S
--- v2.4.9/linux/arch/ppc/lib/checksum.S	Mon May 21 17:04:47 2001
+++ linux/arch/ppc/lib/checksum.S	Tue Aug 28 06:58:33 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.checksum.S 1.5 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.checksum.S 1.8 08/20/01 22:09:34 paulus
  */
 /*
  * This file contains assembly-language implementations
@@ -122,12 +122,30 @@
 	addc	r0,r0,r6
 	srwi.	r6,r5,2		/* # words to do */
 	beq	3f
-1:	mtctr	r6
-82:	lwzu	r6,4(r3)	/* the bdnz has zero overhead, so it should */
-92:	stwu	r6,4(r4)	/* be unnecessary to unroll this loop */
+1:	srwi.	r6,r5,4		/* # groups of 4 words to do */
+	beq	10f
+	mtctr	r6
+71:	lwz	r6,4(r3)
+72:	lwz	r9,8(r3)
+73:	lwz	r10,12(r3)
+74:	lwzu	r11,16(r3)
 	adde	r0,r0,r6
+75:	stw	r6,4(r4)
+	adde	r0,r0,r9
+76:	stw	r9,8(r4)
+	adde	r0,r0,r10
+77:	stw	r10,12(r4)
+	adde	r0,r0,r11
+78:	stwu	r11,16(r4)
+	bdnz	71b
+10:	rlwinm.	r6,r5,30,30,31	/* # words left to do */
+	beq	13f
+	mtctr	r6
+82:	lwzu	r9,4(r3)
+92:	stwu	r9,4(r4)
+	adde	r0,r0,r9
 	bdnz	82b
-	andi.	r5,r5,3
+13:	andi.	r5,r5,3
 3:	cmpi	0,r5,2
 	blt+	4f
 83:	lhz	r6,4(r3)
@@ -148,12 +166,16 @@
 /* These shouldn't go in the fixup section, since that would
    cause the ex_table addresses to get out of order. */
 
+src_error_4:
+	mfctr	r6		/* update # bytes remaining from ctr */
+	rlwimi	r5,r6,4,0,27
+	b	79f
 src_error_1:
 	li	r6,0
 	subi	r5,r5,2
 95:	sth	r6,4(r4)
 	addi	r4,r4,2
-	srwi.	r6,r5,2
+79:	srwi.	r6,r5,2
 	beq	3f
 	mtctr	r6
 src_error_2:
@@ -187,6 +209,14 @@
 .section __ex_table,"a"
 	.long	81b,src_error_1
 	.long	91b,dst_error
+	.long	71b,src_error_4
+	.long	72b,src_error_4
+	.long	73b,src_error_4
+	.long	74b,src_error_4
+	.long	75b,dst_error
+	.long	76b,dst_error
+	.long	77b,dst_error
+	.long	78b,dst_error
 	.long	82b,src_error_2
 	.long	92b,dst_error
 	.long	83b,src_error_3
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/lib/locks.c linux/arch/ppc/lib/locks.c
--- v2.4.9/linux/arch/ppc/lib/locks.c	Mon May 21 17:04:47 2001
+++ linux/arch/ppc/lib/locks.c	Tue Aug 28 06:58:33 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.locks.c 1.8 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.locks.c 1.11 08/19/01 22:27:32 paulus
  */
 /*
  * Locks for smp ppc 
@@ -16,29 +16,53 @@
 #include <asm/system.h>
 #include <asm/io.h>
 
-#define DEBUG_LOCKS 1
+#ifdef SPINLOCK_DEBUG
 
 #undef INIT_STUCK
 #define INIT_STUCK 200000000 /*0xffffffff*/
 
+/*
+ * Try to acquire a spinlock.
+ * Only does the stwcx. if the load returned 0 - the Programming
+ * Environments Manual suggests not doing unnecessary stcwx.'s
+ * since they may inhibit forward progress by other CPUs in getting
+ * a lock.
+ */
+static unsigned long __spin_trylock(volatile unsigned long *lock)
+{
+	unsigned long ret;
+
+	__asm__ __volatile__ ("\n\
+1:	lwarx	%0,0,%1\n\
+	cmpwi	0,%0,0\n\
+	bne	2f\n\
+	stwcx.	%2,0,%1\n\
+	bne-	1b\n\
+	isync\n\
+2:"
+	: "=&r"(ret)
+	: "r"(lock), "r"(1)
+	: "cr0", "memory");
+
+	return ret;
+}
+
 void _spin_lock(spinlock_t *lock)
 {
 	int cpu = smp_processor_id();
-#ifdef DEBUG_LOCKS
 	unsigned int stuck = INIT_STUCK;
-#endif /* DEBUG_LOCKS */
 	while (__spin_trylock(&lock->lock)) {
-#ifdef DEBUG_LOCKS
-		if(!--stuck) {
-			printk("_spin_lock(%p) CPU#%d NIP %p"
-			       " holder: cpu %ld pc %08lX\n",
-			       lock, cpu, __builtin_return_address(0),
-			       lock->owner_cpu,lock->owner_pc);
-			stuck = INIT_STUCK;
-			/* steal the lock */
-			/*xchg_u32((void *)&lock->lock,0);*/
+		while ((unsigned volatile long)lock->lock != 0) {
+			if (!--stuck) {
+				printk("_spin_lock(%p) CPU#%d NIP %p"
+				       " holder: cpu %ld pc %08lX\n",
+				       lock, cpu, __builtin_return_address(0),
+				       lock->owner_cpu,lock->owner_pc);
+				stuck = INIT_STUCK;
+				/* steal the lock */
+				/*xchg_u32((void *)&lock->lock,0);*/
+			}
 		}
-#endif /* DEBUG_LOCKS */
 	}
 	lock->owner_pc = (unsigned long)__builtin_return_address(0);
 	lock->owner_cpu = cpu;
@@ -53,11 +77,8 @@
 	return 1;
 }
 
-
-
 void _spin_unlock(spinlock_t *lp)
 {
-#ifdef DEBUG_LOCKS
   	if ( !lp->lock )
 		printk("_spin_unlock(%p): no lock cpu %d curr PC %p %s/%d\n",
 		       lp, smp_processor_id(), __builtin_return_address(0),
@@ -66,13 +87,12 @@
 		printk("_spin_unlock(%p): cpu %d trying clear of cpu %d pc %lx val %lx\n",
 		      lp, smp_processor_id(), (int)lp->owner_cpu,
 		      lp->owner_pc,lp->lock);
-#endif /* DEBUG_LOCKS */
 	lp->owner_pc = lp->owner_cpu = 0;
 	wmb();
 	lp->lock = 0;
-	wmb();
 }
 
+
 /*
  * Just like x86, implement read-write locks as a 32-bit counter
  * with the high bit (sign) being the "write" bit.
@@ -80,14 +100,11 @@
  */
 void _read_lock(rwlock_t *rw)
 {
-#ifdef DEBUG_LOCKS
 	unsigned long stuck = INIT_STUCK;
 	int cpu = smp_processor_id();
-#endif /* DEBUG_LOCKS */		  
 
 again:	
 	/* get our read lock in there */
-	wmb();
 	atomic_inc((atomic_t *) &(rw)->lock);
 	if ( (signed long)((rw)->lock) < 0) /* someone has a write lock */
 	{
@@ -96,13 +113,11 @@
 		/* wait for the write lock to go away */
 		while ((signed long)((rw)->lock) < 0)
 		{
-#ifdef DEBUG_LOCKS
 			if(!--stuck)
 			{
 				printk("_read_lock(%p) CPU#%d\n", rw, cpu);
 				stuck = INIT_STUCK;
 			}
-#endif /* DEBUG_LOCKS */
 		}
 		/* try to get the read lock again */
 		goto again;
@@ -112,38 +127,30 @@
 
 void _read_unlock(rwlock_t *rw)
 {
-#ifdef DEBUG_LOCKS
 	if ( rw->lock == 0 )
 		printk("_read_unlock(): %s/%d (nip %08lX) lock %lx\n",
 		       current->comm,current->pid,current->thread.regs->nip,
 		      rw->lock);
-#endif /* DEBUG_LOCKS */
 	wmb();
 	atomic_dec((atomic_t *) &(rw)->lock);
-	wmb();
 }
 
 void _write_lock(rwlock_t *rw)
 {
-#ifdef DEBUG_LOCKS
 	unsigned long stuck = INIT_STUCK;
 	int cpu = smp_processor_id();
-#endif /* DEBUG_LOCKS */		  
 
 again:
-	wmb();
 	if ( test_and_set_bit(31,&(rw)->lock) ) /* someone has a write lock */
 	{
 		while ( (rw)->lock & (1<<31) ) /* wait for write lock */
 		{
-#ifdef DEBUG_LOCKS
 			if(!--stuck)
 			{
 				printk("write_lock(%p) CPU#%d lock %lx)\n",
 				       rw, cpu,rw->lock);
 				stuck = INIT_STUCK;
 			}
-#endif /* DEBUG_LOCKS */		  
 			barrier();
 		}
 		goto again;
@@ -155,14 +162,12 @@
 		clear_bit(31,&(rw)->lock);
 		while ( (rw)->lock & ~(1<<31) )
 		{
-#ifdef DEBUG_LOCKS
 			if(!--stuck)
 			{
 				printk("write_lock(%p) 2 CPU#%d lock %lx)\n",
 				       rw, cpu,rw->lock);
 				stuck = INIT_STUCK;
 			}
-#endif /* DEBUG_LOCKS */
 			barrier();
 		}
 		goto again;
@@ -172,79 +177,12 @@
 
 void _write_unlock(rwlock_t *rw)
 {
-#ifdef DEBUG_LOCKS
 	if ( !(rw->lock & (1<<31)) )
 		printk("_write_lock(): %s/%d (nip %08lX) lock %lx\n",
 		      current->comm,current->pid,current->thread.regs->nip,
 		      rw->lock);
-#endif /* DEBUG_LOCKS */
 	wmb();
 	clear_bit(31,&(rw)->lock);
-	wmb();
-}
-
-void __lock_kernel(struct task_struct *task)
-{
-#ifdef DEBUG_LOCKS
-	unsigned long stuck = INIT_STUCK;
-	
-	if ( (signed long)(task->lock_depth) < 0 )
-	{
-		printk("__lock_kernel(): %s/%d (nip %08lX) lock depth %x\n",
-		      task->comm,task->pid,task->thread.regs->nip,
-		      task->lock_depth);
-	}
-#endif /* DEBUG_LOCKS */
-
-	if (atomic_inc_return((atomic_t *) &task->lock_depth) != 1)
-		return;
-	/* mine! */
-	while (__spin_trylock(&klock_info.kernel_flag)) {
-#ifdef DEBUG_LOCKS
-		if(!--stuck) {
-			printk("_lock_kernel() CPU#%d NIP %p\n",
-			       smp_processor_id(),
-			       __builtin_return_address(0));
-			stuck = INIT_STUCK;
-		}
-#endif /* DEBUG_LOCKS */
-	}
-	
-	klock_info.akp = smp_processor_id();
-	/* my kernel mode! mine!!! */
 }
 
-void __unlock_kernel(struct task_struct *task)
-{
-#ifdef DEBUG_LOCKS
- 	if ((task->lock_depth == 0) || (klock_info.kernel_flag != KLOCK_HELD))
-	{
-		printk("__unlock_kernel(): %s/%d (nip %08lX) "
-		       "lock depth %x flags %lx\n",
-		       task->comm,task->pid,task->thread.regs->nip,
-		       task->lock_depth, klock_info.kernel_flag);
-		klock_info.akp = NO_PROC_ID;		
-		klock_info.kernel_flag = 0;
-		return;
-	}
-#endif /* DEBUG_LOCKS */
-	if (atomic_dec_and_test((atomic_t *) &task->lock_depth))
-	{
-		wmb();
-		klock_info.akp = NO_PROC_ID;
-		wmb();
-		klock_info.kernel_flag = KLOCK_CLEAR;
-		wmb();
-	}
-}	
-
-void reacquire_kernel_lock(struct task_struct *task, int cpu,int depth)
-{
-	if (depth)
-	{
-		__cli();
-		__lock_kernel(task);
-		task->lock_depth = depth;
-		__sti();
-	}
-}
+#endif
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/mm/4xx_mmu.c linux/arch/ppc/mm/4xx_mmu.c
--- v2.4.9/linux/arch/ppc/mm/4xx_mmu.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/mm/4xx_mmu.c	Tue Aug 28 06:58:33 2001
@@ -0,0 +1,98 @@
+/*
+ * BK Id: %F% %I% %G% %U% %#%
+ */
+/*
+ * This file contains the routines for initializing the MMU
+ * on the 4xx series of chips.
+ *  -- paulus
+ * 
+ *  Derived from arch/ppc/mm/init.c:
+ *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ *  Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
+ *  and Cort Dougan (PReP) (cort@cs.nmt.edu)
+ *    Copyright (C) 1996 Paul Mackerras
+ *  Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ *
+ *  Derived from "arch/i386/mm/init.c"
+ *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
+ *
+ *  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/config.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/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/stddef.h>
+#include <linux/vmalloc.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/bootmem.h>
+#include <linux/highmem.h>
+
+#include <asm/pgalloc.h>
+#include <asm/prom.h>
+#include <asm/io.h>
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
+#include <asm/mmu.h>
+#include <asm/uaccess.h>
+#include <asm/smp.h>
+#include <asm/bootx.h>
+#include <asm/machdep.h>
+#include <asm/setup.h>
+
+/* Used by the 4xx TLB replacement exception handler.
+ * Just needed it declared someplace (and initialized to zero).
+ */
+unsigned int tlb_4xx_index;
+
+/*
+ * MMU_init_hw does the chip-specific initialization of the MMU hardware.
+ */
+void __init MMU_init_hw(void)
+{
+	/*
+	 * The Zone Protection Register (ZPR) defines how protection will
+	 * be applied to every page which is a member of a given zone. At
+	 * present, we utilize only two of the 4xx's zones.
+	 * The zone index bits (of ZSEL) in the PTE are used for software
+	 * indicators, except the LSB.  For user access, zone 15 is used,
+	 * for kernel access, zone 14 is used.  We set all but zone 15
+	 * to zero, allowing only kernel access as indicated in the PTE.
+	 * For zone 15, we set a 01 binary (a value of 10 will not work)
+	 * to allow user access as indicated in the PTE.  This also allows
+	 * kernel access as indicated in the PTE.
+	 */
+
+        mtspr(SPRN_ZPR, 0x00000001);
+
+	flush_instruction_cache();
+
+	/*
+	 * Set up the real-mode cache parameters for the exception vector
+	 * handlers (which are run in real-mode).
+	 */
+
+        mtspr(SPRN_DCWR, 0x00000000);	/* All caching is write-back */
+
+        /*
+	 * Cache instruction and data space where the exception
+	 * vectors and the kernel live in real-mode.
+	 */
+
+        mtspr(SPRN_DCCR, 0x80000000);	/* 128 MB of data space at 0x0. */
+        mtspr(SPRN_ICCR, 0x80000000);	/* 128 MB of instr. space at 0x0. */
+}
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/mm/Makefile linux/arch/ppc/mm/Makefile
--- v2.4.9/linux/arch/ppc/mm/Makefile	Tue Jul  3 17:08:18 2001
+++ linux/arch/ppc/mm/Makefile	Tue Aug 28 06:58:33 2001
@@ -1,4 +1,4 @@
-# BK Id: SCCS/s.Makefile 1.6 06/28/01 15:50:17 paulus
+# BK Id: SCCS/s.Makefile 1.8 08/16/01 17:25:47 paulus
 #
 #
 # Makefile for the linux ppc-specific parts of the memory manager.
@@ -15,15 +15,13 @@
 EXTRA_AFLAGS		:= -Wa,-mppc64bridge
 endif
 
-O_TARGET		:= mm.o
-obj-y			:= fault.o init.o mem_pieces.o extable.o
+O_TARGET			:= mm.o
+obj-y				:= fault.o init.o mem_pieces.o extable.o \
+					mmu_context.o pgtable.o
 
-ifneq ($(CONFIG_8xx),y)
-ifneq ($(CONFIG_4xx),y)
-obj-y			+= hashtable.o
-endif
-endif
-
-obj-$(CONFIG_4xx)	+= 4xx_tlb.o
+obj-$(CONFIG_PPC_STD_MMU)	+= hashtable.o ppc_mmu.o tlb.o
+obj-$(CONFIG_PPC_ISERIES)	+= iSeries_hashtable.o iSeries_mmu.o tlb.o
+obj-$(CONFIG_4xx)		+= cachemap.o 4xx_mmu.o
+obj-$(CONFIG_8xx)		+= cachemap.o
 
 include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/mm/cachemap.c linux/arch/ppc/mm/cachemap.c
--- v2.4.9/linux/arch/ppc/mm/cachemap.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/mm/cachemap.c	Tue Aug 28 06:58:33 2001
@@ -0,0 +1,163 @@
+/*
+ * BK Id: %F% %I% %G% %U% %#%
+ *
+ *  PowerPC version derived from arch/arm/mm/consistent.c
+ *    Copyright (C) 2001 Dan Malek (dmalek@jlc.net)
+ *
+ *  linux/arch/arm/mm/consistent.c
+ *
+ *  Copyright (C) 2000 Russell King
+ *
+ * Consistent memory allocators.  Used for DMA devices that want to
+ * share uncached memory with the processor core.  The function return
+ * is the virtual address and 'dma_handle' is the physical address.
+ * Mostly stolen from the ARM port, with some changes for PowerPC.
+ *						-- Dan
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/config.h>
+#include <linux/module.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/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/stddef.h>
+#include <linux/vmalloc.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/bootmem.h>
+#include <linux/highmem.h>
+#include <linux/pci.h>
+
+#include <asm/pgalloc.h>
+#include <asm/prom.h>
+#include <asm/io.h>
+#include <asm/hardirq.h>
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
+#include <asm/mmu.h>
+#include <asm/uaccess.h>
+#include <asm/smp.h>
+#include <asm/machdep.h>
+
+void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle)
+{
+	int order, rsize;
+	unsigned long page;
+	void *ret;
+	pte_t	*pte;
+
+	if (in_interrupt())
+		BUG();
+
+	/* Only allocate page size areas.
+	*/
+	size = PAGE_ALIGN(size);
+	order = get_order(size);
+
+	page = __get_free_pages(gfp, order);
+	if (!page) {
+		BUG();
+		return NULL;
+	}
+
+	/*
+	 * we need to ensure that there are no cachelines in use,
+	 * or worse dirty in this area.
+	 */
+	invalidate_dcache_range(page, page + size);
+
+	ret = (void *)page;
+	*dma_handle = virt_to_bus(ret);
+
+	/* Chase down all of the PTEs and mark them uncached.
+	*/
+	rsize = (int)size;
+	while (rsize > 0) {
+		if (get_pteptr(&init_mm, page, &pte)) {
+			pte_val(*pte) |= _PAGE_NO_CACHE | _PAGE_GUARDED;
+			flush_tlb_page(find_vma(&init_mm,page),page);
+		}
+		else {
+			BUG();
+			return NULL;
+		}
+		page += PAGE_SIZE;
+		rsize -= PAGE_SIZE;
+	}
+
+	return ret;
+}
+
+/*
+ * free page(s) as defined by the above mapping.
+ * The caller has to tell us the size so we can free the proper number
+ * of pages.  We can't vmalloc() a new space for these pages and simply
+ * call vfree() like some other architectures because we could end up
+ * with aliased cache lines (or at least a cache line with the wrong
+ * attributes).  This can happen when the PowerPC speculative loads
+ * across page boundaries.
+ */
+void consistent_free(void *vaddr, size_t size)
+{
+	int order, rsize;
+	unsigned long addr;
+	pte_t	*pte;
+
+	if (in_interrupt())
+		BUG();
+
+	size = PAGE_ALIGN(size);
+	order = get_order(size);
+
+	/* Chase down all of the PTEs and mark them cached again.
+	*/
+	addr = (unsigned long)vaddr;
+	rsize = (int)size;
+	while (rsize > 0) {
+		if (get_pteptr(&init_mm, addr, &pte)) {
+			pte_val(*pte) &= ~(_PAGE_NO_CACHE | _PAGE_GUARDED);
+			flush_tlb_page(find_vma(&init_mm,addr),addr);
+		}
+		else {
+			BUG();
+			return;
+		}
+		addr += PAGE_SIZE;
+		rsize -= PAGE_SIZE;
+	}
+	free_pages((unsigned long)vaddr, order);
+}
+
+/*
+ * make an area consistent.
+ */
+void consistent_sync(void *vaddr, size_t size, int direction)
+{
+	unsigned long start = (unsigned long)vaddr;
+	unsigned long end   = start + size;
+
+	switch (direction) {
+	case PCI_DMA_NONE:
+		BUG();
+	case PCI_DMA_FROMDEVICE:	/* invalidate only */
+		invalidate_dcache_range(start, end);
+		break;
+	case PCI_DMA_TODEVICE:		/* writeback only */
+		clean_dcache_range(start, end);
+		break;
+	case PCI_DMA_BIDIRECTIONAL:	/* writeback and invalidate */
+		flush_dcache_range(start, end);
+		break;
+	}
+}
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/mm/hashtable.S linux/arch/ppc/mm/hashtable.S
--- v2.4.9/linux/arch/ppc/mm/hashtable.S	Tue Jul  3 17:08:18 2001
+++ linux/arch/ppc/mm/hashtable.S	Tue Aug 28 06:58:33 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.hashtable.S 1.16 06/29/01 08:51:52 paulus
+ * BK Id: SCCS/s.hashtable.S 1.18 08/15/01 22:43:07 paulus
  */
 /*
  *  arch/ppc/kernel/hashtable.S
@@ -31,6 +31,7 @@
 #include <asm/processor.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
+#include <asm/cputable.h>
 
 #ifdef CONFIG_SMP
 	.comm	hash_table_lock,4
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/mm/init.c linux/arch/ppc/mm/init.c
--- v2.4.9/linux/arch/ppc/mm/init.c	Mon Aug 27 12:41:39 2001
+++ linux/arch/ppc/mm/init.c	Tue Aug 28 06:58:33 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.init.c 1.30 07/06/01 09:19:29 trini
+ * BK Id: SCCS/s.init.c 1.34 08/20/01 22:12:43 paulus
  */
 /*
  *  PowerPC version 
@@ -21,20 +21,14 @@
  */
 
 #include <linux/config.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/ptrace.h>
-#include <linux/mman.h>
 #include <linux/mm.h>
-#include <linux/swap.h>
 #include <linux/stddef.h>
-#include <linux/vmalloc.h>
 #include <linux/init.h>
-#include <linux/delay.h>
 #include <linux/bootmem.h>
 #include <linux/highmem.h>
 #ifdef CONFIG_BLK_DEV_INITRD
@@ -47,138 +41,49 @@
 #include <asm/mmu_context.h>
 #include <asm/pgtable.h>
 #include <asm/mmu.h>
-#include <asm/uaccess.h>
-#ifdef CONFIG_8xx
-#include <asm/8xx_immap.h>
-#include <asm/mpc8xx.h>
-#endif
-#ifdef CONFIG_8260
-#include <asm/immap_8260.h>
-#include <asm/mpc8260.h>
-#endif
 #include <asm/smp.h>
-#include <asm/bootx.h>
 #include <asm/machdep.h>
-#include <asm/setup.h>
-#include <asm/amigahw.h>
-#include <asm/gemini.h>
+#include <asm/btext.h>
 
 #include "mem_pieces.h"
+#include "mmu_decl.h"
 
-#if defined(CONFIG_4xx)
-#include "4xx_tlb.h"
-#endif
-
-#define MAX_LOW_MEM	(512 << 20)
+#define MAX_LOW_MEM	(0xF0000000UL - KERNELBASE)
 
-#define	PGTOKB(pages)	(((pages) * PAGE_SIZE) >> 10)
-
-mm_context_t next_mmu_context;
-unsigned long context_map[(LAST_CONTEXT+1) / (8*sizeof(unsigned long))];
-#ifdef FEW_CONTEXTS
-atomic_t nr_free_contexts;
-struct mm_struct *context_mm[LAST_CONTEXT+1];
-void steal_context(void);
-#endif /* FEW_CONTEXTS */
-
-int prom_trashed;
-unsigned long *end_of_DRAM;
+void *end_of_DRAM;
 unsigned long total_memory;
 unsigned long total_lowmem;
-unsigned long ram_phys_base;
+
 int mem_init_done;
 int init_bootmem_done;
 int boot_mapsize;
 unsigned long totalram_pages;
 unsigned long totalhigh_pages;
-extern pgd_t swapper_pg_dir[];
-extern char _start[], _end[];
+
+extern char _end[];
 extern char etext[], _stext[];
 extern char __init_begin, __init_end;
 extern char __prep_begin, __prep_end;
 extern char __chrp_begin, __chrp_end;
 extern char __pmac_begin, __pmac_end;
 extern char __openfirmware_begin, __openfirmware_end;
-unsigned long ioremap_base;
-unsigned long ioremap_bot;
-unsigned long avail_start;
-extern int num_memory;
-extern struct mem_info memory[];
-extern boot_infos_t *boot_infos;
-extern unsigned int rtas_data, rtas_size;
-#ifndef CONFIG_SMP
-struct pgtable_cache_struct quicklists;
-#endif
+
 #ifdef CONFIG_HIGHMEM
 pte_t *kmap_pte;
 pgprot_t kmap_prot;
 #endif
 
 void MMU_init(void);
-void *early_get_page(void);
-static void mapin_ram(void);
-int map_page(unsigned long va, unsigned long pa, int flags);
 void set_phys_avail(unsigned long total_ram);
-extern void die_if_kernel(char *,struct pt_regs *,long);
 
-extern char _start[], _end[];
-extern char _stext[], etext[];
+/* XXX should be in current.h  -- paulus */
 extern struct task_struct *current_set[NR_CPUS];
 
 char *klimit = _end;
 struct mem_pieces phys_avail;
 
-PTE *Hash, *Hash_end;
-unsigned long Hash_size, Hash_mask;
-#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
-unsigned long _SDR1;
-static void hash_init(void);
-
-union ubat {			/* BAT register values to be loaded */
-	BAT	bat;
-#ifdef CONFIG_PPC64BRIDGE
-	u64	word[2];
-#else
-	u32	word[2];
-#endif	
-} BATS[4][2];			/* 4 pairs of IBAT, DBAT */
-
-struct batrange {		/* stores address ranges mapped by BATs */
-	unsigned long start;
-	unsigned long limit;
-	unsigned long phys;
-} bat_addrs[4];
-
-/*
- * Return PA for this VA if it is mapped by a BAT, or 0
- */
-static inline unsigned long v_mapped_by_bats(unsigned long va)
-{
-	int b;
-	for (b = 0; b < 4; ++b)
-		if (va >= bat_addrs[b].start && va < bat_addrs[b].limit)
-			return bat_addrs[b].phys + (va - bat_addrs[b].start);
-	return 0;
-}
-
-/*
- * Return VA for a given PA or 0 if not mapped
- */
-static inline unsigned long p_mapped_by_bats(unsigned long pa)
-{
-	int b;
-	for (b = 0; b < 4; ++b)
-		if (pa >= bat_addrs[b].phys
-	    	    && pa < (bat_addrs[b].limit-bat_addrs[b].start)
-		              +bat_addrs[b].phys)
-			return bat_addrs[b].start+(pa-bat_addrs[b].phys);
-	return 0;
-}
-
-#else /* CONFIG_4xx || CONFIG_8xx */
-#define v_mapped_by_bats(x)	(0UL)
-#define p_mapped_by_bats(x)	(0UL)
-#endif /* !CONFIG_4xx && !CONFIG_8xx */
+extern char *sysmap; 
+extern unsigned long sysmap_size;
 
 /*
  * this tells the system to map all of ram with the segregs
@@ -298,421 +203,7 @@
 	val->mem_unit = PAGE_SIZE;
 }
 
-void *
-ioremap(unsigned long addr, unsigned long size)
-{
-	return __ioremap(addr, size, _PAGE_NO_CACHE);
-}
-
-void *
-__ioremap(unsigned long addr, unsigned long size, unsigned long flags)
-{
-	unsigned long p, v, i;
-	int err;
-
-	/*
-	 * Choose an address to map it to.
-	 * Once the vmalloc system is running, we use it.
-	 * Before then, we map addresses >= ioremap_base
-	 * virt == phys; for addresses below this we use
-	 * space going down from ioremap_base (ioremap_bot
-	 * records where we're up to).
-	 */
-	p = addr & PAGE_MASK;
-	size = PAGE_ALIGN(addr + size) - p;
-
-	/*
-	 * If the address lies within the first 16 MB, assume it's in ISA
-	 * memory space
-	 */
-	if ( p < 16*1024*1024 )
-		p += _ISA_MEM_BASE;
-
-	/*
-	 * Don't allow anybody to remap normal RAM that we're using.
-	 * mem_init() sets high_memory so only do the check after that.
-	 */
-	if ( mem_init_done && (p < virt_to_phys(high_memory)) )
-	{
-		printk("__ioremap(): phys addr %0lx is RAM lr %p\n", p,
-		       __builtin_return_address(0));
-		return NULL;
-	}
-
-	if (size == 0)
-		return NULL;
-
-	/*
-	 * Is it already mapped?  Perhaps overlapped by a previous
-	 * BAT mapping.  If the whole area is mapped then we're done,
-	 * otherwise remap it since we want to keep the virt addrs for
-	 * each request contiguous.
-	 *
-	 * We make the assumption here that if the bottom and top
-	 * of the range we want are mapped then it's mapped to the
-	 * same virt address (and this is contiguous).
-	 *  -- Cort
-	 */
-	if ((v = p_mapped_by_bats(p)) /*&& p_mapped_by_bats(p+size-1)*/ )
-		goto out;
-	
-	if (mem_init_done) {
-		struct vm_struct *area;
-		area = get_vm_area(size, VM_IOREMAP);
-		if (area == 0)
-			return NULL;
-		v = VMALLOC_VMADDR(area->addr);
-	} else {
-#ifndef CONFIG_HIGHMEM
-		if (p >= ioremap_base)
-#else
-		if (p >= ioremap_base && p < PKMAP_BASE)
-#endif /* CONFIG_HIGHMEM */
-			v = p;
-		else
-			v = (ioremap_bot -= size);
-	}
-
-	if ((flags & _PAGE_PRESENT) == 0)
-		flags |= pgprot_val(PAGE_KERNEL);
-	if (flags & (_PAGE_NO_CACHE | _PAGE_WRITETHRU))
-		flags |= _PAGE_GUARDED;
-
-	/*
-	 * Should check if it is a candidate for a BAT mapping
-	 */
-
-	err = 0;
-	for (i = 0; i < size && err == 0; i += PAGE_SIZE)
-		err = map_page(v+i, p+i, flags);
-	if (err) {
-		if (mem_init_done)
-			vfree((void *)v);
-		return NULL;
-	}
-
-out:
-	return (void *) (v + (addr & ~PAGE_MASK));
-}
-
-void iounmap(void *addr)
-{
-	if (addr > high_memory && (unsigned long) addr < ioremap_bot)
-		vfree((void *) (PAGE_MASK & (unsigned long) addr));
-}
-
-unsigned long iopa(unsigned long addr)
-{
-	unsigned long pa;
-	pmd_t *pd;
-	pte_t *pg;
-
-	/* Check the BATs */
-	pa = v_mapped_by_bats(addr);
-	if (pa)
-		return pa;
-
-	/* Do we have a page table? */
-	if (init_mm.pgd == NULL)
-		return 0;
-
-	/* Use upper 10 bits of addr to index the first level map */
-	pd = (pmd_t *) (init_mm.pgd + (addr >> PGDIR_SHIFT));
-	if (pmd_none(*pd))
-		return 0;
-
-	/* Use middle 10 bits of addr to index the second-level map */
-	pg = pte_offset(pd, addr);
-	return (pte_val(*pg) & PAGE_MASK) | (addr & ~PAGE_MASK);
-}
-
-int
-map_page(unsigned long va, unsigned long pa, int flags)
-{
-	pmd_t *pd;
-	pte_t *pg;
-	int err = -ENOMEM;
-
-	spin_lock(&init_mm.page_table_lock);
-	/* Use upper 10 bits of VA to index the first level map */
-	pd = pmd_offset(pgd_offset_k(va), va);
-	/* Use middle 10 bits of VA to index the second-level map */
-	pg = pte_alloc(&init_mm, pd, va);
-	if (pg != 0) {
-		err = 0;
-		set_pte(pg, mk_pte_phys(pa & PAGE_MASK, __pgprot(flags)));
-#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
-		if (mem_init_done && Hash != 0)
-			flush_hash_page(0, va, pg);
-#endif /* !4xx && !8xx */
-	}
-	spin_unlock(&init_mm.page_table_lock);
-	return err;
-}
-
-#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
-/*
- * TLB flushing:
- *
- *  - flush_tlb_all() flushes all processes TLBs
- *  - flush_tlb_mm(mm) flushes the specified mm context TLB's
- *  - flush_tlb_page(vma, vmaddr) flushes one page
- *  - flush_tlb_range(mm, start, end) flushes a range of pages
- *
- * since the hardware hash table functions as an extension of the
- * tlb as far as the linux tables are concerned, flush it too.
- *    -- Cort
- */
-
-/*
- * Flush all tlb/hash table entries (except perhaps for those
- * mapping RAM starting at PAGE_OFFSET, since they never change).
- */
-void
-local_flush_tlb_all(void)
-{
-	/* aargh!!! */
-	/* just flush the kernel part of the address space, that's
-	   all that the current callers of this require.  -- paulus. */
-	local_flush_tlb_range(&init_mm, TASK_SIZE, ~0UL);
-
-#ifdef CONFIG_SMP
-	smp_send_tlb_invalidate(0);
-#endif /* CONFIG_SMP */
-}
-
-/*
- * Flush all the (user) entries for the address space described
- * by mm.  We can't rely on mm->mmap describing all the entries
- * that might be in the hash table.
- */
-void
-local_flush_tlb_mm(struct mm_struct *mm)
-{
-	if (Hash == 0) {
-		_tlbia();
-		return;
-	}
-
-	if (mm->map_count) {
-		struct vm_area_struct *mp;
-		for (mp = mm->mmap; mp != NULL; mp = mp->vm_next)
-			local_flush_tlb_range(mm, mp->vm_start, mp->vm_end);
-	} else
-		local_flush_tlb_range(mm, 0, TASK_SIZE);
-
-#ifdef CONFIG_SMP
-	smp_send_tlb_invalidate(0);
-#endif	
-}
-
-void
-local_flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
-{
-	struct mm_struct *mm;
-	pmd_t *pmd;
-	pte_t *pte;
-
-	if (Hash == 0) {
-		_tlbie(vmaddr);
-		return;
-	}
-	mm = (vmaddr < TASK_SIZE)? vma->vm_mm: &init_mm;
-	pmd = pmd_offset(pgd_offset(mm, vmaddr), vmaddr);
-	if (!pmd_none(*pmd)) {
-		pte = pte_offset(pmd, vmaddr);
-		if (pte_val(*pte) & _PAGE_HASHPTE)
-			flush_hash_page(mm->context, vmaddr, pte);
-	}
-#ifdef CONFIG_SMP
-	smp_send_tlb_invalidate(0);
-#endif	
-}
-
-
-/*
- * For each address in the range, find the pte for the address
- * and check _PAGE_HASHPTE bit; if it is set, find and destroy
- * the corresponding HPTE.
- */
-void
-local_flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long end)
-{
-	pmd_t *pmd;
-	pte_t *pte;
-	unsigned long pmd_end;
-	unsigned int ctx = mm->context;
-
-	if (Hash == 0) {
-		_tlbia();
-		return;
-	}
-	start &= PAGE_MASK;
-	if (start >= end)
-		return;
-	pmd = pmd_offset(pgd_offset(mm, start), start);
-	do {
-		pmd_end = (start + PGDIR_SIZE) & PGDIR_MASK;
-		if (!pmd_none(*pmd)) {
-			if (!pmd_end || pmd_end > end)
-				pmd_end = end;
-			pte = pte_offset(pmd, start);
-			do {
-				if ((pte_val(*pte) & _PAGE_HASHPTE) != 0)
-					flush_hash_page(ctx, start, pte);
-				start += PAGE_SIZE;
-				++pte;
-			} while (start && start < pmd_end);
-		} else {
-			start = pmd_end;
-		}
-		++pmd;
-	} while (start && start < end);
-
-#ifdef CONFIG_SMP
-	smp_send_tlb_invalidate(0);
-#endif	
-}
-
-/*
- * Set up one of the I/D BAT (block address translation) register pairs.
- * The parameters are not checked; in particular size must be a power
- * of 2 between 128k and 256M.
- */
-void __init setbat(int index, unsigned long virt, unsigned long phys,
-       unsigned int size, int flags)
-{
-	unsigned int bl;
-	int wimgxpp;
-	union ubat *bat = BATS[index];
-
-	bl = (size >> 17) - 1;
-	if ((_get_PVR() >> 16) != 1) {
-		/* 603, 604, etc. */
-		/* Do DBAT first */
-		wimgxpp = flags & (_PAGE_WRITETHRU | _PAGE_NO_CACHE
-				   | _PAGE_COHERENT | _PAGE_GUARDED);
-		wimgxpp |= (flags & _PAGE_RW)? BPP_RW: BPP_RX;
-		bat[1].word[0] = virt | (bl << 2) | 2; /* Vs=1, Vp=0 */
-		bat[1].word[1] = phys | wimgxpp;
-#ifndef CONFIG_KGDB /* want user access for breakpoints */
-		if (flags & _PAGE_USER)
-#endif
-			bat[1].bat.batu.vp = 1;
-		if (flags & _PAGE_GUARDED) {
-			/* G bit must be zero in IBATs */
-			bat[0].word[0] = bat[0].word[1] = 0;
-		} else {
-			/* make IBAT same as DBAT */
-			bat[0] = bat[1];
-		}
-	} else {
-		/* 601 cpu */
-		if (bl > BL_8M)
-			bl = BL_8M;
-		wimgxpp = flags & (_PAGE_WRITETHRU | _PAGE_NO_CACHE
-				   | _PAGE_COHERENT);
-		wimgxpp |= (flags & _PAGE_RW)?
-			((flags & _PAGE_USER)? PP_RWRW: PP_RWXX): PP_RXRX;
-		bat->word[0] = virt | wimgxpp | 4;	/* Ks=0, Ku=1 */
-		bat->word[1] = phys | bl | 0x40;	/* V=1 */
-	}
-
-	bat_addrs[index].start = virt;
-	bat_addrs[index].limit = virt + ((bl + 1) << 17) - 1;
-	bat_addrs[index].phys = phys;
-}
-
-#define IO_PAGE	(_PAGE_NO_CACHE | _PAGE_GUARDED | _PAGE_RW)
-#ifdef CONFIG_SMP
-#define RAM_PAGE (_PAGE_RW|_PAGE_COHERENT)
-#else
-#define RAM_PAGE (_PAGE_RW)
-#endif
-#endif /* CONFIG_8xx */
-
-/*
- * Map in all of physical memory starting at KERNELBASE.
- */
-static void __init mapin_ram(void)
-{
-	unsigned long v, p, s, f;
-
-#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx) && !defined(CONFIG_POWER4)
-	if (!__map_without_bats) {
-		unsigned long tot, bl, done;
-		unsigned long max_size = (256<<20);
-		unsigned long align;
-
-		/* Set up BAT2 and if necessary BAT3 to cover RAM. */
-
-		/* Make sure we don't map a block larger than the
-		   smallest alignment of the physical address. */
-		/* alignment of ram_phys_base */
-		align = ~(ram_phys_base-1) & ram_phys_base;
-		/* set BAT block size to MIN(max_size, align) */
-		if (align && align < max_size)
-			max_size = align;
-
-		tot = total_lowmem;
-		for (bl = 128<<10; bl < max_size; bl <<= 1) {
-			if (bl * 2 > tot)
-				break;
-		}
-
-		setbat(2, KERNELBASE, ram_phys_base, bl, RAM_PAGE);
-		done = (unsigned long)bat_addrs[2].limit - KERNELBASE + 1;
-		if ((done < tot) && !bat_addrs[3].limit) {
-			/* use BAT3 to cover a bit more */
-			tot -= done;
-			for (bl = 128<<10; bl < max_size; bl <<= 1)
-				if (bl * 2 > tot)
-					break;
-			setbat(3, KERNELBASE+done, ram_phys_base+done, bl, 
-			       RAM_PAGE);
-		}
-	}
-#endif /* !CONFIG_4xx && !CONFIG_8xx && !CONFIG_POWER4 */
-
-	v = KERNELBASE;
-	p = ram_phys_base;
-	for (s = 0; s < total_lowmem; s += PAGE_SIZE) {
-		/* On the MPC8xx, we want the page shared so we
-		 * don't get ASID compares on kernel space.
-		 */
-		f = _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_SHARED;
-#if defined(CONFIG_KGDB) || defined(CONFIG_XMON)
-		/* Allows stub to set breakpoints everywhere */
-		f |= _PAGE_RW | _PAGE_DIRTY;
-#else
-		if ((char *) v < _stext || (char *) v >= etext)
-			f |= _PAGE_RW | _PAGE_DIRTY;
-#ifndef CONFIG_8xx
-		else
-			/* On the powerpc (not 8xx), no user access
-			   forces R/W kernel access */
-			f |= _PAGE_USER;
-#endif /* CONFIG_8xx */
-#endif /* CONFIG_KGDB */
-		map_page(v, p, f);
-		v += PAGE_SIZE;
-		p += PAGE_SIZE;
-	}
-}
-
-/* This is only called until mem_init is done. */
-void __init *early_get_page(void)
-{
-	void *p;
-
-	if (init_bootmem_done) {
-		p = alloc_bootmem_pages(PAGE_SIZE);
-	} else {
-		p = mem_pieces_find(PAGE_SIZE, PAGE_SIZE);
-	}
-	return p;
-}
-
+/* Free up now-unused memory */
 static void free_sec(unsigned long start, unsigned long end, const char *name)
 {
 	unsigned long cnt = 0;
@@ -725,7 +216,7 @@
 		start += PAGE_SIZE;
  	}
 	if (cnt) {
-		printk(" %ldk %s", PGTOKB(cnt), name);
+		printk(" %ldk %s", cnt << (PAGE_SHIFT - 10), name);
 		totalram_pages += cnt;
 	}
 }
@@ -766,110 +257,54 @@
 #endif
 
 /*
- * Initialize the context management stuff.
+ * Check for command-line options that affect what MMU_init will do.
  */
-static void mmu_context_init(void)
+void MMU_setup(void)
 {
-	context_map[0] = 1;	/* init_mm uses context 0 */
-	next_mmu_context = 1;
-#ifdef FEW_CONTEXTS
-	atomic_set(&nr_free_contexts, LAST_CONTEXT);
-	context_mm[0] = &init_mm;
-#endif /* FEW_CONTEXTS */
-}
-
-#ifdef FEW_CONTEXTS
-/*
- * Steal a context from a task that has one at the moment.
- * This is only used on 8xx and 4xx and we presently assume that
- * they don't do SMP.  If they do then this will have to check
- * whether the MM we steal is in use.
- * We also assume that this is only used on systems that don't
- * use an MMU hash table - this is true for 8xx and 4xx.
- * This isn't an LRU system, it just frees up each context in
- * turn (sort-of pseudo-random replacement :).  This would be the
- * place to implement an LRU scheme if anyone was motivated to do it.
- *  -- paulus
- */
-void steal_context(void)
-{
-	struct mm_struct *mm;
-
-	/* free up context `next_mmu_context' */
-	/* if we shouldn't free context 0, don't... */
-#ifdef CONFIG_4xx
-	if (next_mmu_context == 0)
-		next_mmu_context = 1;
-#endif /* CONFIG_4xx */
-	mm = context_mm[next_mmu_context];
-	flush_tlb_mm(mm);
-	destroy_context(mm);
+	/* Check for nobats option (used in mapin_ram). */
+	if (strstr(cmd_line, "nobats")) {
+		__map_without_bats = 1;
+	}
+
+	/* Look for mem= option on command line */
+	if (strstr(cmd_line, "mem=")) {
+		char *p, *q;
+		unsigned long maxmem = 0;
+
+		for (q = cmd_line; (p = strstr(q, "mem=")) != 0; ) {
+			q = p + 4;
+			if (p > cmd_line && p[-1] != ' ')
+				continue;
+			maxmem = simple_strtoul(q, &q, 0);
+			if (*q == 'k' || *q == 'K') {
+				maxmem <<= 10;
+				++q;
+			} else if (*q == 'm' || *q == 'M') {
+				maxmem <<= 20;
+				++q;
+			}
+		}
+		__max_memory = maxmem;
+	}
 }
-#endif /* FEW_CONTEXTS */
-
-extern boot_infos_t *disp_bi;
 
 /*
- * Do very early mm setup such as finding the size of memory
- * and setting up the hash table.
- * A lot of this is prep/pmac specific but a lot of it could
- * still be merged.
- * -- Cort
+ * MMU_init sets up the basic memory mappings for the kernel,
+ * including both RAM and possibly some I/O regions,
+ * and sets up the page tables and the MMU hardware ready to go.
  */
-#if defined(CONFIG_4xx)
-void __init
-MMU_init(void)
+void __init MMU_init(void)
 {
-	/*
-	 * The Zone Protection Register (ZPR) defines how protection will
-	 * be applied to every page which is a member of a given zone. At
-	 * present, we utilize only two of the 4xx's zones.
-	 * The zone index bits (of ZSEL) in the PTE are used for software
-	 * indicators, except the LSB.  For user access, zone 15 is used,
-	 * for kernel access, zone 14 is used.  We set all but zone 15
-	 * to zero, allowing only kernel access as indicated in the PTE.
-	 * For zone 15, we set a 10 binary (I guess a 01 would work too)
-	 * to allow user access as indicated in the PTE.  This also allows
-	 * kernel access as indicated in the PTE.
-	 */
+	if (ppc_md.progress)
+		ppc_md.progress("MMU:enter", 0x111);
 
-        mtspr(SPRN_ZPR, 0x00000002);
-
-	flush_instruction_cache();
+	/* parse args from command line */
+	MMU_setup();
 
 	/*
-	 * Find the top of physical memory and map all of it in starting
-	 * at KERNELBASE.
+	 * Figure out how much memory we have, how much
+	 * is lowmem, and how much is highmem.
 	 */
-
-        total_memory = total_lowmem = ppc_md.find_end_of_memory();
-	end_of_DRAM = __va(total_lowmem);
-	set_phys_avail(total_lowmem);
-        mapin_ram();
-
-	/*
-	 * Set up the real-mode cache parameters for the exception vector
-	 * handlers (which are run in real-mode).
-	 */
-
-        mtspr(SPRN_DCWR, 0x00000000);	/* All caching is write-back */
-
-        /*
-	 * Cache instruction and data space where the exception
-	 * vectors and the kernel live in real-mode.
-	 */
-
-        mtspr(SPRN_DCCR, 0x80000000);	/* 128 MB of data space at 0x0. */
-        mtspr(SPRN_ICCR, 0x80000000);	/* 128 MB of instr. space at 0x0. */
-
-	mmu_context_init();
-}
-
-#else /* !CONFIG_4xx */
-void __init MMU_init(void)
-{
-	if ( ppc_md.progress ) ppc_md.progress("MMU:enter", 0x111);
-
 	total_memory = ppc_md.find_end_of_memory();
 
 	if (__max_memory && total_memory > __max_memory)
@@ -884,114 +319,54 @@
 	end_of_DRAM = __va(total_lowmem);
 	set_phys_avail(total_lowmem);
 
-#if !defined(CONFIG_8xx)
-	if ( ppc_md.progress ) ppc_md.progress("MMU:hash init", 0x300);
-        hash_init();
-#ifndef CONFIG_PPC64BRIDGE
-        _SDR1 = __pa(Hash) | (Hash_mask >> 10);
-#endif
-	
-	ioremap_base = 0xf8000000;
-#endif /* CONFIG_8xx */
+	/* Initialize the MMU hardware */
+	if (ppc_md.progress)
+		ppc_md.progress("MMU:hw init", 0x300);
+	MMU_init_hw();
 
-	if ( ppc_md.progress ) ppc_md.progress("MMU:mapin", 0x301);
 	/* Map in all of RAM starting at KERNELBASE */
+	if (ppc_md.progress)
+		ppc_md.progress("MMU:mapin", 0x301);
 	mapin_ram();
 
-#if defined(CONFIG_8xx)
-        /* Now map in some of the I/O space that is generically needed
-         * or shared with multiple devices.
-         * All of this fits into the same 4Mbyte region, so it only
-         * requires one page table page.
-         */
-        ioremap(IMAP_ADDR, IMAP_SIZE);
-#ifdef CONFIG_MBX
-        ioremap(NVRAM_ADDR, NVRAM_SIZE);
-        ioremap(MBX_CSR_ADDR, MBX_CSR_SIZE);
-        ioremap(PCI_CSR_ADDR, PCI_CSR_SIZE);
-
-	/* Map some of the PCI/ISA I/O space to get the IDE interface.
-	*/
-        ioremap(PCI_ISA_IO_ADDR, 0x4000);
-        ioremap(PCI_IDE_ADDR, 0x4000);
-#endif
-#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC)
-	ioremap(RPX_CSR_ADDR, RPX_CSR_SIZE);
-#if !defined(CONFIG_PCI)
-	ioremap(_IO_BASE,_IO_BASE_SIZE);
-#endif
-#endif
-#ifdef CONFIG_HTDMSOUND
-	ioremap(HIOX_CSR_ADDR, HIOX_CSR_SIZE);
-#endif
-#ifdef CONFIG_FADS
-	ioremap(BCSR_ADDR, BCSR_SIZE);
-#endif
-#ifdef CONFIG_PCI
-        ioremap(PCI_CSR_ADDR, PCI_CSR_SIZE);
-#endif
-#else /* !CONFIG_8xx */
-	/*
-	 * Setup the bat mappings we're going to load that cover
-	 * the io areas.  RAM was mapped by mapin_ram().
-	 * -- Cort
-	 */
-	if ( ppc_md.progress ) ppc_md.progress("MMU:setbat", 0x302);
-	switch (_machine) {
-	case _MACH_prep:
-		setbat(0, 0x80000000, 0x80000000, 0x10000000, IO_PAGE);
-		setbat(1, 0xf0000000, 0xc0000000, 0x08000000, IO_PAGE);
-		ioremap_base = 0xf0000000;
-		break;
-	case _MACH_chrp:
-		/*
-		 * The code below tends to get removed, please don't take it out.
-		 * The F50 needs this mapping and it you take it out I'll track you
-		 * down and slap your hands.  If it causes problems please email me.
-		 *  -- Cort <cort@fsmlabs.com>
-		 */
-#ifndef CONFIG_POWER3
-		setbat(0, 0x80000000, 0x80000000, 0x10000000, IO_PAGE);
-		setbat(1, 0x90000000, 0x90000000, 0x10000000, IO_PAGE);
-#endif
-		break;
-	case _MACH_Pmac:
-		ioremap_base = 0xfe000000;
-		break;
-	case _MACH_apus:
-		/* Map PPC exception vectors. */
-		setbat(0, 0xfff00000, 0xfff00000, 0x00020000, RAM_PAGE);
-		/* Map chip and ZorroII memory */
-		setbat(1, zTwoBase,   0x00000000, 0x01000000, IO_PAGE);
-		break;
-	case _MACH_gemini:
-		setbat(0, 0xf0000000, 0xf0000000, 0x10000000, IO_PAGE);
-		setbat(1, 0x80000000, 0x80000000, 0x10000000, IO_PAGE);
-		break;
-	case _MACH_8260:
-		/* Map the IMMR, plus anything else we can cover
-		 * in that upper space according to the memory controller
-		 * chip select mapping.  Grab another bunch of space
-		 * below that for stuff we can't cover in the upper.
-		 */
-		setbat(0, 0xf0000000, 0xf0000000, 0x10000000, IO_PAGE);
-		setbat(1, 0xe0000000, 0xe0000000, 0x10000000, IO_PAGE);
-		ioremap_base = 0xe0000000;
-		break;
-	}
+#ifdef CONFIG_HIGHMEM
+	ioremap_base = PKMAP_BASE;
+#else
+	ioremap_base = 0xfe000000UL;	/* for now, could be 0xfffff000 */
+#endif /* CONFIG_HIGHMEM */
 	ioremap_bot = ioremap_base;
-#endif /* CONFIG_8xx */
 
-	if ( ppc_md.progress ) ppc_md.progress("MMU:exit", 0x211);
+	/* Map in I/O resources */
+	if (ppc_md.progress)
+		ppc_md.progress("MMU:setio", 0x302);
+	if (ppc_md.setup_io_mappings)
+		ppc_md.setup_io_mappings();
+
+	/* Initialize the context management stuff */
+	mmu_context_init();
+
+	if (ppc_md.progress)
+		ppc_md.progress("MMU:exit", 0x211);
+
 #ifdef CONFIG_BOOTX_TEXT
 	/* Must be done last, or ppc_md.progress will die */
-	if (_machine == _MACH_Pmac || _machine == _MACH_chrp)
-		map_bootx_text();
+	if (have_of)
+		map_boot_text();
 #endif
+}
 
-	mmu_context_init();
+/* This is only called until mem_init is done. */
+void __init *early_get_page(void)
+{
+	void *p;
+
+	if (init_bootmem_done) {
+		p = alloc_bootmem_pages(PAGE_SIZE);
+	} else {
+		p = mem_pieces_find(PAGE_SIZE, PAGE_SIZE);
+	}
+	return p;
 }
-#endif /* CONFIG_4xx */
 
 /*
  * Initialize the bootmem system and give it all the memory we
@@ -1068,8 +443,6 @@
 
 void __init mem_init(void)
 {
-	extern char *sysmap; 
-	extern unsigned long sysmap_size;
 	unsigned long addr;
 	int codepages = 0;
 	int datapages = 0;
@@ -1094,7 +467,7 @@
 	   make sure the ramdisk pages aren't reserved. */
 	if (initrd_start) {
 		for (addr = initrd_start; addr < initrd_end; addr += PAGE_SIZE)
-			clear_bit(PG_reserved, &virt_to_page(addr)->flags);
+			ClearPageReserved(virt_to_page(addr));
 	}
 #endif /* CONFIG_BLK_DEV_INITRD */
 
@@ -1106,7 +479,7 @@
 		     addr += PAGE_SIZE)
 			SetPageReserved(virt_to_page(addr));
 #endif /* defined(CONFIG_ALL_PPC) */
-	if ( sysmap_size )
+	if ( sysmap )
 		for (addr = (unsigned long)sysmap;
 		     addr < PAGE_ALIGN((unsigned long)sysmap+sysmap_size) ;
 		     addr += PAGE_SIZE)
@@ -1147,133 +520,12 @@
 	       codepages<< (PAGE_SHIFT-10), datapages<< (PAGE_SHIFT-10),
 	       initpages<< (PAGE_SHIFT-10),
 	       (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10)));
+	if (sysmap)
+		printk("System.map loaded at 0x%08x for debugger, size: %ld bytes\n",
+			(unsigned int)sysmap, sysmap_size);
 	mem_init_done = 1;
 }
 
-#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
-/*
- * Initialize the hash table and patch the instructions in hashtable.S.
- */
-static void __init hash_init(void)
-{
-	int Hash_bits, mb, mb2;
-	unsigned int hmask, h;
-
-	extern unsigned int hash_page_patch_A[];
-	extern unsigned int hash_page_patch_B[], hash_page_patch_C[];
-	extern unsigned int hash_page[];
-	extern unsigned int flush_hash_patch_A[], flush_hash_patch_B[];
-
-#ifdef CONFIG_PPC64BRIDGE
-	/* The hash table has already been allocated and initialized
-	   in prom.c */
-	Hash_mask = (Hash_size >> 7) - 1;
-	hmask = Hash_mask >> 9;
-	Hash_bits = __ilog2(Hash_size) - 7;
-	mb = 25 - Hash_bits;
-	if (Hash_bits > 16)
-		Hash_bits = 16;
-	mb2 = 25 - Hash_bits;
-
-#else /* CONFIG_PPC64BRIDGE */
-
-	if ( ppc_md.progress ) ppc_md.progress("hash:enter", 0x105);
-	/*
-	 * Allow 64k of hash table for every 16MB of memory,
-	 * up to a maximum of 2MB.
-	 */
-	for (h = 64<<10; h < total_memory / 256 && h < (2<<20); h *= 2)
-		;
-	Hash_size = h;
-	Hash_mask = (h >> 6) - 1;
-	hmask = Hash_mask >> 10;
-	Hash_bits = __ilog2(h) - 6;
-	mb = 26 - Hash_bits;
-	if (Hash_bits > 16)
-		Hash_bits = 16;
-	mb2 = 26 - Hash_bits;
-
-	/* shrink the htab since we don't use it on 603's -- Cort */
-	switch (_get_PVR()>>16) {
-	case 3: /* 603 */
-	case 6: /* 603e */
-	case 7: /* 603ev */
-	case 0x0081: /* 82xx */
-		Hash_size = 0;
-		Hash_mask = 0;
-		break;
-	default:
-	        /* on 601/4 let things be */
-		break;
- 	}
-	
-	if ( ppc_md.progress ) ppc_md.progress("hash:find piece", 0x322);
-	/* Find some memory for the hash table. */
-	if ( Hash_size ) {
-		Hash = mem_pieces_find(Hash_size, Hash_size);
-		cacheable_memzero(Hash, Hash_size);
-		_SDR1 = __pa(Hash) | (Hash_mask >> 10);
-	} else
-		Hash = 0;
-#endif /* CONFIG_PPC64BRIDGE */
-
-	printk("Total memory = %ldMB; using %ldkB for hash table (at %p)\n",
-	       total_memory >> 20, Hash_size >> 10, Hash);
-	if ( Hash_size )
-	{
-		if ( ppc_md.progress ) ppc_md.progress("hash:patch", 0x345);
-		Hash_end = (PTE *) ((unsigned long)Hash + Hash_size);
-
-		/*
-		 * Patch up the instructions in hashtable.S:create_hpte
-		 */
-		hash_page_patch_A[0] = (hash_page_patch_A[0] & ~0xffff)
-			| ((unsigned int)(Hash) >> 16);
-		hash_page_patch_A[1] = (hash_page_patch_A[1] & ~0x7c0)
-			| (mb << 6);
-		hash_page_patch_A[2] = (hash_page_patch_A[2] & ~0x7c0)
-			| (mb2 << 6);
-		hash_page_patch_B[0] = (hash_page_patch_B[0] & ~0xffff)
-			| hmask;
-		hash_page_patch_C[0] = (hash_page_patch_C[0] & ~0xffff)
-			| hmask;
-		/*
-		 * Ensure that the locations we've patched have been written
-		 * out from the data cache and invalidated in the instruction
-		 * cache, on those machines with split caches.
-		 */
-		flush_icache_range((unsigned long) &hash_page_patch_A[0],
-				   (unsigned long) &hash_page_patch_C[1]);
-		/*
-		 * Patch up the instructions in hashtable.S:flush_hash_page
-		 */
-		flush_hash_patch_A[0] = (flush_hash_patch_A[0] & ~0xffff)
-			| ((unsigned int)(Hash) >> 16);
-		flush_hash_patch_A[1] = (flush_hash_patch_A[1] & ~0x7c0)
-			| (mb << 6);
-		flush_hash_patch_A[2] = (flush_hash_patch_A[2] & ~0x7c0)
-			| (mb2 << 6);
-		flush_hash_patch_B[0] = (flush_hash_patch_B[0] & ~0xffff)
-			| hmask;
-		flush_icache_range((unsigned long) &flush_hash_patch_A[0],
-				   (unsigned long) &flush_hash_patch_B[1]);
-	}
-	else {
-		Hash_end = 0;
-		/*
-		 * Put a blr (procedure return) instruction at the
-		 * start of hash_page, since we can still get DSI
-		 * exceptions on a 603.
-		 */
-		hash_page[0] = 0x4e800020;
-		flush_icache_range((unsigned long) &hash_page[0],
-				   (unsigned long) &hash_page[1]);
-	}
-
-	if ( ppc_md.progress ) ppc_md.progress("hash:done", 0x205);
-}
-#endif /* !CONFIG_4xx && !CONFIG_8xx */
-
 /*
  * Set phys_avail to the amount of physical memory,
  * less the kernel text/data/bss.
@@ -1314,12 +566,16 @@
 	/* remove the RTAS pages from the available memory */
 	if (rtas_data)
 		mem_pieces_remove(&phys_avail, rtas_data, rtas_size, 1);
+	/* remove the sysmap pages from the available memory */
+	if (sysmap)
+		mem_pieces_remove(&phys_avail, __pa(sysmap), sysmap_size, 1);
 #endif /* CONFIG_ALL_PPC */
-#ifdef CONFIG_PPC64BRIDGE
-	/* Remove the hash table from the available memory */
-	if (Hash)
-		mem_pieces_remove(&phys_avail, __pa(Hash), Hash_size, 1);
-#endif /* CONFIG_PPC64BRIDGE */
+}
+
+/* Mark some memory as reserved by removing it from phys_avail. */
+void __init reserve_phys_mem(unsigned long start, unsigned long size)
+{
+	mem_pieces_remove(&phys_avail, start, size, 1);
 }
 
 void flush_page_to_ram(struct page *page)
@@ -1328,32 +584,6 @@
 	__flush_page_to_ram(vaddr);
 	kunmap(page);
 }
-
-#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
-/*
- * This is called at the end of handling a user page fault, when the
- * fault has been handled by updating a PTE in the linux page tables.
- * We use it to preload an HPTE into the hash table corresponding to
- * the updated linux PTE.
- */
-void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
-		      pte_t pte)
-{
-	struct mm_struct *mm;
-	pmd_t *pmd;
-	pte_t *ptep;
-	static int nopreload;
-
-	if (Hash == 0 || nopreload)
-		return;
-	mm = (address < TASK_SIZE)? vma->vm_mm: &init_mm;
-	pmd = pmd_offset(pgd_offset(mm, address), address);
-	if (!pmd_none(*pmd)) {
-		ptep = pte_offset(pmd, address);
-		add_hash_page(mm->context, address, ptep);
-	}
-}
-#endif /* !4xx && !8xx */
 
 /*
  * set_pte stores a linux PTE into the linux page table.
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/mm/mmu_context.c linux/arch/ppc/mm/mmu_context.c
--- v2.4.9/linux/arch/ppc/mm/mmu_context.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/mm/mmu_context.c	Tue Aug 28 06:58:33 2001
@@ -0,0 +1,89 @@
+/*
+ * BK Id: %F% %I% %G% %U% %#%
+ */
+/*
+ * This file contains the routines for handling the MMU on those
+ * PowerPC implementations where the MMU substantially follows the
+ * architecture specification.  This includes the 6xx, 7xx, 7xxx,
+ * 8260, and POWER3 implementations but excludes the 8xx and 4xx.
+ * Although the iSeries hardware does comply with the architecture
+ * specification, the need to work through the hypervisor makes
+ * things sufficiently different that it is handled elsewhere.
+ *  -- paulus
+ * 
+ *  Derived from arch/ppc/mm/init.c:
+ *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ *  Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
+ *  and Cort Dougan (PReP) (cort@cs.nmt.edu)
+ *    Copyright (C) 1996 Paul Mackerras
+ *  Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ *
+ *  Derived from "arch/i386/mm/init.c"
+ *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
+ *
+ *  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/config.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/mmu_context.h>
+
+mm_context_t next_mmu_context;
+unsigned long context_map[(LAST_CONTEXT+1) / (8*sizeof(unsigned long))];
+#ifdef FEW_CONTEXTS
+atomic_t nr_free_contexts;
+struct mm_struct *context_mm[LAST_CONTEXT+1];
+void steal_context(void);
+#endif /* FEW_CONTEXTS */
+
+/*
+ * Initialize the context management stuff.
+ */
+void __init mmu_context_init(void)
+{
+	/*
+	 * Some processors have too few contexts to reserve one for
+	 * init_mm, and require using context 0 for a normal task.
+	 * Other processors reserve the use of context zero for the kernel.
+	 * This code assumes FIRST_CONTEXT < 32.
+	 */
+	context_map[0] = (1 << FIRST_CONTEXT) - 1;
+	next_mmu_context = FIRST_CONTEXT;
+#ifdef FEW_CONTEXTS
+	atomic_set(&nr_free_contexts, LAST_CONTEXT);
+#endif /* FEW_CONTEXTS */
+}
+
+#ifdef FEW_CONTEXTS
+/*
+ * Steal a context from a task that has one at the moment.
+ * This is only used on 8xx and 4xx and we presently assume that
+ * they don't do SMP.  If they do then this will have to check
+ * whether the MM we steal is in use.
+ * We also assume that this is only used on systems that don't
+ * use an MMU hash table - this is true for 8xx and 4xx.
+ * This isn't an LRU system, it just frees up each context in
+ * turn (sort-of pseudo-random replacement :).  This would be the
+ * place to implement an LRU scheme if anyone was motivated to do it.
+ *  -- paulus
+ */
+void steal_context(void)
+{
+	struct mm_struct *mm;
+
+	/* free up context `next_mmu_context' */
+	/* if we shouldn't free context 0, don't... */
+	if (next_mmu_context < FIRST_CONTEXT)
+		next_mmu_context = FIRST_CONTEXT;
+	mm = context_mm[next_mmu_context];
+	flush_tlb_mm(mm);
+	destroy_context(mm);
+}
+#endif /* FEW_CONTEXTS */
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/mm/mmu_decl.h linux/arch/ppc/mm/mmu_decl.h
--- v2.4.9/linux/arch/ppc/mm/mmu_decl.h	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/mm/mmu_decl.h	Tue Aug 28 06:58:33 2001
@@ -0,0 +1,73 @@
+/*
+ * BK Id: %F% %I% %G% %U% %#%
+ */
+/*
+ * Declarations of procedures and variables shared between files
+ * in arch/ppc/mm/.
+ * 
+ *  Derived from arch/ppc/mm/init.c:
+ *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ *  Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
+ *  and Cort Dougan (PReP) (cort@cs.nmt.edu)
+ *    Copyright (C) 1996 Paul Mackerras
+ *  Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ *
+ *  Derived from "arch/i386/mm/init.c"
+ *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
+ *
+ *  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.
+ *
+ */
+
+extern void mapin_ram(void);
+extern void bat_mapin_ram(void);
+extern int map_page(unsigned long va, unsigned long pa, int flags);
+extern void setbat(int index, unsigned long virt, unsigned long phys,
+		   unsigned int size, int flags);
+extern void reserve_phys_mem(unsigned long start, unsigned long size);
+
+extern int __map_without_bats;
+extern void *end_of_DRAM;
+extern unsigned long ioremap_base;
+extern unsigned long ioremap_bot;
+extern unsigned int rtas_data, rtas_size;
+
+extern unsigned long total_memory;
+extern unsigned long total_lowmem;
+extern unsigned long ram_phys_base;
+extern int mem_init_done;
+
+extern PTE *Hash, *Hash_end;
+extern unsigned long Hash_size, Hash_mask;
+
+/* ...and now those things that may be slightly different between processor
+ * architectures.  -- Dan
+ */
+#if defined(CONFIG_8xx)
+#define flush_HPTE(X, va, pg)	_tlbie(va)
+#define MMU_init_hw()		do { } while(0)
+
+#elif defined(CONFIG_4xx)
+#define flush_HPTE(X, va, pg)	_tlbie(va)
+
+#else
+/* anything except 4xx or 8xx */
+extern void MMU_init_hw(void);
+
+/* Be careful....this needs to be updated if we ever encounter 603 SMPs,
+ * which includes all new 82xx processors.  We need tlbie/tlbsync here
+ * in that case (I think). -- Dan.
+ */
+static inline void flush_HPTE(unsigned context, unsigned long va, pte_t *pg)
+{
+	if ((Hash != 0) &&
+	    (cur_cpu_spec[0]->cpu_features & CPU_FTR_HPTE_TABLE))
+		flush_hash_page(0, va, pg);
+	else
+		_tlbie(va);
+}
+#endif
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/mm/pgtable.c linux/arch/ppc/mm/pgtable.c
--- v2.4.9/linux/arch/ppc/mm/pgtable.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/mm/pgtable.c	Tue Aug 28 06:58:33 2001
@@ -0,0 +1,360 @@
+/*
+ * BK Id: %F% %I% %G% %U% %#%
+ */
+/*
+ * This file contains the routines setting up the linux page tables.
+ *  -- paulus
+ * 
+ *  Derived from arch/ppc/mm/init.c:
+ *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ *  Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
+ *  and Cort Dougan (PReP) (cort@cs.nmt.edu)
+ *    Copyright (C) 1996 Paul Mackerras
+ *  Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ *
+ *  Derived from "arch/i386/mm/init.c"
+ *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
+ *
+ *  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/config.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/vmalloc.h>
+#include <linux/init.h>
+
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/io.h>
+
+#include "mmu_decl.h"
+
+unsigned long ram_phys_base;
+
+unsigned long ioremap_base;
+unsigned long ioremap_bot;
+int io_bat_index;
+
+#ifndef CONFIG_SMP
+struct pgtable_cache_struct quicklists;
+#endif
+
+#if defined(CONFIG_6xx) || defined(CONFIG_POWER3)
+#define HAVE_BATS	1
+#endif
+
+extern char etext[], _stext[];
+
+#ifdef HAVE_BATS
+extern unsigned long v_mapped_by_bats(unsigned long va);
+extern unsigned long p_mapped_by_bats(unsigned long pa);
+void setbat(int index, unsigned long virt, unsigned long phys,
+	    unsigned int size, int flags);
+
+#else /* !HAVE_BATS */
+#define v_mapped_by_bats(x)	(0UL)
+#define p_mapped_by_bats(x)	(0UL)
+#endif /* HAVE_BATS */
+
+#ifndef CONFIG_PPC_ISERIES
+void *
+ioremap(unsigned long addr, unsigned long size)
+{
+	return __ioremap(addr, size, _PAGE_NO_CACHE);
+}
+
+void *
+__ioremap(unsigned long addr, unsigned long size, unsigned long flags)
+{
+	unsigned long p, v, i;
+	int err;
+
+	/*
+	 * Choose an address to map it to.
+	 * Once the vmalloc system is running, we use it.
+	 * Before then, we use space going down from ioremap_base
+	 * (ioremap_bot records where we're up to).
+	 */
+	p = addr & PAGE_MASK;
+	size = PAGE_ALIGN(addr + size) - p;
+
+	/*
+	 * If the address lies within the first 16 MB, assume it's in ISA
+	 * memory space
+	 */
+	if (p < 16*1024*1024)
+		p += _ISA_MEM_BASE;
+
+	/*
+	 * Don't allow anybody to remap normal RAM that we're using.
+	 * mem_init() sets high_memory so only do the check after that.
+	 */
+	if ( mem_init_done && (p < virt_to_phys(high_memory)) )
+	{
+		printk("__ioremap(): phys addr %0lx is RAM lr %p\n", p,
+		       __builtin_return_address(0));
+		return NULL;
+	}
+
+	if (size == 0)
+		return NULL;
+
+	/*
+	 * Is it already mapped?  Perhaps overlapped by a previous
+	 * BAT mapping.  If the whole area is mapped then we're done,
+	 * otherwise remap it since we want to keep the virt addrs for
+	 * each request contiguous.
+	 *
+	 * We make the assumption here that if the bottom and top
+	 * of the range we want are mapped then it's mapped to the
+	 * same virt address (and this is contiguous).
+	 *  -- Cort
+	 */
+	if ((v = p_mapped_by_bats(p)) /*&& p_mapped_by_bats(p+size-1)*/ )
+		goto out;
+	
+	if (mem_init_done) {
+		struct vm_struct *area;
+		area = get_vm_area(size, VM_IOREMAP);
+		if (area == 0)
+			return NULL;
+		v = VMALLOC_VMADDR(area->addr);
+	} else {
+		v = (ioremap_bot -= size);
+	}
+
+	if ((flags & _PAGE_PRESENT) == 0)
+		flags |= _PAGE_KERNEL;
+	if (flags & _PAGE_NO_CACHE)
+		flags |= _PAGE_GUARDED;
+
+	/*
+	 * Should check if it is a candidate for a BAT mapping
+	 */
+
+	err = 0;
+	for (i = 0; i < size && err == 0; i += PAGE_SIZE)
+		err = map_page(v+i, p+i, flags);
+	if (err) {
+		if (mem_init_done)
+			vfree((void *)v);
+		return NULL;
+	}
+
+out:
+	return (void *) (v + (addr & ~PAGE_MASK));
+}
+
+void iounmap(void *addr)
+{
+	/*
+	 * If mapped by BATs then there is nothing to do.
+	 * Calling vfree() generates a benign warning.
+	 */
+	if (v_mapped_by_bats((unsigned long)addr)) return;
+
+	if (addr > high_memory && (unsigned long) addr < ioremap_bot)
+		vfree((void *) (PAGE_MASK & (unsigned long) addr));
+}
+#endif /* CONFIG_PPC_ISERIES */
+
+int
+map_page(unsigned long va, unsigned long pa, int flags)
+{
+	pmd_t *pd;
+	pte_t *pg;
+	int err = -ENOMEM;
+
+	spin_lock(&init_mm.page_table_lock);
+	/* Use upper 10 bits of VA to index the first level map */
+	pd = pmd_offset(pgd_offset_k(va), va);
+	/* Use middle 10 bits of VA to index the second-level map */
+	pg = pte_alloc(&init_mm, pd, va);
+	if (pg != 0) {
+		err = 0;
+		set_pte(pg, mk_pte_phys(pa & PAGE_MASK, __pgprot(flags)));
+		if (mem_init_done)
+			flush_HPTE(0, va, pg);
+	}
+	spin_unlock(&init_mm.page_table_lock);
+	return err;
+}
+
+/*
+ * Map in all of physical memory starting at KERNELBASE.
+ */
+void __init mapin_ram(void)
+{
+	unsigned long v, p, s, f;
+
+#ifdef HAVE_BATS
+	if (!__map_without_bats)
+		bat_mapin_ram();
+#endif /* HAVE_BATS */
+
+	v = KERNELBASE;
+	p = ram_phys_base;
+	for (s = 0; s < total_lowmem; s += PAGE_SIZE) {
+		/* On the MPC8xx, we want the page shared so we
+		 * don't get ASID compares on kernel space.
+		 */
+		f = _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_SHARED;
+#if defined(CONFIG_KGDB) || defined(CONFIG_XMON)
+		/* Allows stub to set breakpoints everywhere */
+		f |= _PAGE_RW | _PAGE_DIRTY;
+#else
+		if ((char *) v < _stext || (char *) v >= etext)
+			f |= _PAGE_RW | _PAGE_DIRTY;
+#ifndef CONFIG_8xx
+		else
+			/* On the powerpc (not 8xx), no user access
+			   forces R/W kernel access */
+			f |= _PAGE_USER;
+#endif /* CONFIG_8xx */
+#endif /* CONFIG_KGDB */
+		map_page(v, p, f);
+		v += PAGE_SIZE;
+		p += PAGE_SIZE;
+	}
+}
+
+/* is x a power of 2? */
+#define is_power_of_2(x)	((x) != 0 && (((x) & ((x) - 1)) == 0))
+
+/*
+ * Set up a mapping for a block of I/O.
+ * virt, phys, size must all be page-aligned.
+ * This should only be called before ioremap is called.
+ */
+void __init io_block_mapping(unsigned long virt, unsigned long phys,
+			     unsigned int size, int flags)
+{
+	int i;
+
+	if (virt > KERNELBASE && virt < ioremap_bot)
+		ioremap_bot = ioremap_base = virt;
+
+#ifdef HAVE_BATS
+	/*
+	 * Use a BAT for this if possible...
+	 */
+	if (io_bat_index < 2 && is_power_of_2(size)
+	    && (virt & (size - 1)) == 0 && (phys & (size - 1)) == 0) {
+		setbat(io_bat_index, virt, phys, size, flags);
+		++io_bat_index;
+		return;
+	}
+#endif /* HAVE_BATS */
+
+	/* No BATs available, put it in the page tables. */
+	for (i = 0; i < size; i += PAGE_SIZE)
+		map_page(virt + i, phys + i, flags);
+}
+
+/* Scan the real Linux page tables and return a PTE pointer for
+ * a virtual address in a context.
+ * Returns true (1) if PTE was found, zero otherwise.  The pointer to
+ * the PTE pointer is unmodified if PTE is not found.
+ */
+int
+get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep)
+{
+        pgd_t	*pgd;
+        pmd_t	*pmd;
+        pte_t	*pte;
+        int     retval = 0;
+
+        pgd = pgd_offset(mm, addr & PAGE_MASK);
+        if (pgd) {
+                pmd = pmd_offset(pgd, addr & PAGE_MASK);
+                if (pmd_present(*pmd)) {
+                        pte = pte_offset(pmd, addr & PAGE_MASK);
+                        if (pte) {
+				retval = 1;
+				*ptep = pte;
+                        }
+                }
+        }
+        return(retval);
+}
+
+/* Find physical address for this virtual address.  Normally used by
+ * I/O functions, but anyone can call it.
+ */
+unsigned long iopa(unsigned long addr)
+{
+	unsigned long pa;
+
+	/* I don't know why this won't work on PMacs or CHRP.  It
+	 * appears there is some bug, or there is some implicit
+	 * mapping done not properly represented by BATs or in page
+	 * tables.......I am actively working on resolving this, but
+	 * can't hold up other stuff.  -- Dan
+	 */
+	pte_t *pte;
+	struct mm_struct *mm;
+
+	/* Check the BATs */
+	pa = v_mapped_by_bats(addr);
+	if (pa)
+		return pa;
+
+	/* Allow mapping of user addresses (within the thread)
+	 * for DMA if necessary.
+	 */
+	if (addr < TASK_SIZE)
+		mm = current->mm;
+	else
+		mm = &init_mm;
+	
+	pa = 0;
+	if (get_pteptr(mm, addr, &pte))
+		pa = (pte_val(*pte) & PAGE_MASK) | (addr & ~PAGE_MASK);
+
+	return(pa);
+}
+
+/* This is will find the virtual address for a physical one....
+ * Swiped from APUS, could be dangerous :-).
+ * This is only a placeholder until I really find a way to make this
+ * work.  -- Dan
+ */
+unsigned long
+mm_ptov (unsigned long paddr)
+{
+	unsigned long ret;
+#if 0
+	if (paddr < 16*1024*1024)
+		ret = ZTWO_VADDR(paddr);
+	else {
+		int i;
+
+		for (i = 0; i < kmap_chunk_count;){
+			unsigned long phys = kmap_chunks[i++];
+			unsigned long size = kmap_chunks[i++];
+			unsigned long virt = kmap_chunks[i++];
+			if (paddr >= phys
+			    && paddr < (phys + size)){
+				ret = virt + paddr - phys;
+				goto exit;
+			}
+		}
+		
+		ret = (unsigned long) __va(paddr);
+	}
+exit:
+#ifdef DEBUGPV
+	printk ("PTOV(%lx)=%lx\n", paddr, ret);
+#endif
+#else
+	ret = (unsigned long)paddr + KERNELBASE;
+#endif
+	return ret;
+}
+
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/mm/ppc_mmu.c linux/arch/ppc/mm/ppc_mmu.c
--- v2.4.9/linux/arch/ppc/mm/ppc_mmu.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/mm/ppc_mmu.c	Tue Aug 28 06:58:33 2001
@@ -0,0 +1,313 @@
+/*
+ * BK Id: %F% %I% %G% %U% %#%
+ */
+/*
+ * This file contains the routines for handling the MMU on those
+ * PowerPC implementations where the MMU substantially follows the
+ * architecture specification.  This includes the 6xx, 7xx, 7xxx,
+ * 8260, and POWER3 implementations but excludes the 8xx and 4xx.
+ * Although the iSeries hardware does comply with the architecture
+ * specification, the need to work through the hypervisor makes
+ * things sufficiently different that it is handled elsewhere.
+ *  -- paulus
+ * 
+ *  Derived from arch/ppc/mm/init.c:
+ *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ *  Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
+ *  and Cort Dougan (PReP) (cort@cs.nmt.edu)
+ *    Copyright (C) 1996 Paul Mackerras
+ *  Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ *
+ *  Derived from "arch/i386/mm/init.c"
+ *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
+ *
+ *  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/config.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/prom.h>
+#include <asm/mmu.h>
+#include <asm/machdep.h>
+
+#include "mmu_decl.h"
+#include "mem_pieces.h"
+
+PTE *Hash, *Hash_end;
+unsigned long Hash_size, Hash_mask;
+unsigned long _SDR1;
+
+union ubat {			/* BAT register values to be loaded */
+	BAT	bat;
+#ifdef CONFIG_PPC64BRIDGE
+	u64	word[2];
+#else
+	u32	word[2];
+#endif	
+} BATS[4][2];			/* 4 pairs of IBAT, DBAT */
+
+struct batrange {		/* stores address ranges mapped by BATs */
+	unsigned long start;
+	unsigned long limit;
+	unsigned long phys;
+} bat_addrs[4];
+
+/*
+ * Return PA for this VA if it is mapped by a BAT, or 0
+ */
+unsigned long v_mapped_by_bats(unsigned long va)
+{
+	int b;
+	for (b = 0; b < 4; ++b)
+		if (va >= bat_addrs[b].start && va < bat_addrs[b].limit)
+			return bat_addrs[b].phys + (va - bat_addrs[b].start);
+	return 0;
+}
+
+/*
+ * Return VA for a given PA or 0 if not mapped
+ */
+unsigned long p_mapped_by_bats(unsigned long pa)
+{
+	int b;
+	for (b = 0; b < 4; ++b)
+		if (pa >= bat_addrs[b].phys
+	    	    && pa < (bat_addrs[b].limit-bat_addrs[b].start)
+		              +bat_addrs[b].phys)
+			return bat_addrs[b].start+(pa-bat_addrs[b].phys);
+	return 0;
+}
+
+void __init bat_mapin_ram(void)
+{
+	unsigned long tot, bl, done;
+	unsigned long max_size = (256<<20);
+	unsigned long align;
+
+	/* Set up BAT2 and if necessary BAT3 to cover RAM. */
+
+	/* Make sure we don't map a block larger than the
+	   smallest alignment of the physical address. */
+	/* alignment of ram_phys_base */
+	align = ~(ram_phys_base-1) & ram_phys_base;
+	/* set BAT block size to MIN(max_size, align) */
+	if (align && align < max_size)
+		max_size = align;
+
+	tot = total_lowmem;
+	for (bl = 128<<10; bl < max_size; bl <<= 1) {
+		if (bl * 2 > tot)
+			break;
+	}
+
+	setbat(2, KERNELBASE, ram_phys_base, bl, _PAGE_KERNEL);
+	done = (unsigned long)bat_addrs[2].limit - KERNELBASE + 1;
+	if ((done < tot) && !bat_addrs[3].limit) {
+		/* use BAT3 to cover a bit more */
+		tot -= done;
+		for (bl = 128<<10; bl < max_size; bl <<= 1)
+			if (bl * 2 > tot)
+				break;
+		setbat(3, KERNELBASE+done, ram_phys_base+done, bl, 
+		       _PAGE_KERNEL);
+	}
+}
+
+/*
+ * Set up one of the I/D BAT (block address translation) register pairs.
+ * The parameters are not checked; in particular size must be a power
+ * of 2 between 128k and 256M.
+ */
+void __init setbat(int index, unsigned long virt, unsigned long phys,
+		   unsigned int size, int flags)
+{
+	unsigned int bl;
+	int wimgxpp;
+	union ubat *bat = BATS[index];
+
+#ifdef CONFIG_SMP
+	if ((flags & _PAGE_NO_CACHE) == 0)
+		flags |= _PAGE_COHERENT;
+#endif
+	bl = (size >> 17) - 1;
+	if (PVR_VER(mfspr(PVR)) != 1) {
+		/* 603, 604, etc. */
+		/* Do DBAT first */
+		wimgxpp = flags & (_PAGE_WRITETHRU | _PAGE_NO_CACHE
+				   | _PAGE_COHERENT | _PAGE_GUARDED);
+		wimgxpp |= (flags & _PAGE_RW)? BPP_RW: BPP_RX;
+		bat[1].word[0] = virt | (bl << 2) | 2; /* Vs=1, Vp=0 */
+		bat[1].word[1] = phys | wimgxpp;
+#ifndef CONFIG_KGDB /* want user access for breakpoints */
+		if (flags & _PAGE_USER)
+#endif
+			bat[1].bat.batu.vp = 1;
+		if (flags & _PAGE_GUARDED) {
+			/* G bit must be zero in IBATs */
+			bat[0].word[0] = bat[0].word[1] = 0;
+		} else {
+			/* make IBAT same as DBAT */
+			bat[0] = bat[1];
+		}
+	} else {
+		/* 601 cpu */
+		if (bl > BL_8M)
+			bl = BL_8M;
+		wimgxpp = flags & (_PAGE_WRITETHRU | _PAGE_NO_CACHE
+				   | _PAGE_COHERENT);
+		wimgxpp |= (flags & _PAGE_RW)?
+			((flags & _PAGE_USER)? PP_RWRW: PP_RWXX): PP_RXRX;
+		bat->word[0] = virt | wimgxpp | 4;	/* Ks=0, Ku=1 */
+		bat->word[1] = phys | bl | 0x40;	/* V=1 */
+	}
+
+	bat_addrs[index].start = virt;
+	bat_addrs[index].limit = virt + ((bl + 1) << 17) - 1;
+	bat_addrs[index].phys = phys;
+}
+
+/*
+ * Initialize the hash table and patch the instructions in hashtable.S.
+ */
+void __init MMU_init_hw(void)
+{
+	int Hash_bits, mb, mb2;
+	unsigned int hmask;
+
+	extern unsigned int hash_page_patch_A[];
+	extern unsigned int hash_page_patch_B[], hash_page_patch_C[];
+	extern unsigned int hash_page[];
+	extern unsigned int flush_hash_patch_A[], flush_hash_patch_B[];
+
+#ifdef CONFIG_PPC64BRIDGE
+	/* The hash table has already been allocated and initialized
+	   in prom.c */
+	Hash_mask = (Hash_size >> 7) - 1;
+	hmask = Hash_mask >> 9;
+	Hash_bits = __ilog2(Hash_size) - 7;
+	mb = 25 - Hash_bits;
+	if (Hash_bits > 16)
+		Hash_bits = 16;
+	mb2 = 25 - Hash_bits;
+
+	/* Remove the hash table from the available memory */
+	if (Hash)
+		reserve_phys_mem(__pa(Hash), Hash_size);
+
+#else /* CONFIG_PPC64BRIDGE */
+	unsigned int h;
+
+	if ((cur_cpu_spec[0]->cpu_features & CPU_FTR_HPTE_TABLE) == 0)
+		return;
+	if ( ppc_md.progress ) ppc_md.progress("hash:enter", 0x105);
+	/*
+	 * Allow 64k of hash table for every 16MB of memory,
+	 * up to a maximum of 2MB.
+	 */
+	for (h = 64<<10; h < total_memory / 256 && h < (2<<20); h *= 2)
+		;
+	Hash_size = h;
+	Hash_mask = (h >> 6) - 1;
+	hmask = Hash_mask >> 10;
+	Hash_bits = __ilog2(h) - 6;
+	mb = 26 - Hash_bits;
+	if (Hash_bits > 16)
+		Hash_bits = 16;
+	mb2 = 26 - Hash_bits;
+
+	if ( ppc_md.progress ) ppc_md.progress("hash:find piece", 0x322);
+	/* Find some memory for the hash table. */
+	if ( Hash_size ) {
+		Hash = mem_pieces_find(Hash_size, Hash_size);
+		cacheable_memzero(Hash, Hash_size);
+		_SDR1 = __pa(Hash) | (Hash_mask >> 10);
+	} else
+		Hash = 0;
+#endif /* CONFIG_PPC64BRIDGE */
+
+	printk("Total memory = %ldMB; using %ldkB for hash table (at %p)\n",
+	       total_memory >> 20, Hash_size >> 10, Hash);
+	if (Hash_size) {
+		if ( ppc_md.progress ) ppc_md.progress("hash:patch", 0x345);
+		Hash_end = (PTE *) ((unsigned long)Hash + Hash_size);
+
+		/*
+		 * Patch up the instructions in hashtable.S:create_hpte
+		 */
+		hash_page_patch_A[0] = (hash_page_patch_A[0] & ~0xffff)
+			| ((unsigned int)(Hash) >> 16);
+		hash_page_patch_A[1] = (hash_page_patch_A[1] & ~0x7c0)
+			| (mb << 6);
+		hash_page_patch_A[2] = (hash_page_patch_A[2] & ~0x7c0)
+			| (mb2 << 6);
+		hash_page_patch_B[0] = (hash_page_patch_B[0] & ~0xffff)
+			| hmask;
+		hash_page_patch_C[0] = (hash_page_patch_C[0] & ~0xffff)
+			| hmask;
+		/*
+		 * Ensure that the locations we've patched have been written
+		 * out from the data cache and invalidated in the instruction
+		 * cache, on those machines with split caches.
+		 */
+		flush_icache_range((unsigned long) &hash_page_patch_A[0],
+				   (unsigned long) &hash_page_patch_C[1]);
+		/*
+		 * Patch up the instructions in hashtable.S:flush_hash_page
+		 */
+		flush_hash_patch_A[0] = (flush_hash_patch_A[0] & ~0xffff)
+			| ((unsigned int)(Hash) >> 16);
+		flush_hash_patch_A[1] = (flush_hash_patch_A[1] & ~0x7c0)
+			| (mb << 6);
+		flush_hash_patch_A[2] = (flush_hash_patch_A[2] & ~0x7c0)
+			| (mb2 << 6);
+		flush_hash_patch_B[0] = (flush_hash_patch_B[0] & ~0xffff)
+			| hmask;
+		flush_icache_range((unsigned long) &flush_hash_patch_A[0],
+				   (unsigned long) &flush_hash_patch_B[1]);
+	}
+	else {
+		Hash_end = 0;
+		/*
+		 * Put a blr (procedure return) instruction at the
+		 * start of hash_page, since we can still get DSI
+		 * exceptions on a 603.
+		 */
+		hash_page[0] = 0x4e800020;
+		flush_icache_range((unsigned long) &hash_page[0],
+				   (unsigned long) &hash_page[1]);
+	}
+
+	if ( ppc_md.progress ) ppc_md.progress("hash:done", 0x205);
+}
+
+/*
+ * This is called at the end of handling a user page fault, when the
+ * fault has been handled by updating a PTE in the linux page tables.
+ * We use it to preload an HPTE into the hash table corresponding to
+ * the updated linux PTE.
+ */
+void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
+		      pte_t pte)
+{
+	struct mm_struct *mm;
+	pmd_t *pmd;
+	pte_t *ptep;
+	static int nopreload;
+
+	if (Hash == 0 || nopreload)
+		return;
+	mm = (address < TASK_SIZE)? vma->vm_mm: &init_mm;
+	pmd = pmd_offset(pgd_offset(mm, address), address);
+	if (!pmd_none(*pmd)) {
+		ptep = pte_offset(pmd, address);
+		add_hash_page(mm->context, address, ptep);
+	}
+}
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/mm/tlb.c linux/arch/ppc/mm/tlb.c
--- v2.4.9/linux/arch/ppc/mm/tlb.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/mm/tlb.c	Tue Aug 28 06:58:33 2001
@@ -0,0 +1,162 @@
+/*
+ * BK Id: %F% %I% %G% %U% %#%
+ */
+/*
+ * This file contains the routines for TLB flushing.
+ * On machines where the MMU uses a hash table to store virtual to
+ * physical translations, these routines flush entries from the the
+ * hash table also.
+ *  -- paulus
+ * 
+ *  Derived from arch/ppc/mm/init.c:
+ *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ *  Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
+ *  and Cort Dougan (PReP) (cort@cs.nmt.edu)
+ *    Copyright (C) 1996 Paul Mackerras
+ *  Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ *
+ *  Derived from "arch/i386/mm/init.c"
+ *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
+ *
+ *  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/config.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include "mmu_decl.h"
+
+/*
+ * TLB flushing:
+ *
+ *  - flush_tlb_all() flushes all processes TLBs
+ *  - flush_tlb_mm(mm) flushes the specified mm context TLB's
+ *  - flush_tlb_page(vma, vmaddr) flushes one page
+ *  - flush_tlb_range(mm, start, end) flushes a range of pages
+ *
+ * since the hardware hash table functions as an extension of the
+ * tlb as far as the linux tables are concerned, flush it too.
+ *    -- Cort
+ */
+
+/*
+ * Flush all tlb/hash table entries (except perhaps for those
+ * mapping RAM starting at PAGE_OFFSET, since they never change).
+ */
+void
+local_flush_tlb_all(void)
+{
+	/* aargh!!! */
+	/*
+	 * Just flush the kernel part of the address space, that's
+	 * all that the current callers of this require.
+	 * Eventually I hope to persuade the powers that be that
+	 * we can and should dispense with flush_tlb_all().
+	 *  -- paulus.
+	 */
+	local_flush_tlb_range(&init_mm, TASK_SIZE, ~0UL);
+
+#ifdef CONFIG_SMP
+	smp_send_tlb_invalidate(0);
+#endif /* CONFIG_SMP */
+}
+
+/*
+ * Flush all the (user) entries for the address space described
+ * by mm.  We can't rely on mm->mmap describing all the entries
+ * that might be in the hash table.
+ */
+void
+local_flush_tlb_mm(struct mm_struct *mm)
+{
+	if (Hash == 0) {
+		_tlbia();
+		return;
+	}
+
+	if (mm->map_count) {
+		struct vm_area_struct *mp;
+		for (mp = mm->mmap; mp != NULL; mp = mp->vm_next)
+			local_flush_tlb_range(mm, mp->vm_start, mp->vm_end);
+	} else
+		local_flush_tlb_range(mm, 0, TASK_SIZE);
+
+#ifdef CONFIG_SMP
+	smp_send_tlb_invalidate(0);
+#endif	
+}
+
+void
+local_flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
+{
+	struct mm_struct *mm;
+	pmd_t *pmd;
+	pte_t *pte;
+
+	if (Hash == 0) {
+		_tlbie(vmaddr);
+		return;
+	}
+	mm = (vmaddr < TASK_SIZE)? vma->vm_mm: &init_mm;
+	pmd = pmd_offset(pgd_offset(mm, vmaddr), vmaddr);
+	if (!pmd_none(*pmd)) {
+		pte = pte_offset(pmd, vmaddr);
+		if (pte_val(*pte) & _PAGE_HASHPTE)
+			flush_hash_page(mm->context, vmaddr, pte);
+	}
+#ifdef CONFIG_SMP
+	smp_send_tlb_invalidate(0);
+#endif	
+}
+
+
+/*
+ * For each address in the range, find the pte for the address
+ * and check _PAGE_HASHPTE bit; if it is set, find and destroy
+ * the corresponding HPTE.
+ */
+void
+local_flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long end)
+{
+	pmd_t *pmd;
+	pte_t *pte;
+	unsigned long pmd_end;
+	unsigned int ctx = mm->context;
+
+	if (Hash == 0) {
+		_tlbia();
+		return;
+	}
+	start &= PAGE_MASK;
+	if (start >= end)
+		return;
+	pmd = pmd_offset(pgd_offset(mm, start), start);
+	do {
+		pmd_end = (start + PGDIR_SIZE) & PGDIR_MASK;
+		if (!pmd_none(*pmd)) {
+			if (!pmd_end || pmd_end > end)
+				pmd_end = end;
+			pte = pte_offset(pmd, start);
+			do {
+				if ((pte_val(*pte) & _PAGE_HASHPTE) != 0)
+					flush_hash_page(ctx, start, pte);
+				start += PAGE_SIZE;
+				++pte;
+			} while (start && start < pmd_end);
+		} else {
+			start = pmd_end;
+		}
+		++pmd;
+	} while (start && start < end);
+
+#ifdef CONFIG_SMP
+	smp_send_tlb_invalidate(0);
+#endif	
+}
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/vmlinux.lds linux/arch/ppc/vmlinux.lds
--- v2.4.9/linux/arch/ppc/vmlinux.lds	Mon Aug 27 12:41:39 2001
+++ linux/arch/ppc/vmlinux.lds	Tue Aug 28 06:58:33 2001
@@ -70,6 +70,10 @@
   __ksymtab : { *(__ksymtab) }
   __stop___ksymtab = .;
 
+  __start___ftr_fixup = .;
+  __ftr_fixup : { *(__ftr_fixup) }
+  __stop___ftr_fixup = .;
+
   . = ALIGN(32);
   .data.cacheline_aligned : { *(.data.cacheline_aligned) }
 
diff -u --recursive --new-file v2.4.9/linux/arch/ppc/xmon/start.c linux/arch/ppc/xmon/start.c
--- v2.4.9/linux/arch/ppc/xmon/start.c	Mon May 21 17:04:47 2001
+++ linux/arch/ppc/xmon/start.c	Tue Aug 28 06:58:33 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.start.c 1.12 05/21/01 21:39:13 paulus
+ * BK Id: SCCS/s.start.c 1.16 08/20/01 22:17:58 paulus
  */
 /*
  * Copyright (C) 1996 Paul Mackerras.
@@ -18,6 +18,7 @@
 #include <asm/feature.h>
 #include <asm/processor.h>
 #include <asm/delay.h>
+#include <asm/btext.h>
 #ifdef CONFIG_SMP
 #include <asm/bitops.h>
 #endif
@@ -25,8 +26,6 @@
 static volatile unsigned char *sccc, *sccd;
 unsigned long TXRDY, RXRDY;
 extern void xmon_printf(const char *fmt, ...);
-extern void prom_drawchar(char);
-extern void prom_drawstring(const char *str);
 static int xmon_expect(const char *str, unsigned int timeout);
 
 static int console;
@@ -56,6 +55,7 @@
 void
 xmon_map_scc(void)
 {
+#ifdef CONFIG_ALL_PPC
 	volatile unsigned char *base;
 
 	use_screen = 0;
@@ -85,14 +85,34 @@
 				use_screen = 1;
 #endif
 		}
-		prom_drawstring("xmon uses ");
+		if (!use_screen && (np = find_devices("escc")) != NULL) {
+			/*
+			 * look for the device node for the serial port
+			 * we're using and see if it says it has a modem
+			 */
+			char *name = xmon_use_sccb? "ch-b": "ch-a";
+			char *slots;
+			int l;
+
+			np = np->child;
+			while (np != NULL && strcmp(np->name, name) != 0)
+				np = np->sibling;
+			if (np != NULL) {
+				/* XXX should parse this properly */
+				slots = get_property(np, "slot-names", &l);
+				if (slots != NULL && l >= 10
+				    && strcmp(slots+4, "Modem") == 0)
+					via_modem = 1;
+			}
+		}
+		btext_drawstring("xmon uses ");
 		if (use_screen)
-			prom_drawstring("screen and keyboard\n");
+			btext_drawstring("screen and keyboard\n");
 		else {
 			if (via_modem)
-				prom_drawstring("modem on ");
-			prom_drawstring(xmon_use_sccb? "printer": "modem");
-			prom_drawstring(" port\n");
+				btext_drawstring("modem on ");
+			btext_drawstring(xmon_use_sccb? "printer": "modem");
+			btext_drawstring(" port\n");
 		}
 
 #endif /* CONFIG_BOOTX_TEXT */
@@ -114,15 +134,6 @@
 		sccc = base + (addr & ~PAGE_MASK);
 		sccd = sccc + 0x10;
 	}
-	else if ( _machine & _MACH_gemini )
-	{
-		/* should already be mapped by the kernel boot */
-		sccc = (volatile unsigned char *) 0xffeffb0d;
-		sccd = (volatile unsigned char *) 0xffeffb08;
-		TXRDY = 0x20;
-		RXRDY = 1;
-		console = 1;
-	}
 	else
 	{
 		/* should already be mapped by the kernel boot */
@@ -135,6 +146,14 @@
 		TXRDY = 0x20;
 		RXRDY = 1;
 	}
+#elif defined(CONFIG_GEMINI)
+	/* should already be mapped by the kernel boot */
+	sccc = (volatile unsigned char *) 0xffeffb0d;
+	sccd = (volatile unsigned char *) 0xffeffb08;
+	TXRDY = 0x20;
+	RXRDY = 1;
+	console = 1;
+#endif /* platform */
 }
 
 static int scc_initialized = 0;
@@ -175,7 +194,7 @@
 	if (use_screen) {
 		/* write it on the screen */
 		for (i = 0; i < nb; ++i)
-			prom_drawchar(*p++);
+			btext_drawchar(*p++);
 		goto out;
 	}
 #endif
@@ -216,7 +235,7 @@
 
 static unsigned char xmon_keytab[128] =
 	"asdfhgzxcv\000bqwer"				/* 0x00 - 0x0f */
-	"yt123465=97-80o]"				/* 0x10 - 0x1f */
+	"yt123465=97-80]o"				/* 0x10 - 0x1f */
 	"u[ip\rlj'k;\\,/nm."				/* 0x20 - 0x2f */
 	"\t `\177\0\033\0\0\0\0\0\0\0\0\0\0"		/* 0x30 - 0x3f */
 	"\0.\0*\0+\0\0\0\0\0/\r\0-\0"			/* 0x40 - 0x4f */
@@ -224,7 +243,7 @@
 
 static unsigned char xmon_shift_keytab[128] =
 	"ASDFHGZXCV\000BQWER"				/* 0x00 - 0x0f */
-	"YT!@#$^%+(&=*)}O"				/* 0x10 - 0x1f */
+	"YT!@#$^%+(&_*)}O"				/* 0x10 - 0x1f */
 	"U{IP\rLJ\"K:|<?NM>"				/* 0x20 - 0x2f */
 	"\t ~\177\0\033\0\0\0\0\0\0\0\0\0\0"		/* 0x30 - 0x3f */
 	"\0.\0*\0+\0\0\0\0\0/\r\0-\0"			/* 0x40 - 0x4f */
@@ -243,15 +262,15 @@
 		do {
 			if (--t < 0) {
 				on = 1 - on;
-				prom_drawchar(on? 0xdb: 0x20);
-				prom_drawchar('\b');
+				btext_drawchar(on? 0xdb: 0x20);
+				btext_drawchar('\b');
 				t = 200000;
 			}
 			do_poll_adb();
 		} while (xmon_adb_keycode == -1);
 		k = xmon_adb_keycode;
 		if (on)
-			prom_drawstring(" \b");
+			btext_drawstring(" \b");
 
 		/* test for shift keys */
 		if ((k & 0x7f) == 0x38 || (k & 0x7f) == 0x7b) {
@@ -544,7 +563,9 @@
 xmon_enter(void)
 {
 #ifdef CONFIG_ADB_PMU
-	pmu_suspend();
+	if (_machine == _MACH_Pmac) {
+		pmu_suspend();
+	}
 #endif
 }
 
@@ -552,6 +573,8 @@
 xmon_leave(void)
 {
 #ifdef CONFIG_ADB_PMU
-	pmu_resume();
+	if (_machine == _MACH_Pmac) {
+		pmu_resume();
+	}
 #endif
 }
diff -u --recursive --new-file v2.4.9/linux/arch/sh/Makefile linux/arch/sh/Makefile
--- v2.4.9/linux/arch/sh/Makefile	Fri Dec 29 14:07:20 2000
+++ linux/arch/sh/Makefile	Sat Sep  8 12:29:09 2001
@@ -75,6 +75,11 @@
 
 MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
 
+ifneq ($(CONFIG_SH_GENERIC)$(CONFIG_SH_STB1_HARP)$(CONFIG_SH_STB1_OVERDRIVE),)
+SUBDIRS += arch/sh/stboards
+CORE_FILES += arch/sh/stboards/stboards.o
+endif
+
 vmlinux: arch/sh/vmlinux.lds
 
 arch/sh/vmlinux.lds: arch/sh/vmlinux.lds.S FORCE
@@ -93,6 +98,7 @@
 archclean:
 	@$(MAKEBOOT) clean
 	$(MAKE) -C arch/$(ARCH)/kernel clean
+	$(MAKE) -C arch/$(ARCH)/stboards clean
 #	$(MAKE) -C arch/$(ARCH)/tools clean
 
 archmrproper:
diff -u --recursive --new-file v2.4.9/linux/arch/sh/config.in linux/arch/sh/config.in
--- v2.4.9/linux/arch/sh/config.in	Tue Jul  3 17:08:18 2001
+++ linux/arch/sh/config.in	Sat Sep  8 12:29:09 2001
@@ -42,6 +42,7 @@
 	 CAT68701		CONFIG_SH_CAT68701		\
 	 BigSur			CONFIG_SH_BIGSUR		\
 	 SH2000			CONFIG_SH_SH2000		\
+	 ADX			CONFIG_SH_ADX			\
 	 BareCPU		CONFIG_SH_UNKNOWN" Generic
 
 # The SH7750 RTC module is disabled in the Dreamcast
@@ -88,24 +89,40 @@
    define_bool CONFIG_CPU_SH4 y
 fi
 bool 'Little Endian' CONFIG_CPU_LITTLE_ENDIAN
+# Platform-specific memory start and size definitions
 if [ "$CONFIG_SH_SOLUTION_ENGINE" = "y" -o "$CONFIG_SH_HP600" = "y" -o \
      "$CONFIG_SH_BIGSUR" = "y" -o "$CONFIG_SH_7751_SOLUTION_ENGINE" = "y" -o \
      "$CONFIG_SH_DREAMCAST" = "y" -o "$CONFIG_SH_SH2000" = "y" ]; then
-  define_hex CONFIG_MEMORY_START 0c000000
-else
-  if [ "$CONFIG_CPU_SUBTYPE_ST40STB1" = "y" ]; then
-    bool 'Memory on LMI' CONFIG_ST40_LMI_MEMORY
-    if [ "$CONFIG_ST40_LMI_MEMORY" = "y" ] ; then
+   define_hex CONFIG_MEMORY_START 0c000000
+   define_hex CONFIG_MEMORY_SIZE 00400000
+   define_bool CONFIG_MEMORY_SET y
+fi
+if [ "$CONFIG_CPU_SUBTYPE_ST40STB1" = "y" ]; then
+   bool 'Memory on LMI' CONFIG_ST40_LMI_MEMORY
+   if [ "$CONFIG_ST40_LMI_MEMORY" = "y" ] ; then
       define_hex CONFIG_MEMORY_START 08000000
-    else
-      hex 'EMI physical memory start address' CONFIG_MEMORY_START 08000000
-    fi
-  else
-    hex 'Physical memory start address' CONFIG_MEMORY_START 08000000
-  fi
+      define_hex CONFIG_MEMORY_SIZE 00400000
+      define_bool CONFIG_MEMORY_SET y
+   fi
+fi
+if [ "$CONFIG_SH_ADX" = "y" ]; then
+   define_hex CONFIG_MEMORY_START 08000000
+   define_hex CONFIG_MEMORY_SIZE 00400000
+   define_bool CONFIG_MEMORY_SET y
+fi
+# If none of the above have set memory start/size, ask the user.
+if [ "$CONFIG_MEMORY_SET" != "y" ]; then
+   hex 'Physical memory start address' CONFIG_MEMORY_START 08000000
+   hex 'Physical memory size' CONFIG_MEMORY_SIZE 00400000
 fi
 endmenu
 
+if [ "$CONFIG_SH_HP690" = "y" ]; then
+  define_bool CONFIG_DISCONTIGMEM y
+else
+  define_bool CONFIG_DISCONTIGMEM n
+fi
+
 mainmenu_option next_comment
 comment 'General setup'
 
@@ -120,10 +137,23 @@
 bool 'Networking support' CONFIG_NET
 
 if [ "$CONFIG_SH_GENERIC" = "y" -o "$CONFIG_SH_SOLUTION_ENGINE" = "y" -o \
-     "$CONFIG_SH_UNKNOWN" = "y" -o "$CONFIG_SH_CAT68701" = "y" ]; then
+     "$CONFIG_SH_UNKNOWN" = "y" -o "$CONFIG_SH_CAT68701" = "y" -o \
+     "$CONFIG_SH_ADX" = "y" ]; then
   bool 'Compact Flash Enabler support' CONFIG_CF_ENABLER
 fi
 
+if [ "$CONFIG_CF_ENABLER" = "y" ]; then
+   choice 'Compact Flash Connection Area' \
+	"Area5 CONFIG_CF_AREA5 \
+	 Area6 CONFIG_CF_AREA6" Area6
+   if [ "$CONFIG_CF_AREA5" = "y" ]; then
+      define_hex CONFIG_CF_BASE_ADDR b4000000
+   fi
+   if [ "$CONFIG_CF_AREA6" = "y" ]; then
+      define_hex CONFIG_CF_BASE_ADDR b8000000
+   fi
+fi
+
 bool 'Hitachi HD64461 companion chip support' CONFIG_HD64461
 if [ "$CONFIG_HD64461" = "y" ]; then
    int 'HD64461 IRQ' CONFIG_HD64461_IRQ 36
@@ -136,6 +166,8 @@
    int 'HD64465 IRQ' CONFIG_HD64465_IRQ 5
 fi
 
+bool 'DMA controller (DMAC) support' CONFIG_SH_DMA
+
 bool 'PCI support' CONFIG_PCI
 if [ "$CONFIG_PCI" = "y" ]; then
    choice '  PCI access mode' \
@@ -148,6 +180,7 @@
    if [ "$CONFIG_PCI_GODIRECT" = "y" -o "$CONFIG_PCI_GOANY" = "y" ]; then
       define_bool CONFIG_PCI_DIRECT y
    fi
+   define_bool CONFIG_SH_PCIDMA_NONCOHERENT n
 fi
 
 source drivers/pci/Config.in
@@ -224,13 +257,22 @@
    endmenu
 fi
 
+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
+
 #
 # input before char - char/joystick depends on it. As does USB.
 #
 source drivers/input/Config.in
 
 if [ "$CONFIG_SH_DREAMCAST" = "y" ]; then
-source drivers/maple/Config.in
+   source drivers/maple/Config.in
 fi
 
 mainmenu_option next_comment
@@ -259,7 +301,7 @@
      "$CONFIG_SH_BIGSUR" = "y" -o \
      "$CONFIG_SH_7751_SOLUTION_ENGINE" = "y" -o \
      "$CONFIG_SH_SOLUTION_ENGINE" = "y" ]; then
-  bool 'Heartbeat LED' CONFIG_HEARTBEAT
+   bool 'Heartbeat LED' CONFIG_HEARTBEAT
 fi
 
 if [ "$CONFIG_SH_DREAMCAST" = "y" -a "$CONFIG_MAPLE" != "n" ]; then
@@ -322,7 +364,6 @@
 bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
 bool 'Use LinuxSH standard BIOS' CONFIG_SH_STANDARD_BIOS
 if [ "$CONFIG_SH_STANDARD_BIOS" = "y" ]; then
-   bool 'GDB Stub kernel debug' CONFIG_DEBUG_KERNEL_WITH_GDB_STUB
    bool 'Early printk support' CONFIG_SH_EARLY_PRINTK
 fi
 endmenu
diff -u --recursive --new-file v2.4.9/linux/arch/sh/kernel/Makefile linux/arch/sh/kernel/Makefile
--- v2.4.9/linux/arch/sh/kernel/Makefile	Tue Jul  3 17:08:18 2001
+++ linux/arch/sh/kernel/Makefile	Sat Sep  8 12:29:09 2001
@@ -21,13 +21,14 @@
 obj-$(CONFIG_CF_ENABLER)	+= cf-enabler.o
 obj-$(CONFIG_CPU_SH4)		+= fpu.o
 obj-$(CONFIG_SH_RTC)            += rtc.o
+obj-$(CONFIG_SH_DMA)		+= dma.o
 obj-$(CONFIG_SH_STANDARD_BIOS)	+= sh_bios.o
 
 ifeq ($(CONFIG_PCI),y)
 ifeq ($(CONFIG_SH_DREAMCAST),y)
-obj-y 				+= pci-dc.o
+obj-y 				+= pci-dc.o pcibios.o
 else
-obj-y                           += pci-dma.o 
+obj-y                           += pci-dma.o pcibios.o
 obj-$(CONFIG_CPU_SUBTYPE_ST40STB1)+= pci_st40.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7751)+= pci-sh7751.o 
 obj-$(CONFIG_SH_BIGSUR)+= pci-bigsur.o
@@ -41,8 +42,10 @@
 obj-$(CONFIG_SH_SOLUTION_ENGINE)+= mach_se.o setup_se.o io_se.o led_se.o
 machine-specific-objs		+= mach_se.o setup_se.o io_se.o led_se.o
 
-obj-$(CONFIG_SH_7751_SOLUTION_ENGINE)+= mach_se.o setup_se.o io_se.o led_se.o pci-7751se.o
-machine-specific-objs           += mach_se.o setup_se.o io_se.o led_se.o pci-7751se.o
+obj-$(CONFIG_SH_7751_SOLUTION_ENGINE)+= mach_7751se.o setup_7751se.o \
+					io_7751se.o led_7751se.o
+machine-specific-objs           += mach_7751se.o 7751setup_se.o \
+				   io_7751se.o led_7751se.o pci-7751se.o
 
 obj-$(CONFIG_SH_BIGSUR)		+= mach_bigsur.o setup_bigsur.o io_bigsur.o led_bigsur.o
 machine-specific-objs		+= mach_bigsur.o setup_bigsur.o io_bigsur.o led_bigsur.o
@@ -64,11 +67,14 @@
 
 obj-$(CONFIG_CPU_SUBTYPE_ST40STB1) +=irq_intc2.o
 
+obj-$(CONFIG_SH_ADX)		+= mach_adx.o setup_adx.o io_adx.o irq_maskreg.o
+machine-specific-objs		+= mach_adx.o setup_adx.o io_adx.o irq_maskreg.o
+
 # Doesn't compile well, so don't include in machine-specific-objs
 obj-$(CONFIG_HD64465)		+= setup_hd64465.o io_hd64465.o hd64465_gpio.o
 obj-$(CONFIG_SH_DMIDA)		+= mach_dmida.o
 obj-$(CONFIG_SH_EC3104)         += setup_ec3104.o io_ec3104.o mach_ec3104.o
-obj-$(CONFIG_SH_DREAMCAST)	+= mach_dc.o setup_dc.o io_dc.o
+obj-$(CONFIG_SH_DREAMCAST)	+= mach_dc.o setup_dc.o io_dc.o rtc-aica.o
 
 ifeq ($(CONFIG_SH_GENERIC),y)
 obj-y		+= $(machine-specific-objs)
diff -u --recursive --new-file v2.4.9/linux/arch/sh/kernel/cf-enabler.c linux/arch/sh/kernel/cf-enabler.c
--- v2.4.9/linux/arch/sh/kernel/cf-enabler.c	Wed Apr 11 21:24:52 2001
+++ linux/arch/sh/kernel/cf-enabler.c	Sat Sep  8 12:29:09 2001
@@ -1,9 +1,10 @@
-/* $Id: cf-enabler.c,v 1.2 2000/06/08 05:50:10 gniibe Exp $
+/* $Id: cf-enabler.c,v 1.8 2001/07/18 12:32:21 gniibe Exp $
  *
  *  linux/drivers/block/cf-enabler.c
  *
  *  Copyright (C) 1999  Niibe Yutaka
  *  Copyright (C) 2000  Toshiharu Nozawa
+ *  Copyright (C) 2001  A&D Co., Ltd.
  *
  *  Enable the CF configuration.
  */
@@ -14,7 +15,6 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 
-#define CF_CIS_BASE	0xb8000000
 /*
  * You can connect Compact Flash directly to the bus of SuperH.
  * This is the enabler for that.
@@ -29,15 +29,61 @@
  * 0xB8001000 : Common Memory
  * 0xBA000000 : I/O
  */
+#if defined(CONFIG_IDE) && defined(__SH4__)
+/* SH4 can't access PCMCIA interface through P2 area.
+ * we must remap it with appropreate attribute bit of the page set.
+ * this part is based on Greg Banks' hd64465_ss.c implementation - Masahiro Abe */
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
+
+#if defined(CONFIG_CF_AREA6)
+#define slot_no 0
+#else
+#define slot_no 1
+#endif
+
+/* defined in mm/ioremap.c */
+extern void * p3_ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags);
+
+/* use this pointer to access to directly connected compact flash io area*/
+void *cf_io_base;
+
+static int __init allocate_cf_area(void)
+{
+	pgprot_t prot;
+	unsigned long paddrbase, psize;
+
+	/* open I/O area window */
+	paddrbase = virt_to_phys((void*)CONFIG_CF_BASE_ADDR);
+	psize = PAGE_SIZE;
+	prot = PAGE_KERNEL_PCC(slot_no, _PAGE_PCC_IO16);
+	cf_io_base = p3_ioremap(paddrbase, psize, prot.pgprot);
+	if (!cf_io_base) {
+		printk("allocate_cf_area : can't open CF I/O window!\n");
+		return -ENOMEM;
+	}
+/*	printk("p3_ioremap(paddr=0x%08lx, psize=0x%08lx, prot=0x%08lx)=0x%08lx\n",
+	    	paddrbase, psize, prot.pgprot, cf_io_base);*/
+
+	/* XXX : do we need attribute and common-memory area also? */
+
+	return 0;
+}
+#endif
 
 static int __init cf_init_default(void)
 {
-#ifdef CONFIG_IDE
-	/* Enable the card, and set the level interrupt */
-	ctrl_outw(0x0042, CF_CIS_BASE+0x0200);
+/* You must have enabled the card, and set the level interrupt
+ * before reaching this point. Possibly in boot ROM or boot loader.
+ */
+#if defined(CONFIG_IDE) && defined(__SH4__)
+	allocate_cf_area();
 #endif
+#if defined(CONFIG_SH_UNKNOWN)
+	/* This should be done in each board's init_xxx_irq. */
 	make_imask_irq(14);
 	disable_irq(14);
+#endif
 	return 0;
 }
 
diff -u --recursive --new-file v2.4.9/linux/arch/sh/kernel/dma.c linux/arch/sh/kernel/dma.c
--- v2.4.9/linux/arch/sh/kernel/dma.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/kernel/dma.c	Sat Sep  8 12:29:09 2001
@@ -0,0 +1,142 @@
+/*
+ * arch/sh/kernel/dma.c
+ *
+ * Copyright (C) 2000 Takashi YOSHII
+ *
+ * PC like DMA API for SuperH's DMAC.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+
+#include <asm/signal.h>
+#include <asm/dma.h>
+
+static struct dma_info_t *dma_info[MAX_DMA_CHANNELS];
+static struct dma_info_t *autoinit_info[SH_MAX_DMA_CHANNELS] = {0};
+static spinlock_t  dma_spin_lock;
+
+static unsigned int calc_chcr(struct dma_info_t *info)
+{
+	unsigned int chcr;
+
+	chcr = ( info->mode & DMA_MODE_WRITE )? info->mode_write : info->mode_read;
+	if( info->mode & DMA_AUTOINIT )
+		chcr |= CHCR_IE;
+	return chcr;
+}
+
+static __inline__ int ts_shift(unsigned long chcr)
+{
+	return ((int[]){3,0,1,2,5,0,0,0})[(chcr>>4)&0x000007];
+}
+
+static void dma_tei(int irq, void *dev_id, struct pt_regs *regs)
+{
+	int chan = irq - DMTE_IRQ[0];
+	struct dma_info_t *info = autoinit_info[chan];
+
+	if( info->mode & DMA_MODE_WRITE )
+		ctrl_outl(info->mem_addr, SAR[info->chan]);
+	else
+		ctrl_outl(info->mem_addr, DAR[info->chan]);
+
+	ctrl_outl(info->count>>ts_shift(calc_chcr(info)), DMATCR[info->chan]);
+	ctrl_outl(ctrl_inl(CHCR[info->chan])&~CHCR_TE, CHCR[info->chan]);
+}
+
+static struct irqaction irq_tei = { dma_tei, SA_INTERRUPT, 0, "dma_tei", NULL, NULL};
+
+void setup_dma(unsigned int dmanr, struct dma_info_t *info)
+{
+	make_ipr_irq(DMTE_IRQ[info->chan], DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
+	setup_irq(DMTE_IRQ[info->chan], &irq_tei);
+	dma_info[dmanr] = info;
+}
+
+unsigned long claim_dma_lock(void)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&dma_spin_lock, flags);
+	return flags;
+}
+
+void release_dma_lock(unsigned long flags)
+{
+	spin_unlock_irqrestore(&dma_spin_lock, flags);
+}
+
+void enable_dma(unsigned int dmanr)
+{
+	struct dma_info_t *info = dma_info[dmanr];
+	ctrl_outl(calc_chcr(info)|CHCR_DE, CHCR[info->chan]);
+}
+
+void disable_dma(unsigned int dmanr)
+{
+	struct dma_info_t *info = dma_info[dmanr];
+	ctrl_outl(calc_chcr(info)&~CHCR_DE, CHCR[info->chan]);
+}
+
+void set_dma_mode(unsigned int dmanr, char mode)
+{
+	struct dma_info_t *info = dma_info[dmanr];
+
+	info->mode = mode;
+	set_dma_addr(dmanr, info->mem_addr);
+	set_dma_count(dmanr, info->count);
+	autoinit_info[info->chan] = info;
+}
+
+void set_dma_addr(unsigned int dmanr, unsigned int a)
+{
+	struct dma_info_t *info = dma_info[dmanr];
+	unsigned long sar, dar;
+
+	info->mem_addr = a;
+	sar = (info->mode & DMA_MODE_WRITE)? info->mem_addr: info->dev_addr;
+	dar = (info->mode & DMA_MODE_WRITE)? info->dev_addr: info->mem_addr;
+	ctrl_outl(sar, SAR[info->chan]);
+	ctrl_outl(dar, DAR[info->chan]);
+}
+
+void set_dma_count(unsigned int dmanr, unsigned int count)
+{
+	struct dma_info_t *info = dma_info[dmanr];
+	info->count = count;
+	ctrl_outl(count>>ts_shift(calc_chcr(info)), DMATCR[info->chan]);
+}
+
+int get_dma_residue(unsigned int dmanr)
+{
+	struct dma_info_t *info = dma_info[dmanr];
+	return ctrl_inl(DMATCR[info->chan])<<ts_shift(calc_chcr(info));
+}
+
+#if defined(__SH4__)
+static void dma_err(int irq, void *dev_id, struct pt_regs *regs)
+{
+	printk(KERN_WARNING "DMAE: DMAOR=%lx\n",ctrl_inl(DMAOR));
+	ctrl_outl(ctrl_inl(DMAOR)&~DMAOR_NMIF, DMAOR);
+	ctrl_outl(ctrl_inl(DMAOR)&~DMAOR_AE, DMAOR);
+	ctrl_outl(ctrl_inl(DMAOR)|DMAOR_DME, DMAOR);
+}
+static struct irqaction irq_err = { dma_err, SA_INTERRUPT, 0, "dma_err", NULL, NULL};
+#endif
+
+int __init init_dma(void)
+{
+#if defined(__SH4__)
+	make_ipr_irq(DMAE_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
+	setup_irq(DMAE_IRQ, &irq_err);
+#endif
+
+	ctrl_outl(DMAOR_DME, DMAOR);
+	return 0;
+}
+
+module_init(init_dma);
+
+/**/
diff -u --recursive --new-file v2.4.9/linux/arch/sh/kernel/entry.S linux/arch/sh/kernel/entry.S
--- v2.4.9/linux/arch/sh/kernel/entry.S	Tue Jul  3 17:08:18 2001
+++ linux/arch/sh/kernel/entry.S	Sat Sep  8 12:29:09 2001
@@ -1,4 +1,4 @@
-/* $Id: entry.S,v 1.71 2000/03/22 13:29:33 gniibe Exp $
+/* $Id: entry.S,v 1.71 2001/07/27 11:47:50 gniibe Exp $
  *
  *  linux/arch/sh/entry.S
  *
@@ -220,7 +220,7 @@
 1:	.long	MMU_TEA
 2:	.long   SYMBOL_NAME(do_address_error)
 
-#if defined(CONFIG_DEBUG_KERNEL_WITH_GDB_STUB) || defined(CONFIG_SH_STANDARD_BIOS)
+#if defined(CONFIG_SH_STANDARD_BIOS)
 	.align	2
 	/* Unwind the stack and jmp to the debug entry */
 debug_kernel:
@@ -263,7 +263,7 @@
 
 	.align	2
 debug_trap:	
-#if defined(CONFIG_DEBUG_KERNEL_WITH_GDB_STUB) || defined(CONFIG_SH_STANDARD_BIOS)
+#if defined(CONFIG_SH_STANDARD_BIOS)
 	mov	#OFF_SR, r0
 	mov.l	@(r0,r15), r0		! get status register
 	shll	r0
@@ -293,8 +293,23 @@
 !
 !
 ENTRY(ret_from_fork)
-	bra	SYMBOL_NAME(ret_from_syscall)
-	 add	#4, r15	! pop down bogus r0 (see switch_to MACRO)
+	mov.l	@r15+,r0
+	! Call schedule_tail
+	mov.l	1f, r1
+	jsr @r1
+	 mov	r0, r4
+	! If we're being traced, return via syscall_ret_trace, otherwise
+	! return directly to ret_from_syscall
+	stc	k_current, r0
+	mov.l	@(tsk_ptrace,r0), r0	! Is current PTRACE_SYSCALL'd?
+	mov	#PT_TRACESYS, r1
+	tst	r1, r0
+	bt	ret_from_syscall
+	bra	syscall_ret_trace
+	 nop	 
+
+	.align	2
+1:	.long	SYMBOL_NAME(schedule_tail)
 
 /*
  * Old syscall interface:
diff -u --recursive --new-file v2.4.9/linux/arch/sh/kernel/io_7751se.c linux/arch/sh/kernel/io_7751se.c
--- v2.4.9/linux/arch/sh/kernel/io_7751se.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/kernel/io_7751se.c	Sat Sep  8 12:29:09 2001
@@ -0,0 +1,304 @@
+/* 
+ * linux/arch/sh/kernel/io_7751se.c
+ *
+ * Copyright (C) 2001  Ian da Silva, Jeremy Siegel
+ * Based largely on io_se.c.
+ *
+ * I/O routine for Hitachi 7751 SolutionEngine.
+ *
+ * Initial version only to support LAN access; some
+ * placeholder code from io_se.c left in with the
+ * expectation of later SuperIO and PCMCIA access.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <asm/io.h>
+#include <asm/hitachi_7751se.h>
+#include <asm/addrspace.h>
+
+#include <asm/pci.h>
+#include <asm/pci-sh7751.h>
+
+#if 0
+/******************************************************************
+ * Variables from io_se.c, related to PCMCIA (not PCI); we're not
+ * compiling them in, and have removed references from functions
+ * which follow.  [Many checked for IO ports in the range bounded
+ * by sh_pcic_io_start/stop, and used sh_pcic_io_wbase as offset.
+ * As start/stop are uninitialized, only port 0x0 would match?]
+ * When used, remember to adjust names to avoid clash with io_se?
+ *****************************************************************/
+/* SH pcmcia io window base, start and end.  */
+int sh_pcic_io_wbase = 0xb8400000;
+int sh_pcic_io_start;
+int sh_pcic_io_stop;
+int sh_pcic_io_type;
+int sh_pcic_io_dummy;
+/*************************************************************/
+#endif
+
+/*
+ * The 7751 Solution Engine uses the built-in PCI controller (PCIC)
+ * of the 7751 processor, and has a SuperIO accessible via the PCI.
+ * The board also includes a PCMCIA controller on its memory bus,
+ * like the other Solution Engine boards.
+ */ 
+
+#define PCIIOBR		(volatile long *)PCI_REG(SH7751_PCIIOBR)
+#define PCIMBR          (volatile long *)PCI_REG(SH7751_PCIMBR)
+#define PCI_IO_AREA	SH7751_PCI_IO_BASE
+#define PCI_MEM_AREA	SH7751_PCI_CONFIG_BASE
+
+#define PCI_IOMAP(adr)	(PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK))
+
+#define maybebadio(name,port) \
+  printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \
+	 #name, (port), (__u32) __builtin_return_address(0))
+
+static inline void delay(void)
+{
+	ctrl_inw(0xa0000000);
+}
+
+static inline volatile __u16 *
+port2adr(unsigned int port)
+{
+	if (port >= 0x2000)
+		return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000));
+#if 0
+	else
+		return (volatile __u16 *) (PA_SUPERIO + (port << 1));
+#endif
+	maybebadio(name,port);
+	return (volatile __u16*)port;
+}
+
+#if 0
+/* The 7751 Solution Engine seems to have everything hooked */
+/* up pretty normally (nothing on high-bytes only...) so this */
+/* shouldn't be needed */
+static inline int
+shifted_port(unsigned long port)
+{
+	/* For IDE registers, value is not shifted */
+	if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
+		return 0;
+	else
+		return 1;
+}
+#endif
+
+/* In case someone configures the kernel w/o PCI support: in that */
+/* scenario, don't ever bother to check for PCI-window addresses */
+
+/* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */
+#if defined(CONFIG_PCI)
+#define CHECK_SH7751_PCIIO(port) \
+  ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE)))
+#else
+#define CHECK_SH_7751_PCIIO(port) (0)
+#endif
+
+/*
+ * General outline: remap really low stuff [eventually] to SuperIO,
+ * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
+ * is mapped through the PCI IO window.  Stuff with high bits (PXSEG)
+ * should be way beyond the window, and is used  w/o translation for
+ * compatibility.
+ */
+unsigned char sh7751se_inb(unsigned long port)
+{
+	if (PXSEG(port))
+		return *(volatile unsigned char *)port;
+	else if (CHECK_SH7751_PCIIO(port))
+		return *(volatile unsigned char *)PCI_IOMAP(port);
+	else
+		return (*port2adr(port))&0xff; 
+}
+
+unsigned char sh7751se_inb_p(unsigned long port)
+{
+	unsigned char v;
+
+        if (PXSEG(port))
+                v = *(volatile unsigned char *)port;
+	else if (CHECK_SH7751_PCIIO(port))
+                v = *(volatile unsigned char *)PCI_IOMAP(port);
+	else
+		v = (*port2adr(port))&0xff; 
+	delay();
+	return v;
+}
+
+unsigned short sh7751se_inw(unsigned long port)
+{
+        if (PXSEG(port))
+                return *(volatile unsigned short *)port;
+	else if (CHECK_SH7751_PCIIO(port))
+                return *(volatile unsigned short *)PCI_IOMAP(port);
+	else if (port >= 0x2000)
+		return *port2adr(port);
+	else
+		maybebadio(inw, port);
+	return 0;
+}
+
+unsigned int sh7751se_inl(unsigned long port)
+{
+        if (PXSEG(port))
+                return *(volatile unsigned long *)port;
+	else if (CHECK_SH7751_PCIIO(port))
+                return *(volatile unsigned int *)PCI_IOMAP(port);
+	else if (port >= 0x2000)
+		return *port2adr(port);
+	else
+		maybebadio(inl, port);
+	return 0;
+}
+
+void sh7751se_outb(unsigned char value, unsigned long port)
+{
+
+        if (PXSEG(port))
+                *(volatile unsigned char *)port = value;
+	else if (CHECK_SH7751_PCIIO(port))
+        	*((unsigned char*)PCI_IOMAP(port)) = value;
+	else
+		*(port2adr(port)) = value;
+}
+
+void sh7751se_outb_p(unsigned char value, unsigned long port)
+{
+        if (PXSEG(port))
+                *(volatile unsigned char *)port = value;
+	else if (CHECK_SH7751_PCIIO(port))
+        	*((unsigned char*)PCI_IOMAP(port)) = value;
+	else
+		*(port2adr(port)) = value;
+	delay();
+}
+
+void sh7751se_outw(unsigned short value, unsigned long port)
+{
+        if (PXSEG(port))
+                *(volatile unsigned short *)port = value;
+	else if (CHECK_SH7751_PCIIO(port))
+        	*((unsigned short *)PCI_IOMAP(port)) = value;
+	else if (port >= 0x2000)
+		*port2adr(port) = value;
+	else
+		maybebadio(outw, port);
+}
+
+void sh7751se_outl(unsigned int value, unsigned long port)
+{
+        if (PXSEG(port))
+                *(volatile unsigned long *)port = value;
+	else if (CHECK_SH7751_PCIIO(port))
+        	*((unsigned long*)PCI_IOMAP(port)) = value;
+	else
+		maybebadio(outl, port);
+}
+
+void sh7751se_insb(unsigned long port, void *addr, unsigned long count)
+{
+	unsigned char *p = addr;
+	while (count--) *p++ = sh7751se_inb(port);
+}
+
+void sh7751se_insw(unsigned long port, void *addr, unsigned long count)
+{
+	unsigned short *p = addr;
+	while (count--) *p++ = sh7751se_inw(port);
+}
+
+void sh7751se_insl(unsigned long port, void *addr, unsigned long count)
+{
+	maybebadio(insl, port);
+}
+
+void sh7751se_outsb(unsigned long port, const void *addr, unsigned long count)
+{
+	unsigned char *p = (unsigned char*)addr;
+	while (count--) sh7751se_outb(*p++, port);
+}
+
+void sh7751se_outsw(unsigned long port, const void *addr, unsigned long count)
+{
+	unsigned short *p = (unsigned short*)addr;
+	while (count--) sh7751se_outw(*p++, port);
+}
+
+void sh7751se_outsl(unsigned long port, const void *addr, unsigned long count)
+{
+	maybebadio(outsw, port);
+}
+
+/* For read/write calls, just copy generic (pass-thru); PCIMBR is  */
+/* already set up.  For a larger memory space, these would need to */
+/* reset PCIMBR as needed on a per-call basis...                   */
+
+unsigned char sh7751se_readb(unsigned long addr)
+{
+	return *(volatile unsigned char*)addr;
+}
+
+unsigned short sh7751se_readw(unsigned long addr)
+{
+	return *(volatile unsigned short*)addr;
+}
+
+unsigned int sh7751se_readl(unsigned long addr)
+{
+	return *(volatile unsigned long*)addr;
+}
+
+void sh7751se_writeb(unsigned char b, unsigned long addr)
+{
+	*(volatile unsigned char*)addr = b;
+}
+
+void sh7751se_writew(unsigned short b, unsigned long addr)
+{
+	*(volatile unsigned short*)addr = b;
+}
+
+void sh7751se_writel(unsigned int b, unsigned long addr)
+{
+        *(volatile unsigned long*)addr = b;
+}
+
+
+
+/* Map ISA bus address to the real address. Only for PCMCIA.  */
+
+/* ISA page descriptor.  */
+static __u32 sh_isa_memmap[256];
+
+static int
+sh_isa_mmap(__u32 start, __u32 length, __u32 offset)
+{
+	int idx;
+
+	if (start >= 0x100000 || (start & 0xfff) || (length != 0x1000))
+		return -1;
+
+	idx = start >> 12;
+	sh_isa_memmap[idx] = 0xb8000000 + (offset &~ 0xfff);
+#if 0
+	printk("sh_isa_mmap: start %x len %x offset %x (idx %x paddr %x)\n",
+	       start, length, offset, idx, sh_isa_memmap[idx]);
+#endif
+	return 0;
+}
+
+unsigned long
+sh7751se_isa_port2addr(unsigned long offset)
+{
+	int idx;
+
+	idx = (offset >> 12) & 0xff;
+	offset &= 0xfff;
+	return sh_isa_memmap[idx] + offset;
+}
diff -u --recursive --new-file v2.4.9/linux/arch/sh/kernel/io_adx.c linux/arch/sh/kernel/io_adx.c
--- v2.4.9/linux/arch/sh/kernel/io_adx.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/kernel/io_adx.c	Sat Sep  8 12:29:09 2001
@@ -0,0 +1,192 @@
+/* 
+ * linux/arch/sh/kernel/io_adx.c
+ *
+ * Copyright (C) 2001 A&D Co., Ltd.
+ *
+ * I/O routine and setup routines for A&D ADX Board
+ *
+ * This file 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.
+ *
+ */
+
+#include <asm/io.h>
+#include <asm/machvec.h>
+#include <linux/module.h>
+
+#define PORT2ADDR(x) (adx_isa_port2addr(x))
+
+static inline void delay(void)
+{
+	ctrl_inw(0xa0000000);
+}
+
+unsigned char adx_inb(unsigned long port)
+{
+	return *(volatile unsigned char*)PORT2ADDR(port);
+}
+
+unsigned short adx_inw(unsigned long port)
+{
+	return *(volatile unsigned short*)PORT2ADDR(port);
+}
+
+unsigned int adx_inl(unsigned long port)
+{
+	return *(volatile unsigned long*)PORT2ADDR(port);
+}
+
+unsigned char adx_inb_p(unsigned long port)
+{
+	unsigned long v = *(volatile unsigned char*)PORT2ADDR(port);
+
+	delay();
+	return v;
+}
+
+unsigned short adx_inw_p(unsigned long port)
+{
+	unsigned long v = *(volatile unsigned short*)PORT2ADDR(port);
+
+	delay();
+	return v;
+}
+
+unsigned int adx_inl_p(unsigned long port)
+{
+	unsigned long v = *(volatile unsigned long*)PORT2ADDR(port);
+
+	delay();
+	return v;
+}
+
+void adx_insb(unsigned long port, void *buffer, unsigned long count)
+{
+	unsigned char *buf = buffer;
+	while(count--) *buf++ = inb(port);
+}
+
+void adx_insw(unsigned long port, void *buffer, unsigned long count)
+{
+	unsigned short *buf = buffer;
+	while(count--) *buf++ = inw(port);
+}
+
+void adx_insl(unsigned long port, void *buffer, unsigned long count)
+{
+	unsigned long *buf = buffer;
+	while(count--) *buf++ = inl(port);
+}
+
+void adx_outb(unsigned char b, unsigned long port)
+{
+	*(volatile unsigned char*)PORT2ADDR(port) = b;
+}
+
+void adx_outw(unsigned short b, unsigned long port)
+{
+	*(volatile unsigned short*)PORT2ADDR(port) = b;
+}
+
+void adx_outl(unsigned int b, unsigned long port)
+{
+	*(volatile unsigned long*)PORT2ADDR(port) = b;
+}
+
+void adx_outb_p(unsigned char b, unsigned long port)
+{
+	*(volatile unsigned char*)PORT2ADDR(port) = b;
+	delay();
+}
+
+void adx_outw_p(unsigned short b, unsigned long port)
+{
+	*(volatile unsigned short*)PORT2ADDR(port) = b;
+	delay();
+}
+
+void adx_outl_p(unsigned int b, unsigned long port)
+{
+	*(volatile unsigned long*)PORT2ADDR(port) = b;
+	delay();
+}
+
+void adx_outsb(unsigned long port, const void *buffer, unsigned long count)
+{
+	const unsigned char *buf = buffer;
+	while(count--) outb(*buf++, port);
+}
+
+void adx_outsw(unsigned long port, const void *buffer, unsigned long count)
+{
+	const unsigned short *buf = buffer;
+	while(count--) outw(*buf++, port);
+}
+
+void adx_outsl(unsigned long port, const void *buffer, unsigned long count)
+{
+	const unsigned long *buf = buffer;
+	while(count--) outl(*buf++, port);
+}
+
+unsigned char adx_readb(unsigned long addr)
+{
+	return *(volatile unsigned char*)addr;
+}
+
+unsigned short adx_readw(unsigned long addr)
+{
+	return *(volatile unsigned short*)addr;
+}
+
+unsigned int adx_readl(unsigned long addr)
+{
+	return *(volatile unsigned long*)addr;
+}
+
+void adx_writeb(unsigned char b, unsigned long addr)
+{
+	*(volatile unsigned char*)addr = b;
+}
+
+void adx_writew(unsigned short b, unsigned long addr)
+{
+	*(volatile unsigned short*)addr = b;
+}
+
+void adx_writel(unsigned int b, unsigned long addr)
+{
+	*(volatile unsigned long*)addr = b;
+}
+
+void *adx_ioremap(unsigned long offset, unsigned long size)
+{
+	return (void *)P2SEGADDR(offset);
+}
+
+EXPORT_SYMBOL (adx_ioremap);
+
+void adx_iounmap(void *addr)
+{
+}
+
+EXPORT_SYMBOL(adx_iounmap);
+
+#include <linux/vmalloc.h>
+extern void *cf_io_base;
+
+unsigned long adx_isa_port2addr(unsigned long offset)
+{
+  /* CompactFlash (IDE) */
+	if (((offset >= 0x1f0) && (offset <= 0x1f7)) || (offset == 0x3f6)) {
+		return (unsigned long)cf_io_base + offset;
+	}
+
+  /* eth0 */
+	if ((offset >= 0x300) && (offset <= 0x30f)) {
+		return 0xa5000000 + offset;	/* COMM BOARD (AREA1) */
+	}
+
+	return offset + 0xb0000000; /* IOBUS (AREA 4)*/
+}
diff -u --recursive --new-file v2.4.9/linux/arch/sh/kernel/irq.c linux/arch/sh/kernel/irq.c
--- v2.4.9/linux/arch/sh/kernel/irq.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/sh/kernel/irq.c	Sat Sep  8 12:29:09 2001
@@ -1,4 +1,4 @@
-/* $Id: irq.c,v 1.12 2000/03/06 14:07:50 gniibe Exp $
+/* $Id: irq.c,v 1.21 2001/07/17 02:26:53 gniibe Exp $
  *
  * linux/arch/sh/kernel/irq.c
  *
@@ -31,7 +31,6 @@
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/bitops.h>
-#include <asm/smp.h>
 #include <asm/pgalloc.h>
 #include <asm/delay.h>
 #include <asm/irq.h>
@@ -399,7 +398,7 @@
 
 		spin_lock_irq(&desc->lock);
 		if (!desc->action)
-		  desc->handler->startup(i);
+			desc->handler->startup(i);
 		spin_unlock_irq(&desc->lock);
 	}
 
@@ -452,7 +451,6 @@
 		}
 		spin_unlock_irq(&desc->lock);
 	}
-	spin_unlock_irq(&desc->lock);
 
 	return val;
 }
@@ -536,7 +534,7 @@
 
 	if (!shared) {
 		desc->depth = 0;
-		desc->status &= ~IRQ_DISABLED;
+		desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING);
 		desc->handler->startup(irq);
 	}
 	spin_unlock_irqrestore(&desc->lock,flags);
diff -u --recursive --new-file v2.4.9/linux/arch/sh/kernel/irq_imask.c linux/arch/sh/kernel/irq_imask.c
--- v2.4.9/linux/arch/sh/kernel/irq_imask.c	Sun Jan 28 18:56:00 2001
+++ linux/arch/sh/kernel/irq_imask.c	Sat Sep  8 12:29:09 2001
@@ -1,4 +1,4 @@
-/* $Id: irq_imask.c,v 1.6 2000/03/06 14:11:32 gniibe Exp $
+/* $Id: irq_imask.c,v 1.13 2001/07/12 08:13:56 gniibe Exp $
  *
  * linux/arch/sh/kernel/irq_imask.c
  *
@@ -99,7 +99,8 @@
 
 static void end_imask_irq(unsigned int irq)
 {
-	enable_imask_irq(irq);
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_imask_irq(irq);
 }
 
 static void shutdown_imask_irq(unsigned int irq)
diff -u --recursive --new-file v2.4.9/linux/arch/sh/kernel/irq_intc2.c linux/arch/sh/kernel/irq_intc2.c
--- v2.4.9/linux/arch/sh/kernel/irq_intc2.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/sh/kernel/irq_intc2.c	Sat Sep  8 12:29:09 2001
@@ -92,7 +92,8 @@
 
 static void end_intc2_irq(unsigned int irq)
 {
-	enable_intc2_irq(irq);
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_intc2_irq(irq);
 }
 
 void make_intc2_irq(unsigned int irq, unsigned int addr, 
diff -u --recursive --new-file v2.4.9/linux/arch/sh/kernel/irq_ipr.c linux/arch/sh/kernel/irq_ipr.c
--- v2.4.9/linux/arch/sh/kernel/irq_ipr.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/sh/kernel/irq_ipr.c	Sat Sep  8 12:29:09 2001
@@ -1,4 +1,4 @@
-/* $Id: irq_ipr.c,v 1.6 2000/05/14 08:41:25 gniibe Exp $
+/* $Id: irq_ipr.c,v 1.20 2001/07/15 23:26:56 gniibe Exp $
  *
  * linux/arch/sh/kernel/irq_ipr.c
  *
@@ -102,7 +102,8 @@
 
 static void end_ipr_irq(unsigned int irq)
 {
-	enable_ipr_irq(irq);
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_ipr_irq(irq);
 }
 
 void make_ipr_irq(unsigned int irq, unsigned int addr, int pos, int priority)
@@ -176,7 +177,8 @@
 
 static void end_pint_irq(unsigned int irq)
 {
-	enable_pint_irq(irq);
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_pint_irq(irq);
 }
 
 void make_pint_irq(unsigned int irq)
diff -u --recursive --new-file v2.4.9/linux/arch/sh/kernel/irq_maskreg.c linux/arch/sh/kernel/irq_maskreg.c
--- v2.4.9/linux/arch/sh/kernel/irq_maskreg.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/kernel/irq_maskreg.c	Sat Sep  8 12:29:09 2001
@@ -0,0 +1,107 @@
+/*
+ * linux/arch/sh/kernel/irq_maskreg.c
+ *
+ * Copyright (C) 2001 A&D Co., Ltd. <http://www.aandd.co.jp>
+ *
+ * This file may be copied or modified under the terms of the GNU
+ * General Public License.  See linux/COPYING for more information.
+ *
+ * Interrupt handling for Simple external interrupt mask register
+ *
+ * This is for the machine which have single 16 bit register
+ * for masking external IRQ individually.
+ * Each bit of the register is for masking each interrupt.  
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/machvec.h>
+
+/* address of external interrupt mask register
+ * address must be set prior to use these (maybe in init_XXX_irq())
+ * XXX : is it better to use .config than specifying it in code? */
+unsigned short *irq_mask_register = 0;
+
+/* forward declaration */
+static unsigned int startup_maskreg_irq(unsigned int irq);
+static void shutdown_maskreg_irq(unsigned int irq);
+static void enable_maskreg_irq(unsigned int irq);
+static void disable_maskreg_irq(unsigned int irq);
+static void mask_and_ack_maskreg(unsigned int);
+static void end_maskreg_irq(unsigned int irq);
+
+/* hw_interrupt_type */
+static struct hw_interrupt_type maskreg_irq_type = {
+	" Mask Register",
+	startup_maskreg_irq,
+	shutdown_maskreg_irq,
+	enable_maskreg_irq,
+	disable_maskreg_irq,
+	mask_and_ack_maskreg,
+	end_maskreg_irq
+};
+
+/* actual implementatin */
+static unsigned int startup_maskreg_irq(unsigned int irq)
+{ 
+	enable_maskreg_irq(irq);
+	return 0; /* never anything pending */
+}
+
+static void shutdown_maskreg_irq(unsigned int irq)
+{
+	disable_maskreg_irq(irq);
+}
+
+static void disable_maskreg_irq(unsigned int irq)
+{
+	if (irq_mask_register) {
+		unsigned long flags;
+		unsigned short val, mask = 0x01 << irq;
+
+		/* Set "irq"th bit */
+		save_and_cli(flags);
+		val = ctrl_inw((unsigned long)irq_mask_register);
+		val |= mask;
+		ctrl_outw(val, (unsigned long)irq_mask_register);
+		restore_flags(flags);
+	}
+}
+
+static void enable_maskreg_irq(unsigned int irq)
+{
+	if (irq_mask_register) {
+		unsigned long flags;
+		unsigned short val, mask = ~(0x01 << irq);
+
+		/* Clear "irq"th bit */
+		save_and_cli(flags);
+		val = ctrl_inw((unsigned long)irq_mask_register);
+		val &= mask;
+		ctrl_outw(val, (unsigned long)irq_mask_register);
+		restore_flags(flags);
+	}
+}
+
+static void mask_and_ack_maskreg(unsigned int irq)
+{
+	disable_maskreg_irq(irq);
+}
+
+static void end_maskreg_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_maskreg_irq(irq);
+}
+
+void make_maskreg_irq(unsigned int irq)
+{
+	disable_irq_nosync(irq);
+	irq_desc[irq].handler = &maskreg_irq_type;
+	disable_maskreg_irq(irq);
+}
diff -u --recursive --new-file v2.4.9/linux/arch/sh/kernel/led_7751se.c linux/arch/sh/kernel/led_7751se.c
--- v2.4.9/linux/arch/sh/kernel/led_7751se.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/kernel/led_7751se.c	Sat Sep  8 12:29:09 2001
@@ -0,0 +1,68 @@
+/*
+ * linux/arch/sh/kernel/led_se.c
+ *
+ * Copyright (C) 2000 Stuart Menefy <stuart.menefy@st.com>
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ *
+ * This file contains Solution Engine specific LED code.
+ */
+
+#include <linux/config.h>
+#include <asm/hitachi_7751se.h>
+
+static void mach_led(int position, int value)
+{
+	volatile unsigned short* p = (volatile unsigned short*)PA_LED;
+
+	if (value) {
+		*p |= (1<<8);
+	} else {
+		*p &= ~(1<<8);
+	}
+}
+
+#ifdef CONFIG_HEARTBEAT
+
+#include <linux/sched.h>
+
+/* Cycle the LED's in the clasic Knightrider/Sun pattern */
+void heartbeat_7751se(void)
+{
+	static unsigned int cnt = 0, period = 0;
+	volatile unsigned short* p = (volatile unsigned short*)PA_LED;
+	static unsigned bit = 0, up = 1;
+
+	cnt += 1;
+	if (cnt < period) {
+		return;
+	}
+
+	cnt = 0;
+
+	/* Go through the points (roughly!):
+	 * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
+	 */
+	period = 110 - ( (300<<FSHIFT)/
+			 ((avenrun[0]/5) + (3<<FSHIFT)) );
+
+	if (up) {
+		if (bit == 7) {
+			bit--;
+			up=0;
+		} else {
+			bit ++;
+		}
+	} else {
+		if (bit == 0) {
+			bit++;
+			up=1;
+		} else {
+			bit--;
+		}
+	}
+	*p = 1<<(bit+8);
+
+}
+#endif /* CONFIG_HEARTBEAT */
diff -u --recursive --new-file v2.4.9/linux/arch/sh/kernel/led_se.c linux/arch/sh/kernel/led_se.c
--- v2.4.9/linux/arch/sh/kernel/led_se.c	Wed Aug  9 13:59:04 2000
+++ linux/arch/sh/kernel/led_se.c	Sat Sep  8 12:29:09 2001
@@ -10,10 +10,11 @@
  */
 
 #include <linux/config.h>
+#include <asm/hitachi_se.h>
 
 static void mach_led(int position, int value)
 {
-	volatile unsigned short* p = (volatile unsigned short*)0xb0c00000;
+	volatile unsigned short* p = (volatile unsigned short*)PA_LED;
 
 	if (value) {
 		*p |= (1<<8);
@@ -30,7 +31,7 @@
 void heartbeat_se(void)
 {
 	static unsigned int cnt = 0, period = 0;
-	volatile unsigned short* p = (volatile unsigned short*)0xb0c00000;
+	volatile unsigned short* p = (volatile unsigned short*)PA_LED;
 	static unsigned bit = 0, up = 1;
 
 	cnt += 1;
diff -u --recursive --new-file v2.4.9/linux/arch/sh/kernel/mach_7751se.c linux/arch/sh/kernel/mach_7751se.c
--- v2.4.9/linux/arch/sh/kernel/mach_7751se.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/kernel/mach_7751se.c	Sat Sep  8 12:29:09 2001
@@ -0,0 +1,78 @@
+/*
+ * linux/arch/sh/kernel/mach_7751se.c
+ *
+ * Minor tweak of mach_se.c file to reference 7751se-specific items.
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ *
+ * Machine vector for the Hitachi 7751 SolutionEngine
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <asm/machvec.h>
+#include <asm/rtc.h>
+#include <asm/machvec_init.h>
+
+#include <asm/io_7751se.h>
+
+void heartbeat_7751se(void);
+void setup_7751se(void);
+void init_7751se_IRQ(void);
+
+/*
+ * The Machine Vector
+ */
+
+struct sh_machine_vector mv_7751se __initmv = {
+	mv_name:		"7751 SolutionEngine",
+
+	mv_nr_irqs:		72,
+
+	mv_inb:			sh7751se_inb,
+	mv_inw:			sh7751se_inw,
+	mv_inl:			sh7751se_inl,
+	mv_outb:		sh7751se_outb,
+	mv_outw:		sh7751se_outw,
+	mv_outl:		sh7751se_outl,
+
+	mv_inb_p:		sh7751se_inb_p,
+	mv_inw_p:		sh7751se_inw,
+	mv_inl_p:		sh7751se_inl,
+	mv_outb_p:		sh7751se_outb_p,
+	mv_outw_p:		sh7751se_outw,
+	mv_outl_p:		sh7751se_outl,
+
+	mv_insb:		sh7751se_insb,
+	mv_insw:		sh7751se_insw,
+	mv_insl:		sh7751se_insl,
+	mv_outsb:		sh7751se_outsb,
+	mv_outsw:		sh7751se_outsw,
+	mv_outsl:		sh7751se_outsl,
+
+	mv_readb:		sh7751se_readb,
+	mv_readw:		sh7751se_readw,
+	mv_readl:		sh7751se_readl,
+	mv_writeb:		sh7751se_writeb,
+	mv_writew:		sh7751se_writew,
+	mv_writel:		sh7751se_writel,
+
+	mv_ioremap:		generic_ioremap,
+	mv_iounmap:		generic_iounmap,
+
+	mv_isa_port2addr:	sh7751se_isa_port2addr,
+
+	mv_init_arch:		setup_7751se,
+	mv_init_irq:		init_7751se_IRQ,
+#ifdef CONFIG_HEARTBEAT
+	mv_heartbeat:		heartbeat_7751se,
+#endif
+
+	mv_rtc_gettimeofday:	sh_rtc_gettimeofday,
+	mv_rtc_settimeofday:	sh_rtc_settimeofday,
+
+	mv_hw_7751se:		1,
+};
+ALIAS_MV(7751se)
diff -u --recursive --new-file v2.4.9/linux/arch/sh/kernel/mach_adx.c linux/arch/sh/kernel/mach_adx.c
--- v2.4.9/linux/arch/sh/kernel/mach_adx.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/kernel/mach_adx.c	Sat Sep  8 12:29:09 2001
@@ -0,0 +1,73 @@
+/*
+ * linux/arch/sh/kernel/mach_adx.c
+ *
+ * Copyright (C) 2001 A&D Co., Ltd.
+ *
+ * This file may be copied or modified under the terms of the GNU
+ * General Public License.  See linux/COPYING for more information.
+ *
+ * Machine vector for the A&D ADX Board
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <asm/machvec.h>
+#include <asm/rtc.h>
+#include <asm/machvec_init.h>
+#include <asm/io_adx.h>
+
+extern void setup_adx(void);
+extern void init_adx_IRQ(void);
+
+/*
+ * The Machine Vector
+ */
+
+struct sh_machine_vector mv_adx __initmv = {
+	mv_name:		"A&D_ADX",
+
+	mv_nr_irqs:		48,
+
+	mv_inb:			adx_inb,
+	mv_inw:			adx_inw,
+	mv_inl:			adx_inl,
+	mv_outb:		adx_outb,
+	mv_outw:		adx_outw,
+	mv_outl:		adx_outl,
+
+	mv_inb_p:		adx_inb_p,
+	mv_inw_p:		adx_inw,
+	mv_inl_p:		adx_inl,
+	mv_outb_p:		adx_outb_p,
+	mv_outw_p:		adx_outw,
+	mv_outl_p:		adx_outl,
+
+	mv_insb:		adx_insb,
+	mv_insw:		adx_insw,
+	mv_insl:		adx_insl,
+	mv_outsb:		adx_outsb,
+	mv_outsw:		adx_outsw,
+	mv_outsl:		adx_outsl,
+
+	mv_readb:		adx_readb,
+	mv_readw:		adx_readw,
+	mv_readl:		adx_readl,
+	mv_writeb:		adx_writeb,
+	mv_writew:		adx_writew,
+	mv_writel:		adx_writel,
+
+	mv_ioremap:		adx_ioremap,
+	mv_iounmap:		adx_iounmap,
+
+	mv_isa_port2addr:	adx_isa_port2addr,
+
+	mv_init_arch:		setup_adx,
+	mv_init_irq:		init_adx_IRQ,
+
+	mv_rtc_gettimeofday:	sh_rtc_gettimeofday,
+	mv_rtc_settimeofday:	sh_rtc_settimeofday,
+
+	mv_hw_adx:		1,
+};
+ALIAS_MV(adx)
diff -u --recursive --new-file v2.4.9/linux/arch/sh/kernel/mach_dc.c linux/arch/sh/kernel/mach_dc.c
--- v2.4.9/linux/arch/sh/kernel/mach_dc.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/sh/kernel/mach_dc.c	Sat Sep  8 12:29:09 2001
@@ -1,10 +1,11 @@
 /*
- *	$Id: mach_dc.c,v 1.4 2001/05/24 05:09:16 mrbrown Exp $
+ *	$Id: mach_dc.c,v 1.5 2001/09/01 14:34:31 mrbrown Exp $
  *	SEGA Dreamcast machine vector
  */
 
 #include <linux/config.h>
 #include <linux/init.h>
+#include <linux/time.h>
 
 #include <asm/machvec.h>
 #include <asm/machvec_init.h>
@@ -16,6 +17,10 @@
 void __init setup_dreamcast(void);
 void __init dreamcast_pcibios_init(void);
 
+/* Custom Dreamcast RTC routines */
+void aica_rtc_gettimeofday(struct timeval *tv);
+int aica_rtc_settimeofday(const struct timeval *tv);
+
 /*
  * The Machine Vector
  */
@@ -59,6 +64,9 @@
 	mv_init_arch:		setup_dreamcast,
 	mv_isa_port2addr:	dreamcast_isa_port2addr,
 	mv_irq_demux:		systemasic_irq_demux,
+
+	mv_rtc_gettimeofday:	aica_rtc_gettimeofday,
+	mv_rtc_settimeofday:	aica_rtc_settimeofday,
 
 	mv_hw_dreamcast:	1,
 };
diff -u --recursive --new-file v2.4.9/linux/arch/sh/kernel/mach_hp600.c linux/arch/sh/kernel/mach_hp600.c
--- v2.4.9/linux/arch/sh/kernel/mach_hp600.c	Wed Apr 11 21:24:52 2001
+++ linux/arch/sh/kernel/mach_hp600.c	Sat Sep  8 12:29:09 2001
@@ -15,8 +15,8 @@
 #include <asm/rtc.h>
 #include <asm/machvec_init.h>
 
-#include <asm/io_hd64461.h>
-#include <asm/io_generic.h>
+#include <asm/io.h>
+#include <asm/hd64461.h>
 #include <asm/irq.h>
 
 /*
@@ -26,7 +26,7 @@
 struct sh_machine_vector mv_hp620 __initmv = {
 	mv_name:		"hp620",
 
-	mv_nr_irqs:		80, /* HD64461_IRQBASE+16, see hd64461.h */
+	mv_nr_irqs:		HD64461_IRQBASE+HD64461_IRQ_NUM,
 
 	mv_inb:			hd64461_inb,
 	mv_inw:			hd64461_inw,
@@ -71,7 +71,7 @@
 struct sh_machine_vector mv_hp680 __initmv = {
 	mv_name:		"hp680",
 
-	mv_nr_irqs:		80, /* HD64461_IRQBASE+16, see hd64461.h */
+	mv_nr_irqs:		HD64461_IRQBASE+HD64461_IRQ_NUM,
 
 	mv_inb:			hd64461_inb,
 	mv_inw:			hd64461_inw,
@@ -116,7 +116,7 @@
 struct sh_machine_vector mv_hp690 __initmv = {
 	mv_name:		"hp690",
 
-	mv_nr_irqs:		80, /* HD64461_IRQBASE+16, see hd64461.h */
+	mv_nr_irqs:		HD64461_IRQBASE+HD64461_IRQ_NUM,
 
 	mv_inb:			hd64461_inb,
 	mv_inw:			hd64461_inw,
diff -u --recursive --new-file v2.4.9/linux/arch/sh/kernel/pci-7751se.c linux/arch/sh/kernel/pci-7751se.c
--- v2.4.9/linux/arch/sh/kernel/pci-7751se.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/sh/kernel/pci-7751se.c	Sat Sep  8 12:29:09 2001
@@ -41,13 +41,13 @@
    unsigned long bcr1, wcr1, wcr2, wcr3, mcr;
    unsigned short bcr2;
 
-   //
-   // Initialize the slave bus controller on the pcic.  The values used
-   // here should not be hardcoded, but they should be taken from the bsc
-   // on the processor, to make this function as generic as possible.
-   // (i.e. Another sbc may usr different SDRAM timing settings -- in order
-   // for the pcic to work, its settings need to be exactly the same.)
-   //
+   /*
+    * Initialize the slave bus controller on the pcic.  The values used
+    * here should not be hardcoded, but they should be taken from the bsc
+    * on the processor, to make this function as generic as possible.
+    * (i.e. Another sbc may usr different SDRAM timing settings -- in order
+    * for the pcic to work, its settings need to be exactly the same.)
+    */
    bcr1 = (*(volatile unsigned long*)(SH7751_BCR1));
    bcr2 = (*(volatile unsigned short*)(SH7751_BCR2));
    wcr1 = (*(volatile unsigned long*)(SH7751_WCR1));
@@ -67,21 +67,47 @@
    mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF;
    PCIC_WRITE(SH7751_PCIMCR, mcr);      /* PCIC MCR */
 
+
+   /* Enable all interrupts, so we know what to fix */
    PCIC_WRITE(SH7751_PCIINTM, 0x0000c3ff);
-   PCIC_WRITE(SH7751_PCIAINTM, 0x0000980f);
-   PCIC_WRITE(SH7751_PCICONF1, 0xF39000C7);  /* FB9000C7 */
-   PCIC_WRITE(SH7751_PCICONF2, 0x00000000);  /* PCI Class code & Revision ID */
-   PCIC_WRITE(SH7751_PCICONF4, 0xab000001);  /* PCI I/O */
-   PCIC_WRITE(SH7751_PCICONF5, 0x0c000000);  /* PCI MEM0 old val: 0xb0000000 */
-   PCIC_WRITE(SH7751_PCICONF6, 0xd0000000);  /* PCI MEM1 */
-   PCIC_WRITE(SH7751_PCICONF11, 0x35051054); /* PCI Sub system ID & Sub system vendor ID */
-   PCIC_WRITE(SH7751_PCILSR0, 0x03f00000);   /* PCI MEM0 */
-   PCIC_WRITE(SH7751_PCILSR1, 0x00000000);   /* PCI MEM1 */
-   PCIC_WRITE(SH7751_PCILAR0, 0x0c000000);   /* MEM0 */
-   PCIC_WRITE(SH7751_PCILAR1, 0x00000000);   /* MEM1 */
+   PCIC_WRITE(SH7751_PCIAINTM, 0x0000380f);
+
+   /* Set up standard PCI config registers */
+   PCIC_WRITE(SH7751_PCICONF1, 	0xF39000C7); /* Bus Master, Mem & I/O access */
+   PCIC_WRITE(SH7751_PCICONF2, 	0x00000000); /* PCI Class code & Revision ID */
+   PCIC_WRITE(SH7751_PCICONF4, 	0xab000001); /* PCI I/O address (local regs) */
+   PCIC_WRITE(SH7751_PCICONF5, 	0x0c000000); /* PCI MEM address (local RAM)  */
+   PCIC_WRITE(SH7751_PCICONF6, 	0xd0000000); /* PCI MEM address (unused)     */
+   PCIC_WRITE(SH7751_PCICONF11, 0x35051054); /* PCI Subsystem ID & Vendor ID */
+   PCIC_WRITE(SH7751_PCILSR0, 0x03f00000);   /* MEM (full 64M exposed)       */
+   PCIC_WRITE(SH7751_PCILSR1, 0x00000000);   /* MEM (unused)                 */
+   PCIC_WRITE(SH7751_PCILAR0, 0x0c000000);   /* MEM (direct map from PCI)    */
+   PCIC_WRITE(SH7751_PCILAR1, 0x00000000);   /* MEM (unused)                 */
 
+   /* Now turn it on... */
    PCIC_WRITE(SH7751_PCICR, 0xa5000001);
 
+   /*
+    * Set PCIMBR and PCIIOBR here, assuming a single window
+    * (16M MEM, 256K IO) is enough.  If a larger space is
+    * needed, the readx/writex and inx/outx functions will
+    * have to do more (e.g. setting registers for each call).
+    */
+
+   /*
+    * Set the MBR so PCI address is one-to-one with window,
+    * meaning all calls go straight through... use ifdef to
+    * catch erroneous assumption.
+    */
+#if PCIBIOS_MIN_MEM != SH7751_PCI_MEMORY_BASE
+#error One-to-one assumption for PCI memory mapping is wrong!?!?!?
+#endif   
+   PCIC_WRITE(SH7751_PCIMBR, PCIBIOS_MIN_MEM);
+
+   /* Set IOBR for window containing area specified in pci.h */
+   PCIC_WRITE(SH7751_PCIIOBR, (PCIBIOS_MIN_IO & SH7751_PCIIOBR_MASK));
+
+   /* All done, may as well say so... */
    printk("SH7751 PCI: Finished initialization of the PCI controller\n");
 
    return 1;
diff -u --recursive --new-file v2.4.9/linux/arch/sh/kernel/pci-dc.c linux/arch/sh/kernel/pci-dc.c
--- v2.4.9/linux/arch/sh/kernel/pci-dc.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/sh/kernel/pci-dc.c	Sat Sep  8 12:29:09 2001
@@ -1,5 +1,5 @@
 /*
- $	$Id: pci-dc.c,v 1.2 2001/05/24 05:09:16 mrbrown Exp $
+ $	$Id: pci-dc.c,v 1.5 2001/08/24 12:38:19 dwmw2 Exp $
  *	Dreamcast PCI: Supports SEGA Broadband Adaptor only.
  */
 
@@ -104,62 +104,6 @@
 };
 
 
-void pcibios_align_resource(void *data, struct resource *res,
-			    unsigned long size)
-{
-}
-
-
-void __init pcibios_update_irq(struct pci_dev *dev, int irq)
-{
-}
-
-
-void __init pcibios_update_resource(struct pci_dev *dev, struct resource *root,
-			     struct resource *res, int resource)
-{
-}
-
-
-void pcibios_set_master(struct pci_dev *dev)
-{
-	/* No special bus mastering setup handling */
-}
-
-
-int pcibios_enable_device(struct pci_dev *dev)
-{
-
-	u16 cmd, old_cmd;
-	int idx;
-	struct resource *r;
-
-	pci_read_config_word(dev, PCI_COMMAND, &cmd);
-	old_cmd = cmd;
-	for (idx = 0; idx < 6; idx++) {
-		r = dev->resource + idx;
-		if (!r->start && r->end) {
-			printk(KERN_ERR
-			       "PCI: Device %s not available because"
-			       " of resource collisions\n",
-			       dev->slot_name);
-			return -EINVAL;
-		}
-		if (r->flags & IORESOURCE_IO)
-			cmd |= PCI_COMMAND_IO;
-		if (r->flags & IORESOURCE_MEM)
-			cmd |= PCI_COMMAND_MEMORY;
-	}
-	if (cmd != old_cmd) {
-		printk("PCI: enabling device %s (%04x -> %04x)\n",
-		       dev->slot_name, old_cmd, cmd);
-		pci_write_config_word(dev, PCI_COMMAND, cmd);
-	}
-	return 0;
-
-}
-
-
 void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
 			   dma_addr_t * dma_handle)
 {
@@ -172,7 +116,7 @@
 
 	gapspci_dma_used = PAGE_ALIGN(gapspci_dma_used+size);
 	
-	printk("pci_alloc_consistent: %ld bytes at 0x%p\n", size, buf);
+	printk("pci_alloc_consistent: %ld bytes at 0x%lx\n", (long)size, buf);
 
 	*dma_handle = (dma_addr_t)buf;
 
@@ -184,6 +128,7 @@
 			 void *vaddr, dma_addr_t dma_handle)
 {
 	/* XXX */
+	gapspci_dma_used = 0;
 }
 
 
diff -u --recursive --new-file v2.4.9/linux/arch/sh/kernel/pci-dma.c linux/arch/sh/kernel/pci-dma.c
--- v2.4.9/linux/arch/sh/kernel/pci-dma.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/sh/kernel/pci-dma.c	Sat Sep  8 12:29:09 2001
@@ -29,7 +29,7 @@
 		*dma_handle = virt_to_bus(ret);
 	}
 	/* We must flush the cache before we pass it on to the device */
-	flush_cache_all();
+	dma_cache_wback_inv(ret, size);
 	return  P2SEGADDR(ret);
 }
 
diff -u --recursive --new-file v2.4.9/linux/arch/sh/kernel/pci-sh7751.c linux/arch/sh/kernel/pci-sh7751.c
--- v2.4.9/linux/arch/sh/kernel/pci-sh7751.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/sh/kernel/pci-sh7751.c	Sat Sep  8 12:29:09 2001
@@ -20,7 +20,6 @@
 #include <linux/errno.h>
 #include <linux/irq.h>
 
-#include <asm/segment.h>
 #include <asm/machvec.h>
 #include <asm/io.h>
 #include <asm/pci-sh7751.h>
@@ -57,10 +56,10 @@
     /* PCIPDR may only be accessed as 32 bit words, 
      * so we must do byte alignment by hand 
      */
-	__save_and_cli(flags);
+	save_and_cli(flags);
 	outl(CONFIG_CMD(dev,where), PCI_REG(SH7751_PCIPAR));
 	word = inl(PCI_REG(SH7751_PCIPDR));
-	__restore_flags(flags);
+	restore_flags(flags);
 	switch (where & 0x3) {
 	    case 3:
 		    *value = (u8)(word >> 24);
@@ -88,10 +87,10 @@
     /* PCIPDR may only be accessed as 32 bit words, 
      * so we must do word alignment by hand 
      */
-	__save_and_cli(flags);
+	save_and_cli(flags);
 	outl(CONFIG_CMD(dev,where), PCI_REG(SH7751_PCIPAR));
 	word = inl(PCI_REG(SH7751_PCIPDR));
-	__restore_flags(flags);
+	restore_flags(flags);
 	switch (where & 0x3) {
 	    case 3:
 		    // This should never happen...
@@ -116,10 +115,10 @@
 {
 	unsigned long flags;
 	
-	__save_and_cli(flags);
+	save_and_cli(flags);
 	outl(CONFIG_CMD(dev,where), PCI_REG(SH7751_PCIPAR));
 	*value = inl(PCI_REG(SH7751_PCIPDR));
-	__restore_flags(flags);
+	restore_flags(flags);
 	PCIDBG(4,"pci_conf1_read_config_dword@0x%08x=0x%x\n",
 	     CONFIG_CMD(dev,where),*value);
 	return PCIBIOS_SUCCESSFUL;    
@@ -135,14 +134,14 @@
     /* Since SH7751 only does 32bit access we'll have to do a
      * read,mask,write operation
      */ 
-	__save_and_cli(flags);
+	save_and_cli(flags);
 	outl(CONFIG_CMD(dev,where), PCI_REG(SH7751_PCIPAR));
 	word = inl(PCI_REG(SH7751_PCIPDR)) ;
 	word &= ~mask;
 	word |= value << shift;
  
 	outl(word, PCI_REG(SH7751_PCIPDR));
-	__restore_flags(flags);
+	restore_flags(flags);
 	PCIDBG(4,"pci_conf1_write_config_byte@0x%08x=0x%x\n",
 	     CONFIG_CMD(dev,where),word);
 	return PCIBIOS_SUCCESSFUL;
@@ -161,14 +160,14 @@
      */ 
 	if (shift == 24)
 	    return PCIBIOS_BAD_REGISTER_NUMBER;
-	__save_and_cli(flags);
+	save_and_cli(flags);
 	outl(CONFIG_CMD(dev,where), PCI_REG(SH7751_PCIPAR));
 	word = inl(PCI_REG(SH7751_PCIPDR)) ;
 	word &= ~mask;
 	word |= value << shift;
  
 	outl(value, PCI_REG(SH7751_PCIPDR));
-	__restore_flags(flags);
+	restore_flags(flags);
 	PCIDBG(4,"pci_conf1_write_config_word@0x%08x=0x%x\n",
 	     CONFIG_CMD(dev,where),word);
 	return PCIBIOS_SUCCESSFUL;
@@ -178,10 +177,10 @@
 {
 	unsigned long flags;
 
-	__save_and_cli(flags);
+	save_and_cli(flags);
 	outl(CONFIG_CMD(dev,where), PCI_REG(SH7751_PCIPAR));
 	outl(value, PCI_REG(SH7751_PCIPDR));
-	__restore_flags(flags);
+	restore_flags(flags);
 	PCIDBG(4,"pci_conf1_write_config_dword@0x%08x=0x%x\n",
 	     CONFIG_CMD(dev,where),value);
 	return PCIBIOS_SUCCESSFUL;
@@ -233,7 +232,7 @@
  * BIOS32 and PCI BIOS handling.
  * 
  * The BIOS version of the pci functions is not yet implemented but it is left
- * in for completeness.  Currently an error will be genereated at compile time. 
+ * in for completeness.  Currently an error will be generated at compile time. 
  */
  
 #ifdef CONFIG_PCI_BIOS
@@ -417,54 +416,6 @@
 	return str;
 }
 
-void
-pcibios_update_resource(struct pci_dev *dev, struct resource *root,
-			struct resource *res, int resource)
-{
-	u32 new, check;
-	int reg;
-
-	new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
-	if (resource < 6) {
-		reg = PCI_BASE_ADDRESS_0 + 4*resource;
-	} else if (resource == PCI_ROM_RESOURCE) {
-		res->flags |= PCI_ROM_ADDRESS_ENABLE;
-		new |= PCI_ROM_ADDRESS_ENABLE;
-		reg = dev->rom_base_reg;
-	} else {
-		/* Somebody might have asked allocation of a non-standard resource */
-		return;
-	}
-	
-	pci_write_config_dword(dev, reg, new);
-	pci_read_config_dword(dev, reg, &check);
-	if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) {
-		printk(KERN_ERR "PCI: Error while updating region "
-		       "%s/%d (%08x != %08x)\n", dev->slot_name, resource,
-		       new, check);
-	}
-}
-
-/*
- * We need to avoid collisions with `mirrored' VGA ports
- * and other strange ISA hardware, so we always want the
- * addresses to be allocated in the 0x000-0x0ff region
- * modulo 0x400.
- */
-void
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
-{
-	if (res->flags & IORESOURCE_IO) {
-		unsigned long start = res->start;
-
-		if (start & 0x300) {
-			start = (start + 0x3ff) & ~0x3ff;
-			res->start = start;
-		}
-	}
-}
-
-
 /*
  *    Allocate the bridge and device resources
  */
@@ -593,53 +544,6 @@
 	pcibios_assign_resources();
 }
 
-int pcibios_enable_device(struct pci_dev *dev)
-{
-	u16 cmd, old_cmd;
-	int idx;
-	struct resource *r;
-
-	pci_read_config_word(dev, PCI_COMMAND, &cmd);
-	old_cmd = cmd;
-	for(idx=0; idx<6; idx++) {
-		r = &dev->resource[idx];
-		if (!r->start && r->end) {
-			printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", dev->slot_name);
-			return -EINVAL;
-		}
-		if (r->flags & IORESOURCE_IO)
-			cmd |= PCI_COMMAND_IO;
-		if (r->flags & IORESOURCE_MEM)
-			cmd |= PCI_COMMAND_MEMORY;
-	}
-	if (dev->resource[PCI_ROM_RESOURCE].start)
-		cmd |= PCI_COMMAND_MEMORY;
-	if (cmd != old_cmd) {
-		printk(KERN_INFO "PCI: Enabling device %s (%04x -> %04x)\n", dev->name, old_cmd, cmd);
-		pci_write_config_word(dev, PCI_COMMAND, cmd);
-	}
-	return 0;
-}
-
-/*
- *  If we set up a device for bus mastering, we need to check and set
- *  the latency timer as it may not be properly set.
- */
-unsigned int pcibios_max_latency = 255;
-
-void pcibios_set_master(struct pci_dev *dev)
-{
-	u8 lat;
-	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
-	if (lat < 16)
-		lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
-	else if (lat > pcibios_max_latency)
-		lat = pcibios_max_latency;
-	else
-		return;
-	printk(KERN_INFO "PCI: Setting latency timer of device %s to %d\n", dev->name, lat);
-	pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
-}
 
 /***************************************************************************************/
 /* 
@@ -665,10 +569,4 @@
 	PCIDBG(2,"Setting IRQ for slot %s to %d\n", dev->slot_name, irq);
 
 	return irq;
-}
-
-void __init pcibios_update_irq(struct pci_dev *dev, int irq)
-{
-	PCIDBG(3,"PCI: Update IRQ for %s on irq %d\n", dev->name, irq);
-	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
 }
diff -u --recursive --new-file v2.4.9/linux/arch/sh/kernel/pci_st40.c linux/arch/sh/kernel/pci_st40.c
--- v2.4.9/linux/arch/sh/kernel/pci_st40.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/sh/kernel/pci_st40.c	Sat Sep  8 12:29:09 2001
@@ -458,91 +458,6 @@
 
 }
 
-int pcibios_enable_device(struct pci_dev *dev)
-{
-
-	u16 cmd, old_cmd;
-	int idx;
-	struct resource *r;
-
-	pci_read_config_word(dev, PCI_COMMAND, &cmd);
-	old_cmd = cmd;
-	for (idx = 0; idx < 6; idx++) {
-		r = dev->resource + idx;
-		if (!r->start && r->end) {
-			printk(KERN_ERR
-			       "PCI: Device %s not available because"
-			       " of resource collisions\n",
-			       dev->slot_name);
-			return -EINVAL;
-		}
-		if (r->flags & IORESOURCE_IO)
-			cmd |= PCI_COMMAND_IO;
-		if (r->flags & IORESOURCE_MEM)
-			cmd |= PCI_COMMAND_MEMORY;
-	}
-	if (cmd != old_cmd) {
-		printk("PCI: enabling device %s (%04x -> %04x)\n",
-		       dev->slot_name, old_cmd, cmd);
-		pci_write_config_word(dev, PCI_COMMAND, cmd);
-	}
-	return 0;
-
-}
-
 void __init pcibios_fixup_bus(struct pci_bus *bus)
 {
-}
-
-void pcibios_align_resource(void *data, struct resource *res,
-			    unsigned long size)
-{
-}
-
-void __init pcibios_update_resource(struct pci_dev *dev,
-				    struct resource *root,
-				    struct resource *res, int resource)
-{
-
-	unsigned long where, size;
-	u32 reg;
-
-	printk("PCI: Assigning %3s %08lx to %s\n",
-	       res->flags & IORESOURCE_IO ? "IO" : "MEM",
-	       res->start, dev->name);
-
-	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)
-{
-	printk("PCI: Assigning IRQ %02d to %s\n", irq, dev->name);
-	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
-}
-
-/*
- *  If we set up a device for bus mastering, we need to check the latency
- *  timer as certain crappy BIOSes forget to set it properly.
- */
-unsigned int pcibios_max_latency = 255;
-
-void pcibios_set_master(struct pci_dev *dev)
-{
-	u8 lat;
-	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
-	if (lat < 16)
-		lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
-	else if (lat > pcibios_max_latency)
-		lat = pcibios_max_latency;
-	else
-		return;
-	printk("PCI: Setting latency timer of device %s to %d\n", dev->slot_name, lat);
-	pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
 }
diff -u --recursive --new-file v2.4.9/linux/arch/sh/kernel/pcibios.c linux/arch/sh/kernel/pcibios.c
--- v2.4.9/linux/arch/sh/kernel/pcibios.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/kernel/pcibios.c	Sat Sep  8 12:29:09 2001
@@ -0,0 +1,126 @@
+/*
+ * $Id: pcibios.c,v 1.1 2001/08/24 12:38:19 dwmw2 Exp $
+ *
+ * arch/sh/kernel/pcibios.c
+ *
+ * This is GPL'd.
+ *
+ * Provided here are generic versions of:
+ *	pcibios_update_resource()
+ *	pcibios_align_resource()
+ *	pcibios_enable_device()
+ *	pcibios_set_master()
+ *	pcibios_update_irq()
+ *
+ * These functions are collected here to reduce duplication of common
+ * code amongst the many platform-specific PCI support code files.
+ *
+ * Platform-specific files are expected to provide:
+ *	pcibios_fixup_bus()
+ *	pcibios_init()
+ *	pcibios_setup()
+ *	pcibios_fixup_pbus_ranges()
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+void
+pcibios_update_resource(struct pci_dev *dev, struct resource *root,
+			struct resource *res, int resource)
+{
+	u32 new, check;
+	int reg;
+
+	new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
+	if (resource < 6) {
+		reg = PCI_BASE_ADDRESS_0 + 4*resource;
+	} else if (resource == PCI_ROM_RESOURCE) {
+		res->flags |= PCI_ROM_ADDRESS_ENABLE;
+		new |= PCI_ROM_ADDRESS_ENABLE;
+		reg = dev->rom_base_reg;
+	} else {
+		/* Somebody might have asked allocation of a non-standard resource */
+		return;
+	}
+	
+	pci_write_config_dword(dev, reg, new);
+	pci_read_config_dword(dev, reg, &check);
+	if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) {
+		printk(KERN_ERR "PCI: Error while updating region "
+		       "%s/%d (%08x != %08x)\n", dev->slot_name, resource,
+		       new, check);
+	}
+}
+
+/*
+ * We need to avoid collisions with `mirrored' VGA ports
+ * and other strange ISA hardware, so we always want the
+ * addresses to be allocated in the 0x000-0x0ff region
+ * modulo 0x400.
+ */
+void pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+{
+	if (res->flags & IORESOURCE_IO) {
+		unsigned long start = res->start;
+
+		if (start & 0x300) {
+			start = (start + 0x3ff) & ~0x3ff;
+			res->start = start;
+		}
+	}
+}
+
+int pcibios_enable_device(struct pci_dev *dev)
+{
+	u16 cmd, old_cmd;
+	int idx;
+	struct resource *r;
+
+	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+	old_cmd = cmd;
+	for(idx=0; idx<6; idx++) {
+		r = &dev->resource[idx];
+		if (!r->start && r->end) {
+			printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", dev->slot_name);
+			return -EINVAL;
+		}
+		if (r->flags & IORESOURCE_IO)
+			cmd |= PCI_COMMAND_IO;
+		if (r->flags & IORESOURCE_MEM)
+			cmd |= PCI_COMMAND_MEMORY;
+	}
+	if (dev->resource[PCI_ROM_RESOURCE].start)
+		cmd |= PCI_COMMAND_MEMORY;
+	if (cmd != old_cmd) {
+		printk(KERN_INFO "PCI: Enabling device %s (%04x -> %04x)\n", dev->name, old_cmd, cmd);
+		pci_write_config_word(dev, PCI_COMMAND, cmd);
+	}
+	return 0;
+}
+
+/*
+ *  If we set up a device for bus mastering, we need to check and set
+ *  the latency timer as it may not be properly set.
+ */
+unsigned int pcibios_max_latency = 255;
+
+void pcibios_set_master(struct pci_dev *dev)
+{
+	u8 lat;
+	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
+	if (lat < 16)
+		lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
+	else if (lat > pcibios_max_latency)
+		lat = pcibios_max_latency;
+	else
+		return;
+	printk(KERN_INFO "PCI: Setting latency timer of device %s to %d\n", dev->name, lat);
+	pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
+}
+
+void __init pcibios_update_irq(struct pci_dev *dev, int irq)
+{
+	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
+}
diff -u --recursive --new-file v2.4.9/linux/arch/sh/kernel/process.c linux/arch/sh/kernel/process.c
--- v2.4.9/linux/arch/sh/kernel/process.c	Wed Apr 11 21:24:52 2001
+++ linux/arch/sh/kernel/process.c	Sat Sep  8 12:29:09 2001
@@ -1,4 +1,4 @@
-/* $Id: process.c,v 1.33 2000/03/25 00:06:15 gniibe Exp $
+/* $Id: process.c,v 1.34 2001/07/30 12:42:11 gniibe Exp $
  *
  *  linux/arch/sh/kernel/process.c
  *
@@ -11,40 +11,13 @@
  * This file handles the architecture-dependent parts of process handling..
  */
 
-#define __KERNEL_SYSCALLS__
-#include <stdarg.h>
-
-#include <linux/config.h>
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-#include <linux/stddef.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/user.h>
-#include <linux/a.out.h>
-#include <linux/interrupt.h>
 #include <linux/unistd.h>
-#include <linux/delay.h>
-#include <linux/reboot.h>
-#include <linux/init.h>
-#include <linux/irq.h>
+#include <linux/slab.h>
 
-#include <asm/uaccess.h>
-#include <asm/pgtable.h>
-#include <asm/system.h>
 #include <asm/io.h>
-#include <asm/processor.h>
+#include <asm/uaccess.h>
 #include <asm/mmu_context.h>
 #include <asm/elf.h>
-#ifdef CONFIG_SH_STANDARD_BIOS
-#include <asm/sh_bios.h>
-#endif
 
 static int hlt_counter=0;
 
@@ -71,11 +44,17 @@
 	current->counter = -100;
 
 	while (1) {
-		while (!current->need_resched) {
-			if (hlt_counter)
-				continue;
+		if (hlt_counter) {
+			if (current->need_resched)
+				break;
+		} else {
+			__cli();
+			while (!current->need_resched) {
+				__sti();
+				asm volatile("sleep" : : : "memory");
+				__cli();
+			}
 			__sti();
-			asm volatile("sleep" : : : "memory");
 		}
 		schedule();
 		check_pgt_cache();
@@ -84,16 +63,15 @@
 
 void machine_restart(char * __unused)
 {
-#ifdef CONFIG_SH_STANDARD_BIOS
-	sh_bios_shutdown(1);
-#endif
+	/* SR.BL=1 and invoke address error to let CPU reset (manual reset) */
+	asm volatile("ldc %0, sr\n\t"
+		     "mov.l @%1, %0" : : "r" (0x10000000), "r" (0x80000001));
 }
 
 void machine_halt(void)
 {
-#ifdef CONFIG_SH_STANDARD_BIOS
-	sh_bios_shutdown(0);
-#endif
+	while (1)
+		asm volatile("sleep" : : : "memory");
 }
 
 void machine_power_off(void)
diff -u --recursive --new-file v2.4.9/linux/arch/sh/kernel/ptrace.c linux/arch/sh/kernel/ptrace.c
--- v2.4.9/linux/arch/sh/kernel/ptrace.c	Wed Jul 25 17:10:19 2001
+++ linux/arch/sh/kernel/ptrace.c	Sat Sep  8 12:29:09 2001
@@ -1,4 +1,4 @@
-/* $Id: ptrace.c,v 1.6 2000/06/08 23:44:50 gniibe Exp $
+/* $Id: ptrace.c,v 1.12 2001/07/23 00:00:56 gniibe Exp $
  *
  * linux/arch/sh/kernel/ptrace.c
  *
@@ -122,24 +122,29 @@
 {
 	ctrl_outl(nextpc1, UBC_BARA);
 	ctrl_outb(asid, UBC_BASRA);
-#if defined(CONFIG_CPU_SUBTYPE_SH7709)
-	ctrl_outl(0x0fff, UBC_BAMRA);
-#else
-	ctrl_outb(BAMR_12, UBC_BAMRA);
-#endif
-	ctrl_outw(BBR_INST | BBR_READ, UBC_BBRA);
+	if(UBC_TYPE_SH7729){
+		ctrl_outl(0x0fff, UBC_BAMRA);
+		ctrl_outw(BBR_INST | BBR_READ | BBR_CPU, UBC_BBRA);
+	}else{
+		ctrl_outb(BAMR_12, UBC_BAMRA);
+		ctrl_outw(BBR_INST | BBR_READ, UBC_BBRA);
+	}
 
 	if (nextpc2 != (unsigned long) -1) {
 		ctrl_outl(nextpc2, UBC_BARB);
 		ctrl_outb(asid, UBC_BASRB);
-#if defined(CONFIG_CPU_SUBTYPE_SH7709)
-		ctrl_outl(0x0fff, UBC_BAMRA);
-#else
-		ctrl_outb(BAMR_12, UBC_BAMRB);
-#endif
-		ctrl_outw(BBR_INST | BBR_READ, UBC_BBRB);
-	}
-	ctrl_outw(BRCR_PCBA | BRCR_PCBB, UBC_BRCR);
+		if(UBC_TYPE_SH7729){
+			ctrl_outl(0x0fff, UBC_BAMRB);
+			ctrl_outw(BBR_INST | BBR_READ | BBR_CPU, UBC_BBRB);
+		}else{
+			ctrl_outb(BAMR_12, UBC_BAMRB);
+			ctrl_outw(BBR_INST | BBR_READ, UBC_BBRB);
+		}
+	}
+	if(UBC_TYPE_SH7729)
+		ctrl_outl(BRCR_PCBA | BRCR_PCBB | BRCR_PCTE, UBC_BRCR);
+	else
+		ctrl_outw(BRCR_PCBA | BRCR_PCBB, UBC_BRCR);
 }
 
 asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
diff -u --recursive --new-file v2.4.9/linux/arch/sh/kernel/rtc-aica.c linux/arch/sh/kernel/rtc-aica.c
--- v2.4.9/linux/arch/sh/kernel/rtc-aica.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/kernel/rtc-aica.c	Sat Sep  8 12:29:09 2001
@@ -0,0 +1,70 @@
+/* arch/sh/kernel/rtc-aica.c
+ *
+ * Dreamcast AICA RTC routines.
+ *
+ * Copyright (c) 2001 M. R. Brown <mrbrown@0xd6.org>
+ *
+ * Released under the terms of the GNU GPL v2.0.
+ *
+ */
+
+#include <linux/time.h>
+
+#include <asm/io.h>
+
+/* The AICA RTC has an Epoch of 1/1/1950, so we must subtract 20 years (in
+   seconds to get the standard Unix Epoch when getting the time, and add 20
+   years when setting the time. */
+#define TWENTY_YEARS ((20 * 365LU + 5) * 86400)
+
+/* The AICA RTC is represented by a 32-bit seconds counter stored in 2 16-bit
+   registers.*/
+#define AICA_RTC_SECS_H		0xa0710000
+#define AICA_RTC_SECS_L		0xa0710004
+
+/**
+ * aica_rtc_gettimeofday - Get the time from the AICA RTC
+ * @tv: pointer to resulting timeval
+ *
+ * Grabs the current RTC seconds counter and adjusts it to the Unix Epoch.
+ */
+void aica_rtc_gettimeofday(struct timeval *tv) {
+	unsigned long val1, val2;
+
+	do {
+		val1 = ((ctrl_inl(AICA_RTC_SECS_H) & 0xffff) << 16) |
+			(ctrl_inl(AICA_RTC_SECS_L) & 0xffff);
+
+		val2 = ((ctrl_inl(AICA_RTC_SECS_H) & 0xffff) << 16) |
+			(ctrl_inl(AICA_RTC_SECS_L) & 0xffff);
+	} while (val1 != val2);
+
+	tv->tv_sec = val1 - TWENTY_YEARS;
+
+	/* Can't get microseconds with just a seconds counter. */
+	tv->tv_usec = 0;
+}
+
+/**
+ * aica_rtc_settimeofday - Set the AICA RTC to the current time
+ * @tv: contains the timeval to set
+ *
+ * Adjusts the given @tv to the AICA Epoch and sets the RTC seconds counter.
+ */
+int aica_rtc_settimeofday(const struct timeval *tv) {
+	unsigned long val1, val2;
+	unsigned long secs = tv->tv_sec + TWENTY_YEARS;
+
+	do {
+		ctrl_outl((secs & 0xffff0000) >> 16, AICA_RTC_SECS_H);
+		ctrl_outl((secs & 0xffff), AICA_RTC_SECS_L);
+
+		val1 = ((ctrl_inl(AICA_RTC_SECS_H) & 0xffff) << 16) |
+			(ctrl_inl(AICA_RTC_SECS_L) & 0xffff);
+
+		val2 = ((ctrl_inl(AICA_RTC_SECS_H) & 0xffff) << 16) |
+			(ctrl_inl(AICA_RTC_SECS_L) & 0xffff);
+	} while (val1 != val2);
+
+	return 0;
+}
diff -u --recursive --new-file v2.4.9/linux/arch/sh/kernel/setup.c linux/arch/sh/kernel/setup.c
--- v2.4.9/linux/arch/sh/kernel/setup.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/sh/kernel/setup.c	Sat Sep  8 12:29:09 2001
@@ -1,4 +1,4 @@
-/* $Id: setup.c,v 1.20 2000/03/05 02:44:41 gniibe Exp $
+/* $Id: setup.c,v 1.31 2001/08/23 16:36:40 dwmw2 Exp $
  *
  *  linux/arch/sh/kernel/setup.c
  *
@@ -38,7 +38,6 @@
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/io_generic.h>
-#include <asm/smp.h>
 #include <asm/machvec.h>
 #ifdef CONFIG_SH_EARLY_PRINTK
 #include <asm/sh_bios.h>
@@ -48,7 +47,12 @@
  * Machine setup..
  */
 
-struct sh_cpuinfo boot_cpu_data = { CPU_SH_NONE, 0, 0, 0, };
+/*
+ * Initialize loops_per_jiffy as 10000000 (1000MIPS).
+ * This value will be used at the very early stage of serial setup.
+ * The bigger value means no problem.
+ */
+struct sh_cpuinfo boot_cpu_data = { CPU_SH_NONE, 0, 10000000, };
 struct screen_info screen_info;
 unsigned char aux_device_present = 0xaa;
 
@@ -209,8 +213,7 @@
 	saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
 
 	memory_start = (unsigned long)PAGE_OFFSET+__MEMORY_START;
-	/* Default is 4Mbyte. */
-	memory_end = (unsigned long)PAGE_OFFSET+0x00400000+__MEMORY_START;
+	memory_end = memory_start + __MEMORY_SIZE;
 
 	for (;;) {
 		/*
@@ -268,7 +271,9 @@
 
 void __init setup_arch(char **cmdline_p)
 {
+#if defined(CONFIG_SH_GENERIC) || defined(CONFIG_SH_UNKNOWN)
 	extern struct sh_machine_vector mv_unknown;
+#endif
 	struct sh_machine_vector *mv = NULL;
 	char mv_name[MV_NAME_SIZE] = "";
 	unsigned long mv_io_base = 0;
@@ -356,6 +361,18 @@
 #define PFN_DOWN(x)	((x) >> PAGE_SHIFT)
 #define PFN_PHYS(x)	((x) << PAGE_SHIFT)
 
+#ifdef CONFIG_DISCONTIGMEM
+	NODE_DATA(0)->bdata = &discontig_node_bdata[0];
+	NODE_DATA(1)->bdata = &discontig_node_bdata[1];
+
+	bootmap_size = init_bootmem_node(NODE_DATA(1), 
+					 PFN_UP(__MEMORY_START_2ND),
+					 PFN_UP(__MEMORY_START_2ND),
+					 PFN_DOWN(__MEMORY_START_2ND+__MEMORY_SIZE_2ND));
+	free_bootmem_node(NODE_DATA(1), __MEMORY_START_2ND, __MEMORY_SIZE_2ND);
+	reserve_bootmem_node(NODE_DATA(1), __MEMORY_START_2ND, bootmap_size);
+#endif
+
 	/*
 	 * Find the highest page frame number we have available
 	 */
@@ -377,7 +394,7 @@
 	 * is intact) must be done via bootmem_alloc().
 	 */
 	bootmap_size = init_bootmem_node(NODE_DATA(0), start_pfn,
-					 __MEMORY_START>>PAGE_SHIFT, 
+					 __MEMORY_START>>PAGE_SHIFT,
 					 max_low_pfn);
 
 	/*
@@ -399,7 +416,8 @@
 			last_pfn = max_low_pfn;
 
 		pages = last_pfn - curr_pfn;
-		free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(pages));
+		free_bootmem_node(NODE_DATA(0), PFN_PHYS(curr_pfn),
+				  PFN_PHYS(pages));
 	}
 
 	/*
@@ -409,19 +427,19 @@
 	 * case of us accidentally initializing the bootmem allocator with
 	 * an invalid RAM area.
 	 */
-	reserve_bootmem(__MEMORY_START+PAGE_SIZE, (PFN_PHYS(start_pfn) + 
-			bootmap_size + PAGE_SIZE-1) - __MEMORY_START);
+	reserve_bootmem_node(NODE_DATA(0), __MEMORY_START+PAGE_SIZE,
+		(PFN_PHYS(start_pfn)+bootmap_size+PAGE_SIZE-1)-__MEMORY_START);
 
 	/*
 	 * reserve physical page 0 - it's a special BIOS page on many boxes,
 	 * enabling clean reboots, SMP operation, laptop functions.
 	 */
-	reserve_bootmem(__MEMORY_START, PAGE_SIZE);
+	reserve_bootmem_node(NODE_DATA(0), __MEMORY_START, PAGE_SIZE);
 
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (LOADER_TYPE && INITRD_START) {
 		if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
-			reserve_bootmem(INITRD_START+__MEMORY_START, INITRD_SIZE);
+			reserve_bootmem_node(NODE_DATA(0), INITRD_START+__MEMORY_START, INITRD_SIZE);
 			initrd_start =
 				INITRD_START ? INITRD_START + PAGE_OFFSET + __MEMORY_START : 0;
 			initrd_end = initrd_start + INITRD_SIZE;
diff -u --recursive --new-file v2.4.9/linux/arch/sh/kernel/setup_7751se.c linux/arch/sh/kernel/setup_7751se.c
--- v2.4.9/linux/arch/sh/kernel/setup_7751se.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/kernel/setup_7751se.c	Sat Sep  8 12:29:09 2001
@@ -0,0 +1,136 @@
+/* 
+ * linux/arch/sh/kernel/setup_7751se.c
+ *
+ * Copyright (C) 2000  Kazumoto Kojima
+ *
+ * Hitachi SolutionEngine Support.
+ *
+ * Modified for 7751 Solution Engine by
+ * Ian da Silva and Jeremy Siegel, 2001.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <linux/hdreg.h>
+#include <linux/ide.h>
+#include <asm/io.h>
+#include <asm/hitachi_7751se.h>
+
+/*
+ * Configure the Super I/O chip
+ */
+#if 0
+/* Leftover code from regular Solution Engine, for reference. */
+/* The SH7751 Solution Engine has a different SuperIO. */
+static void __init smsc_config(int index, int data)
+{
+	outb_p(index, INDEX_PORT);
+	outb_p(data, DATA_PORT);
+}
+
+static void __init init_smsc(void)
+{
+	outb_p(CONFIG_ENTER, CONFIG_PORT);
+	outb_p(CONFIG_ENTER, CONFIG_PORT);
+
+	/* FDC */
+	smsc_config(CURRENT_LDN_INDEX, LDN_FDC);
+	smsc_config(ACTIVATE_INDEX, 0x01);
+	smsc_config(IRQ_SELECT_INDEX, 6); /* IRQ6 */
+
+	/* IDE1 */
+	smsc_config(CURRENT_LDN_INDEX, LDN_IDE1);
+	smsc_config(ACTIVATE_INDEX, 0x01);
+	smsc_config(IRQ_SELECT_INDEX, 14); /* IRQ14 */
+
+	/* AUXIO (GPIO): to use IDE1 */
+	smsc_config(CURRENT_LDN_INDEX, LDN_AUXIO);
+	smsc_config(GPIO46_INDEX, 0x00); /* nIOROP */
+	smsc_config(GPIO47_INDEX, 0x00); /* nIOWOP */
+
+	/* COM1 */
+	smsc_config(CURRENT_LDN_INDEX, LDN_COM1);
+	smsc_config(ACTIVATE_INDEX, 0x01);
+	smsc_config(IO_BASE_HI_INDEX, 0x03);
+	smsc_config(IO_BASE_LO_INDEX, 0xf8);
+	smsc_config(IRQ_SELECT_INDEX, 4); /* IRQ4 */
+
+	/* COM2 */
+	smsc_config(CURRENT_LDN_INDEX, LDN_COM2);
+	smsc_config(ACTIVATE_INDEX, 0x01);
+	smsc_config(IO_BASE_HI_INDEX, 0x02);
+	smsc_config(IO_BASE_LO_INDEX, 0xf8);
+	smsc_config(IRQ_SELECT_INDEX, 3); /* IRQ3 */
+
+	/* RTC */
+	smsc_config(CURRENT_LDN_INDEX, LDN_RTC);
+	smsc_config(ACTIVATE_INDEX, 0x01);
+	smsc_config(IRQ_SELECT_INDEX, 8); /* IRQ8 */
+
+	/* XXX: PARPORT, KBD, and MOUSE will come here... */
+	outb_p(CONFIG_EXIT, CONFIG_PORT);
+}
+#endif
+
+/*
+ * Initialize IRQ setting
+ */
+void __init init_7751se_IRQ(void)
+{
+
+  /* Leave old Solution Engine code in for reference. */
+#if defined(CONFIG_SH_SOLUTION_ENGINE)
+	/*
+	 * Super I/O (Just mimic PC):
+	 *  1: keyboard
+	 *  3: serial 0
+	 *  4: serial 1
+	 *  5: printer
+	 *  6: floppy
+	 *  8: rtc
+	 * 12: mouse
+	 * 14: ide0
+	 */
+	make_ipr_irq(14, BCR_ILCRA, 2, 0x0f-14);
+	make_ipr_irq(12, BCR_ILCRA, 1, 0x0f-12); 
+	make_ipr_irq( 8, BCR_ILCRB, 1, 0x0f- 8); 
+	make_ipr_irq( 6, BCR_ILCRC, 3, 0x0f- 6);
+	make_ipr_irq( 5, BCR_ILCRC, 2, 0x0f- 5);
+	make_ipr_irq( 4, BCR_ILCRC, 1, 0x0f- 4);
+	make_ipr_irq( 3, BCR_ILCRC, 0, 0x0f- 3);
+	make_ipr_irq( 1, BCR_ILCRD, 3, 0x0f- 1);
+
+	make_ipr_irq(10, BCR_ILCRD, 1, 0x0f-10); /* LAN */
+
+	make_ipr_irq( 0, BCR_ILCRE, 3, 0x0f- 0); /* PCIRQ3 */
+	make_ipr_irq(11, BCR_ILCRE, 2, 0x0f-11); /* PCIRQ2 */
+	make_ipr_irq( 9, BCR_ILCRE, 1, 0x0f- 9); /* PCIRQ1 */
+	make_ipr_irq( 7, BCR_ILCRE, 0, 0x0f- 7); /* PCIRQ0 */
+
+	/* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */
+	/* NOTE: #2 and #13 are not used on PC */
+	make_ipr_irq(13, BCR_ILCRG, 1, 0x0f-13); /* SLOTIRQ2 */
+	make_ipr_irq( 2, BCR_ILCRG, 0, 0x0f- 2); /* SLOTIRQ1 */
+
+#elif defined(CONFIG_SH_7751_SOLUTION_ENGINE)
+
+	make_ipr_irq(13, BCR_ILCRD, 3, 2);
+
+	/* Add additional calls to make_ipr_irq() as drivers are added
+	 * and tested.
+	 */
+#endif
+
+}
+
+
+/*
+ * Initialize the board
+ */
+void __init setup_7751se(void)
+{
+	/* Call init_smsc() replacement to set up SuperIO. */
+	/* XXX: RTC setting comes here */
+}
diff -u --recursive --new-file v2.4.9/linux/arch/sh/kernel/setup_adx.c linux/arch/sh/kernel/setup_adx.c
--- v2.4.9/linux/arch/sh/kernel/setup_adx.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/kernel/setup_adx.c	Sat Sep  8 12:29:09 2001
@@ -0,0 +1,40 @@
+/* 
+ * linux/arch/sh/kernel/setup_adx.c
+ *
+ * Copyright (C) 2001 A&D Co., Ltd.
+ *
+ * I/O routine and setup routines for A&D ADX Board
+ *
+ * This file 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.
+ *
+ */
+
+#include <asm/io.h>
+#include <asm/machvec.h>
+#include <asm/irq.h>
+#include <linux/module.h>
+
+void setup_adx(void)
+{
+	/* nothing to do just yet */
+/*	printk("setup_adx()\n");*/
+}
+
+void init_adx_IRQ(void)
+{
+	int i;
+
+/*	printk("init_adx_IRQ()\n");*/
+	/* setup irq_mask_register */
+	irq_mask_register = (unsigned short *)0xa6000008;
+
+	/* cover all external interrupt area by maskreg_irq_type
+	 * (Actually, irq15 doesn't exist)
+	 */
+	for (i = 0; i < 16; i++) {
+		make_maskreg_irq(i);
+		disable_irq(i);
+	}
+}
diff -u --recursive --new-file v2.4.9/linux/arch/sh/kernel/setup_bigsur.c linux/arch/sh/kernel/setup_bigsur.c
--- v2.4.9/linux/arch/sh/kernel/setup_bigsur.c	Tue Jul  3 17:08:19 2001
+++ linux/arch/sh/kernel/setup_bigsur.c	Sat Sep  8 12:29:09 2001
@@ -181,10 +181,12 @@
 static void end_bigsur_irq(unsigned int irq)
 {
    	DPRINTK("end_bigsur_irq IRQ %d\n", irq);
-	if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH)	
-		enable_bigsur_l1irq(irq);
-	else
-		enable_bigsur_l2irq(irq);
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
+		if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH)	
+			enable_bigsur_l1irq(irq);
+		else
+			enable_bigsur_l2irq(irq);
+	}
 }
 
 static unsigned int startup_bigsur_irq(unsigned int irq)
diff -u --recursive --new-file v2.4.9/linux/arch/sh/kernel/setup_cqreek.c linux/arch/sh/kernel/setup_cqreek.c
--- v2.4.9/linux/arch/sh/kernel/setup_cqreek.c	Wed Apr 11 21:24:52 2001
+++ linux/arch/sh/kernel/setup_cqreek.c	Sat Sep  8 12:29:09 2001
@@ -1,4 +1,4 @@
-/* $Id: setup_cqreek.c,v 1.6 2001/02/14 09:36:42 gniibe Exp $
+/* $Id: setup_cqreek.c,v 1.9 2001/07/30 12:43:28 gniibe Exp $
  *
  * arch/sh/kernel/setup_cqreek.c
  *
@@ -85,15 +85,16 @@
 	unsigned short stat_port = cqreek_irq_data[irq].stat_port;
 	unsigned short bit = cqreek_irq_data[irq].bit;
 
-	inw(stat_port);
 	disable_cqreek_irq(irq);
 	/* Clear IRQ (it might be edge IRQ) */
+	inw(stat_port);
 	outw_p(bit, stat_port);
 }
 
 static void end_cqreek_irq(unsigned int irq)
 {
-	enable_cqreek_irq(irq);
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_cqreek_irq(irq);
 }
 
 static unsigned int startup_cqreek_irq(unsigned int irq)
@@ -156,16 +157,9 @@
  */
 void __init setup_cqreek(void)
 {
-	extern void disable_hlt(void);
 	int i;
 /* udelay is not available at setup time yet... */
 #define DELAY() do {for (i=0; i<10000; i++) ctrl_inw(0xa0000000);} while(0)
-
-	/*
-	 * XXX: I don't know the reason, but it becomes so fragile with
-	 * "sleep", so we need to stop sleeping.
-	 */
-	disable_hlt();
 
 	if ((inw (BRIDGE_FEATURE) & 1)) { /* We have IDE interface */
 		outw_p(0, BRIDGE_IDE_INTR_LVL);
diff -u --recursive --new-file v2.4.9/linux/arch/sh/kernel/setup_dc.c linux/arch/sh/kernel/setup_dc.c
--- v2.4.9/linux/arch/sh/kernel/setup_dc.c	Tue Jul  3 17:08:19 2001
+++ linux/arch/sh/kernel/setup_dc.c	Sat Sep  8 12:29:09 2001
@@ -8,8 +8,8 @@
  *
  * Released under the terms of the GNU GPL v2.0.
  * 
- * This file originally bore the message:
- *	$Id: setup_dc.c,v 1.5 2001/05/24 05:09:16 mrbrown Exp $
+ * This file originally bore the message (with enclosed-$):
+ *	Id: setup_dc.c,v 1.5 2001/05/24 05:09:16 mrbrown Exp
  *	SEGA Dreamcast support
  */
 
@@ -70,21 +70,29 @@
 /* Disable the hardware event by masking its bit in its EMR */
 static inline void disable_systemasic_irq(unsigned int irq)
 {
+	unsigned long flags;
 	__u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2);
 	__u32 mask;
+
+	save_and_cli(flags);
 	mask = inl(emr);
 	mask &= ~(1 << EVENT_BIT(irq));
 	outl(mask, emr);
+	restore_flags(flags);
 }
 
 /* Enable the hardware event by setting its bit in its EMR */
 static inline void enable_systemasic_irq(unsigned int irq)
 {
+	unsigned long flags;
 	__u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2);
 	__u32 mask;
+
+	save_and_cli(flags);
 	mask = inl(emr);
 	mask |= (1 << EVENT_BIT(irq));
 	outl(mask, emr);
+	restore_flags(flags);
 }
 
 /* Acknowledge a hardware event by writing its bit back to its ESR */
@@ -98,7 +106,8 @@
 /* After a IRQ has been ack'd and responded to, it needs to be renabled */
 static void end_systemasic_irq(unsigned int irq)
 {
-	enable_systemasic_irq(irq);
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_systemasic_irq(irq);
 }
 
 static unsigned int startup_systemasic_irq(unsigned int irq)
diff -u --recursive --new-file v2.4.9/linux/arch/sh/kernel/setup_ec3104.c linux/arch/sh/kernel/setup_ec3104.c
--- v2.4.9/linux/arch/sh/kernel/setup_ec3104.c	Sun May 20 12:11:38 2001
+++ linux/arch/sh/kernel/setup_ec3104.c	Sat Sep  8 12:29:09 2001
@@ -167,7 +167,8 @@
 
 static void end_ec3104_irq(unsigned int irq)
 {
-	unmask_ec3104_irq(irq);
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		unmask_ec3104_irq(irq);
 }
 
 static unsigned int startup_ec3104_irq(unsigned int irq)
diff -u --recursive --new-file v2.4.9/linux/arch/sh/kernel/setup_hd64461.c linux/arch/sh/kernel/setup_hd64461.c
--- v2.4.9/linux/arch/sh/kernel/setup_hd64461.c	Wed Apr 11 21:24:52 2001
+++ linux/arch/sh/kernel/setup_hd64461.c	Sat Sep  8 12:29:09 2001
@@ -1,5 +1,5 @@
 /*
- *	$Id: setup_hd64461.c,v 1.1 2000/06/10 21:45:18 yaegashi Exp $
+ *	$Id: setup_hd64461.c,v 1.9 2001/07/15 23:26:56 gniibe Exp $
  *	Copyright (C) 2000 YAEGASHI Takeshi
  *	Hitachi HD64461 companion chip support
  */
@@ -57,7 +57,8 @@
 
 static void end_hd64461_irq(unsigned int irq)
 {
-	enable_hd64461_irq(irq);
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_hd64461_irq(irq);
 }
 
 
diff -u --recursive --new-file v2.4.9/linux/arch/sh/kernel/setup_hd64465.c linux/arch/sh/kernel/setup_hd64465.c
--- v2.4.9/linux/arch/sh/kernel/setup_hd64465.c	Wed Apr 11 21:24:52 2001
+++ linux/arch/sh/kernel/setup_hd64465.c	Sat Sep  8 12:29:09 2001
@@ -1,5 +1,5 @@
 /*
- * $Id: setup_hd64465.c,v 1.3 2001/02/07 17:52:53 stuart_menefy Exp $
+ * $Id: setup_hd64465.c,v 1.4 2001/07/15 23:26:56 gniibe Exp $
  *
  * Setup and IRQ handling code for the HD64465 companion chip.
  * by Greg Banks <gbanks@pocketpenguins.com>
@@ -70,7 +70,8 @@
 
 static void end_hd64465_irq(unsigned int irq)
 {
-	enable_hd64465_irq(irq);
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_hd64465_irq(irq);
 }
 
 
diff -u --recursive --new-file v2.4.9/linux/arch/sh/kernel/sh_ksyms.c linux/arch/sh/kernel/sh_ksyms.c
--- v2.4.9/linux/arch/sh/kernel/sh_ksyms.c	Tue Jul  3 17:08:19 2001
+++ linux/arch/sh/kernel/sh_ksyms.c	Sat Sep  8 12:29:09 2001
@@ -9,6 +9,7 @@
 #include <linux/interrupt.h>
 #include <linux/smp_lock.h>
 #include <linux/vmalloc.h>
+#include <linux/pci.h>
 
 #include <asm/semaphore.h>
 #include <asm/processor.h>
@@ -18,7 +19,6 @@
 #include <asm/hardirq.h>
 #include <asm/delay.h>
 #include <asm/pgalloc.h>
-#include <asm/pci.h>
 #include <linux/irq.h>
 
 extern void dump_thread(struct pt_regs *, struct user *);
diff -u --recursive --new-file v2.4.9/linux/arch/sh/kernel/sys_sh.c linux/arch/sh/kernel/sys_sh.c
--- v2.4.9/linux/arch/sh/kernel/sys_sh.c	Mon Mar 19 12:35:10 2001
+++ linux/arch/sh/kernel/sys_sh.c	Sat Sep  8 12:29:09 2001
@@ -43,6 +43,45 @@
 	return error;
 }
 
+#if defined(__SH4__)
+/*
+ * To avoid cache alias, we map the shard page with same color.
+ */
+#define COLOUR_ALIGN(addr)	(((addr)+SHMLBA-1)&~(SHMLBA-1))
+
+unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
+	unsigned long len, unsigned long pgoff, unsigned long flags)
+{
+	struct vm_area_struct *vma;
+
+	if (flags & MAP_FIXED) {
+		/* We do not accept a shared mapping if it would violate
+		 * cache aliasing constraints.
+		 */
+		if ((flags & MAP_SHARED) && (addr & (SHMLBA - 1)))
+			return -EINVAL;
+		return addr;
+	}
+
+	if (len > TASK_SIZE)
+		return -ENOMEM;
+	if (!addr)
+		addr = TASK_UNMAPPED_BASE;
+
+	addr = COLOUR_ALIGN(addr);
+
+	for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) {
+		/* At this point:  (!vma || addr < vma->vm_end). */
+		if (TASK_SIZE - len < addr)
+			return -ENOMEM;
+		if (!vma || addr + len <= vma->vm_start)
+			return addr;
+		addr = vma->vm_end;
+		addr = COLOUR_ALIGN(addr);
+	}
+}
+#endif
+
 static inline long
 do_mmap2(unsigned long addr, unsigned long len, unsigned long prot, 
 	 unsigned long flags, int fd, unsigned long pgoff)
diff -u --recursive --new-file v2.4.9/linux/arch/sh/kernel/time.c linux/arch/sh/kernel/time.c
--- v2.4.9/linux/arch/sh/kernel/time.c	Tue Jul  3 17:08:19 2001
+++ linux/arch/sh/kernel/time.c	Sat Sep  8 12:29:09 2001
@@ -1,4 +1,4 @@
-/* $Id: time.c,v 1.20 2000/02/28 12:42:51 gniibe Exp $
+/* $Id: time.c,v 1.30 2001/09/01 14:34:31 mrbrown Exp $
  *
  *  linux/arch/sh/kernel/time.c
  *
@@ -183,10 +183,9 @@
 static inline void do_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	do_timer(regs);
-#if 0
+
 	if (!user_mode(regs))
 		sh_do_profile(regs->pc);
-#endif
 
 #ifdef CONFIG_HEARTBEAT
 	if (sh_mv.mv_heartbeat != NULL) 
@@ -360,17 +359,11 @@
 #endif
 #endif
 
-	if (MACH_DREAMCAST)
-		xtime.tv_sec = xtime.tv_usec = 0;
-	else
-		rtc_gettimeofday(&xtime);
+	rtc_gettimeofday(&xtime);
 
 	setup_irq(TIMER_IRQ, &irq0);
 
-	if (MACH_DREAMCAST)
-		timer_freq = 50*1000*1000/4;
-	else
-		timer_freq = get_timer_frequency();
+	timer_freq = get_timer_frequency();
 
 	module_clock = timer_freq * 4;
 
@@ -391,10 +384,9 @@
 	}
 #elif defined(__SH4__)
 	{
+#ifdef CONFIG_CPU_SUBTYPE_ST40STB1
 		unsigned long pvr;
-		frqcr = ctrl_inw(FRQCR);
 
-#ifdef CONFIG_CPU_SUBTYPE_ST40STB1
 		/* This should probably be moved into the SH3 probing code, and then use the processor
 		 * structure to determine which CPU we are running on.
 		 */
@@ -435,6 +427,8 @@
 		} else
 #endif
 		{
+			frqcr = ctrl_inw(FRQCR);
+
 			ifc  = ifc_table[(frqcr>> 6) & 0x0007];
 			bfc  = bfc_table[(frqcr>> 3) & 0x0007];
 			pfc = pfc_table[frqcr & 0x0007];
diff -u --recursive --new-file v2.4.9/linux/arch/sh/kernel/traps.c linux/arch/sh/kernel/traps.c
--- v2.4.9/linux/arch/sh/kernel/traps.c	Mon Jan 29 16:19:41 2001
+++ linux/arch/sh/kernel/traps.c	Sat Sep  8 12:29:09 2001
@@ -1,4 +1,4 @@
-/* $Id: traps.c,v 1.5 2000/02/27 08:27:55 gniibe Exp $
+/* $Id: traps.c,v 1.14 2001/07/24 08:07:10 gniibe Exp $
  *
  *  linux/arch/sh/traps.c
  *
@@ -314,10 +314,10 @@
 
 	/* shout about the first ten userspace fixups */
 	if (user_mode(regs) && handle_unaligned_notify_count>0) {
-	    handle_unaligned_notify_count--;
+		handle_unaligned_notify_count--;
 
-	    printk("Fixing up unaligned userspace access in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
-		   current->comm,current->pid,(u16*)regs->pc,instruction);
+		printk("Fixing up unaligned userspace access in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
+		       current->comm,current->pid,(u16*)regs->pc,instruction);
 	}
 
 	ret = -EFAULT;
@@ -502,7 +502,7 @@
 	die_if_kernel("exception", &regs, ex);
 }
 
-#if defined(CONFIG_DEBUG_KERNEL_WITH_GDB_STUB) || defined(CONFIG_SH_STANDARD_BIOS)
+#if defined(CONFIG_SH_STANDARD_BIOS)
 void *gdb_vbr_vector;
 #endif
 
@@ -514,7 +514,7 @@
 	exception_handling_table[12] = (void *)do_reserved_inst;
 	exception_handling_table[13] = (void *)do_illegal_slot_inst;
 
-#if defined(CONFIG_DEBUG_KERNEL_WITH_GDB_STUB) || defined(CONFIG_SH_STANDARD_BIOS)
+#if defined(CONFIG_SH_STANDARD_BIOS)
     	/*
 	 * Read the old value of the VBR register to initialise
 	 * the vector through which debug and BIOS traps are
diff -u --recursive --new-file v2.4.9/linux/arch/sh/lib/Makefile linux/arch/sh/lib/Makefile
--- v2.4.9/linux/arch/sh/lib/Makefile	Fri Dec 29 14:07:20 2000
+++ linux/arch/sh/lib/Makefile	Sat Sep  8 12:29:09 2001
@@ -4,7 +4,7 @@
 
 L_TARGET = lib.a
 obj-y  = delay.o memcpy.o memset.o memmove.o memchr.o old-checksum.o \
-	 checksum.o strcasecmp.o
+	 checksum.o strcasecmp.o strlen.o
 
 USE_STANDARD_AS_RULE := true
 
diff -u --recursive --new-file v2.4.9/linux/arch/sh/lib/checksum.S linux/arch/sh/lib/checksum.S
--- v2.4.9/linux/arch/sh/lib/checksum.S	Sun Jan 28 18:56:00 2001
+++ linux/arch/sh/lib/checksum.S	Sat Sep  8 12:29:09 2001
@@ -1,4 +1,4 @@
-/* $Id: checksum.S,v 1.4 2000/05/14 08:41:26 gniibe Exp $
+/* $Id: checksum.S,v 1.10 2001/07/06 13:11:32 gniibe Exp $
  *
  * INET		An implementation of the TCP/IP protocol suite for the LINUX
  *		operating system.  INET is implemented using the  BSD Socket
@@ -54,13 +54,14 @@
 	tst	#2, r0		! Check alignment.
 	bt	2f		! Jump if alignment is ok.
 	!
-	add	#-2, r5	! Alignment uses up two bytes.
+	add	#-2, r5		! Alignment uses up two bytes.
 	cmp/pz	r5		!
 	bt/s	1f		! Jump if we had at least two bytes.
 	 clrt
 	bra	6f
 	 add	#2, r5		! r5 was < 2.  Deal with it.
 1:
+	mov	r5, r1		! Save new len for later use.
 	mov.w	@r4+, r0
 	extu.w	r0, r0
 	addc	r0, r6
@@ -90,7 +91,7 @@
 	addc	r3, r6
 	addc	r0, r6
 	addc	r2, r6
-	movt	r0	
+	movt	r0
 	dt	r5
 	bf/s	3b
 	 cmp/eq	#1, r0
@@ -185,48 +186,48 @@
 	mov.l	r5,@-r15
 	mov.l	r6,@-r15
 
-	mov	#3, r0			! Check src and dest are equally aligned
-	mov	r4, r1
-	and	r0, r1
-	and	r5, r0
-	cmp/eq	r1, r0
-	bf	3f			! Different alignments, use slow version
-	tst	#1,r0			! Check dest word aligned
-	bf	3f			! If not, do it the slow way
+	mov	#3,r0		! Check src and dest are equally aligned
+	mov	r4,r1
+	and	r0,r1
+	and	r5,r0
+	cmp/eq	r1,r0
+	bf	3f		! Different alignments, use slow version
+	tst	#1,r0		! Check dest word aligned
+	bf	3f		! If not, do it the slow way
 
 	mov	#2,r0
-	tst	r0,r5			! Check dest alignment. 
-	bt	2f			! Jump if alignment is ok.
-	add	#-2,r6			! Alignment uses up two bytes.
-	cmp/pz	r6			! Jump if we had at least two bytes.
+	tst	r0,r5		! Check dest alignment. 
+	bt	2f		! Jump if alignment is ok.
+	add	#-2,r6		! Alignment uses up two bytes.
+	cmp/pz	r6		! Jump if we had at least two bytes.
 	bt/s	1f
 	 clrt
 	bra	4f
-	 add	#2,r6			! r6 was < 2.	Deal with it.
+	 add	#2,r6		! r6 was < 2.	Deal with it.
 
-3:	! Handle different src and dest alinments.
+3:	! Handle different src and dest alignments.
 	! This is not common, so simple byte by byte copy will do.
-	mov	r6, r2
+	mov	r6,r2
 	shlr	r6
-	tst	r6, r6
+	tst	r6,r6
 	bt	4f
 	clrt
-5:	
-SRC(	mov.b	@r4+,r0 )
-DST(	mov.b	r0,@r5	)
-	add	#1, r5
-SRC(	mov.b	@r4+,r1	)
-DST(	mov.b	r1,@r5	)
-	add	#1,r5
-
-	extu.b	r0,r0
+	.align	2
+5:
+SRC(	mov.b	@r4+,r1 	)
+SRC(	mov.b	@r4+,r0		)
 	extu.b	r1,r1
+DST(	mov.b	r1,@r5		)
+DST(	mov.b	r0,@(1,r5)	)
+	extu.b	r0,r0
+	add	#2,r5
+
 #ifdef	__LITTLE_ENDIAN__
-	shll8	r1
-#else
 	shll8	r0
+#else
+	shll8	r1
 #endif
-	or	r1,r0	
+	or	r1,r0
 
 	addc	r0,r7
 	movt	r0
@@ -238,16 +239,16 @@
 
 	mov	r2, r0
 	tst	#1, r0
-	bt	7f	
+	bt	7f
 	bra	5f
 	 clrt
 
 	! src and dest equally aligned, but to a two byte boundary.
 	! Handle first two bytes as a special case
-	.align	5
+	.align	2
 1:	
-SRC(	mov.w	@r4+,r0	)
-DST(	mov.w	r0,@r5	)
+SRC(	mov.w	@r4+,r0		)
+DST(	mov.w	r0,@r5		)
 	add	#2,r5
 	extu.w	r0,r0
 	addc	r0,r7
@@ -260,42 +261,36 @@
 	tst	r6,r6
 	bt/s	2f
 	 clrt
+	.align	2
 1:	
-SRC(	mov.l	@r4+,r0	)
-SRC(	mov.l	@r4+,r1	)
+SRC(	mov.l	@r4+,r0		)
+SRC(	mov.l	@r4+,r1		)
 	addc	r0,r7
-DST(	mov.l	r0,@r5	)
-	add	#4,r5
+DST(	mov.l	r0,@r5		)
+DST(	mov.l	r1,@(4,r5)	)
 	addc	r1,r7
-DST(	mov.l	r1,@r5	)
-	add	#4,r5
 
-SRC(	mov.l	@r4+,r0	)
-SRC(	mov.l	@r4+,r1	)
+SRC(	mov.l	@r4+,r0		)
+SRC(	mov.l	@r4+,r1		)
 	addc	r0,r7
-DST(	mov.l	r0,@r5	)
-	add	#4,r5
+DST(	mov.l	r0,@(8,r5)	)
+DST(	mov.l	r1,@(12,r5)	)
 	addc	r1,r7
-DST(	mov.l	r1,@r5	)
-	add	#4,r5
 
 SRC(	mov.l	@r4+,r0 	)
-SRC(	mov.l	@r4+,r1	)
+SRC(	mov.l	@r4+,r1		)
 	addc	r0,r7
-DST(	mov.l	r0,@r5	)
-	add	#4,r5
+DST(	mov.l	r0,@(16,r5)	)
+DST(	mov.l	r1,@(20,r5)	)
 	addc	r1,r7
-DST(	mov.l	r1,@r5	)
-	add	#4,r5
 
-SRC(	mov.l	@r4+,r0	)
-SRC(	mov.l	@r4+,r1	)
+SRC(	mov.l	@r4+,r0		)
+SRC(	mov.l	@r4+,r1		)
 	addc	r0,r7
-DST(	mov.l	r0,@r5	)
-	add	#4,r5
+DST(	mov.l	r0,@(24,r5)	)
+DST(	mov.l	r1,@(28,r5)	)
 	addc	r1,r7
-DST(	mov.l	r1,@r5	)
-	add	#4,r5
+	add	#32,r5
 	movt	r0
 	dt	r6
 	bf/s	1b
diff -u --recursive --new-file v2.4.9/linux/arch/sh/lib/strlen.S linux/arch/sh/lib/strlen.S
--- v2.4.9/linux/arch/sh/lib/strlen.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/lib/strlen.S	Sat Sep  8 12:29:09 2001
@@ -0,0 +1,70 @@
+/* $Id: strlen.S,v 1.2 2001/06/29 14:07:15 gniibe Exp $
+ *
+ * "strlen" implementation of SuperH
+ *
+ * Copyright (C) 1999  Kaz Kojima
+ *
+ */
+
+/* size_t strlen (const char *s)  */
+
+#include <linux/linkage.h>
+ENTRY(strlen)
+	mov	r4,r0
+	and	#3,r0
+	tst	r0,r0
+	bt/s	1f
+	 mov	#0,r2
+
+	add	#-1,r0
+	shll2	r0
+	shll	r0
+	braf	r0
+	 nop
+
+	mov.b	@r4+,r1
+	tst	r1,r1
+	bt	8f
+	add	#1,r2
+
+	mov.b	@r4+,r1
+	tst	r1,r1
+	bt	8f
+	add	#1,r2
+
+	mov.b	@r4+,r1
+	tst	r1,r1
+	bt	8f
+	add	#1,r2	
+
+1:
+	mov	#0,r3
+2:
+	mov.l	@r4+,r1
+	cmp/str	r3,r1
+	bf/s	2b
+	 add	#4,r2
+
+	add	#-4,r2
+#ifndef __LITTLE_ENDIAN__
+	swap.b	r1,r1
+	swap.w	r1,r1
+	swap.b	r1,r1
+#endif
+	extu.b	r1,r0
+	tst	r0,r0
+	bt/s	8f
+	 shlr8	r1
+	add	#1,r2
+	extu.b	r1,r0
+	tst	r0,r0
+	bt/s	8f
+	 shlr8	r1
+	add	#1,r2
+	extu.b	r1,r0
+	tst	r0,r0
+	bt	8f
+	add	#1,r2
+8:
+	rts
+	 mov	r2,r0
diff -u --recursive --new-file v2.4.9/linux/arch/sh/mm/Makefile linux/arch/sh/mm/Makefile
--- v2.4.9/linux/arch/sh/mm/Makefile	Fri Dec 29 14:07:20 2000
+++ linux/arch/sh/mm/Makefile	Sat Sep  8 12:29:09 2001
@@ -8,6 +8,11 @@
 # Note 2! The CFLAGS definition is now in the main makefile...
 
 O_TARGET := mm.o
-obj-y	 := init.o fault.o extable.o cache.o # ioremap.o 
+obj-y	 := init.o fault.o extable.o clear_page.o copy_page.o
+
+obj-$(CONFIG_CPU_SH3) += cache-sh3.o
+obj-$(CONFIG_CPU_SH4) += cache-sh4.o __clear_user_page-sh4.o __copy_user_page-sh4.o ioremap.o
+
+USE_STANDARD_AS_RULE := true
 
 include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.9/linux/arch/sh/mm/__clear_user_page-sh4.S linux/arch/sh/mm/__clear_user_page-sh4.S
--- v2.4.9/linux/arch/sh/mm/__clear_user_page-sh4.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/mm/__clear_user_page-sh4.S	Sat Sep  8 12:29:09 2001
@@ -0,0 +1,49 @@
+/* $Id$
+ *
+ * __clear_user_page implementation of SuperH
+ *
+ * Copyright (C) 2001  Niibe Yutaka & Kaz Kojima
+ *
+ */
+
+/*
+ * __clear_user_page
+ * @to: P1 address (with same color)
+ * @orig_to: P1 address
+ *
+ * void __clear_user_page(void *to, void *orig_to)
+ */
+
+/*
+ * r0 --- scratch 
+ * r4 --- to
+ * r5 --- orig_to
+ * r6 --- to + 4096
+ */
+#include <linux/linkage.h>
+ENTRY(__clear_user_page)
+	mov	r4,r6
+	mov.w	.L4096,r0
+	add	r0,r6
+	mov	#0,r0
+	!
+1:	ocbi	@r5
+	add	#32,r5
+	movca.l	r0,@r4
+	mov	r4,r1
+	add	#32,r4
+	mov.l	r0,@-r4
+	mov.l	r0,@-r4
+	mov.l	r0,@-r4
+	mov.l	r0,@-r4
+	mov.l	r0,@-r4
+	mov.l	r0,@-r4
+	mov.l	r0,@-r4
+	add	#28,r4
+	cmp/eq	r6,r4
+	bf/s	1b
+	 ocbwb	@r1
+	!
+	rts
+	 nop
+.L4096:	.word	4096
diff -u --recursive --new-file v2.4.9/linux/arch/sh/mm/__copy_user_page-sh4.S linux/arch/sh/mm/__copy_user_page-sh4.S
--- v2.4.9/linux/arch/sh/mm/__copy_user_page-sh4.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/mm/__copy_user_page-sh4.S	Sat Sep  8 12:29:09 2001
@@ -0,0 +1,69 @@
+/* $Id: __copy_user_page-sh4.S,v 1.1 2001/07/23 09:02:17 gniibe Exp $
+ *
+ * __copy_user_page implementation of SuperH
+ *
+ * Copyright (C) 2001  Niibe Yutaka & Kaz Kojima
+ *
+ */
+
+/*
+ * __copy_user_page
+ * @to: P1 address (with same color)
+ * @from: P1 address
+ * @orig_to: P1 address
+ *
+ * void __copy_user_page(void *to, void *from, void *orig_to)
+ */
+
+/*
+ * r0, r1, r2, r3, r4, r5, r6, r7 --- scratch 
+ * r8 --- from + 4096
+ * r9 --- orig_to
+ * r10 --- to
+ * r11 --- from
+ */
+#include <linux/linkage.h>
+ENTRY(__copy_user_page)
+	mov.l	r8,@-r15
+	mov.l	r9,@-r15
+	mov.l	r10,@-r15
+	mov.l	r11,@-r15
+	mov	r4,r10
+	mov	r5,r11
+	mov	r6,r9
+	mov	r5,r8
+	mov.w	.L4096,r0
+	add	r0,r8
+	!
+1:	ocbi	@r9
+	add	#32,r9
+	mov.l	@r11+,r0
+	mov.l	@r11+,r1
+	mov.l	@r11+,r2
+	mov.l	@r11+,r3
+	mov.l	@r11+,r4
+	mov.l	@r11+,r5
+	mov.l	@r11+,r6
+	mov.l	@r11+,r7
+	movca.l	r0,@r10
+	mov	r10,r0
+	add	#32,r10
+	mov.l	r7,@-r10
+	mov.l	r6,@-r10
+	mov.l	r5,@-r10
+	mov.l	r4,@-r10
+	mov.l	r3,@-r10
+	mov.l	r2,@-r10
+	mov.l	r1,@-r10
+	ocbwb	@r0
+	cmp/eq	r11,r8
+	bf/s	1b
+	 add	#28,r10
+	!
+	mov.l	@r15+,r11
+	mov.l	@r15+,r10
+	mov.l	@r15+,r9
+	mov.l	@r15+,r8
+	rts
+	 nop
+.L4096:	.word	4096
diff -u --recursive --new-file v2.4.9/linux/arch/sh/mm/cache-sh3.c linux/arch/sh/mm/cache-sh3.c
--- v2.4.9/linux/arch/sh/mm/cache-sh3.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/mm/cache-sh3.c	Sat Sep  8 12:29:09 2001
@@ -0,0 +1,219 @@
+/* $Id: cache-sh3.c,v 1.5 2001/08/24 15:31:41 dwmw2 Exp $
+ *
+ *  linux/arch/sh/mm/cache-sh3.c
+ *
+ * Copyright (C) 1999, 2000  Niibe Yutaka
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/threads.h>
+#include <asm/addrspace.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/cache.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/pgalloc.h>
+#include <asm/mmu_context.h>
+
+#define CCR		0xffffffec	/* Address of Cache Control Register */
+#define CCR_CACHE_VAL	0x00000005	/* 8k-byte cache, P1-wb, enable */
+#define CCR_CACHE_INIT	0x0000000d	/* 8k-byte cache, CF, P1-wb, enable */
+#define CCR_CACHE_ENABLE	 1
+
+#define CACHE_OC_ADDRESS_ARRAY 0xf0000000
+#define CACHE_VALID	  1
+#define CACHE_UPDATED	  2
+#define CACHE_PHYSADDR_MASK 0x1ffffc00
+
+/* 7709A/7729 has 16K cache (256-entry), while 7702 has only 2K(direct)
+   7702 is not supported (yet) */
+struct _cache_system_info {
+	int way_shift;
+	int entry_mask;
+	int num_entries;
+};
+
+/* Data at BSS is cleared after setting this variable.
+   So, we Should not placed this variable at BSS section.
+   Initialize this, it is placed at data section. */
+static struct _cache_system_info cache_system_info = {0,};
+
+#define CACHE_OC_WAY_SHIFT	(cache_system_info.way_shift)
+#define CACHE_OC_ENTRY_SHIFT    4
+#define CACHE_OC_ENTRY_MASK	(cache_system_info.entry_mask)
+#define CACHE_OC_NUM_ENTRIES	(cache_system_info.num_entries)
+#define CACHE_OC_NUM_WAYS	4
+#define CACHE_OC_ASSOC_BIT    (1<<3)
+
+
+/*
+ * Write back all the cache.
+ *
+ * For SH-4, we only need to flush (write back) Operand Cache,
+ * as Instruction Cache doesn't have "updated" data.
+ *
+ * Assumes that this is called in interrupt disabled context, and P2.
+ * Shuld be INLINE function.
+ */
+static inline void cache_wback_all(void)
+{
+	unsigned long addr, data, i, j;
+
+	for (i=0; i<CACHE_OC_NUM_ENTRIES; i++) {
+		for (j=0; j<CACHE_OC_NUM_WAYS; j++) {
+			addr = CACHE_OC_ADDRESS_ARRAY|(j<<CACHE_OC_WAY_SHIFT)|
+				(i<<CACHE_OC_ENTRY_SHIFT);
+			data = ctrl_inl(addr);
+			if ((data & (CACHE_UPDATED|CACHE_VALID))
+			    == (CACHE_UPDATED|CACHE_VALID))
+				ctrl_outl(data & ~CACHE_UPDATED, addr);
+		}
+	}
+}
+
+static void __init
+detect_cpu_and_cache_system(void)
+{
+	unsigned long addr0, addr1, data0, data1, data2, data3;
+
+	jump_to_P2();
+	/*
+	 * Check if the entry shadows or not.
+	 * When shadowed, it's 128-entry system.
+	 * Otherwise, it's 256-entry system.
+	 */
+	addr0 = CACHE_OC_ADDRESS_ARRAY + (3 << 12);
+	addr1 = CACHE_OC_ADDRESS_ARRAY + (1 << 12);
+
+	/* First, write back & invalidate */
+	data0  = ctrl_inl(addr0);
+	ctrl_outl(data0&~(CACHE_VALID|CACHE_UPDATED), addr0);
+	data1  = ctrl_inl(addr1);
+	ctrl_outl(data1&~(CACHE_VALID|CACHE_UPDATED), addr1);
+
+	/* Next, check if there's shadow or not */
+	data0 = ctrl_inl(addr0);
+	data0 ^= CACHE_VALID;
+	ctrl_outl(data0, addr0);
+	data1 = ctrl_inl(addr1);
+	data2 = data1 ^ CACHE_VALID;
+	ctrl_outl(data2, addr1);
+	data3 = ctrl_inl(addr0);
+
+	/* Lastly, invaliate them. */
+	ctrl_outl(data0&~CACHE_VALID, addr0);
+	ctrl_outl(data2&~CACHE_VALID, addr1);
+	back_to_P1();
+
+	if (data0 == data1 && data2 == data3) {	/* Shadow */
+		cache_system_info.way_shift = 11;
+		cache_system_info.entry_mask = 0x7f0;
+		cache_system_info.num_entries = 128;
+		cpu_data->type = CPU_SH7708;
+	} else {				/* 7709A or 7729  */
+		cache_system_info.way_shift = 12;
+		cache_system_info.entry_mask = 0xff0;
+		cache_system_info.num_entries = 256;
+		cpu_data->type = CPU_SH7729;
+	}
+}
+
+void __init cache_init(void)
+{
+	unsigned long ccr;
+
+	detect_cpu_and_cache_system();
+
+	jump_to_P2();
+	ccr = ctrl_inl(CCR);
+	if (ccr & CCR_CACHE_ENABLE)
+		/*
+		 * XXX: Should check RA here. 
+		 * If RA was 1, we only need to flush the half of the caches.
+		 */
+		cache_wback_all();
+
+	ctrl_outl(CCR_CACHE_INIT, CCR);
+	back_to_P1();
+}
+
+/*
+ * Write back the dirty D-caches, but not invalidate them.
+ *
+ * Is this really worth it, or should we just alias this routine
+ * to __flush_purge_region too?
+ *
+ * START: Virtual Address (U0, P1, or P3)
+ * SIZE: Size of the region.
+ */
+
+void __flush_wback_region(void *start, int size)
+{
+	unsigned long v, j;
+	unsigned long begin, end;
+	unsigned long flags;
+
+	begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
+	end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
+		& ~(L1_CACHE_BYTES-1);
+
+	for (v = begin; v < end; v+=L1_CACHE_BYTES) {
+		for (j=0; j<CACHE_OC_NUM_WAYS; j++) {
+			unsigned long data, addr, p;
+
+			p = __pa(v);
+			addr = CACHE_OC_ADDRESS_ARRAY|(j<<CACHE_OC_WAY_SHIFT)|
+				(v&CACHE_OC_ENTRY_MASK);
+			save_and_cli(flags);
+			data = ctrl_inl(addr);
+			
+			if ((data & CACHE_PHYSADDR_MASK) ==
+			    (p & CACHE_PHYSADDR_MASK)) {
+				data &= ~CACHE_UPDATED;
+				ctrl_outl(data, addr);
+				restore_flags(flags);
+				break;
+			}
+			restore_flags(flags);
+		}
+	}
+}
+
+/*
+ * Write back the dirty D-caches and invalidate them.
+ *
+ * START: Virtual Address (U0, P1, or P3)
+ * SIZE: Size of the region.
+ */
+void __flush_purge_region(void *start, int size)
+{
+	unsigned long v;
+	unsigned long begin, end;
+
+	begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
+	end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
+		& ~(L1_CACHE_BYTES-1);
+
+	for (v = begin; v < end; v+=L1_CACHE_BYTES) {
+		unsigned long data, addr;
+
+		data = (v & 0xfffffc00); /* _Virtual_ address, ~U, ~V */
+		addr = CACHE_OC_ADDRESS_ARRAY | (v&CACHE_OC_ENTRY_MASK) | 
+			CACHE_OC_ASSOC_BIT;
+		ctrl_outl(data, addr);
+	}
+}
+
+/*
+ * No write back please
+ *
+ * Except I don't think there's any way to avoid the writeback. So we
+ * just alias it to __flush_purge_region(). dwmw2.
+ */
+void __flush_invalidate_region(void *start, int size)
+	__attribute__((alias("__flush_purge_region")));
diff -u --recursive --new-file v2.4.9/linux/arch/sh/mm/cache-sh4.c linux/arch/sh/mm/cache-sh4.c
--- v2.4.9/linux/arch/sh/mm/cache-sh4.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/mm/cache-sh4.c	Sat Sep  8 12:29:09 2001
@@ -0,0 +1,439 @@
+/* $Id: cache-sh4.c,v 1.15 2001/08/10 14:13:13 gniibe Exp $
+ *
+ *  linux/arch/sh/mm/cache.c
+ *
+ * Copyright (C) 1999, 2000  Niibe Yutaka
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/threads.h>
+#include <asm/addrspace.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/cache.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/pgalloc.h>
+#include <asm/mmu_context.h>
+
+#define CCR		 0xff00001c	/* Address of Cache Control Register */
+#define CCR_CACHE_VAL	 0x00000105	/* 8k+16k-byte cache,P1-wb,enable */
+#define CCR_CACHE_INIT	 0x0000090d	/* ICI,ICE(8k), OCI,P1-wb,OCE(16k) */
+#define CCR_CACHE_ENABLE 0x00000101
+
+#define CACHE_IC_ADDRESS_ARRAY 0xf0000000
+#define CACHE_OC_ADDRESS_ARRAY 0xf4000000
+#define CACHE_VALID	  1
+#define CACHE_UPDATED	  2
+
+#define CACHE_OC_WAY_SHIFT       13
+#define CACHE_IC_WAY_SHIFT       13
+#define CACHE_OC_ENTRY_SHIFT      5
+#define CACHE_IC_ENTRY_SHIFT      5
+#define CACHE_OC_ENTRY_MASK		0x3fe0
+#define CACHE_OC_ENTRY_PHYS_MASK	0x0fe0
+#define CACHE_IC_ENTRY_MASK		0x1fe0
+#define CACHE_IC_NUM_ENTRIES	256
+#define CACHE_OC_NUM_ENTRIES	512
+
+static void __init
+detect_cpu_and_cache_system(void)
+{
+#ifdef CONFIG_CPU_SUBTYPE_ST40STB1
+	cpu_data->type = CPU_ST40STB1;
+#elif defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7751)
+	cpu_data->type = CPU_SH7750;
+#else
+#error Unknown SH4 CPU type
+#endif
+}
+
+void __init cache_init(void)
+{
+	unsigned long ccr;
+
+	detect_cpu_and_cache_system();
+
+	jump_to_P2();
+	ccr = ctrl_inl(CCR);
+	if (ccr & CCR_CACHE_ENABLE) {
+		/*
+		 * XXX: Should check RA here. 
+		 * If RA was 1, we only need to flush the half of the caches.
+		 */
+		unsigned long addr, data;
+
+		for (addr = CACHE_OC_ADDRESS_ARRAY;
+		     addr < (CACHE_OC_ADDRESS_ARRAY+
+			     (CACHE_OC_NUM_ENTRIES << CACHE_OC_ENTRY_SHIFT));
+		     addr += (1 << CACHE_OC_ENTRY_SHIFT)) {
+			data = ctrl_inl(addr);
+			if ((data & (CACHE_UPDATED|CACHE_VALID))
+			    == (CACHE_UPDATED|CACHE_VALID))
+				ctrl_outl(data & ~CACHE_UPDATED, addr);
+		}
+	}
+
+	ctrl_outl(CCR_CACHE_INIT, CCR);
+	back_to_P1();
+}
+
+/*
+ * SH-4 has virtually indexed and physically tagged cache.
+ */
+
+static struct semaphore p3map_sem[4];
+
+void __init p3_cache_init(void)
+{
+	/* In ioremap.c */
+	extern int remap_area_pages(unsigned long address,
+				    unsigned long phys_addr,
+				    unsigned long size, unsigned long flags);
+
+	if (remap_area_pages(P3SEG, 0, PAGE_SIZE*4, _PAGE_CACHABLE))
+		panic("p3_cachie_init failed.");
+	sema_init (&p3map_sem[0], 1);
+	sema_init (&p3map_sem[1], 1);
+	sema_init (&p3map_sem[2], 1);
+	sema_init (&p3map_sem[3], 1);
+}
+
+/*
+ * Write back the dirty D-caches, but not invalidate them.
+ *
+ * START: Virtual Address (U0, P1, or P3)
+ * SIZE: Size of the region.
+ */
+void __flush_wback_region(void *start, int size)
+{
+	unsigned long v;
+	unsigned long begin, end;
+
+	begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
+	end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
+		& ~(L1_CACHE_BYTES-1);
+	for (v = begin; v < end; v+=L1_CACHE_BYTES) {
+		asm volatile("ocbwb	%0"
+			     : /* no output */
+			     : "m" (__m(v)));
+	}
+}
+
+/*
+ * Write back the dirty D-caches and invalidate them.
+ *
+ * START: Virtual Address (U0, P1, or P3)
+ * SIZE: Size of the region.
+ */
+void __flush_purge_region(void *start, int size)
+{
+	unsigned long v;
+	unsigned long begin, end;
+
+	begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
+	end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
+		& ~(L1_CACHE_BYTES-1);
+	for (v = begin; v < end; v+=L1_CACHE_BYTES) {
+		asm volatile("ocbp	%0"
+			     : /* no output */
+			     : "m" (__m(v)));
+	}
+}
+
+
+/*
+ * No write back please
+ */
+void __flush_invalidate_region(void *start, int size)
+{
+	unsigned long v;
+	unsigned long begin, end;
+
+	begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
+	end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
+		& ~(L1_CACHE_BYTES-1);
+	for (v = begin; v < end; v+=L1_CACHE_BYTES) {
+		asm volatile("ocbi	%0"
+			     : /* no output */
+			     : "m" (__m(v)));
+	}
+}
+
+/*
+ * Write back the range of D-cache, and purge the I-cache.
+ *
+ * Called from kernel/module.c:sys_init_module and routine for a.out format.
+ */
+void flush_icache_range(unsigned long start, unsigned long end)
+{
+	flush_cache_all();
+}
+
+/*
+ * Write back the D-cache and purge the I-cache for signal trampoline. 
+ */
+void flush_cache_sigtramp(unsigned long addr)
+{
+	unsigned long v, index;
+	unsigned long flags; 
+
+	v = addr & ~(L1_CACHE_BYTES-1);
+	asm volatile("ocbwb	%0"
+		     : /* no output */
+		     : "m" (__m(v)));
+
+	index = CACHE_IC_ADDRESS_ARRAY| (v&CACHE_IC_ENTRY_MASK);
+	save_and_cli(flags);
+	jump_to_P2();
+	ctrl_outl(0, index);	/* Clear out Valid-bit */
+	back_to_P1();
+	restore_flags(flags);
+}
+
+/*
+ * Writeback&Invalidate the D-cache of the page
+ */
+static void __flush_dcache_page(unsigned long phys)
+{
+	unsigned long addr, data;
+	unsigned long flags;
+
+	phys |= CACHE_VALID;
+
+	save_and_cli(flags);
+	jump_to_P2();
+
+	/* Loop all the D-cache */
+	for (addr = CACHE_OC_ADDRESS_ARRAY;
+	     addr < (CACHE_OC_ADDRESS_ARRAY
+		     +(CACHE_OC_NUM_ENTRIES<< CACHE_OC_ENTRY_SHIFT));
+	     addr += (1<<CACHE_OC_ENTRY_SHIFT)) {
+		data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID);
+		if (data == phys)
+			ctrl_outl(0, addr);
+	}
+
+#if 0 /* DEBUG DEBUG */
+	/* Loop all the I-cache */
+	for (addr = CACHE_IC_ADDRESS_ARRAY;
+	     addr < (CACHE_IC_ADDRESS_ARRAY
+		     +(CACHE_IC_NUM_ENTRIES<< CACHE_IC_ENTRY_SHIFT));
+	     addr += (1<<CACHE_IC_ENTRY_SHIFT)) {
+		data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID);
+		if (data == phys) {
+			printk(KERN_INFO "__flush_cache_page: I-cache entry found\n");
+			ctrl_outl(0, addr);
+		}
+	}
+#endif
+	back_to_P1();
+	restore_flags(flags);
+}
+
+/*
+ * Write back & invalidate the D-cache of the page.
+ * (To avoid "alias" issues)
+ */
+void flush_dcache_page(struct page *page)
+{
+	if (test_bit(PG_mapped, &page->flags))
+		__flush_dcache_page(PHYSADDR(page_address(page)));
+}
+
+void flush_cache_all(void)
+{
+	extern unsigned long empty_zero_page[1024];
+	unsigned long flags;
+	unsigned long addr;
+
+	save_and_cli(flags);
+
+	/* Prefetch the data to write back D-cache */
+	for (addr = (unsigned long)empty_zero_page;
+	     addr < (unsigned long)empty_zero_page + 1024*16;
+	     addr += L1_CACHE_BYTES)
+		asm volatile("pref @%0"::"r" (addr));
+
+	jump_to_P2();
+	/* Flush D-cache/I-cache */
+	ctrl_outl(CCR_CACHE_INIT, CCR);
+	back_to_P1();
+	restore_flags(flags);
+}
+
+void flush_cache_mm(struct mm_struct *mm)
+{
+	/* Is there any good way? */
+	/* XXX: possibly call flush_cache_range for each vm area */
+	flush_cache_all();
+}
+
+/*
+ * Write back and invalidate D-caches.
+ *
+ * START, END: Virtual Address (U0 address)
+ *
+ * NOTE: We need to flush the _physical_ page entry.
+ * Flushing the cache lines for U0 only isn't enough.
+ * We need to flush for P1 too, which may contain aliases.
+ */
+void flush_cache_range(struct mm_struct *mm, unsigned long start,
+		       unsigned long end)
+{
+	/*
+	 * We could call flush_cache_page for the pages of these range,
+	 * but it's not efficient (scan the caches all the time...).
+	 *
+	 * We can't use A-bit magic, as there's the case we don't have
+	 * valid entry on TLB.
+	 */
+	flush_cache_all();
+}
+
+/*
+ * Write back and invalidate I/D-caches for the page.
+ *
+ * ADDR: Virtual Address (U0 address)
+ */
+void flush_cache_page(struct vm_area_struct *vma, unsigned long address)
+{
+	pgd_t *dir;
+	pmd_t *pmd;
+	pte_t *pte;
+	pte_t entry;
+	unsigned long phys, addr, data;
+	unsigned long flags;
+
+	dir = pgd_offset(vma->vm_mm, address);
+	pmd = pmd_offset(dir, address);
+	if (pmd_none(*pmd) || pmd_bad(*pmd))
+		return;
+	pte = pte_offset(pmd, address);
+	entry = *pte;
+	if (pte_none(entry) || !pte_present(entry))
+		return;
+
+	phys = pte_val(entry)&PTE_PHYS_MASK;
+
+	phys |= CACHE_VALID;
+	save_and_cli(flags);
+	jump_to_P2();
+
+	/* We only need to flush D-cache when we have alias */
+	if ((address^phys) & CACHE_ALIAS) {
+		/* Loop 4K of the D-cache */
+		for (addr = CACHE_OC_ADDRESS_ARRAY | (address & CACHE_ALIAS);
+		     addr < (CACHE_OC_ADDRESS_ARRAY + (address & CACHE_ALIAS) 
+			     +(CACHE_OC_NUM_ENTRIES/4<<CACHE_OC_ENTRY_SHIFT));
+		     addr += (1<<CACHE_OC_ENTRY_SHIFT)) {
+			data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID);
+			if (data == phys)
+				ctrl_outl(0, addr);
+		}
+		/* Loop another 4K of the D-cache */
+		for (addr = CACHE_OC_ADDRESS_ARRAY | (phys & CACHE_ALIAS);
+		     addr < (CACHE_OC_ADDRESS_ARRAY + (phys & CACHE_ALIAS) 
+			     +(CACHE_OC_NUM_ENTRIES/4<<CACHE_OC_ENTRY_SHIFT));
+		     addr += (1<<CACHE_OC_ENTRY_SHIFT)) {
+			data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID);
+			if (data == phys)
+				ctrl_outl(0, addr);
+		}
+	}
+
+	if (vma->vm_flags & VM_EXEC)
+		/* Loop 4K of the I-cache */
+		for (addr = CACHE_IC_ADDRESS_ARRAY|(address&0x1000);
+		     addr < ((CACHE_IC_ADDRESS_ARRAY|(address&0x1000))
+			     +(CACHE_IC_NUM_ENTRIES/2<<CACHE_IC_ENTRY_SHIFT));
+		     addr += (1<<CACHE_IC_ENTRY_SHIFT)) {
+			data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID);
+			if (data == phys)
+				ctrl_outl(0, addr);
+		}
+	back_to_P1();
+	restore_flags(flags);
+}
+
+/*
+ * clear_user_page
+ * @to: P1 address
+ * @address: U0 address to be mapped
+ */
+void clear_user_page(void *to, unsigned long address)
+{
+	struct page *page = virt_to_page(to);
+
+	__set_bit(PG_mapped, &page->flags);
+	if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0)
+		clear_page(to);
+	else {
+		pgprot_t pgprot = __pgprot(_PAGE_PRESENT | 
+					   _PAGE_RW | _PAGE_CACHABLE |
+					   _PAGE_DIRTY | _PAGE_ACCESSED | 
+					   _PAGE_HW_SHARED | _PAGE_FLAGS_HARD);
+		unsigned long phys_addr = PHYSADDR(to);
+		unsigned long p3_addr = P3SEG + (address & CACHE_ALIAS);
+		pgd_t *dir = pgd_offset_k(p3_addr);
+		pmd_t *pmd = pmd_offset(dir, p3_addr);
+		pte_t *pte = pte_offset(pmd, p3_addr);
+		pte_t entry;
+		unsigned long flags;
+
+		entry = mk_pte_phys(phys_addr, pgprot);
+		down(&p3map_sem[(address & CACHE_ALIAS)>>12]);
+		set_pte(pte, entry);
+		save_and_cli(flags);
+		__flush_tlb_page(get_asid(), p3_addr);
+		restore_flags(flags);
+		update_mmu_cache(NULL, p3_addr, entry);
+		__clear_user_page((void *)p3_addr, to);
+		pte_clear(pte);
+		up(&p3map_sem[(address & CACHE_ALIAS)>>12]);
+	}
+}
+
+/*
+ * copy_user_page
+ * @to: P1 address
+ * @from: P1 address
+ * @address: U0 address to be mapped
+ */
+void copy_user_page(void *to, void *from, unsigned long address)
+{
+	struct page *page = virt_to_page(to);
+
+	__set_bit(PG_mapped, &page->flags);
+	if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0)
+		copy_page(to, from);
+	else {
+		pgprot_t pgprot = __pgprot(_PAGE_PRESENT | 
+					   _PAGE_RW | _PAGE_CACHABLE |
+					   _PAGE_DIRTY | _PAGE_ACCESSED | 
+					   _PAGE_HW_SHARED | _PAGE_FLAGS_HARD);
+		unsigned long phys_addr = PHYSADDR(to);
+		unsigned long p3_addr = P3SEG + (address & CACHE_ALIAS);
+		pgd_t *dir = pgd_offset_k(p3_addr);
+		pmd_t *pmd = pmd_offset(dir, p3_addr);
+		pte_t *pte = pte_offset(pmd, p3_addr);
+		pte_t entry;
+		unsigned long flags;
+
+		entry = mk_pte_phys(phys_addr, pgprot);
+		down(&p3map_sem[(address & CACHE_ALIAS)>>12]);
+		set_pte(pte, entry);
+		save_and_cli(flags);
+		__flush_tlb_page(get_asid(), p3_addr);
+		restore_flags(flags);
+		update_mmu_cache(NULL, p3_addr, entry);
+		__copy_user_page((void *)p3_addr, from, to);
+		pte_clear(pte);
+		up(&p3map_sem[(address & CACHE_ALIAS)>>12]);
+	}
+}
diff -u --recursive --new-file v2.4.9/linux/arch/sh/mm/cache.c linux/arch/sh/mm/cache.c
--- v2.4.9/linux/arch/sh/mm/cache.c	Tue Jul  3 17:08:19 2001
+++ linux/arch/sh/mm/cache.c	Wed Dec 31 16:00:00 1969
@@ -1,524 +0,0 @@
-/* $Id: cache.c,v 1.10 2000/03/07 11:58:34 gniibe Exp $
- *
- *  linux/arch/sh/mm/cache.c
- *
- * Copyright (C) 1999, 2000  Niibe Yutaka
- *
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/mman.h>
-#include <linux/mm.h>
-#include <linux/threads.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/processor.h>
-#include <asm/cache.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-
-#if defined(__sh3__)
-#define CCR		0xffffffec	/* Address of Cache Control Register */
-#define CCR_CACHE_VAL	0x00000005	/* 8k-byte cache, P1-wb, enable */
-#define CCR_CACHE_INIT	0x0000000d	/* 8k-byte cache, CF, P1-wb, enable */
-#define CCR_CACHE_ENABLE	 1
-
-#define CACHE_IC_ADDRESS_ARRAY 0xf0000000 /* SH-3 has unified cache system */
-#define CACHE_OC_ADDRESS_ARRAY 0xf0000000
-#define CACHE_VALID	  1
-#define CACHE_UPDATED	  2
-
-/* 7709A/7729 has 16K cache (256-entry), while 7702 has only 2K(direct)
-   7702 is not supported (yet) */
-struct _cache_system_info {
-	int way_shift;
-	int entry_mask;
-	int num_entries;
-};
-
-/* Data at BSS is cleared after setting this variable.
-   So, we Should not placed this variable at BSS section.
-   Initialize this, it is placed at data section. */
-static struct _cache_system_info cache_system_info = {0,};
-
-#define CACHE_OC_WAY_SHIFT	(cache_system_info.way_shift)
-#define CACHE_IC_WAY_SHIFT	(cache_system_info.way_shift)
-#define CACHE_OC_ENTRY_SHIFT    4
-#define CACHE_OC_ENTRY_MASK	(cache_system_info.entry_mask)
-#define CACHE_IC_ENTRY_MASK	(cache_system_info.entry_mask)
-#define CACHE_OC_NUM_ENTRIES	(cache_system_info.num_entries)
-#define CACHE_OC_NUM_WAYS	4
-#define CACHE_IC_NUM_WAYS	4
-#elif defined(__SH4__)
-#define CCR		 0xff00001c	/* Address of Cache Control Register */
-#define CCR_CACHE_VAL	 0x00000105	/* 8k+16k-byte cache,P1-wb,enable */
-#define CCR_CACHE_INIT	 0x0000090d	/* ICI,ICE(8k), OCI,P1-wb,OCE(16k) */
-#define CCR_CACHE_ENABLE 0x00000101
-
-#define CACHE_IC_ADDRESS_ARRAY 0xf0000000
-#define CACHE_OC_ADDRESS_ARRAY 0xf4000000
-#define CACHE_VALID	  1
-#define CACHE_UPDATED	  2
-
-#define CACHE_OC_WAY_SHIFT       13
-#define CACHE_IC_WAY_SHIFT       13
-#define CACHE_OC_ENTRY_SHIFT      5
-#define CACHE_IC_ENTRY_SHIFT      5
-#define CACHE_OC_ENTRY_MASK		0x3fe0
-#define CACHE_OC_ENTRY_PHYS_MASK	0x0fe0
-#define CACHE_IC_ENTRY_MASK		0x1fe0
-#define CACHE_IC_NUM_ENTRIES	256
-#define CACHE_OC_NUM_ENTRIES	512
-#define CACHE_OC_NUM_WAYS	  1
-#define CACHE_IC_NUM_WAYS	  1
-#endif
-
-
-/*
- * Write back all the cache.
- *
- * For SH-4, we only need to flush (write back) Operand Cache,
- * as Instruction Cache doesn't have "updated" data.
- *
- * Assumes that this is called in interrupt disabled context, and P2.
- * Shuld be INLINE function.
- */
-static inline void cache_wback_all(void)
-{
-	unsigned long addr, data, i, j;
-
-	for (i=0; i<CACHE_OC_NUM_ENTRIES; i++) {
-		for (j=0; j<CACHE_OC_NUM_WAYS; j++) {
-			addr = CACHE_OC_ADDRESS_ARRAY|(j<<CACHE_OC_WAY_SHIFT)|
-				(i<<CACHE_OC_ENTRY_SHIFT);
-			data = ctrl_inl(addr);
-			if ((data & (CACHE_UPDATED|CACHE_VALID))
-			    == (CACHE_UPDATED|CACHE_VALID)) {
-				data &= ~CACHE_UPDATED;
-				ctrl_outl(data, addr);
-			}
-		}
-	}
-}
-
-static void __init
-detect_cpu_and_cache_system(void)
-{
-#if defined(__sh3__)
-	unsigned long addr0, addr1, data0, data1, data2, data3;
-
-	jump_to_P2();
-	/*
-	 * Check if the entry shadows or not.
-	 * When shadowed, it's 128-entry system.
-	 * Otherwise, it's 256-entry system.
-	 */
-	addr0 = CACHE_OC_ADDRESS_ARRAY + (3 << 12);
-	addr1 = CACHE_OC_ADDRESS_ARRAY + (1 << 12);
-
-	/* First, write back & invalidate */
-	data0  = ctrl_inl(addr0);
-	ctrl_outl(data0&~(CACHE_VALID|CACHE_UPDATED), addr0);
-	data1  = ctrl_inl(addr1);
-	ctrl_outl(data1&~(CACHE_VALID|CACHE_UPDATED), addr1);
-
-	/* Next, check if there's shadow or not */
-	data0 = ctrl_inl(addr0);
-	data0 ^= CACHE_VALID;
-	ctrl_outl(data0, addr0);
-	data1 = ctrl_inl(addr1);
-	data2 = data1 ^ CACHE_VALID;
-	ctrl_outl(data2, addr1);
-	data3 = ctrl_inl(addr0);
-
-	/* Lastly, invaliate them. */
-	ctrl_outl(data0&~CACHE_VALID, addr0);
-	ctrl_outl(data2&~CACHE_VALID, addr1);
-	back_to_P1();
-
-	if (data0 == data1 && data2 == data3) {	/* Shadow */
-		cache_system_info.way_shift = 11;
-		cache_system_info.entry_mask = 0x7f0;
-		cache_system_info.num_entries = 128;
-		cpu_data->type = CPU_SH7708;
-	} else {				/* 7709A or 7729  */
-		cache_system_info.way_shift = 12;
-		cache_system_info.entry_mask = 0xff0;
-		cache_system_info.num_entries = 256;
-		cpu_data->type = CPU_SH7729;
-	}
-#elif defined(__SH4__)
-#ifdef CONFIG_CPU_SUBTYPE_ST40STB1
-	cpu_data->type = CPU_ST40STB1;
-#elif defined(CONFIG_CPU_SUBTYPE_SH7750) || \
-      defined(CONFIG_CPU_SUBTYPE_SH7751)
-	cpu_data->type = CPU_SH7750;
-#else
-#error Unknown SH4 CPU type
-#endif
-#endif
-}
-
-void __init cache_init(void)
-{
-	unsigned long ccr;
-
-	detect_cpu_and_cache_system();
-
-	ccr = ctrl_inl(CCR);
-	jump_to_P2();
-	if (ccr & CCR_CACHE_ENABLE)
-		/*
-		 * XXX: Should check RA here. 
-		 * If RA was 1, we only need to flush the half of the caches.
-		 */
-		cache_wback_all();
-
-	ctrl_outl(CCR_CACHE_INIT, CCR);
-	back_to_P1();
-}
-
-#if defined(__SH4__)
-/*
- * SH-4 has virtually indexed and physically tagged cache.
- */
-
-/*
- * Write back the dirty D-caches, but not invalidate them.
- *
- * START, END: Virtual Address
- */
-static void dcache_wback_range(unsigned long start, unsigned long end)
-{
-	unsigned long v;
-
-	start &= ~(L1_CACHE_BYTES-1);
-	for (v = start; v < end; v+=L1_CACHE_BYTES) {
-		asm volatile("ocbwb	%0"
-			     : /* no output */
-			     : "m" (__m(v)));
-	}
-}
-
-/*
- * Invalidate I-caches.
- *
- * START, END: Virtual Address
- *
- */
-static void icache_purge_range(unsigned long start, unsigned long end)
-{
-	unsigned long addr, data, v;
-
-	start &= ~(L1_CACHE_BYTES-1);
-
-	jump_to_P2();
-	/*
-	 * To handle the cache-line, we calculate the entry with virtual
-	 * address: entry = vaddr & CACHE_IC_ENTRY_MASK.
-	 *
-	 * With A-bit "on", data written to is translated by MMU and
-	 * compared the tag of cache and if it's not matched, nothing
-	 * will be occurred.  (We can avoid flushing other caches.)
-	 * 
-	 * NOTE: We can use A-bit feature here, because we have valid
-	 * entriy in TLB (at least in UTLB), as dcache_wback_range is
-	 * called before this function is called.
-	 */
-	for (v = start; v < end; v+=L1_CACHE_BYTES) {
-		addr = CACHE_IC_ADDRESS_ARRAY |	(v&CACHE_IC_ENTRY_MASK)
-			| 0x8 /* A-bit */;
-		data = (v&0xfffffc00); /* Valid=0 */
-		ctrl_outl(data, addr);
-	}
-	back_to_P1();
-}
-
-/*
- * Write back the range of D-cache, and purge the I-cache.
- *
- * Called from sh/kernel/signal.c, after accessing the memory
- * through U0 area.  START and END is the address of U0.
- */
-void flush_icache_range(unsigned long start, unsigned long end)
-{
-	unsigned long flags;
-
-	save_and_cli(flags);
-	dcache_wback_range(start, end);
-	icache_purge_range(start, end);
-	restore_flags(flags);
-}
-
-/*
- * Write back the D-cache and purge the I-cache for signal trampoline. 
- */
-void flush_cache_sigtramp(unsigned long addr)
-{
-	unsigned long v, index;
-
-	v = addr & ~(L1_CACHE_BYTES-1);
-	asm volatile("ocbwb	%0"
-		     : /* no output */
-		     : "m" (__m(v)));
-
-	index = CACHE_IC_ADDRESS_ARRAY| (v&CACHE_IC_ENTRY_MASK);
-	ctrl_outl(0, index);	/* Clear out Valid-bit */
-}
-
-/*
- * Invalidate the I-cache of the page (don't need to write back D-cache).
- *
- * Called from kernel/ptrace.c, mm/memory.c after flush_page_to_ram is called.
- */
-void flush_icache_page(struct vm_area_struct *vma, struct page *pg)
-{
-	unsigned long phys, addr, data, i;
-
-	/* Physical address of this page */
-	phys = (pg - mem_map)*PAGE_SIZE + __MEMORY_START;
-
-	jump_to_P2();
-	/* Loop all the I-cache */
-	for (i=0; i<CACHE_IC_NUM_ENTRIES; i++) {
-		addr = CACHE_IC_ADDRESS_ARRAY| (i<<CACHE_IC_ENTRY_SHIFT);
-		data = ctrl_inl(addr);
-		if ((data & CACHE_VALID) && (data&PAGE_MASK) == phys) {
-			data &= ~CACHE_VALID;
-			ctrl_outl(data, addr);
-		}
-	}
-	back_to_P1();
-}
-
-/*
- * Write back & invalidate the D-cache of the page.
- * (To avoid "alias" issues)
- */
-void flush_dcache_page(struct page *pg)
-{
-	unsigned long phys, addr, data, i;
-
-	/* Physical address of this page */
-	phys = (pg - mem_map)*PAGE_SIZE + __MEMORY_START;
-
-	jump_to_P2();
-	/* Loop all the D-cache */
-	for (i=0; i<CACHE_OC_NUM_ENTRIES; i++) {
-		addr = CACHE_OC_ADDRESS_ARRAY| (i<<CACHE_OC_ENTRY_SHIFT);
-		data = ctrl_inl(addr);
-		if ((data & CACHE_VALID) && (data&PAGE_MASK) == phys) {
-			data &= ~(CACHE_VALID|CACHE_UPDATED);
-			ctrl_outl(data, addr);
-		}
-	}
-	back_to_P1();
-}
-
-void flush_cache_all(void)
-{
-	unsigned long addr, data, i;
-	unsigned long flags;
-
-	save_and_cli(flags);
-	jump_to_P2();
-
-	/* Loop all the D-cache */
-	for (i=0; i<CACHE_OC_NUM_ENTRIES; i++) {
-		addr = CACHE_OC_ADDRESS_ARRAY|(i<<CACHE_OC_ENTRY_SHIFT);
-		data = ctrl_inl(addr);
-		if (data & CACHE_VALID) {
-			data &= ~(CACHE_UPDATED|CACHE_VALID);
-			ctrl_outl(data, addr);
-		}
-	}
-
-	/* Loop all the I-cache */
-	for (i=0; i<CACHE_IC_NUM_ENTRIES; i++) {
-		addr = CACHE_IC_ADDRESS_ARRAY| (i<<CACHE_IC_ENTRY_SHIFT);
-		data = ctrl_inl(addr);
-		if (data & CACHE_VALID) {
-			data &= ~CACHE_VALID;
-			ctrl_outl(data, addr);
-		}
-	}
-
-	back_to_P1();
-	restore_flags(flags);
-}
-
-void flush_cache_mm(struct mm_struct *mm)
-{
-	/* Is there any good way? */
-	/* XXX: possibly call flush_cache_range for each vm area */
-	flush_cache_all();
-}
-
-/*
- * Write back and invalidate D-caches.
- *
- * START, END: Virtual Address (U0 address)
- *
- * NOTE: We need to flush the _physical_ page entry.
- * Flushing the cache lines for U0 only isn't enough.
- * We need to flush for P1 too, which may contain aliases.
- */
-void flush_cache_range(struct mm_struct *mm, unsigned long start,
-		       unsigned long end)
-{
-	/*
-	 * We could call flush_cache_page for the pages of these range,
-	 * but it's not efficient (scan the caches all the time...).
-	 *
-	 * We can't use A-bit magic, as there's the case we don't have
-	 * valid entry on TLB.
-	 */
-	flush_cache_all();
-}
-
-/*
- * Write back and invalidate D-caches for the page.
- *
- * ADDR: Virtual Address (U0 address)
- *
- * NOTE: We need to flush the _physical_ page entry.
- * Flushing the cache lines for U0 only isn't enough.
- * We need to flush for P1 too, which may contain aliases.
- */
-void flush_cache_page(struct vm_area_struct *vma, unsigned long addr)
-{
-	pgd_t *dir;
-	pmd_t *pmd;
-	pte_t *pte;
-	pte_t entry;
-	unsigned long phys;
-	struct page *pg;
-
-	dir = pgd_offset(vma->vm_mm, addr);
-	pmd = pmd_offset(dir, addr);
-	if (pmd_none(*pmd))
-		return;
-	if (pmd_bad(*pmd))
-		return;
-	pte = pte_offset(pmd, addr);
-	entry = *pte;
-	if (pte_none(entry) || !pte_present(entry))
-		return;
-	phys = pte_val(entry)&PAGE_MASK;
-	pg = virt_to_page(__va(phys));
-	flush_dcache_page(pg);
-}
-
-/*
- * Write-back & invalidate the cache.
- *
- * After accessing the memory from kernel space (P1-area), we need to 
- * write back the cache line.
- *
- * We search the D-cache to see if we have the entries corresponding to
- * the page, and if found, write back them.
- */
-void __flush_page_to_ram(void *kaddr)
-{
-	unsigned long phys, addr, data, i;
-
-	/* Physical address of this page */
-	phys = PHYSADDR(kaddr);
-
-	jump_to_P2();
-	/* Loop all the D-cache */
-	for (i=0; i<CACHE_OC_NUM_ENTRIES; i++) {
-		addr = CACHE_OC_ADDRESS_ARRAY| (i<<CACHE_OC_ENTRY_SHIFT);
-		data = ctrl_inl(addr);
-		if ((data & CACHE_VALID) && (data&PAGE_MASK) == phys) {
-			data &= ~(CACHE_UPDATED|CACHE_VALID);
-			ctrl_outl(data, addr);
-		}
-	}
-	back_to_P1();
-}
-
-void flush_page_to_ram(struct page *pg)
-{
-	unsigned long phys;
-
-	/* Physical address of this page */
-	phys = (pg - mem_map)*PAGE_SIZE + __MEMORY_START;
-	__flush_page_to_ram(phys_to_virt(phys));
-}
-
-/*
- * Check entries of the I-cache & D-cache of the page.
- * (To see "alias" issues)
- */
-void check_cache_page(struct page *pg)
-{
-	unsigned long phys, addr, data, i;
-	unsigned long kaddr;
-	unsigned long cache_line_index;
-	int bingo = 0;
-
-	/* Physical address of this page */
-	phys = (pg - mem_map)*PAGE_SIZE + __MEMORY_START;
-	kaddr = phys + PAGE_OFFSET;
-	cache_line_index = (kaddr&CACHE_OC_ENTRY_MASK)>>CACHE_OC_ENTRY_SHIFT;
-
-	jump_to_P2();
-	/* Loop all the D-cache */
-	for (i=0; i<CACHE_OC_NUM_ENTRIES; i++) {
-		addr = CACHE_OC_ADDRESS_ARRAY| (i<<CACHE_OC_ENTRY_SHIFT);
-		data = ctrl_inl(addr);
-		if ((data & (CACHE_UPDATED|CACHE_VALID))
-		    == (CACHE_UPDATED|CACHE_VALID)
-		    && (data&PAGE_MASK) == phys) {
-			data &= ~(CACHE_VALID|CACHE_UPDATED);
-			ctrl_outl(data, addr);
-			if ((i^cache_line_index)&0x180)
-				bingo = 1;
-		}
-	}
-
-	cache_line_index &= 0xff;
-	/* Loop all the I-cache */
-	for (i=0; i<CACHE_IC_NUM_ENTRIES; i++) {
-		addr = CACHE_IC_ADDRESS_ARRAY| (i<<CACHE_IC_ENTRY_SHIFT);
-		data = ctrl_inl(addr);
-		if ((data & CACHE_VALID) && (data&PAGE_MASK) == phys) {
-			data &= ~CACHE_VALID;
-			ctrl_outl(data, addr);
-			if (((i^cache_line_index)&0x80))
-				bingo = 2;
-		}
-	}
-	back_to_P1();
-
-	if (bingo) {
-		extern void dump_stack(void);
-
-		if (bingo ==1)
-			printk("BINGO!\n");
-		else
-			printk("Bingo!\n");
-		dump_stack();
-		printk("--------------------\n");
-	}
-}
-
-/* Page is 4K, OC size is 16K, there are four lines. */
-#define CACHE_ALIAS 0x00003000
-
-void clear_user_page(void *to, unsigned long address)
-{
-	clear_page(to);
-	if (((address ^ (unsigned long)to) & CACHE_ALIAS))
-		__flush_page_to_ram(to);
-}
-
-void copy_user_page(void *to, void *from, unsigned long address)
-{
-	copy_page(to, from);
-	if (((address ^ (unsigned long)to) & CACHE_ALIAS))
-		__flush_page_to_ram(to);
-}
-#endif
diff -u --recursive --new-file v2.4.9/linux/arch/sh/mm/clear_page.S linux/arch/sh/mm/clear_page.S
--- v2.4.9/linux/arch/sh/mm/clear_page.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/mm/clear_page.S	Sat Sep  8 12:29:09 2001
@@ -0,0 +1,52 @@
+/* $Id: clear_page.S,v 1.1 2001/07/23 10:08:50 gniibe Exp $
+ *
+ * clear_page implementation of SuperH
+ *
+ * Copyright (C) 2001  Niibe Yutaka & Kaz Kojima
+ *
+ */
+
+/*
+ * clear_page
+ * @to: P1 address
+ *
+ * void clear_page(void *to)
+ */
+
+/*
+ * r0 --- scratch
+ * r4 --- to
+ * r5 --- to + 4096
+ */
+#include <linux/linkage.h>
+ENTRY(clear_page)
+	mov	r4,r5
+	mov.w	.Llimit,r0
+	add	r0,r5
+	mov	#0,r0
+	!
+1:
+#if defined(__sh3__)
+	mov.l	r0,@r4
+#elif defined(__SH4__)
+	movca.l	r0,@r4
+	mov	r4,r1
+#endif
+	add	#32,r4
+	mov.l	r0,@-r4
+	mov.l	r0,@-r4
+	mov.l	r0,@-r4
+	mov.l	r0,@-r4
+	mov.l	r0,@-r4
+	mov.l	r0,@-r4
+	mov.l	r0,@-r4
+#if defined(__SH4__)
+	ocbwb	@r1
+#endif
+	cmp/eq	r5,r4
+	bf/s	1b
+	 add	#28,r4
+	!
+	rts
+	 nop
+.Llimit:	.word	(4096-28)
diff -u --recursive --new-file v2.4.9/linux/arch/sh/mm/copy_page.S linux/arch/sh/mm/copy_page.S
--- v2.4.9/linux/arch/sh/mm/copy_page.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/mm/copy_page.S	Sat Sep  8 12:29:09 2001
@@ -0,0 +1,69 @@
+/* $Id: copy_page.S,v 1.2 2001/07/23 10:27:25 gniibe Exp $
+ *
+ * copy_page implementation of SuperH
+ *
+ * Copyright (C) 2001  Niibe Yutaka & Kaz Kojima
+ *
+ */
+
+/*
+ * copy_page
+ * @to: P1 address
+ * @from: P1 address
+ *
+ * void copy_page(void *to, void *from)
+ */
+
+/*
+ * r0, r1, r2, r3, r4, r5, r6, r7 --- scratch 
+ * r8 --- from + 4096
+ * r9 --- not used
+ * r10 --- to
+ * r11 --- from
+ */
+#include <linux/linkage.h>
+ENTRY(copy_page)
+	mov.l	r8,@-r15
+	mov.l	r10,@-r15
+	mov.l	r11,@-r15
+	mov	r4,r10
+	mov	r5,r11
+	mov	r5,r8
+	mov.w	.L4096,r0
+	add	r0,r8
+	!
+1:	mov.l	@r11+,r0
+	mov.l	@r11+,r1
+	mov.l	@r11+,r2
+	mov.l	@r11+,r3
+	mov.l	@r11+,r4
+	mov.l	@r11+,r5
+	mov.l	@r11+,r6
+	mov.l	@r11+,r7
+#if defined(__sh3__)
+	mov.l	r0,@r10
+#elif defined(__SH4__)
+	movca.l	r0,@r10
+	mov	r10,r0
+#endif
+	add	#32,r10
+	mov.l	r7,@-r10
+	mov.l	r6,@-r10
+	mov.l	r5,@-r10
+	mov.l	r4,@-r10
+	mov.l	r3,@-r10
+	mov.l	r2,@-r10
+	mov.l	r1,@-r10
+#if defined(__SH4__)
+	ocbwb	@r0
+#endif
+	cmp/eq	r11,r8
+	bf/s	1b
+	 add	#28,r10
+	!
+	mov.l	@r15+,r11
+	mov.l	@r15+,r10
+	mov.l	@r15+,r8
+	rts
+	 nop
+.L4096:	.word	4096
diff -u --recursive --new-file v2.4.9/linux/arch/sh/mm/extable.c linux/arch/sh/mm/extable.c
--- v2.4.9/linux/arch/sh/mm/extable.c	Wed Apr 11 21:24:52 2001
+++ linux/arch/sh/mm/extable.c	Sat Sep  8 12:29:09 2001
@@ -1,4 +1,4 @@
-/* $Id: extable.c,v 1.1 1999/09/18 16:57:37 gniibe Exp $
+/* $Id: extable.c,v 1.2 2001/03/31 10:43:18 gniibe Exp $
  *
  * linux/arch/sh/mm/extable.c
  *  Taken from:
diff -u --recursive --new-file v2.4.9/linux/arch/sh/mm/fault.c linux/arch/sh/mm/fault.c
--- v2.4.9/linux/arch/sh/mm/fault.c	Tue Jul  3 17:08:19 2001
+++ linux/arch/sh/mm/fault.c	Sat Sep  8 12:29:09 2001
@@ -1,4 +1,4 @@
-/* $Id: fault.c,v 1.13 2000/03/07 12:05:24 gniibe Exp $
+/* $Id: fault.c,v 1.48 2001/08/09 00:27:04 gniibe Exp $
  *
  *  linux/arch/sh/mm/fault.c
  *  Copyright (C) 1999  Niibe Yutaka
@@ -28,10 +28,6 @@
 #include <asm/mmu_context.h>
 
 extern void die(const char *,struct pt_regs *,long);
-static void __flush_tlb_page(unsigned long asid, unsigned long page);
-#if defined(__SH4__)
-static void __flush_tlb_phys(unsigned long phys);
-#endif
 
 /*
  * Ugly, ugly, but the goto's result in better assembly..
@@ -242,8 +238,10 @@
 	pte_t *pte;
 	pte_t entry;
 
-	if (address >= VMALLOC_START && address < VMALLOC_END)
+	if (address >= P3SEG && address < P4SEG)
 		dir = pgd_offset_k(address);
+	else if (address >= TASK_SIZE)
+		return 1;
 	else
 		dir = pgd_offset(current->mm, address);
 
@@ -257,7 +255,7 @@
 	}
 	pte = pte_offset(pmd, address);
 	entry = *pte;
-	if (pte_none(entry) || !pte_present(entry)
+	if (pte_none(entry) || pte_not_present(entry)
 	    || (writeaccess && !pte_write(entry)))
 		return 1;
 
@@ -283,27 +281,24 @@
 	unsigned long pteval;
 	unsigned long vpn;
 #if defined(__SH4__)
+	struct page *page;
 	unsigned long ptea;
 #endif
 
-	save_and_cli(flags);
-#if defined(__SH4__)
-	if (pte_shared(pte)) {
-		struct page *pg;
+	/* Ptrace may call this routine. */
+	if (vma && current->active_mm != vma->vm_mm)
+		return;
 
-		pteval = pte_val(pte);
-		pteval &= PAGE_MASK; /* Physicall page address */
-		__flush_tlb_phys(pteval);
-		pg = virt_to_page(__va(pteval));
-		flush_dcache_page(pg);
+#if defined(__SH4__)
+	page = pte_page(pte);
+	if (VALID_PAGE(page) && !test_bit(PG_mapped, &page->flags)) {
+		unsigned long phys = pte_val(pte) & PTE_PHYS_MASK;
+		__flush_wback_region((void *)P1SEGADDR(phys), PAGE_SIZE);
+		__set_bit(PG_mapped, &page->flags);
 	}
 #endif
 
-	/* Ptrace may call this routine. */
-	if (vma && current->active_mm != vma->vm_mm) {
-		restore_flags(flags);
-		return;
-	}
+	save_and_cli(flags);
 
 	/* Set PTEH register */
 	vpn = (address & MMU_VPN_MASK) | get_asid();
@@ -327,7 +322,7 @@
 	restore_flags(flags);
 }
 
-static void __flush_tlb_page(unsigned long asid, unsigned long page)
+void __flush_tlb_page(unsigned long asid, unsigned long page)
 {
 	unsigned long addr, data;
 
@@ -349,40 +344,6 @@
 	back_to_P1();
 #endif
 }
-
-#if defined(__SH4__)
-static void __flush_tlb_phys(unsigned long phys)
-{
-	unsigned long addr, data, pte;
-
-	pte = phys | MMU_UTLB_VALID;
-	for (addr = MMU_UTLB_DATA_ARRAY;
-	     addr < MMU_UTLB_DATA_ARRAY+(MMU_UTLB_ENTRIES<<MMU_U_ENTRY_SHIFT);
-	     addr += (1<<MMU_U_ENTRY_SHIFT)) {
-		data = ctrl_inl(addr);
-		if ((data & (MMU_UTLB_VALID|PAGE_MASK)) == pte) {
-			data &= ~MMU_UTLB_VALID;
-			jump_to_P2();
-			ctrl_outl(data, addr);
-			back_to_P1();
-			break;
-		}
-	}
-	pte = phys | MMU_ITLB_VALID;
-	for (addr = MMU_ITLB_DATA_ARRAY;
-	     addr < MMU_ITLB_DATA_ARRAY+(MMU_ITLB_ENTRIES<<MMU_I_ENTRY_SHIFT);
-	     addr += (1<<MMU_I_ENTRY_SHIFT)) {
-		data = ctrl_inl(addr);
-		if ((data & (MMU_ITLB_VALID|PAGE_MASK)) == pte) {
-			data &= ~MMU_ITLB_VALID;
-			jump_to_P2();
-			ctrl_outl(data, addr);
-			back_to_P1();
-			break;
-		}
-	}
-}
-#endif
 
 void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
 {
diff -u --recursive --new-file v2.4.9/linux/arch/sh/mm/init.c linux/arch/sh/mm/init.c
--- v2.4.9/linux/arch/sh/mm/init.c	Tue Jul  3 17:08:19 2001
+++ linux/arch/sh/mm/init.c	Sat Sep  8 12:29:09 2001
@@ -1,4 +1,4 @@
-/* $Id: init.c,v 1.17 2000-04-08 15:38:54+09 gniibe Exp $
+/* $Id: init.c,v 1.18 2001/08/03 11:22:06 gniibe Exp $
  *
  *  linux/arch/sh/mm/init.c
  *
@@ -40,35 +40,14 @@
  */
 unsigned long mmu_context_cache;
 
+#ifdef CONFIG_DISCONTIGMEM
+pg_data_t discontig_page_data[NR_NODES];
+bootmem_data_t discontig_node_bdata[NR_NODES];
+#endif
+
 static unsigned long totalram_pages;
 static unsigned long totalhigh_pages;
 
-extern unsigned long init_smp_mappings(unsigned long);
-
-extern unsigned long empty_zero_page[1024];
-
-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) {
-				pmd_free_slow(pmd_alloc_one_fast(NULL, 0));
-				freed++;
-			}
-			if (pte_quicklist) {
-				pte_free_slow(pte_alloc_one_fast(NULL, 0));
-				freed++;
-			}
-		} while (pgtable_cache_size > low);
-	}
-	return freed;
-}
-
 void show_mem(void)
 {
 	int i, total = 0, reserved = 0;
@@ -91,7 +70,6 @@
 	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);
 	show_buffers();
 }
 
@@ -146,12 +124,18 @@
 			zones_size[ZONE_DMA] = max_dma - start_pfn;
 			zones_size[ZONE_NORMAL] = low - max_dma;
 		}
-		free_area_init_node(0, 0, 0, zones_size, __MEMORY_START, 0);
+		free_area_init_node(0, NODE_DATA(0), 0, zones_size, __MEMORY_START, 0);
+#ifdef CONFIG_DISCONTIGMEM
+		zones_size[ZONE_DMA] = __MEMORY_SIZE_2ND >> PAGE_SHIFT;
+		zones_size[ZONE_NORMAL] = 0;
+		free_area_init_node(1, NODE_DATA(1), 0, zones_size, __MEMORY_START_2ND, 0);
+#endif
  	}
 }
 
 void __init mem_init(void)
 {
+	extern unsigned long empty_zero_page[1024];
 	int codesize, reservedpages, datasize, initsize;
 	int tmp;
 
@@ -160,10 +144,13 @@
 
 	/* clear the zero-page */
 	memset(empty_zero_page, 0, PAGE_SIZE);
-	flush_page_to_ram(virt_to_page(empty_zero_page));
+	__flush_wback_region(empty_zero_page, PAGE_SIZE);
 
 	/* this will put all low memory onto the freelists */
-	totalram_pages += free_all_bootmem();
+	totalram_pages += free_all_bootmem_node(NODE_DATA(0));
+#ifdef CONFIG_DISCONTIGMEM
+	totalram_pages += free_all_bootmem_node(NODE_DATA(1));
+#endif
 	reservedpages = 0;
 	for (tmp = 0; tmp < num_physpages; tmp++)
 		/*
@@ -182,6 +169,8 @@
 		reservedpages << (PAGE_SHIFT-10),
 		datasize >> 10,
 		initsize >> 10);
+
+	p3_cache_init();
 }
 
 void free_initmem(void)
diff -u --recursive --new-file v2.4.9/linux/arch/sh/mm/ioremap.c linux/arch/sh/mm/ioremap.c
--- v2.4.9/linux/arch/sh/mm/ioremap.c	Wed Apr 11 21:24:52 2001
+++ linux/arch/sh/mm/ioremap.c	Sat Sep  8 12:29:09 2001
@@ -1,4 +1,4 @@
-/* $Id: ioremap.c,v 1.2 1999/11/25 14:00:28 gniibe Exp $
+/* $Id: ioremap.c,v 1.4 2001/06/30 09:18:39 gniibe Exp $
  *
  * arch/sh/mm/ioremap.c
  *
@@ -13,8 +13,8 @@
 #include <asm/io.h>
 #include <asm/pgalloc.h>
 
-static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
-	unsigned long phys_addr, unsigned long flags)
+static inline void remap_area_pte(pte_t * pte, unsigned long address,
+	unsigned long size, unsigned long phys_addr, unsigned long flags)
 {
 	unsigned long end;
 	pgprot_t pgprot = __pgprot(_PAGE_PRESENT | _PAGE_RW |
@@ -36,11 +36,11 @@
 		address += PAGE_SIZE;
 		phys_addr += PAGE_SIZE;
 		pte++;
-	} while (address && address < end);
+	} while (address && (address < end));
 }
 
-static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
-	unsigned long phys_addr, unsigned long flags)
+static inline int remap_area_pmd(pmd_t * pmd, unsigned long address,
+	unsigned long size, unsigned long phys_addr, unsigned long flags)
 {
 	unsigned long end;
 
@@ -58,19 +58,19 @@
 		remap_area_pte(pte, address, end - address, address + phys_addr, flags);
 		address = (address + PMD_SIZE) & PMD_MASK;
 		pmd++;
-	} while (address && address < end);
+	} while (address && (address < end));
 	return 0;
 }
 
-static int remap_area_pages(unsigned long address, unsigned long phys_addr,
-			    unsigned long size, unsigned long flags)
+int remap_area_pages(unsigned long address, unsigned long phys_addr,
+		     unsigned long size, unsigned long flags)
 {
 	int error;
 	pgd_t * dir;
 	unsigned long end = address + size;
 
 	phys_addr -= address;
-	dir = pgd_offset(&init_mm, address);
+	dir = pgd_offset_k(address);
 	flush_cache_all();
 	if (address >= end)
 		BUG();
@@ -106,7 +106,7 @@
  * have to convert them into an offset in a page-aligned mapping, but the
  * caller shouldn't need to know that small detail.
  */
-void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)
+void * p3_ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)
 {
 	void * addr;
 	struct vm_struct * area;
@@ -150,7 +150,7 @@
 	return (void *) (offset + (char *)addr);
 }
 
-void iounmap(void *addr)
+void p3_iounmap(void *addr)
 {
 	if (addr > high_memory)
 		return vfree((void *) (PAGE_MASK & (unsigned long) addr));
diff -u --recursive --new-file v2.4.9/linux/arch/sh/vmlinux.lds.S linux/arch/sh/vmlinux.lds.S
--- v2.4.9/linux/arch/sh/vmlinux.lds.S	Tue Jul  3 17:08:19 2001
+++ linux/arch/sh/vmlinux.lds.S	Sat Sep  8 12:29:09 2001
@@ -1,4 +1,4 @@
-/* $Id: vmlinux.lds.S,v 1.4 1999/12/23 11:37:45 gniibe Exp $
+/* $Id: vmlinux.lds.in,v 1.5 2001/07/27 11:45:55 gniibe Exp $
  * ld script to make SuperH Linux kernel
  * Written by Niibe Yutaka
  */
@@ -74,7 +74,11 @@
   . = ALIGN(4096);
   .data.page_aligned : { *(.data.idt) }
 
+#ifdef CONFIG_CPU_SH3	
+  . = ALIGN(16);
+#else
   . = ALIGN(32);
+#endif	
   .data.cacheline_aligned : { *(.data.cacheline_aligned) }
 
   . = ALIGN(4);
diff -u --recursive --new-file v2.4.9/linux/arch/sparc/boot/btfixupprep.c linux/arch/sparc/boot/btfixupprep.c
--- v2.4.9/linux/arch/sparc/boot/btfixupprep.c	Sun Oct  4 10:22:42 1998
+++ linux/arch/sparc/boot/btfixupprep.c	Tue Aug 28 07:09:44 2001
@@ -1,4 +1,4 @@
-/* $Id: btfixupprep.c,v 1.5 1998/09/16 12:24:55 jj Exp $
+/* $Id: btfixupprep.c,v 1.6 2001/08/22 15:27:47 davem Exp $
    Simple utility to prepare vmlinux image for sparc.
    Resolves all BTFIXUP uses and settings and creates
    a special .s object to link to the image.
@@ -88,6 +88,16 @@
 	return array + last - 1;
 }
 
+void set_mode (char *buffer)
+{
+  	for (mode = 0;; mode++)
+		if (buffer[mode] < '0' || buffer[mode] > '9')
+			break;
+	if (mode != 8 && mode != 16)
+		fatal();
+}
+
+
 int main(int argc,char **argv)
 {
 	char *p, *q;
@@ -106,14 +116,6 @@
 			goto main0;
 	fatal();
 main0:
-	if (fgets (buffer, 1024, stdin) == NULL || buffer[0] < '0' || buffer[0] > '9')
-		fatal();
-	for (mode = 0;; mode++)
-		if (buffer[mode] < '0' || buffer[mode] > '9')
-			break;
-	if (mode != 8 && mode != 16)
-		fatal();
-	
 	rellen = strlen(relrec);
 	while (fgets (buffer, 1024, stdin) != NULL)
 		if (!strncmp (buffer, relrec, rellen))
@@ -132,6 +134,8 @@
 		int nbase;
 		if (!strncmp (buffer, relrec, rellen))
 			goto main1;
+		if (mode == 0)
+			set_mode (buffer);
 		p = strchr (buffer, '\n');
 		if (p) *p = 0;
 		if (strlen (buffer) < 22+mode)
diff -u --recursive --new-file v2.4.9/linux/arch/sparc64/defconfig linux/arch/sparc64/defconfig
--- v2.4.9/linux/arch/sparc64/defconfig	Mon Aug 27 12:41:40 2001
+++ linux/arch/sparc64/defconfig	Fri Sep  7 11:01:20 2001
@@ -255,6 +255,7 @@
 CONFIG_BLK_DEV_IDEPCI=y
 # CONFIG_IDEPCI_SHARE_IRQ is not set
 CONFIG_BLK_DEV_IDEDMA_PCI=y
+CONFIG_BLK_DEV_ADMA=y
 # CONFIG_BLK_DEV_OFFBOARD is not set
 CONFIG_IDEDMA_PCI_AUTO=y
 CONFIG_BLK_DEV_IDEDMA=y
@@ -264,8 +265,8 @@
 # CONFIG_AEC62XX_TUNING is not set
 CONFIG_BLK_DEV_ALI15X3=y
 # CONFIG_WDC_ALI15X3 is not set
-# CONFIG_BLK_DEV_AMD7409 is not set
-# CONFIG_AMD7409_OVERRIDE is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_AMD74XX_OVERRIDE is not set
 CONFIG_BLK_DEV_CMD64X=y
 # CONFIG_BLK_DEV_CY82C693 is not set
 # CONFIG_BLK_DEV_CS5530 is not set
@@ -276,7 +277,8 @@
 # CONFIG_BLK_DEV_OPTI621 is not set
 # CONFIG_BLK_DEV_PDC202XX is not set
 # CONFIG_PDC202XX_BURST is not set
-# CONFIG_BLK_DEV_OSB4 is not set
+# CONFIG_PDC202XX_FORCE is not set
+# CONFIG_BLK_DEV_SVWKS is not set
 # CONFIG_BLK_DEV_SIS5513 is not set
 # CONFIG_BLK_DEV_SLC90E66 is not set
 # CONFIG_BLK_DEV_TRM290 is not set
@@ -709,7 +711,10 @@
 CONFIG_USB_STORAGE=m
 # CONFIG_USB_STORAGE_DEBUG is not set
 CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
 CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_HP8200e=y
+CONFIG_USB_STORAGE_SDDR09=y
 CONFIG_USB_ACM=m
 CONFIG_USB_PRINTER=m
 
@@ -740,10 +745,10 @@
 #
 # USB Network adaptors
 #
-CONFIG_USB_PLUSB=m
 CONFIG_USB_PEGASUS=m
 CONFIG_USB_CATC=m
-CONFIG_USB_NET1080=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_USBNET=m
 
 #
 # USB port drivers
diff -u --recursive --new-file v2.4.9/linux/arch/sparc64/kernel/dtlb_backend.S linux/arch/sparc64/kernel/dtlb_backend.S
--- v2.4.9/linux/arch/sparc64/kernel/dtlb_backend.S	Mon Aug 27 12:41:40 2001
+++ linux/arch/sparc64/kernel/dtlb_backend.S	Tue Aug 28 07:09:44 2001
@@ -1,4 +1,4 @@
-/* $Id: dtlb_backend.S,v 1.12 2001/08/13 20:41:54 kanoj Exp $
+/* $Id: dtlb_backend.S,v 1.13 2001/08/17 04:55:09 kanoj Exp $
  * dtlb_backend.S: Back end to DTLB miss replacement strategy.
  *                 This is included directly into the trap table.
  *
@@ -6,11 +6,27 @@
  * Copyright (C) 1997,1998 Jakub Jelinek   (jj@ultra.linux.cz)
  */
 
-#define TAG_CONTEXT_BITS	0x3ff
+#include <asm/pgtable.h>
+
+#if PAGE_SHIFT == 13
+#define FILL_VALID_SZ_BITS1(r1) \
+	 sllx		%g2, 62, r1
+#define FILL_VALID_SZ_BITS2(r1)
+#define FILL_VALID_SZ_BITS_NOP nop
+#else /* PAGE_SHIFT */
+#define FILL_VALID_SZ_BITS1(r1) \
+	or		%g0, 5, r1
+#define FILL_VALID_SZ_BITS2(r1) \
+	sllx		r1, 61, r1
+#define FILL_VALID_SZ_BITS_NOP
+#endif /* PAGE_SHIFT */
+
+#define VPTE_BITS		(_PAGE_CP | _PAGE_CV | _PAGE_P )
 #define VPTE_SHIFT		(PAGE_SHIFT - 3)
-#define PMD_SHIFT		(23 - PAGE_SHIFT + 3)
-#define PGD_SHIFT		(34 - PAGE_SHIFT + 3)
-#define VPTE_BITS		(_PAGE_CP | _PAGE_CV | _PAGE_P)
+#define TLB_PMD_SHIFT		(PAGE_SHIFT - 3 + 3)
+#define TLB_PGD_SHIFT		(PAGE_SHIFT - 2 + PAGE_SHIFT - 3 + 3)
+#define TLB_PMD_MASK		(((1 << PMD_BITS) - 1) << 1)
+#define TLB_PGD_MASK		(((1 << (VA_BITS - PAGE_SHIFT - (PAGE_SHIFT - 3) - PMD_BITS)) - 1) << 2)
 
 /* Ways we can get here:
  *
@@ -31,13 +47,13 @@
 
 /* TLB1 ** ICACHE line 2: Quick VPTE miss	  	*/
 	ldxa		[%g1] ASI_DMMU, %g5		! Doing PGD caching?
-	srlx		%g6, (PMD_SHIFT - 1), %g1	! Position PMD offset
+	srlx		%g6, (TLB_PMD_SHIFT - 1), %g1	! Position PMD offset
 	be,pn		%xcc, sparc64_vpte_nucleus	! Is it from Nucleus?
-	 and		%g1, 0xffe, %g1			! Mask PMD offset bits
+	 and		%g1, TLB_PMD_MASK, %g1		! Mask PMD offset bits
 	brnz,pt		%g5, sparc64_vpte_continue	! Yep, go like smoke
 	 add		%g1, %g1, %g1			! Position PMD offset some more
-	srlx		%g6, (PGD_SHIFT - 2), %g5	! Position PGD offset
-	and		%g5, 0xffc, %g5			! Mask PGD offset
+	srlx		%g6, (TLB_PGD_SHIFT - 2), %g5	! Position PGD offset
+	and		%g5, TLB_PGD_MASK, %g5		! Mask PGD offset
 
 /* TLB1 ** ICACHE line 3: Quick VPTE miss	  	*/
 	lduwa		[%g7 + %g5] ASI_PHYS_USE_EC, %g5! Load PGD
@@ -48,7 +64,8 @@
 	lduwa		[%g5 + %g1] ASI_PHYS_USE_EC, %g5! Load PMD
 	sllx		%g5, 11, %g5			! Shift into place
 	brz,pn		%g5, vpte_noent			! Valid?
-	 sllx		%g2, 62, %g1			! Put _PAGE_VALID into %g1
+	 FILL_VALID_SZ_BITS1(%g1)			! Put _PAGE_VALID into %g1
+	FILL_VALID_SZ_BITS2(%g1)			! Put _PAGE_VALID into %g1
 	or		%g5, VPTE_BITS, %g5		! Prepare VPTE data
 
 /* TLB1 ** ICACHE line 4: Quick VPTE miss	  	*/
@@ -59,10 +76,15 @@
 	retry						! Load PTE once again
 	nop
 	nop
-	nop
+	FILL_VALID_SZ_BITS_NOP
 
-#undef TAG_CONTEXT_BITS
 #undef VPTE_SHIFT
-#undef PMD_SHIFT
-#undef PGD_SHIFT
+#undef TLB_PMD_SHIFT
+#undef TLB_PGD_SHIFT
 #undef VPTE_BITS
+#undef TLB_PMD_MASK
+#undef TLB_PGD_MASK
+#undef FILL_VALID_SZ_BITS1
+#undef FILL_VALID_SZ_BITS2
+#undef FILL_VALID_SZ_BITS_NOP
+
diff -u --recursive --new-file v2.4.9/linux/arch/sparc64/kernel/dtlb_base.S linux/arch/sparc64/kernel/dtlb_base.S
--- v2.4.9/linux/arch/sparc64/kernel/dtlb_base.S	Mon Aug 27 12:41:40 2001
+++ linux/arch/sparc64/kernel/dtlb_base.S	Tue Aug 28 07:09:44 2001
@@ -1,4 +1,4 @@
-/* $Id: dtlb_base.S,v 1.10 2001/08/13 20:41:54 kanoj Exp $
+/* $Id: dtlb_base.S,v 1.12 2001/08/17 04:55:09 kanoj Exp $
  * dtlb_base.S:	Front end to DTLB miss replacement strategy.
  *              This is included directly into the trap table.
  *
@@ -6,11 +6,6 @@
  * Copyright (C) 1997,1998 Jakub Jelinek   (jj@ultra.linux.cz)
  */
 
-#define TAG_CONTEXT_BITS	0x3ff
-#define VPTE_SHIFT		(PAGE_SHIFT - 3)
-#define KERN_HIGHBITS		((_PAGE_VALID | _PAGE_SZ4MB) ^ 0xfffff80000000000)
-#define KERN_LOWBITS		(_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_W)
-
 /* %g1	TLB_SFSR	(%g1 + %g1 == TLB_TAG_ACCESS)
  * %g2	(KERN_HIGHBITS | KERN_LOWBITS)
  * %g3  VPTE base	(0xfffffffe00000000)	Spitfire/Blackbird (44-bit VA space)
@@ -48,26 +43,47 @@
  * 4) User space accesses by nucleus at tl0
  */
 
+#if PAGE_SHIFT == 13
+/*
+ * To compute vpte offset, we need to do ((addr >> 13) << 3),
+ * which can be optimized to (addr >> 10) if bits 10/11/12 can
+ * be guaranteed to be 0 ... mmu_context.h does guarantee this
+ * by only using 10 bits in the hwcontext value.
+ */
+#define CREATE_VPTE_OFFSET1(r1, r2)
+#define CREATE_VPTE_OFFSET2(r1, r2) \
+				srax	r1, 10, r2
+#define CREATE_VPTE_NOP		nop
+#else
+#define CREATE_VPTE_OFFSET1(r1, r2) \
+				srax	r1, PAGE_SHIFT, r2
+#define CREATE_VPTE_OFFSET2(r1, r2) \
+				sllx	r2, 3, r2
+#define CREATE_VPTE_NOP
+#endif
+
 /* DTLB ** ICACHE line 1: Quick user TLB misses		*/
 	ldxa		[%g1 + %g1] ASI_DMMU, %g4	! Get TAG_ACCESS
 	andcc		%g4, TAG_CONTEXT_BITS, %g0	! From Nucleus?
 from_tl1_trap:
+	CREATE_VPTE_OFFSET1(%g4, %g6)			! Create VPTE offset
 	be,pn		%xcc, 3f			! Yep, special processing
-	 srax		%g4, VPTE_SHIFT, %g6		! Create VPTE offset
+	 CREATE_VPTE_OFFSET2(%g4, %g6)			! Create VPTE offset
 	ldxa		[%g3 + %g6] ASI_S, %g5		! Load VPTE
 1:	brlz,pt		%g5, 9f				! Valid, load into TLB
 	 nop						! Delay-slot
-	ba,a,pt		%xcc, 4f			! Invalid, branch out
+	ba,a,pt		%xcc, longpath			! Invalid, branch out
 
 /* DTLB ** ICACHE line 2: Quick kernel TLB misses	*/
 3:	brlz,pt		%g4, 9f				! Kernel virtual map?
 	 xor		%g2, %g4, %g5			! Finish bit twiddles
-	ldxa		[%g3 + %g6] ASI_N, %g5		! Yep, load k-vpte
-	ba,pt		%xcc, 1b			! Continue tlb reload
+	ba,pt		%xcc, kvmap			! Yep, go check for obp/vmalloc
 	 nop
+	nop
 9:	stxa		%g5, [%g0] ASI_DTLB_DATA_IN	! Reload TLB
 	retry						! Trap return
-4:	rdpr		%pstate, %g5			! Move into alternate globals
+longpath:
+	rdpr		%pstate, %g5			! Move into alternate globals
 
 /* DTLB ** ICACHE line 3: winfixups+real_faults		*/
 	wrpr		%g5, PSTATE_AG|PSTATE_MG, %pstate
@@ -87,9 +103,8 @@
 	nop
 	nop
 	nop
-	nop
+	CREATE_VPTE_NOP
 
-#undef TAG_CONTEXT_BITS
-#undef VPTE_SHIFT
-#undef KERN_HIGHBITS
-#undef KERN_LOWBITS
+#undef CREATE_VPTE_OFFSET1
+#undef CREATE_VPTE_OFFSET2
+#undef CREATE_VPTE_NOP
diff -u --recursive --new-file v2.4.9/linux/arch/sparc64/kernel/entry.S linux/arch/sparc64/kernel/entry.S
--- v2.4.9/linux/arch/sparc64/kernel/entry.S	Mon Aug 27 12:41:40 2001
+++ linux/arch/sparc64/kernel/entry.S	Tue Aug 28 07:09:44 2001
@@ -1,4 +1,4 @@
-/* $Id: entry.S,v 1.129 2001/08/13 20:41:54 kanoj Exp $
+/* $Id: entry.S,v 1.134 2001/08/27 18:42:07 kanoj Exp $
  * arch/sparc64/kernel/entry.S:  Sparc64 trap low-level entry points.
  *
  * Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu)
@@ -21,7 +21,7 @@
 #include <asm/visasm.h>
 #include <asm/estate.h>
 
-/* #define SYSCALL_TRACING */
+/* #define SYSCALL_TRACING	1 */
 
 #define curptr      g6
 
@@ -32,7 +32,25 @@
 
 	.globl		sparc64_vpte_patchme1
 	.globl		sparc64_vpte_patchme2
+/*
+ * On a second level vpte miss, check whether the original fault is to the OBP 
+ * range (note that this is only possible for instruction miss, data misses to
+ * obp range do not use vpte). If so, go back directly to the faulting address.
+ * This is because we want to read the tpc, otherwise we have no way of knowing
+ * the 8k aligned faulting address if we are using >8k kernel pagesize. This also
+ * ensures no vpte range addresses are dropped into tlb while obp is executing
+ * (see inherit_locked_prom_mappings() rant).
+ */
 sparc64_vpte_nucleus:
+	mov		0xf, %g5
+	sllx		%g5, 28, %g5			! Load 0xf0000000
+	cmp		%g4, %g5			! Is addr >= LOW_OBP_ADDRESS?
+	blu,pn		%xcc, sparc64_vpte_patchme1
+	 mov		0x1, %g5
+	sllx		%g5, 32, %g5			! Load 0x100000000
+	cmp		%g4, %g5			! Is addr < HI_OBP_ADDRESS?
+	blu,pn		%xcc, obp_iaddr_patch
+	 nop
 sparc64_vpte_patchme1:
 	sethi		%hi(0), %g5			! This has to be patched
 sparc64_vpte_patchme2:
@@ -45,6 +63,74 @@
 	stxa		%g4, [%g1 + %g1] ASI_DMMU	! Restore previous TAG_ACCESS
 	done						! Slick trick
 
+	.globl		obp_iaddr_patch
+	.globl		obp_daddr_patch
+
+obp_iaddr_patch:
+	sethi		%hi(0), %g5			! This and following is patched
+	or		%g5, %lo(0), %g5		! g5 now holds obp pmd base physaddr
+	wrpr		%g0, 1, %tl			! Behave as if we are at TL0
+	rdpr		%tpc, %g4			! Find original faulting iaddr
+	srlx		%g4, 13, %g4			! Throw out context bits
+	sllx		%g4, 13, %g4			! g4 has vpn + ctx0 now
+	mov		TLB_SFSR, %g1			! Restore %g1 value
+	stxa		%g4, [%g1 + %g1] ASI_IMMU	! Restore previous TAG_ACCESS
+	srlx		%g4, 23, %g6			! Find pmd number
+	and		%g6, 0x7ff, %g6			! Find pmd number
+	sllx		%g6, 2, %g6			! Find pmd offset
+	lduwa		[%g5 + %g6] ASI_PHYS_USE_EC, %g5! Load pmd, ie pagetable physaddr
+	brz,pn		%g5, longpath			! Kill the PROM ? :-)
+	 sllx		%g5, 11, %g5			! Shift into place
+	srlx		%g4, 13, %g6			! find pte number in pagetable
+	and		%g6, 0x3ff, %g6			! find pte number in pagetable
+	sllx		%g6, 3, %g6			! find pte offset in pagetable
+	ldxa		[%g5 + %g6] ASI_PHYS_USE_EC, %g5! Load pte
+	brgez,pn	%g5, longpath			! Kill the PROM ? :-)
+	 nop
+	stxa		%g5, [%g0] ASI_ITLB_DATA_IN	! put into tlb
+	retry						! go back to original fault
+
+obp_daddr_patch:
+	sethi		%hi(0), %g5			! This and following is patched
+	or		%g5, %lo(0), %g5		! g5 now holds obp pmd base physaddr
+	srlx		%g4, 23, %g6			! Find pmd number
+	and		%g6, 0x7ff, %g6			! Find pmd number
+	sllx		%g6, 2, %g6			! Find pmd offset
+	lduwa		[%g5 + %g6] ASI_PHYS_USE_EC, %g5! Load pmd, ie pagetable physaddr
+	brz,pn		%g5, longpath
+	 sllx		%g5, 11, %g5			! Shift into place
+	srlx		%g4, 13, %g6			! find pte number in pagetable
+	and		%g6, 0x3ff, %g6			! find pte number in pagetable
+	sllx		%g6, 3, %g6			! find pte offset in pagetable
+	ldxa		[%g5 + %g6] ASI_PHYS_USE_EC, %g5! Load pte
+	brgez,pn	%g5, longpath
+	 nop
+	stxa		%g5, [%g0] ASI_DTLB_DATA_IN	! put into tlb
+	retry
+
+/*
+ * On a first level data miss, check whether this is to the OBP range (note that
+ * such accesses can be made by prom, as well as by kernel using prom_getproperty
+ * on "address"), and if so, do not use vpte access ... rather, use information
+ * saved during inherit_prom_mappings() using 8k pagesize.
+ */
+kvmap:
+	mov		0xf, %g5
+	sllx		%g5, 28, %g5			! Load 0xf0000000
+	cmp		%g4, %g5			! Is addr >= LOW_OBP_ADDRESS?
+	blu,pn		%xcc, vmalloc_addr
+	 mov		0x1, %g5
+	sllx		%g5, 32, %g5			! Load 0x100000000
+	cmp		%g4, %g5			! Is addr < HI_OBP_ADDRESS?
+	blu,pn		%xcc, obp_daddr_patch
+	 nop
+vmalloc_addr:						! vmalloc addr accessed
+	ldxa		[%g3 + %g6] ASI_N, %g5		! Yep, load k-vpte
+	brgez,pn	%g5, longpath			! Valid, load into TLB
+	 nop
+	stxa		%g5, [%g0] ASI_DTLB_DATA_IN	! Reload TLB
+	retry
+
 	/* This is trivial with the new code... */
 	.globl		do_fpdis
 do_fpdis:
@@ -1413,9 +1499,8 @@
 	 srl		%i0, 0, %o0				! IEU0
 	sll		%g1, 2, %l4				! IEU0	Group
 #ifdef SYSCALL_TRACING
-	add		%sp, STACK_BIAS + REGWIN_SZ, %o1
 	call		syscall_trace_entry
-	 mov		%g1, %o0
+	 add		%sp, STACK_BIAS + REGWIN_SZ, %o0
 	srl		%i0, 0, %o0
 #endif
 	mov		%i4, %o4				! IEU1
@@ -1442,9 +1527,8 @@
 	 mov		%i0, %o0				! IEU0
 	sll		%g1, 2, %l4				! IEU0	Group
 #ifdef SYSCALL_TRACING
-	add		%sp, STACK_BIAS + REGWIN_SZ, %o1
 	call		syscall_trace_entry
-	 mov		%g1, %o0
+	 add		%sp, STACK_BIAS + REGWIN_SZ, %o0
 	mov		%i0, %o0
 #endif
 	mov		%i1, %o1				! IEU1
@@ -1464,8 +1548,10 @@
 3:	stx		%o0, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I0]
 ret_sys_call:
 #ifdef SYSCALL_TRACING
+	mov		%o0, %o1
 	call		syscall_trace_exit
-	 add		%sp, STACK_BIAS + REGWIN_SZ, %o1
+	 add		%sp, STACK_BIAS + REGWIN_SZ, %o0
+	mov		%o1, %o0
 #endif
 	ldx		[%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TSTATE], %g3
 	ldx		[%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TNPC], %l1 ! pc = npc
diff -u --recursive --new-file v2.4.9/linux/arch/sparc64/kernel/head.S linux/arch/sparc64/kernel/head.S
--- v2.4.9/linux/arch/sparc64/kernel/head.S	Thu Apr 12 12:10:25 2001
+++ linux/arch/sparc64/kernel/head.S	Fri Sep  7 11:01:20 2001
@@ -1,4 +1,4 @@
-/* $Id: head.S,v 1.77 2001/04/05 12:44:34 davem Exp $
+/* $Id: head.S,v 1.78 2001/08/30 03:22:00 kanoj Exp $
  * head.S: Initial boot code for the Sparc64 port of Linux.
  *
  * Copyright (C) 1996,1997 David S. Miller (davem@caip.rutgers.edu)
@@ -488,13 +488,6 @@
 	call	__bzero
 	 sub	%o1, %o0, %o1
 
-	/* Now clear empty_zero_page */
-	sethi	%hi(8192), %o1
-	or	%o1, %lo(8192), %o1
-	sethi	%hi(KERNBASE), %g3
-	call	__bzero
-	 or	%g3, %lo(KERNBASE), %o0
-
 	mov	%l6, %o1			! OpenPROM stack
 	call	prom_init
 	 mov	%l7, %o0			! OpenPROM cif handler
@@ -647,12 +640,13 @@
 	ret
 	 restore
 
+/*
+ * The following skips make sure the trap table in ttable.S is aligned
+ * on a 32K boundary as required by the v9 specs for TBA register.
+ */
 sparc64_boot_end:
 	.skip	0x2000 + _start - sparc64_boot_end
 bootup_user_stack_end:
-
-	.globl	empty_bad_page
-empty_bad_page:
 	.skip	0x2000
 
 #ifdef CONFIG_SBUS
diff -u --recursive --new-file v2.4.9/linux/arch/sparc64/kernel/ioctl32.c linux/arch/sparc64/kernel/ioctl32.c
--- v2.4.9/linux/arch/sparc64/kernel/ioctl32.c	Sun Aug 12 13:27:59 2001
+++ linux/arch/sparc64/kernel/ioctl32.c	Fri Sep  7 11:01:20 2001
@@ -1,4 +1,4 @@
-/* $Id: ioctl32.c,v 1.121 2001/08/03 14:27:21 davem Exp $
+/* $Id: ioctl32.c,v 1.123 2001/09/02 03:52:07 davem Exp $
  * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
  *
  * Copyright (C) 1997-2000  Jakub Jelinek  (jakub@redhat.com)
@@ -3691,6 +3691,8 @@
 COMPATIBLE_IOCTL(BLKFRASET)
 COMPATIBLE_IOCTL(BLKSECTSET)
 COMPATIBLE_IOCTL(BLKSSZGET)
+COMPATIBLE_IOCTL(BLKBSZGET)
+COMPATIBLE_IOCTL(BLKBSZSET)
 
 /* RAID */
 COMPATIBLE_IOCTL(RAID_VERSION)
@@ -3733,6 +3735,7 @@
 COMPATIBLE_IOCTL(KDGKBSENT)
 COMPATIBLE_IOCTL(KDSKBSENT)
 COMPATIBLE_IOCTL(KDGKBDIACR)
+COMPATIBLE_IOCTL(KDKBDREP)
 COMPATIBLE_IOCTL(KDSKBDIACR)
 COMPATIBLE_IOCTL(KDGKBLED)
 COMPATIBLE_IOCTL(KDSKBLED)
diff -u --recursive --new-file v2.4.9/linux/arch/sparc64/kernel/iommu_common.c linux/arch/sparc64/kernel/iommu_common.c
--- v2.4.9/linux/arch/sparc64/kernel/iommu_common.c	Mon Jun 19 17:59:38 2000
+++ linux/arch/sparc64/kernel/iommu_common.c	Tue Aug 28 07:09:44 2001
@@ -1,4 +1,4 @@
-/* $Id: iommu_common.c,v 1.4 2000/06/04 21:50:23 anton Exp $
+/* $Id: iommu_common.c,v 1.5 2001/08/24 17:57:51 kanoj Exp $
  * iommu_common.c: UltraSparc SBUS/PCI common iommu code.
  *
  * Copyright (C) 1999 David S. Miller (davem@redhat.com)
@@ -36,12 +36,12 @@
 		unsigned long start, end;
 
 		start = sg[i].dvma_address;
-		start = start & PAGE_MASK;
+		start = start & IO_PAGE_MASK;
 
 		end = sg[i].dvma_address + sg[i].dvma_length;
-		end = (end + (PAGE_SIZE - 1)) & PAGE_MASK;
+		end = (end + (IO_PAGE_SIZE - 1)) & IO_PAGE_MASK;
 
-		pgcount += ((end - start) >> PAGE_SHIFT);
+		pgcount += ((end - start) >> IO_PAGE_SHIFT);
 	}
 
 	if (pgcount != npages) {
@@ -70,7 +70,7 @@
 		unsigned long paddr;
 
 		/* SG and DMA_SG must begin at the same sub-page boundary. */
-		if ((sgaddr & ~PAGE_MASK) != (daddr & ~PAGE_MASK)) {
+		if ((sgaddr & ~IO_PAGE_MASK) != (daddr & ~IO_PAGE_MASK)) {
 			printk("verify_one_map: Wrong start offset "
 			       "sg[%08lx] dma[%08x]\n",
 			       sgaddr, daddr);
@@ -80,10 +80,10 @@
 
 		/* Verify the IOPTE points to the right page. */
 		paddr = iopte_val(*iopte) & IOPTE_PAGE;
-		if ((paddr + PAGE_OFFSET) != (sgaddr & PAGE_MASK)) {
+		if ((paddr + PAGE_OFFSET) != (sgaddr & IO_PAGE_MASK)) {
 			printk("verify_one_map: IOPTE[%08lx] maps the "
 			       "wrong page, should be [%08lx]\n",
-			       iopte_val(*iopte), (sgaddr & PAGE_MASK) - PAGE_OFFSET);
+			       iopte_val(*iopte), (sgaddr & IO_PAGE_MASK) - PAGE_OFFSET);
 			nents = -1;
 			goto out;
 		}
@@ -91,10 +91,10 @@
 		/* If this SG crosses a page, adjust to that next page
 		 * boundary and loop.
 		 */
-		if ((sgaddr & PAGE_MASK) ^ ((sgaddr + sglen - 1) & PAGE_MASK)) {
+		if ((sgaddr & IO_PAGE_MASK) ^ ((sgaddr + sglen - 1) & IO_PAGE_MASK)) {
 			unsigned long next_page, diff;
 
-			next_page = (sgaddr + PAGE_SIZE) & PAGE_MASK;
+			next_page = (sgaddr + IO_PAGE_SIZE) & IO_PAGE_MASK;
 			diff = next_page - sgaddr;
 			sgaddr += diff;
 			daddr += diff;
@@ -109,7 +109,7 @@
 		daddr += sglen;
 		dlen -= sglen;
 
-		if (dlen > 0 && ((daddr & ~PAGE_MASK) == 0))
+		if (dlen > 0 && ((daddr & ~IO_PAGE_MASK) == 0))
 			iopte++;
 
 		sg++;
@@ -175,7 +175,7 @@
 		int i;
 
 		printk("verify_sglist: Crap, messed up mappings, dumping, iodma at %08x.\n",
-		       (u32) (sg->dvma_address & PAGE_MASK));
+		       (u32) (sg->dvma_address & IO_PAGE_MASK));
 		for (i = 0; i < nents; i++) {
 			printk("sg(%d): address(%p) length(%x) "
 			       "dma_address[%08x] dma_length[%08x]\n",
@@ -189,13 +189,6 @@
 }
 #endif
 
-/* Two addresses are "virtually contiguous" if and only if:
- * 1) They are equal, or...
- * 2) They are both on a page boundry
- */
-#define VCONTIG(__X, __Y)	(((__X) == (__Y)) || \
-				 (((__X) | (__Y)) << (64UL - PAGE_SHIFT)) == 0UL)
-
 unsigned long prepare_sg(struct scatterlist *sg, int nents)
 {
 	struct scatterlist *dma_sg = sg;
@@ -204,7 +197,7 @@
 
 	prev  = (unsigned long) sg->address;
 	prev += (unsigned long) (dent_len = sg->length);
-	dent_addr = (u32) ((unsigned long)sg->address & (PAGE_SIZE - 1UL));
+	dent_addr = (u32) ((unsigned long)sg->address & (IO_PAGE_SIZE - 1UL));
 	while (--nents) {
 		unsigned long addr;
 
@@ -217,9 +210,9 @@
 
 			dent_addr = ((dent_addr +
 				      dent_len +
-				      (PAGE_SIZE - 1UL)) >> PAGE_SHIFT);
-			dent_addr <<= PAGE_SHIFT;
-			dent_addr += addr & (PAGE_SIZE - 1UL);
+				      (IO_PAGE_SIZE - 1UL)) >> IO_PAGE_SHIFT);
+			dent_addr <<= IO_PAGE_SHIFT;
+			dent_addr += addr & (IO_PAGE_SIZE - 1UL);
 			dent_len = 0;
 		}
 		dent_len += sg->length;
@@ -230,5 +223,5 @@
 
 	return ((unsigned long) dent_addr +
 		(unsigned long) dent_len +
-		(PAGE_SIZE - 1UL)) >> PAGE_SHIFT;
+		(IO_PAGE_SIZE - 1UL)) >> IO_PAGE_SHIFT;
 }
diff -u --recursive --new-file v2.4.9/linux/arch/sparc64/kernel/iommu_common.h linux/arch/sparc64/kernel/iommu_common.h
--- v2.4.9/linux/arch/sparc64/kernel/iommu_common.h	Mon Dec 20 22:05:52 1999
+++ linux/arch/sparc64/kernel/iommu_common.h	Tue Aug 28 07:09:44 2001
@@ -1,4 +1,4 @@
-/* $Id: iommu_common.h,v 1.1 1999/12/17 12:31:54 jj Exp $
+/* $Id: iommu_common.h,v 1.3 2001/08/24 19:36:58 kanoj Exp $
  * iommu_common.h: UltraSparc SBUS/PCI common iommu declarations.
  *
  * Copyright (C) 1999 David S. Miller (davem@redhat.com)
@@ -10,6 +10,22 @@
 #include <asm/page.h>
 #include <asm/iommu.h>
 #include <asm/scatterlist.h>
+
+/*
+ * These give mapping size of each iommu pte/tlb.
+ */
+#define IO_PAGE_SHIFT			13
+#define IO_PAGE_SIZE			(1UL << IO_PAGE_SHIFT)
+#define IO_PAGE_MASK			(~(IO_PAGE_SIZE-1))
+#define IO_PAGE_ALIGN(addr)		(((addr)+IO_PAGE_SIZE-1)&IO_PAGE_MASK)
+
+#define IO_TSB_ENTRIES			(128*1024)
+#define IO_TSB_SIZE			(IO_TSB_ENTRIES * 8)
+
+/*
+ * This is the hardwired shift in the iotlb tag/data parts.
+ */
+#define IOMMU_PAGE_SHIFT		13
 
 /* You are _strongly_ advised to enable the following debugging code
  * any time you make changes to the sg code below, run it for a while
diff -u --recursive --new-file v2.4.9/linux/arch/sparc64/kernel/itlb_base.S linux/arch/sparc64/kernel/itlb_base.S
--- v2.4.9/linux/arch/sparc64/kernel/itlb_base.S	Sun Nov 12 20:37:16 2000
+++ linux/arch/sparc64/kernel/itlb_base.S	Tue Aug 28 07:09:44 2001
@@ -1,4 +1,4 @@
-/* $Id: itlb_base.S,v 1.10 2000/11/10 08:28:45 davem Exp $
+/* $Id: itlb_base.S,v 1.11 2001/08/17 04:55:09 kanoj Exp $
  * itlb_base.S:	Front end to ITLB miss replacement strategy.
  *              This is included directly into the trap table.
  *
@@ -6,8 +6,25 @@
  * Copyright (C) 1997,1998 Jakub Jelinek   (jj@ultra.linux.cz)
  */
 
-#define TAG_CONTEXT_BITS	0x3ff
-#define VPTE_SHIFT		(PAGE_SHIFT - 3)
+#if PAGE_SHIFT == 13
+/*
+ * To compute vpte offset, we need to do ((addr >> 13) << 3),
+ * which can be optimized to (addr >> 10) if bits 10/11/12 can
+ * be guaranteed to be 0 ... mmu_context.h does guarantee this
+ * by only using 10 bits in the hwcontext value.
+ */
+#define CREATE_VPTE_OFFSET1(r1, r2) \
+				srax	r1, 10, r2
+#define CREATE_VPTE_OFFSET2(r1, r2)
+#define CREATE_VPTE_NOP		nop
+#else /* PAGE_SHIFT */
+#define CREATE_VPTE_OFFSET1(r1, r2) \
+				srax	r1, PAGE_SHIFT, r2
+#define CREATE_VPTE_OFFSET2(r1, r2) \
+				sllx	r2, 3, r2
+#define CREATE_VPTE_NOP
+#endif /* PAGE_SHIFT */
+
 
 /* Ways we can get here:
  *
@@ -20,7 +37,8 @@
 
 /* ITLB ** ICACHE line 1: Quick user TLB misses		*/
 	ldxa		[%g1 + %g1] ASI_IMMU, %g4	! Get TAG_ACCESS
-	srax		%g4, VPTE_SHIFT, %g6		! Create VPTE offset
+	CREATE_VPTE_OFFSET1(%g4, %g6)			! Create VPTE offset
+	CREATE_VPTE_OFFSET2(%g4, %g6)			! Create VPTE offset
 	ldxa		[%g3 + %g6] ASI_P, %g5		! Load VPTE
 1:	brgez,pn	%g5, 3f				! Not valid, branch out
 	 nop						! Delay-slot
@@ -58,7 +76,8 @@
 	nop
 	nop
 	nop
-	nop
+	CREATE_VPTE_NOP
 
-#undef TAG_CONTEXT_BITS
-#undef VPTE_SHIFT
+#undef CREATE_VPTE_OFFSET1
+#undef CREATE_VPTE_OFFSET2
+#undef CREATE_VPTE_NOP
diff -u --recursive --new-file v2.4.9/linux/arch/sparc64/kernel/pci_iommu.c linux/arch/sparc64/kernel/pci_iommu.c
--- v2.4.9/linux/arch/sparc64/kernel/pci_iommu.c	Thu May 24 15:00:58 2001
+++ linux/arch/sparc64/kernel/pci_iommu.c	Tue Aug 28 07:09:44 2001
@@ -1,4 +1,4 @@
-/* $Id: pci_iommu.c,v 1.14 2001/05/23 03:06:51 davem Exp $
+/* $Id: pci_iommu.c,v 1.15 2001/08/24 19:36:58 kanoj Exp $
  * pci_iommu.c: UltraSparc PCI controller IOM/STC support.
  *
  * Copyright (C) 1999 David S. Miller (davem@redhat.com)
@@ -121,7 +121,7 @@
 	while ((1UL << cnum) < npages)
 		cnum++;
 
-	ent = (base << (32 - PAGE_SHIFT + PBM_LOGCLUSTERS - iommu->page_table_sz_bits))
+	ent = (base << (32 - IO_PAGE_SHIFT + PBM_LOGCLUSTERS - iommu->page_table_sz_bits))
 		>> (32 + PBM_LOGCLUSTERS + cnum - iommu->page_table_sz_bits);
 
 	/* If the global flush might not have caught this entry,
@@ -184,7 +184,7 @@
 	void *ret;
 	int npages;
 
-	size = PAGE_ALIGN(size);
+	size = IO_PAGE_ALIGN(size);
 	order = get_order(size);
 	if (order >= 10)
 		return NULL;
@@ -198,7 +198,7 @@
 	iommu = pcp->pbm->iommu;
 
 	spin_lock_irqsave(&iommu->lock, flags);
-	iopte = alloc_consistent_cluster(iommu, size >> PAGE_SHIFT);
+	iopte = alloc_consistent_cluster(iommu, size >> IO_PAGE_SHIFT);
 	if (iopte == NULL) {
 		spin_unlock_irqrestore(&iommu->lock, flags);
 		free_pages(first_page, order);
@@ -206,9 +206,9 @@
 	}
 
 	*dma_addrp = (iommu->page_table_map_base +
-		      ((iopte - iommu->page_table) << PAGE_SHIFT));
+		      ((iopte - iommu->page_table) << IO_PAGE_SHIFT));
 	ret = (void *) first_page;
-	npages = size >> PAGE_SHIFT;
+	npages = size >> IO_PAGE_SHIFT;
 	ctx = 0;
 	if (iommu->iommu_ctxflush)
 		ctx = iommu->iommu_cur_ctx++;
@@ -218,17 +218,17 @@
 				     IOPTE_WRITE |
 				     (first_page & IOPTE_PAGE));
 		iopte++;
-		first_page += PAGE_SIZE;
+		first_page += IO_PAGE_SIZE;
 	}
 
 	{
 		int i;
 		u32 daddr = *dma_addrp;
 
-		npages = size >> PAGE_SHIFT;
+		npages = size >> IO_PAGE_SHIFT;
 		for (i = 0; i < npages; i++) {
 			pci_iommu_write(iommu->iommu_flush, daddr);
-			daddr += PAGE_SIZE;
+			daddr += IO_PAGE_SIZE;
 		}
 	}
 
@@ -245,11 +245,11 @@
 	iopte_t *iopte;
 	unsigned long flags, order, npages, i, ctx;
 
-	npages = PAGE_ALIGN(size) >> PAGE_SHIFT;
+	npages = IO_PAGE_ALIGN(size) >> IO_PAGE_SHIFT;
 	pcp = pdev->sysdata;
 	iommu = pcp->pbm->iommu;
 	iopte = iommu->page_table +
-		((dvma - iommu->page_table_map_base) >> PAGE_SHIFT);
+		((dvma - iommu->page_table_map_base) >> IO_PAGE_SHIFT);
 
 	spin_lock_irqsave(&iommu->lock, flags);
 
@@ -286,7 +286,7 @@
 		pci_iommu_write(iommu->iommu_ctxflush, ctx);
 	} else {
 		for (i = 0; i < npages; i++) {
-			u32 daddr = dvma + (i << PAGE_SHIFT);
+			u32 daddr = dvma + (i << IO_PAGE_SHIFT);
 
 			pci_iommu_write(iommu->iommu_flush, daddr);
 		}
@@ -321,8 +321,8 @@
 		BUG();
 
 	oaddr = (unsigned long)ptr;
-	npages = PAGE_ALIGN(oaddr + sz) - (oaddr & PAGE_MASK);
-	npages >>= PAGE_SHIFT;
+	npages = IO_PAGE_ALIGN(oaddr + sz) - (oaddr & IO_PAGE_MASK);
+	npages >>= IO_PAGE_SHIFT;
 
 	spin_lock_irqsave(&iommu->lock, flags);
 
@@ -330,9 +330,9 @@
 	if (base == NULL)
 		goto bad;
 	bus_addr = (iommu->page_table_map_base +
-		    ((base - iommu->page_table) << PAGE_SHIFT));
-	ret = bus_addr | (oaddr & ~PAGE_MASK);
-	base_paddr = __pa(oaddr & PAGE_MASK);
+		    ((base - iommu->page_table) << IO_PAGE_SHIFT));
+	ret = bus_addr | (oaddr & ~IO_PAGE_MASK);
+	base_paddr = __pa(oaddr & IO_PAGE_MASK);
 	ctx = 0;
 	if (iommu->iommu_ctxflush)
 		ctx = iommu->iommu_cur_ctx++;
@@ -343,7 +343,7 @@
 	if (direction != PCI_DMA_TODEVICE)
 		iopte_protection |= IOPTE_WRITE;
 
-	for (i = 0; i < npages; i++, base++, base_paddr += PAGE_SIZE)
+	for (i = 0; i < npages; i++, base++, base_paddr += IO_PAGE_SIZE)
 		iopte_val(*base) = iopte_protection | base_paddr;
 
 	spin_unlock_irqrestore(&iommu->lock, flags);
@@ -372,15 +372,15 @@
 	iommu = pcp->pbm->iommu;
 	strbuf = &pcp->pbm->stc;
 
-	npages = PAGE_ALIGN(bus_addr + sz) - (bus_addr & PAGE_MASK);
-	npages >>= PAGE_SHIFT;
+	npages = IO_PAGE_ALIGN(bus_addr + sz) - (bus_addr & IO_PAGE_MASK);
+	npages >>= IO_PAGE_SHIFT;
 	base = iommu->page_table +
-		((bus_addr - iommu->page_table_map_base) >> PAGE_SHIFT);
+		((bus_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT);
 #ifdef DEBUG_PCI_IOMMU
 	if (iopte_val(*base) == IOPTE_INVALID)
 		printk("pci_unmap_single called on non-mapped region %08x,%08x from %016lx\n", bus_addr, sz, __builtin_return_address(0));
 #endif
-	bus_addr &= PAGE_MASK;
+	bus_addr &= IO_PAGE_MASK;
 
 	spin_lock_irqsave(&iommu->lock, flags);
 
@@ -404,7 +404,7 @@
 				pci_iommu_write(flushreg, ctx);
 			} while(((long)pci_iommu_read(matchreg)) < 0L);
 		} else {
-			for (i = 0; i < npages; i++, vaddr += PAGE_SIZE)
+			for (i = 0; i < npages; i++, vaddr += IO_PAGE_SIZE)
 				pci_iommu_write(strbuf->strbuf_pflush, vaddr);
 		}
 
@@ -432,9 +432,9 @@
 		unsigned long pteval = ~0UL;
 		u32 dma_npages;
 
-		dma_npages = ((dma_sg->dvma_address & (PAGE_SIZE - 1UL)) +
+		dma_npages = ((dma_sg->dvma_address & (IO_PAGE_SIZE - 1UL)) +
 			      dma_sg->dvma_length +
-			      ((u32)(PAGE_SIZE - 1UL))) >> PAGE_SHIFT;
+			      ((u32)(IO_PAGE_SIZE - 1UL))) >> IO_PAGE_SHIFT;
 		do {
 			unsigned long offset;
 			signed int len;
@@ -449,15 +449,15 @@
 
 				tmp = (unsigned long) __pa(sg->address);
 				len = sg->length;
-				if (((tmp ^ pteval) >> PAGE_SHIFT) != 0UL) {
-					pteval = tmp & PAGE_MASK;
-					offset = tmp & (PAGE_SIZE - 1UL);
+				if (((tmp ^ pteval) >> IO_PAGE_SHIFT) != 0UL) {
+					pteval = tmp & IO_PAGE_MASK;
+					offset = tmp & (IO_PAGE_SIZE - 1UL);
 					break;
 				}
-				if (((tmp ^ (tmp + len - 1UL)) >> PAGE_SHIFT) != 0UL) {
-					pteval = (tmp + PAGE_SIZE) & PAGE_MASK;
+				if (((tmp ^ (tmp + len - 1UL)) >> IO_PAGE_SHIFT) != 0UL) {
+					pteval = (tmp + IO_PAGE_SIZE) & IO_PAGE_MASK;
 					offset = 0UL;
-					len -= (PAGE_SIZE - (tmp & (PAGE_SIZE - 1UL)));
+					len -= (IO_PAGE_SIZE - (tmp & (IO_PAGE_SIZE - 1UL)));
 					break;
 				}
 				sg++;
@@ -466,8 +466,8 @@
 			pteval = iopte_protection | (pteval & IOPTE_PAGE);
 			while (len > 0) {
 				*iopte++ = __iopte(pteval);
-				pteval += PAGE_SIZE;
-				len -= (PAGE_SIZE - offset);
+				pteval += IO_PAGE_SIZE;
+				len -= (IO_PAGE_SIZE - offset);
 				offset = 0;
 				dma_npages--;
 			}
@@ -479,14 +479,14 @@
 			 * adjusting pteval along the way.  Stop when we
 			 * detect a page crossing event.
 			 */
-			while ((pteval << (64 - PAGE_SHIFT)) != 0UL &&
+			while ((pteval << (64 - IO_PAGE_SHIFT)) != 0UL &&
 			       pteval == __pa(sg->address) &&
 			       ((pteval ^
-				 (__pa(sg->address) + sg->length - 1UL)) >> PAGE_SHIFT) == 0UL) {
+				 (__pa(sg->address) + sg->length - 1UL)) >> IO_PAGE_SHIFT) == 0UL) {
 				pteval += sg->length;
 				sg++;
 			}
-			if ((pteval << (64 - PAGE_SHIFT)) == 0UL)
+			if ((pteval << (64 - IO_PAGE_SHIFT)) == 0UL)
 				pteval = ~0UL;
 		} while (dma_npages != 0);
 		dma_sg++;
@@ -534,7 +534,7 @@
 	base = alloc_streaming_cluster(iommu, npages);
 	if (base == NULL)
 		goto bad;
-	dma_base = iommu->page_table_map_base + ((base - iommu->page_table) << PAGE_SHIFT);
+	dma_base = iommu->page_table_map_base + ((base - iommu->page_table) << IO_PAGE_SHIFT);
 
 	/* Step 3: Normalize DMA addresses. */
 	used = nelems;
@@ -591,16 +591,16 @@
 	iommu = pcp->pbm->iommu;
 	strbuf = &pcp->pbm->stc;
 	
-	bus_addr = sglist->dvma_address & PAGE_MASK;
+	bus_addr = sglist->dvma_address & IO_PAGE_MASK;
 
 	for (i = 1; i < nelems; i++)
 		if (sglist[i].dvma_length == 0)
 			break;
 	i--;
-	npages = (PAGE_ALIGN(sglist[i].dvma_address + sglist[i].dvma_length) - bus_addr) >> PAGE_SHIFT;
+	npages = (IO_PAGE_ALIGN(sglist[i].dvma_address + sglist[i].dvma_length) - bus_addr) >> IO_PAGE_SHIFT;
 
 	base = iommu->page_table +
-		((bus_addr - iommu->page_table_map_base) >> PAGE_SHIFT);
+		((bus_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT);
 
 #ifdef DEBUG_PCI_IOMMU
 	if (iopte_val(*base) == IOPTE_INVALID)
@@ -629,7 +629,7 @@
 				pci_iommu_write(flushreg, ctx);
 			} while(((long)pci_iommu_read(matchreg)) < 0L);
 		} else {
-			for (i = 0; i < npages; i++, vaddr += PAGE_SIZE)
+			for (i = 0; i < npages; i++, vaddr += IO_PAGE_SIZE)
 				pci_iommu_write(strbuf->strbuf_pflush, vaddr);
 		}
 
@@ -667,9 +667,9 @@
 
 	spin_lock_irqsave(&iommu->lock, flags);
 
-	npages = PAGE_ALIGN(bus_addr + sz) - (bus_addr & PAGE_MASK);
-	npages >>= PAGE_SHIFT;
-	bus_addr &= PAGE_MASK;
+	npages = IO_PAGE_ALIGN(bus_addr + sz) - (bus_addr & IO_PAGE_MASK);
+	npages >>= IO_PAGE_SHIFT;
+	bus_addr &= IO_PAGE_MASK;
 
 	/* Step 1: Record the context, if any. */
 	ctx = 0;
@@ -678,7 +678,7 @@
 		iopte_t *iopte;
 
 		iopte = iommu->page_table +
-			((bus_addr - iommu->page_table_map_base)>>PAGE_SHIFT);
+			((bus_addr - iommu->page_table_map_base)>>IO_PAGE_SHIFT);
 		ctx = (iopte_val(*iopte) & IOPTE_CONTEXT) >> 47UL;
 	}
 
@@ -696,7 +696,7 @@
 	} else {
 		unsigned long i;
 
-		for (i = 0; i < npages; i++, bus_addr += PAGE_SIZE)
+		for (i = 0; i < npages; i++, bus_addr += IO_PAGE_SIZE)
 			pci_iommu_write(strbuf->strbuf_pflush, bus_addr);
 	}
 
@@ -735,7 +735,7 @@
 		iopte_t *iopte;
 
 		iopte = iommu->page_table +
-			((sglist[0].dvma_address - iommu->page_table_map_base) >> PAGE_SHIFT);
+			((sglist[0].dvma_address - iommu->page_table_map_base) >> IO_PAGE_SHIFT);
 		ctx = (iopte_val(*iopte) & IOPTE_CONTEXT) >> 47UL;
 	}
 
@@ -754,14 +754,14 @@
 		unsigned long i, npages;
 		u32 bus_addr;
 
-		bus_addr = sglist[0].dvma_address & PAGE_MASK;
+		bus_addr = sglist[0].dvma_address & IO_PAGE_MASK;
 
 		for(i = 1; i < nelems; i++)
 			if (!sglist[i].dvma_length)
 				break;
 		i--;
-		npages = (PAGE_ALIGN(sglist[i].dvma_address + sglist[i].dvma_length) - bus_addr) >> PAGE_SHIFT;
-		for (i = 0; i < npages; i++, bus_addr += PAGE_SIZE)
+		npages = (IO_PAGE_ALIGN(sglist[i].dvma_address + sglist[i].dvma_length) - bus_addr) >> IO_PAGE_SHIFT;
+		for (i = 0; i < npages; i++, bus_addr += IO_PAGE_SIZE)
 			pci_iommu_write(strbuf->strbuf_pflush, bus_addr);
 	}
 
diff -u --recursive --new-file v2.4.9/linux/arch/sparc64/kernel/pci_psycho.c linux/arch/sparc64/kernel/pci_psycho.c
--- v2.4.9/linux/arch/sparc64/kernel/pci_psycho.c	Mon Aug 27 12:41:40 2001
+++ linux/arch/sparc64/kernel/pci_psycho.c	Tue Aug 28 07:09:44 2001
@@ -1,4 +1,4 @@
-/* $Id: pci_psycho.c,v 1.27 2001/08/12 13:18:23 davem Exp $
+/* $Id: pci_psycho.c,v 1.28 2001/08/24 19:36:58 kanoj Exp $
  * pci_psycho.c: PSYCHO/U2P specific PCI controller support.
  *
  * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu)
@@ -18,6 +18,7 @@
 #include <asm/starfire.h>
 
 #include "pci_impl.h"
+#include "iommu_common.h"
 
 /* All PSYCHO registers are 64-bits.  The following accessor
  * routines are how they are accessed.  The REG parameter
@@ -715,12 +716,12 @@
 			       ((tag & PSYCHO_IOMMU_TAG_WRITE) ? 1 : 0),
 			       ((tag & PSYCHO_IOMMU_TAG_STREAM) ? 1 : 0),
 			       ((tag & PSYCHO_IOMMU_TAG_SIZE) ? 64 : 8),
-			       (tag & PSYCHO_IOMMU_TAG_VPAGE) << PAGE_SHIFT);
+			       (tag & PSYCHO_IOMMU_TAG_VPAGE) << IOMMU_PAGE_SHIFT);
 			printk("PSYCHO%d: IOMMU DATA(%d)[valid(%d) cache(%d) ppg(%016lx)]\n",
 			       p->index, i,
 			       ((data & PSYCHO_IOMMU_DATA_VALID) ? 1 : 0),
 			       ((data & PSYCHO_IOMMU_DATA_CACHE) ? 1 : 0),
-			       (data & PSYCHO_IOMMU_DATA_PPAGE) << PAGE_SHIFT);
+			       (data & PSYCHO_IOMMU_DATA_PPAGE) << IOMMU_PAGE_SHIFT);
 		}
 	}
 	__psycho_check_stc_error(p, afsr, afar, type);
@@ -1322,7 +1323,7 @@
 	 * table (128K ioptes * 8 bytes per iopte).  This is
 	 * page order 7 on UltraSparc.
 	 */
-	tsbbase = __get_free_pages(GFP_KERNEL, 7);
+	tsbbase = __get_free_pages(GFP_KERNEL, get_order(IO_TSB_SIZE));
 	if (!tsbbase) {
 		prom_printf("PSYCHO_IOMMU: Error, gfp(tsb) failed.\n");
 		prom_halt();
@@ -1331,7 +1332,7 @@
 	iommu->page_table_sz_bits = 17;
 	iommu->page_table_map_base = 0xc0000000;
 	iommu->dma_addr_mask = 0xffffffff;
-	memset((char *)tsbbase, 0, PAGE_SIZE << 7);
+	memset((char *)tsbbase, 0, IO_TSB_SIZE);
 
 	/* We start with no consistent mappings. */
 	iommu->lowest_consistent_map =
diff -u --recursive --new-file v2.4.9/linux/arch/sparc64/kernel/pci_sabre.c linux/arch/sparc64/kernel/pci_sabre.c
--- v2.4.9/linux/arch/sparc64/kernel/pci_sabre.c	Mon Aug 27 12:41:40 2001
+++ linux/arch/sparc64/kernel/pci_sabre.c	Tue Aug 28 07:09:44 2001
@@ -1,4 +1,4 @@
-/* $Id: pci_sabre.c,v 1.38 2001/08/12 13:18:23 davem Exp $
+/* $Id: pci_sabre.c,v 1.39 2001/08/24 19:36:58 kanoj Exp $
  * pci_sabre.c: Sabre specific PCI controller support.
  *
  * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu)
@@ -19,6 +19,7 @@
 #include <asm/smp.h>
 
 #include "pci_impl.h"
+#include "iommu_common.h"
 
 /* All SABRE registers are 64-bits.  The following accessor
  * routines are how they are accessed.  The REG parameter
@@ -759,13 +760,13 @@
 			       p->index, i, tag, type_string,
 			       ((tag & SABRE_IOMMUTAG_WRITE) ? 1 : 0),
 			       ((tag & SABRE_IOMMUTAG_SIZE) ? 64 : 8),
-			       ((tag & SABRE_IOMMUTAG_VPN) << PAGE_SHIFT));
+			       ((tag & SABRE_IOMMUTAG_VPN) << IOMMU_PAGE_SHIFT));
 			printk("SABRE%d: IOMMU DATA(%d)[RAW(%016lx)valid(%d)used(%d)cache(%d)ppg(%016lx)\n",
 			       p->index, i, data,
 			       ((data & SABRE_IOMMUDATA_VALID) ? 1 : 0),
 			       ((data & SABRE_IOMMUDATA_USED) ? 1 : 0),
 			       ((data & SABRE_IOMMUDATA_CACHE) ? 1 : 0),
-			       ((data & SABRE_IOMMUDATA_PPN) << PAGE_SHIFT));
+			       ((data & SABRE_IOMMUDATA_PPN) << IOMMU_PAGE_SHIFT));
 		}
 	}
 	spin_unlock_irqrestore(&iommu->lock, flags);
diff -u --recursive --new-file v2.4.9/linux/arch/sparc64/kernel/pci_schizo.c linux/arch/sparc64/kernel/pci_schizo.c
--- v2.4.9/linux/arch/sparc64/kernel/pci_schizo.c	Mon Aug 27 12:41:40 2001
+++ linux/arch/sparc64/kernel/pci_schizo.c	Tue Aug 28 07:09:44 2001
@@ -1,4 +1,4 @@
-/* $Id: pci_schizo.c,v 1.20 2001/08/12 13:18:23 davem Exp $
+/* $Id: pci_schizo.c,v 1.21 2001/08/24 19:36:58 kanoj Exp $
  * pci_schizo.c: SCHIZO specific PCI controller support.
  *
  * Copyright (C) 2001 David S. Miller (davem@redhat.com)
@@ -16,6 +16,7 @@
 #include <asm/upa.h>
 
 #include "pci_impl.h"
+#include "iommu_common.h"
 
 /* All SCHIZO registers are 64-bits.  The following accessor
  * routines are how they are accessed.  The REG parameter
@@ -659,12 +660,12 @@
 			       ((tag & SCHIZO_IOMMU_TAG_WRITE) ? 1 : 0),
 			       ((tag & SCHIZO_IOMMU_TAG_STREAM) ? 1 : 0),
 			       ((tag & SCHIZO_IOMMU_TAG_SIZE) ? 64 : 8),
-			       (tag & SCHIZO_IOMMU_TAG_VPAGE) << PAGE_SHIFT);
+			       (tag & SCHIZO_IOMMU_TAG_VPAGE) << IOMMU_PAGE_SHIFT);
 			printk("SCHIZO%d: PBM-%c IOMMU DATA(%d)[valid(%d) cache(%d) ppg(%016lx)]\n",
 			       p->index, pbm_name, i,
 			       ((data & SCHIZO_IOMMU_DATA_VALID) ? 1 : 0),
 			       ((data & SCHIZO_IOMMU_DATA_CACHE) ? 1 : 0),
-			       (data & SCHIZO_IOMMU_DATA_PPAGE) << PAGE_SHIFT);
+			       (data & SCHIZO_IOMMU_DATA_PPAGE) << IOMMU_PAGE_SHIFT);
 		}
 	}
 	__schizo_check_stc_error_pbm(pbm, type);
@@ -1639,7 +1640,7 @@
 	 * table (128K ioptes * 8 bytes per iopte).  This is
 	 * page order 7 on UltraSparc.
 	 */
-	tsbbase = __get_free_pages(GFP_KERNEL, 7);
+	tsbbase = __get_free_pages(GFP_KERNEL, get_order(IO_TSB_SIZE));
 	if (!tsbbase) {
 		prom_printf("SCHIZO_IOMMU: Error, gfp(tsb) failed.\n");
 		prom_halt();
@@ -1648,7 +1649,7 @@
 	iommu->page_table_sz_bits = 17;
 	iommu->page_table_map_base = 0xc0000000;
 	iommu->dma_addr_mask = 0xffffffff;
-	memset((char *)tsbbase, 0, PAGE_SIZE << 7);
+	memset((char *)tsbbase, 0, IO_TSB_SIZE);
 
 	/* We start with no consistent mappings. */
 	iommu->lowest_consistent_map =
diff -u --recursive --new-file v2.4.9/linux/arch/sparc64/kernel/sbus.c linux/arch/sparc64/kernel/sbus.c
--- v2.4.9/linux/arch/sparc64/kernel/sbus.c	Thu May 24 15:00:58 2001
+++ linux/arch/sparc64/kernel/sbus.c	Tue Aug 28 07:09:44 2001
@@ -1,4 +1,4 @@
-/* $Id: sbus.c,v 1.14 2001/05/23 03:06:51 davem Exp $
+/* $Id: sbus.c,v 1.16 2001/08/24 19:36:58 kanoj Exp $
  * sbus.c: UltraSparc SBUS controller support.
  *
  * Copyright (C) 1999 David S. Miller (davem@redhat.com)
@@ -37,7 +37,7 @@
 #define ONE_GIG		(1UL * 1024UL * 1024UL * 1024UL)
 #define CLUSTER_SIZE	(ONE_GIG / NCLUSTERS)
 #define CLUSTER_MASK	(CLUSTER_SIZE - 1)
-#define CLUSTER_NPAGES	(CLUSTER_SIZE >> PAGE_SHIFT)
+#define CLUSTER_NPAGES	(CLUSTER_SIZE >> IO_PAGE_SHIFT)
 #define MAP_BASE	((u32)0xc0000000)
 
 struct sbus_iommu {
@@ -99,7 +99,7 @@
 static void iommu_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages)
 {
 	while (npages--)
-		upa_writeq(base + (npages << PAGE_SHIFT),
+		upa_writeq(base + (npages << IO_PAGE_SHIFT),
 			   iommu->iommu_regs + IOMMU_FLUSH);
 	upa_readq(iommu->sbus_control_reg);
 }
@@ -120,7 +120,7 @@
 {
 	iommu->strbuf_flushflag = 0UL;
 	while (npages--)
-		upa_writeq(base + (npages << PAGE_SHIFT),
+		upa_writeq(base + (npages << IO_PAGE_SHIFT),
 			   iommu->strbuf_regs + STRBUF_PFLUSH);
 
 	/* Whoopee cushion! */
@@ -191,8 +191,8 @@
 	cnum = 0;
 	while ((1UL << cnum) < npages)
 		cnum++;
-	ent = (base & CLUSTER_MASK) >> (PAGE_SHIFT + cnum);
-	iopte = iommu->page_table + ((base - MAP_BASE) >> PAGE_SHIFT);
+	ent = (base & CLUSTER_MASK) >> (IO_PAGE_SHIFT + cnum);
+	iopte = iommu->page_table + ((base - MAP_BASE) >> IO_PAGE_SHIFT);
 	iopte_val(*iopte) = 0UL;
 
 	/* If the global flush might not have caught this entry,
@@ -235,7 +235,7 @@
 
 static void free_consistent_cluster(struct sbus_iommu *iommu, u32 base, unsigned long npages)
 {
-	iopte_t *iopte = iommu->page_table + ((base - MAP_BASE) >> PAGE_SHIFT);
+	iopte_t *iopte = iommu->page_table + ((base - MAP_BASE) >> IO_PAGE_SHIFT);
 
 	if ((iopte - iommu->page_table) == iommu->lowest_consistent_map) {
 		iopte_t *walk = iopte + npages;
@@ -266,7 +266,7 @@
 	if (size <= 0 || sdev == NULL || dvma_addr == NULL)
 		return NULL;
 
-	size = PAGE_ALIGN(size);
+	size = IO_PAGE_ALIGN(size);
 	order = get_order(size);
 	if (order >= 10)
 		return NULL;
@@ -278,7 +278,7 @@
 	iommu = sdev->bus->iommu;
 
 	spin_lock_irqsave(&iommu->lock, flags);
-	iopte = alloc_consistent_cluster(iommu, size >> PAGE_SHIFT);
+	iopte = alloc_consistent_cluster(iommu, size >> IO_PAGE_SHIFT);
 	if (iopte == NULL) {
 		spin_unlock_irqrestore(&iommu->lock, flags);
 		free_pages(first_page, order);
@@ -286,15 +286,15 @@
 	}
 
 	/* Ok, we're committed at this point. */
-	*dvma_addr = MAP_BASE +	((iopte - iommu->page_table) << PAGE_SHIFT);
+	*dvma_addr = MAP_BASE +	((iopte - iommu->page_table) << IO_PAGE_SHIFT);
 	ret = (void *) first_page;
-	npages = size >> PAGE_SHIFT;
+	npages = size >> IO_PAGE_SHIFT;
 	while (npages--) {
 		*iopte++ = __iopte(IOPTE_VALID | IOPTE_CACHE | IOPTE_WRITE |
 				   (__pa(first_page) & IOPTE_PAGE));
-		first_page += PAGE_SIZE;
+		first_page += IO_PAGE_SIZE;
 	}
-	iommu_flush(iommu, *dvma_addr, size >> PAGE_SHIFT);
+	iommu_flush(iommu, *dvma_addr, size >> IO_PAGE_SHIFT);
 	spin_unlock_irqrestore(&iommu->lock, flags);
 
 	return ret;
@@ -308,7 +308,7 @@
 	if (size <= 0 || sdev == NULL || cpu == NULL)
 		return;
 
-	npages = PAGE_ALIGN(size) >> PAGE_SHIFT;
+	npages = IO_PAGE_ALIGN(size) >> IO_PAGE_SHIFT;
 	iommu = sdev->bus->iommu;
 
 	spin_lock_irq(&iommu->lock);
@@ -333,25 +333,25 @@
 		BUG();
 
 	pbase = (unsigned long) ptr;
-	offset = (u32) (pbase & ~PAGE_MASK);
-	size = (PAGE_ALIGN(pbase + size) - (pbase & PAGE_MASK));
-	pbase = (unsigned long) __pa(pbase & PAGE_MASK);
+	offset = (u32) (pbase & ~IO_PAGE_MASK);
+	size = (IO_PAGE_ALIGN(pbase + size) - (pbase & IO_PAGE_MASK));
+	pbase = (unsigned long) __pa(pbase & IO_PAGE_MASK);
 
 	spin_lock_irqsave(&iommu->lock, flags);
-	npages = size >> PAGE_SHIFT;
+	npages = size >> IO_PAGE_SHIFT;
 	iopte = alloc_streaming_cluster(iommu, npages);
 	if (iopte == NULL)
 		goto bad;
-	dma_base = MAP_BASE + ((iopte - iommu->page_table) << PAGE_SHIFT);
-	npages = size >> PAGE_SHIFT;
+	dma_base = MAP_BASE + ((iopte - iommu->page_table) << IO_PAGE_SHIFT);
+	npages = size >> IO_PAGE_SHIFT;
 	iopte_bits = IOPTE_VALID | IOPTE_STBUF | IOPTE_CACHE;
 	if (dir != SBUS_DMA_TODEVICE)
 		iopte_bits |= IOPTE_WRITE;
 	while (npages--) {
 		*iopte++ = __iopte(iopte_bits | (pbase & IOPTE_PAGE));
-		pbase += PAGE_SIZE;
+		pbase += IO_PAGE_SIZE;
 	}
-	npages = size >> PAGE_SHIFT;
+	npages = size >> IO_PAGE_SHIFT;
 	spin_unlock_irqrestore(&iommu->lock, flags);
 
 	return (dma_base | offset);
@@ -365,14 +365,14 @@
 void sbus_unmap_single(struct sbus_dev *sdev, dma_addr_t dma_addr, size_t size, int direction)
 {
 	struct sbus_iommu *iommu = sdev->bus->iommu;
-	u32 dma_base = dma_addr & PAGE_MASK;
+	u32 dma_base = dma_addr & IO_PAGE_MASK;
 	unsigned long flags;
 
-	size = (PAGE_ALIGN(dma_addr + size) - dma_base);
+	size = (IO_PAGE_ALIGN(dma_addr + size) - dma_base);
 
 	spin_lock_irqsave(&iommu->lock, flags);
-	free_streaming_cluster(iommu, dma_base, size >> PAGE_SHIFT);
-	strbuf_flush(iommu, dma_base, size >> PAGE_SHIFT);
+	free_streaming_cluster(iommu, dma_base, size >> IO_PAGE_SHIFT);
+	strbuf_flush(iommu, dma_base, size >> IO_PAGE_SHIFT);
 	spin_unlock_irqrestore(&iommu->lock, flags);
 }
 
@@ -385,9 +385,9 @@
 		unsigned long pteval = ~0UL;
 		u32 dma_npages;
 
-		dma_npages = ((dma_sg->dvma_address & (PAGE_SIZE - 1UL)) +
+		dma_npages = ((dma_sg->dvma_address & (IO_PAGE_SIZE - 1UL)) +
 			      dma_sg->dvma_length +
-			      ((u32)(PAGE_SIZE - 1UL))) >> PAGE_SHIFT;
+			      ((u32)(IO_PAGE_SIZE - 1UL))) >> IO_PAGE_SHIFT;
 		do {
 			unsigned long offset;
 			signed int len;
@@ -402,15 +402,15 @@
 
 				tmp = (unsigned long) __pa(sg->address);
 				len = sg->length;
-				if (((tmp ^ pteval) >> PAGE_SHIFT) != 0UL) {
-					pteval = tmp & PAGE_MASK;
-					offset = tmp & (PAGE_SIZE - 1UL);
+				if (((tmp ^ pteval) >> IO_PAGE_SHIFT) != 0UL) {
+					pteval = tmp & IO_PAGE_MASK;
+					offset = tmp & (IO_PAGE_SIZE - 1UL);
 					break;
 				}
-				if (((tmp ^ (tmp + len - 1UL)) >> PAGE_SHIFT) != 0UL) {
-					pteval = (tmp + PAGE_SIZE) & PAGE_MASK;
+				if (((tmp ^ (tmp + len - 1UL)) >> IO_PAGE_SHIFT) != 0UL) {
+					pteval = (tmp + IO_PAGE_SIZE) & IO_PAGE_MASK;
 					offset = 0UL;
-					len -= (PAGE_SIZE - (tmp & (PAGE_SIZE - 1UL)));
+					len -= (IO_PAGE_SIZE - (tmp & (IO_PAGE_SIZE - 1UL)));
 					break;
 				}
 				sg++;
@@ -419,8 +419,8 @@
 			pteval = ((pteval & IOPTE_PAGE) | iopte_bits);
 			while (len > 0) {
 				*iopte++ = __iopte(pteval);
-				pteval += PAGE_SIZE;
-				len -= (PAGE_SIZE - offset);
+				pteval += IO_PAGE_SIZE;
+				len -= (IO_PAGE_SIZE - offset);
 				offset = 0;
 				dma_npages--;
 			}
@@ -432,14 +432,14 @@
 			 * adjusting pteval along the way.  Stop when we
 			 * detect a page crossing event.
 			 */
-			while ((pteval << (64 - PAGE_SHIFT)) != 0UL &&
+			while ((pteval << (64 - IO_PAGE_SHIFT)) != 0UL &&
 			       pteval == __pa(sg->address) &&
 			       ((pteval ^
-				 (__pa(sg->address) + sg->length - 1UL)) >> PAGE_SHIFT) == 0UL) {
+				 (__pa(sg->address) + sg->length - 1UL)) >> IO_PAGE_SHIFT) == 0UL) {
 				pteval += sg->length;
 				sg++;
 			}
-			if ((pteval << (64 - PAGE_SHIFT)) == 0UL)
+			if ((pteval << (64 - IO_PAGE_SHIFT)) == 0UL)
 				pteval = ~0UL;
 		} while (dma_npages != 0);
 		dma_sg++;
@@ -472,7 +472,7 @@
 	iopte = alloc_streaming_cluster(iommu, npages);
 	if (iopte == NULL)
 		goto bad;
-	dma_base = MAP_BASE + ((iopte - iommu->page_table) << PAGE_SHIFT);
+	dma_base = MAP_BASE + ((iopte - iommu->page_table) << IO_PAGE_SHIFT);
 
 	/* Normalize DVMA addresses. */
 	sgtmp = sg;
@@ -516,18 +516,18 @@
 		return;
 	}
 
-	dvma_base = sg[0].dvma_address & PAGE_MASK;
+	dvma_base = sg[0].dvma_address & IO_PAGE_MASK;
 	for (i = 0; i < nents; i++) {
 		if (sg[i].dvma_length == 0)
 			break;
 	}
 	i--;
-	size = PAGE_ALIGN(sg[i].dvma_address + sg[i].dvma_length) - dvma_base;
+	size = IO_PAGE_ALIGN(sg[i].dvma_address + sg[i].dvma_length) - dvma_base;
 
 	iommu = sdev->bus->iommu;
 	spin_lock_irqsave(&iommu->lock, flags);
-	free_streaming_cluster(iommu, dvma_base, size >> PAGE_SHIFT);
-	strbuf_flush(iommu, dvma_base, size >> PAGE_SHIFT);
+	free_streaming_cluster(iommu, dvma_base, size >> IO_PAGE_SHIFT);
+	strbuf_flush(iommu, dvma_base, size >> IO_PAGE_SHIFT);
 	spin_unlock_irqrestore(&iommu->lock, flags);
 }
 
@@ -536,10 +536,10 @@
 	struct sbus_iommu *iommu = sdev->bus->iommu;
 	unsigned long flags;
 
-	size = (PAGE_ALIGN(base + size) - (base & PAGE_MASK));
+	size = (IO_PAGE_ALIGN(base + size) - (base & IO_PAGE_MASK));
 
 	spin_lock_irqsave(&iommu->lock, flags);
-	strbuf_flush(iommu, base & PAGE_MASK, size >> PAGE_SHIFT);
+	strbuf_flush(iommu, base & IO_PAGE_MASK, size >> IO_PAGE_SHIFT);
 	spin_unlock_irqrestore(&iommu->lock, flags);
 }
 
@@ -550,16 +550,16 @@
 	u32 base;
 	int i;
 
-	base = sg[0].dvma_address & PAGE_MASK;
+	base = sg[0].dvma_address & IO_PAGE_MASK;
 	for (i = 0; i < nents; i++) {
 		if (sg[i].dvma_length == 0)
 			break;
 	}
 	i--;
-	size = PAGE_ALIGN(sg[i].dvma_address + sg[i].dvma_length) - base;
+	size = IO_PAGE_ALIGN(sg[i].dvma_address + sg[i].dvma_length) - base;
 
 	spin_lock_irqsave(&iommu->lock, flags);
-	strbuf_flush(iommu, base, size >> PAGE_SHIFT);
+	strbuf_flush(iommu, base, size >> IO_PAGE_SHIFT);
 	spin_unlock_irqrestore(&iommu->lock, flags);
 }
 
@@ -1123,14 +1123,14 @@
 	 * table (128K ioptes * 8 bytes per iopte).  This is
 	 * page order 7 on UltraSparc.
 	 */
-	tsb_base = __get_free_pages(GFP_ATOMIC, 7);
+	tsb_base = __get_free_pages(GFP_ATOMIC, get_order(IO_TSB_SIZE));
 	if (tsb_base == 0UL) {
 		prom_printf("sbus_iommu_init: Fatal error, cannot alloc TSB table.\n");
 		prom_halt();
 	}
 
 	iommu->page_table = (iopte_t *) tsb_base;
-	memset(iommu->page_table, 0, (PAGE_SIZE << 7));
+	memset(iommu->page_table, 0, IO_TSB_SIZE);
 
 	upa_writeq(control, iommu->iommu_regs + IOMMU_CONTROL);
 
diff -u --recursive --new-file v2.4.9/linux/arch/sparc64/kernel/smp.c linux/arch/sparc64/kernel/smp.c
--- v2.4.9/linux/arch/sparc64/kernel/smp.c	Mon Aug 27 12:41:40 2001
+++ linux/arch/sparc64/kernel/smp.c	Tue Aug 28 07:09:44 2001
@@ -702,7 +702,7 @@
 		int cpu = smp_processor_id();
 
 		start &= PAGE_MASK;
-		end   &= PAGE_MASK;
+		end    = PAGE_ALIGN(end);
 
 		if (mm == current->active_mm && atomic_read(&mm->mm_users) == 1) {
 			mm->cpu_vm_mask = (1UL << cpu);
diff -u --recursive --new-file v2.4.9/linux/arch/sparc64/kernel/sparc64_ksyms.c linux/arch/sparc64/kernel/sparc64_ksyms.c
--- v2.4.9/linux/arch/sparc64/kernel/sparc64_ksyms.c	Mon Aug 27 12:41:40 2001
+++ linux/arch/sparc64/kernel/sparc64_ksyms.c	Fri Sep  7 11:01:20 2001
@@ -1,4 +1,4 @@
-/* $Id: sparc64_ksyms.c,v 1.108 2001/06/05 03:39:50 davem Exp $
+/* $Id: sparc64_ksyms.c,v 1.111 2001/08/30 03:22:00 kanoj Exp $
  * arch/sparc64/kernel/sparc64_ksyms.c: Sparc64 specific ksyms support.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -163,7 +163,9 @@
 /* Atomic counter implementation. */
 EXPORT_SYMBOL(__atomic_add);
 EXPORT_SYMBOL(__atomic_sub);
+#ifdef CONFIG_SMP
 EXPORT_SYMBOL(atomic_dec_and_lock);
+#endif
 
 /* Atomic bit operations. */
 EXPORT_SYMBOL(___test_and_set_bit);
@@ -206,7 +208,6 @@
 EXPORT_SYMBOL(ebus_chain);
 EXPORT_SYMBOL(isa_chain);
 EXPORT_SYMBOL(pci_memspace_mask);
-EXPORT_SYMBOL(empty_zero_page);
 EXPORT_SYMBOL(outsb);
 EXPORT_SYMBOL(outsw);
 EXPORT_SYMBOL(outsl);
diff -u --recursive --new-file v2.4.9/linux/arch/sparc64/lib/blockops.S linux/arch/sparc64/lib/blockops.S
--- v2.4.9/linux/arch/sparc64/lib/blockops.S	Thu Apr 12 12:10:25 2001
+++ linux/arch/sparc64/lib/blockops.S	Fri Sep  7 11:01:20 2001
@@ -1,4 +1,4 @@
-/* $Id: blockops.S,v 1.31 2001/04/05 11:08:12 davem Exp $
+/* $Id: blockops.S,v 1.34 2001/09/03 01:34:18 kanoj Exp $
  * blockops.S: UltraSparc block zero optimized routines.
  *
  * Copyright (C) 1996, 1998, 1999, 2000 David S. Miller (davem@redhat.com)
diff -u --recursive --new-file v2.4.9/linux/arch/sparc64/mm/fault.c linux/arch/sparc64/mm/fault.c
--- v2.4.9/linux/arch/sparc64/mm/fault.c	Mon Aug 27 12:41:40 2001
+++ linux/arch/sparc64/mm/fault.c	Fri Sep  7 11:01:20 2001
@@ -1,4 +1,4 @@
-/* $Id: fault.c,v 1.55 2001/08/09 20:18:43 davem Exp $
+/* $Id: fault.c,v 1.58 2001/09/01 00:11:16 kanoj Exp $
  * arch/sparc64/mm/fault.c: Page fault handlers for the 64-bit Sparc.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -22,11 +22,58 @@
 #include <asm/openprom.h>
 #include <asm/oplib.h>
 #include <asm/uaccess.h>
+#include <asm/asi.h>
+#include <asm/lsu.h>
 
 #define ELEMENTS(arr) (sizeof (arr)/sizeof (arr[0]))
 
 extern struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS];
 
+/*
+ * To debug kernel during syscall entry.
+ */
+void syscall_trace_entry(struct pt_regs *regs)
+{
+	printk("scall entry: %s[%d]/cpu%d: %d\n", current->comm, current->pid, smp_processor_id(), (int) regs->u_regs[UREG_G1]);
+}
+
+/*
+ * To debug kernel during syscall exit.
+ */
+void syscall_trace_exit(struct pt_regs *regs)
+{
+	printk("scall exit: %s[%d]/cpu%d: %d\n", current->comm, current->pid, smp_processor_id(), (int) regs->u_regs[UREG_G1]);
+}
+
+/*
+ * To debug kernel to catch accesses to certain virtual/physical addresses.
+ * Mode = 0 selects physical watchpoints, mode = 1 selects virtual watchpoints.
+ * flags = VM_READ watches memread accesses, flags = VM_WRITE watches memwrite accesses.
+ * Caller passes in a 64bit aligned addr, with mask set to the bytes that need to be
+ * watched. This is only useful on a single cpu machine for now. After the watchpoint
+ * is detected, the process causing it will be killed, thus preventing an infinite loop.
+ */
+void set_brkpt(unsigned long addr, unsigned char mask, int flags, int mode)
+{
+	unsigned long lsubits = LSU_CONTROL_IC|LSU_CONTROL_DC|LSU_CONTROL_IM|LSU_CONTROL_DM;
+
+	__asm__ __volatile__("stxa	%0, [%1] %2\n\t"
+			     "membar	#Sync"
+			     : /* no outputs */
+			     : "r" (addr), "r" (mode ? VIRT_WATCHPOINT : PHYS_WATCHPOINT),
+			       "i" (ASI_DMMU));
+	lsubits |= ((unsigned long)mask << (mode ? 25 : 33));
+	if (flags & VM_READ)
+		lsubits |= (mode ? LSU_CONTROL_VR : LSU_CONTROL_PR);
+	if (flags & VM_WRITE)
+		lsubits |= (mode ? LSU_CONTROL_VW : LSU_CONTROL_PW);
+	__asm__ __volatile__("stxa %0, [%%g0] %1\n\t"
+			     "membar #Sync"
+			     : /* no outputs */
+			     : "r" (lsubits), "i" (ASI_LSU_CONTROL)
+			     : "memory");
+}
+
 /* Nice, simple, prom library does all the sweating for us. ;) */
 unsigned long __init prom_probe_memory (void)
 {
@@ -170,7 +217,7 @@
 	unsigned long g2;
 	unsigned char asi = ASI_P;
  
-	if (!insn)
+	if ((!insn) && (regs->tstate & TSTATE_PRIV))
 		goto cannot_handle;
 
 	/* If user insn could be read (thus insn is zero), that
diff -u --recursive --new-file v2.4.9/linux/arch/sparc64/mm/init.c linux/arch/sparc64/mm/init.c
--- v2.4.9/linux/arch/sparc64/mm/init.c	Mon Aug 27 12:41:40 2001
+++ linux/arch/sparc64/mm/init.c	Fri Sep  7 11:01:20 2001
@@ -1,4 +1,4 @@
-/*  $Id: init.c,v 1.179 2001/08/08 07:52:00 davem Exp $
+/*  $Id: init.c,v 1.189 2001/09/02 23:27:18 kanoj Exp $
  *  arch/sparc64/mm/init.c
  *
  *  Copyright (C) 1996-1999 David S. Miller (davem@caip.rutgers.edu)
@@ -27,7 +27,6 @@
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
-#include <asm/vaddrs.h>
 #include <asm/dma.h>
 #include <asm/starfire.h>
 
@@ -55,6 +54,8 @@
 extern unsigned int sparc_ramdisk_image;
 extern unsigned int sparc_ramdisk_size;
 
+struct page *mem_map_zero;
+
 int do_check_pgt_cache(int low, int high)
 {
         int freed = 0;
@@ -130,28 +131,6 @@
 	}
 }
 
-/*
- * 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 an 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.
- */
-pte_t __bad_page(void)
-{
-	memset((void *) &empty_bad_page, 0, PAGE_SIZE);
-	return pte_mkdirty(mk_pte_phys((((unsigned long) &empty_bad_page) 
-					- ((unsigned long)&empty_zero_page)
-					+ phys_base),
-				       PAGE_SHARED));
-}
-
 void show_mem(void)
 {
 	printk("Mem-info:\n");
@@ -202,10 +181,10 @@
 	struct linux_prom_translation *trans;
 	unsigned long phys_page, tte_vaddr, tte_data;
 	void (*remap_func)(unsigned long, unsigned long, int);
-	pgd_t *pgdp;
-	pmd_t *pmdp;
+	pmd_t *pmdp, *pmd;
 	pte_t *ptep;
 	int node, n, i, tsz;
+	extern unsigned int obp_iaddr_patch[2], obp_daddr_patch[2];
 
 	node = prom_finddevice("/virtual-memory");
 	n = prom_getproplen(node, "translations");
@@ -229,36 +208,39 @@
 	}
 	n = n / sizeof(*trans);
 
+	/*
+	 * The obp translations are saved based on 8k pagesize, since obp can use
+	 * a mixture of pagesizes. Misses to the 0xf0000000 - 0x100000000, ie obp 
+	 * range, are handled in entry.S and do not use the vpte scheme (see rant
+	 * in inherit_locked_prom_mappings()).
+	 */
+#define OBP_PMD_SIZE 2048
+#define BASE_PAGE_SIZE 8192
+	pmd = __alloc_bootmem(OBP_PMD_SIZE, OBP_PMD_SIZE, 0UL);
+	if (pmd == NULL)
+		early_pgtable_allocfail("pmd");
+	memset(pmd, 0, OBP_PMD_SIZE);
 	for (i = 0; i < n; i++) {
 		unsigned long vaddr;
 
 		if (trans[i].virt >= 0xf0000000 && trans[i].virt < 0x100000000) {
 			for (vaddr = trans[i].virt;
 			     vaddr < trans[i].virt + trans[i].size;
-			     vaddr += PAGE_SIZE) {
+			     vaddr += BASE_PAGE_SIZE) {
 				unsigned long val;
 
-				pgdp = pgd_offset(&init_mm, vaddr);
-				if (pgd_none(*pgdp)) {
-					pmdp = __alloc_bootmem(PMD_TABLE_SIZE,
-							       PMD_TABLE_SIZE,
-							       0UL);
-					if (pmdp == NULL)
-						early_pgtable_allocfail("pmd");
-					memset(pmdp, 0, PMD_TABLE_SIZE);
-					pgd_set(pgdp, pmdp);
-				}
-				pmdp = pmd_offset(pgdp, vaddr);
+				pmdp = pmd + ((vaddr >> 23) & 0x7ff);
 				if (pmd_none(*pmdp)) {
-					ptep = __alloc_bootmem(PTE_TABLE_SIZE,
-							       PTE_TABLE_SIZE,
+					ptep = __alloc_bootmem(BASE_PAGE_SIZE,
+							       BASE_PAGE_SIZE,
 							       0UL);
 					if (ptep == NULL)
 						early_pgtable_allocfail("pte");
-					memset(ptep, 0, PTE_TABLE_SIZE);
+					memset(ptep, 0, BASE_PAGE_SIZE);
 					pmd_set(pmdp, ptep);
 				}
-				ptep = pte_offset(pmdp, vaddr);
+				ptep = (pte_t *)pmd_page(*pmdp) +
+						((vaddr >> 13) & 0x3ff);
 
 				val = trans[i].data;
 
@@ -267,10 +249,17 @@
 					val &= ~0x0003fe0000000000UL;
 
 				set_pte (ptep, __pte(val | _PAGE_MODIFIED));
-				trans[i].data += PAGE_SIZE;
+				trans[i].data += BASE_PAGE_SIZE;
 			}
 		}
 	}
+	phys_page = __pa(pmd);
+	obp_iaddr_patch[0] |= (phys_page >> 10);
+	obp_iaddr_patch[1] |= (phys_page & 0x3ff);
+	flushi((long)&obp_iaddr_patch[0]);
+	obp_daddr_patch[0] |= (phys_page >> 10);
+	obp_daddr_patch[1] |= (phys_page & 0x3ff);
+	flushi((long)&obp_daddr_patch[0]);
 
 	/* Now fixup OBP's idea about where we really are mapped. */
 	prom_printf("Remapping the kernel... ");
@@ -295,7 +284,7 @@
 
 	phys_page &= _PAGE_PADDR;
 	phys_page += ((unsigned long)&prom_boot_page -
-		      (unsigned long)&empty_zero_page);
+		      (unsigned long)KERNBASE);
 
 	if (tlb_type == spitfire) {
 		/* Lock this into i/d tlb entry 59 */
@@ -336,7 +325,7 @@
 		BUG();
 	}
 
-	tte_vaddr = (unsigned long) &empty_zero_page;
+	tte_vaddr = (unsigned long) KERNBASE;
 
 	/* Spitfire Errata #32 workaround */
 	__asm__ __volatile__("stxa	%0, [%1] %2\n\t"
@@ -366,7 +355,7 @@
 	remap_func((tlb_type == spitfire ?
 		    (spitfire_get_dtlb_data(sparc64_highest_locked_tlbent()) & _PAGE_PADDR) :
 		    (cheetah_get_litlb_data(sparc64_highest_locked_tlbent()) & _PAGE_PADDR)),
-		   (unsigned long) &empty_zero_page,
+		   (unsigned long) KERNBASE,
 		   prom_get_mmu_ihandle());
 
 	/* Flush out that temporary mapping. */
@@ -389,7 +378,7 @@
 		unsigned long size = trans[i].size;
 
 		if (vaddr < 0xf0000000UL) {
-			unsigned long avoid_start = (unsigned long) &empty_zero_page;
+			unsigned long avoid_start = (unsigned long) KERNBASE;
 			unsigned long avoid_end = avoid_start + (4 * 1024 * 1024);
 
 			if (vaddr < avoid_start) {
@@ -1048,7 +1037,7 @@
 	 * 4MB locked TLB translation.
 	 */
 	start_pfn  = PAGE_ALIGN((unsigned long) &_end) -
-		((unsigned long) &empty_zero_page);
+		((unsigned long) KERNBASE);
 
 	/* Adjust up to the physical address where the kernel begins. */
 	start_pfn += phys_base;
@@ -1133,7 +1122,7 @@
 	unsigned long alias_base = phys_base + PAGE_OFFSET;
 	unsigned long second_alias_page = 0;
 	unsigned long pt, flags, end_pfn, pages_avail;
-	unsigned long shift = alias_base - ((unsigned long)&empty_zero_page);
+	unsigned long shift = alias_base - ((unsigned long)KERNBASE);
 	unsigned long real_end;
 
 	set_bit(0, mmu_context_bmap);
@@ -1429,7 +1418,7 @@
 
 	addr = PAGE_OFFSET + phys_base;
 	last = PAGE_ALIGN((unsigned long)&_end) -
-		((unsigned long) &empty_zero_page);
+		((unsigned long) KERNBASE);
 	last += PAGE_OFFSET + phys_base;
 	while (addr < last) {
 		set_bit(__pa(addr) >> 22, sparc64_valid_addr_bitmap);
@@ -1441,7 +1430,20 @@
 	max_mapnr = last_valid_pfn - (phys_base >> PAGE_SHIFT);
 	high_memory = __va(last_valid_pfn << PAGE_SHIFT);
 
-	num_physpages = free_all_bootmem();
+	num_physpages = free_all_bootmem() - 1;
+
+	/*
+	 * Set up the zero page, mark it reserved, so that page count
+	 * is not manipulated when freeing the page from user ptes.
+	 */
+	mem_map_zero = _alloc_pages(GFP_KERNEL, 0);
+	if (mem_map_zero == NULL) {
+		prom_printf("paging_init: Cannot alloc zero page.\n");
+		prom_halt();
+	}
+	SetPageReserved(mem_map_zero);
+	clear_page(page_address(mem_map_zero));
+
 	codepages = (((unsigned long) &etext) - ((unsigned long)&_start));
 	codepages = PAGE_ALIGN(codepages) >> PAGE_SHIFT;
 	datapages = (((unsigned long) &edata) - ((unsigned long)&etext));
@@ -1455,7 +1457,7 @@
 		extern pgd_t empty_pg_dir[1024];
 		unsigned long addr = (unsigned long)empty_pg_dir;
 		unsigned long alias_base = phys_base + PAGE_OFFSET -
-			(long)(&empty_zero_page);
+			(long)(KERNBASE);
 		
 		memset(empty_pg_dir, 0, sizeof(empty_pg_dir));
 		addr += alias_base;
@@ -1477,16 +1479,20 @@
 
 void free_initmem (void)
 {
-	unsigned long addr;
+	unsigned long addr, initend;
 
-	addr = (unsigned long)(&__init_begin);
-	for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
+	/*
+	 * The init section is aligned to 8k in vmlinux.lds. Page align for >8k pagesizes.
+	 */
+	addr = PAGE_ALIGN((unsigned long)(&__init_begin));
+	initend = (unsigned long)(&__init_end) & PAGE_MASK;
+	for (; addr < initend; addr += PAGE_SIZE) {
 		unsigned long page;
 		struct page *p;
 
 		page = (addr +
 			((unsigned long) __va(phys_base)) -
-			((unsigned long) &empty_zero_page));
+			((unsigned long) KERNBASE));
 		p = virt_to_page(page);
 
 		ClearPageReserved(p);
diff -u --recursive --new-file v2.4.9/linux/arch/sparc64/mm/modutil.c linux/arch/sparc64/mm/modutil.c
--- v2.4.9/linux/arch/sparc64/mm/modutil.c	Thu Apr 12 12:10:25 2001
+++ linux/arch/sparc64/mm/modutil.c	Tue Aug 28 07:09:44 2001
@@ -1,4 +1,4 @@
-/*  $Id: modutil.c,v 1.8 2001/04/04 00:49:39 davem Exp $
+/*  $Id: modutil.c,v 1.9 2001/08/14 22:10:56 davem Exp $
  *  arch/sparc64/mm/modutil.c
  *
  *  Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -10,7 +10,10 @@
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
-#include <asm/vaddrs.h>
+
+#define  MODULES_VADDR	0x0000000001000000ULL  /* Where to map modules */
+#define  MODULES_LEN	0x000000007f000000ULL
+#define  MODULES_END	0x0000000080000000ULL
 
 static struct vm_struct * modvmlist = NULL;
 
diff -u --recursive --new-file v2.4.9/linux/arch/sparc64/mm/ultra.S linux/arch/sparc64/mm/ultra.S
--- v2.4.9/linux/arch/sparc64/mm/ultra.S	Sun Mar 25 18:14:21 2001
+++ linux/arch/sparc64/mm/ultra.S	Fri Sep  7 11:01:20 2001
@@ -1,4 +1,4 @@
-/* $Id: ultra.S,v 1.54 2001/03/22 07:26:04 davem Exp $
+/* $Id: ultra.S,v 1.56 2001/08/30 10:10:32 davem Exp $
  * ultra.S: Don't expand these all over the place...
  *
  * Copyright (C) 1997, 2000 David S. Miller (davem@redhat.com)
@@ -302,7 +302,7 @@
 	 nop
 
 flush_dcpage_cheetah:
-	sethi		%hi(8192), %o4
+	sethi		%hi(PAGE_SIZE), %o4
 1:	subcc		%o4, (1 << 5), %o4
 	stxa		%g0, [%o0 + %o4] ASI_DCACHE_INVALIDATE
 	membar		#Sync
@@ -440,13 +440,13 @@
 	retry
 
 xcall_flush_tlb_range:
-	sethi		%hi(8192 - 1), %g2
-	or		%g2, %lo(8192 - 1), %g2
+	sethi		%hi(PAGE_SIZE - 1), %g2
+	or		%g2, %lo(PAGE_SIZE - 1), %g2
 	andn		%g1, %g2, %g1
 	andn		%g7, %g2, %g7
 	sub		%g7, %g1, %g3
 	add		%g2, 1, %g2
-	srlx		%g3, 13, %g4
+	srlx		%g3, PAGE_SHIFT, %g4
 	cmp		%g4, 96
 
 	bgu,pn		%icc, xcall_flush_tlb_mm
diff -u --recursive --new-file v2.4.9/linux/arch/sparc64/vmlinux.lds linux/arch/sparc64/vmlinux.lds
--- v2.4.9/linux/arch/sparc64/vmlinux.lds	Tue Jul  3 17:08:19 2001
+++ linux/arch/sparc64/vmlinux.lds	Fri Sep  7 11:01:20 2001
@@ -5,7 +5,6 @@
 
 SECTIONS
 {
-  empty_zero_page = 0x0000000000400000;
   swapper_pmd_dir = 0x0000000000402000;
   empty_pg_dir = 0x0000000000403000;
   . = 0x4000;
diff -u --recursive --new-file v2.4.9/linux/drivers/acorn/block/mfmhd.c linux/drivers/acorn/block/mfmhd.c
--- v2.4.9/linux/drivers/acorn/block/mfmhd.c	Mon Aug 27 12:41:40 2001
+++ linux/drivers/acorn/block/mfmhd.c	Sun Sep  9 16:27:47 2001
@@ -1311,15 +1311,13 @@
 }
 
 static struct gendisk mfm_gendisk = {
-	MAJOR_NR,		/* Major number */
-	"mfm",			/* Major name */
-	6,			/* Bits to shift to get real from partition */
-	1 << 6,			/* Number of partitions per real */
-	mfm,			/* hd struct */
-	mfm_sizes,		/* block sizes */
-	0,			/* number */
-	(void *) mfm_info,	/* internal */
-	NULL			/* next */
+	major:		MAJOR_NR,
+	major_name:	"mfm",
+	minor_shift:	6,
+	max_p:		1 << 6,
+	part:		mfm,
+	sizes:		mfm_sizes,
+	real_devices:	(void *)mfm_info,
 };
 
 static struct block_device_operations mfm_fops =
@@ -1450,10 +1448,7 @@
 	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
 	read_ahead[MAJOR_NR] = 8;	/* 8 sector (4kB?) read ahread */
 
-#ifndef MODULE
-	mfm_gendisk.next = gendisk_head;
-	gendisk_head = &mfm_gendisk;
-#endif
+	add_gendisk(&mfm_gendisk);
 
 	Busy = 0;
 	lastspecifieddrive = -1;
@@ -1512,6 +1507,7 @@
 		outw (0, mfm_irqenable);	/* Required to enable IRQs from MFM podule */
 	free_irq(mfm_irq, NULL);
 	unregister_blkdev(MAJOR_NR, "mfm");
+	del_gendisk(&mfm_gendisk);
 	if (ecs)
 		ecard_release(ecs);
 	if (mfm_addr)
diff -u --recursive --new-file v2.4.9/linux/drivers/acpi/Makefile linux/drivers/acpi/Makefile
--- v2.4.9/linux/drivers/acpi/Makefile	Tue Jul  3 17:08:19 2001
+++ linux/drivers/acpi/Makefile	Sat Sep  8 12:26:47 2001
@@ -38,9 +38,8 @@
 obj-$(CONFIG_ACPI)	+= $(foreach dir,$(acpi-subdirs),$(dir)/$(dir).o) 
 ifdef CONFIG_ACPI_KERNEL_CONFIG
    obj-$(CONFIG_ACPI) 	+= acpiconf.o osconf.o
-else
-   obj-$(CONFIG_ACPI)	+= driver.o
 endif
+obj-$(CONFIG_ACPI)	+= driver.o
 
 ifeq ($(CONFIG_ACPI_BUSMGR),y)
 	obj-y			+= ospm/ospm.o
diff -u --recursive --new-file v2.4.9/linux/drivers/acpi/include/platform/acgcc.h linux/drivers/acpi/include/platform/acgcc.h
--- v2.4.9/linux/drivers/acpi/include/platform/acgcc.h	Tue Jul  3 17:08:19 2001
+++ linux/drivers/acpi/include/platform/acgcc.h	Sat Sep  1 11:01:28 2001
@@ -39,7 +39,6 @@
 #define BREAKPOINT3
 #define disable() __cli()
 #define enable()  __sti()
-#define wbinvd()
 
 /*! [Begin] no source code translation */
 
@@ -101,7 +100,6 @@
 #define disable() __cli()
 #define enable()  __sti()
 #define halt()    __asm__ __volatile__ ("sti; hlt":::"memory")
-#define wbinvd()
 
 /*! [Begin] no source code translation
  *
diff -u --recursive --new-file v2.4.9/linux/drivers/acpi/ospm/busmgr/Makefile linux/drivers/acpi/ospm/busmgr/Makefile
--- v2.4.9/linux/drivers/acpi/ospm/busmgr/Makefile	Tue Jul  3 17:08:19 2001
+++ linux/drivers/acpi/ospm/busmgr/Makefile	Sun Sep  2 07:48:02 2001
@@ -1,3 +1,5 @@
+export-objs	:= bm_osl.o
+
 O_TARGET	:= ospm_$(notdir $(CURDIR)).o
 obj-m		:= $(O_TARGET)
 EXTRA_CFLAGS	+= $(ACPI_CFLAGS)
diff -u --recursive --new-file v2.4.9/linux/drivers/atm/Makefile linux/drivers/atm/Makefile
--- v2.4.9/linux/drivers/atm/Makefile	Mon Mar 26 15:36:30 2001
+++ linux/drivers/atm/Makefile	Mon Aug 27 09:01:33 2001
@@ -25,6 +25,7 @@
 obj-$(CONFIG_ATM_AMBASSADOR) += ambassador.o
 obj-$(CONFIG_ATM_TCP) += atmtcp.o
 obj-$(CONFIG_ATM_IA) += iphase.o suni.o
+obj-$(CONFIG_ATM_FIRESTREAM) += firestream.o
 
 ifeq ($(CONFIG_ATM_FORE200E_PCA),y)
   FORE200E_FW_OBJS += fore200e_pca_fw.o
diff -u --recursive --new-file v2.4.9/linux/drivers/atm/firestream.h linux/drivers/atm/firestream.h
--- v2.4.9/linux/drivers/atm/firestream.h	Wed Apr 11 19:02:30 2001
+++ linux/drivers/atm/firestream.h	Sat Sep  8 12:28:14 2001
@@ -345,18 +345,28 @@
 #define CELLOSCONF_COST   (0x1 <<  0)
 /* Bits? */
 
-
 #define RAS0 0x1bc
 #define RAS0_DCD_XHLT (0x1 << 31)
 
 #define RAS0_VPSEL    (0x1 << 16)
 #define RAS0_VCSEL    (0x1 <<  0)
 
+#define RAS1 0x1c0
+#define RAS1_UTREG    (0x1 << 5)
+
 
 #define DMAMR 0x1cc
 #define DMAMR_TX_MODE_FULL (0x0 << 0)
 #define DMAMR_TX_MODE_PART (0x1 << 0)
 #define DMAMR_TX_MODE_NONE (0x2 << 0) /* And 3 */
+
+
+
+#define RAS2 0x280
+
+#define RAS2_NNI  (0x1 << 0)
+#define RAS2_USEL (0x1 << 1)
+#define RAS2_UBS  (0x1 << 2)
 
 
 
diff -u --recursive --new-file v2.4.9/linux/drivers/block/DAC960.c linux/drivers/block/DAC960.c
--- v2.4.9/linux/drivers/block/DAC960.c	Sun Aug 12 13:27:59 2001
+++ linux/drivers/block/DAC960.c	Sun Sep  9 18:59:43 2001
@@ -31,6 +31,7 @@
 #include <linux/completion.h>
 #include <linux/delay.h>
 #include <linux/hdreg.h>
+#include <linux/blkpg.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/locks.h>
@@ -1882,7 +1883,6 @@
 static boolean DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller)
 {
   int MajorNumber = DAC960_MAJOR + Controller->ControllerNumber;
-  GenericDiskInfo_T *GenericDiskInfo;
   RequestQueue_T *RequestQueue;
   int MinorNumber;
   /*
@@ -1937,13 +1937,7 @@
   /*
     Install the Generic Disk Information structure at the end of the list.
   */
-  if ((GenericDiskInfo = gendisk_head) != NULL)
-    {
-      while (GenericDiskInfo->next != NULL)
-	GenericDiskInfo = GenericDiskInfo->next;
-      GenericDiskInfo->next = &Controller->GenericDiskInfo;
-    }
-  else gendisk_head = &Controller->GenericDiskInfo;
+  add_gendisk(&Controller->GenericDiskInfo);
   /*
     Indicate the Block Device Registration completed successfully,
   */
@@ -1979,16 +1973,7 @@
   /*
     Remove the Generic Disk Information structure from the list.
   */
-  if (gendisk_head != &Controller->GenericDiskInfo)
-    {
-      GenericDiskInfo_T *GenericDiskInfo = gendisk_head;
-      while (GenericDiskInfo != NULL &&
-	     GenericDiskInfo->next != &Controller->GenericDiskInfo)
-	GenericDiskInfo = GenericDiskInfo->next;
-      if (GenericDiskInfo != NULL)
-	GenericDiskInfo->next = GenericDiskInfo->next->next;
-    }
-  else gendisk_head = Controller->GenericDiskInfo.next;
+  del_gendisk(&Controller->GenericDiskInfo);
 }
 
 
@@ -5094,21 +5079,12 @@
 						 .nr_sects,
 		      (long *) Argument);
     case BLKRAGET:
-      /* Get Read-Ahead. */
-      if ((long *) Argument == NULL) return -EINVAL;
-      return put_user(read_ahead[MAJOR(Inode->i_rdev)], (long *) Argument);
     case BLKRASET:
-      /* Set Read-Ahead. */
-      if (!capable(CAP_SYS_ADMIN)) return -EACCES;
-      if (Argument > 256) return -EINVAL;
-      read_ahead[MAJOR(Inode->i_rdev)] = Argument;
-      return 0;
     case BLKFLSBUF:
-      /* Flush Buffers. */
-      if (!capable(CAP_SYS_ADMIN)) return -EACCES;
-      fsync_dev(Inode->i_rdev);
-      invalidate_buffers(Inode->i_rdev);
-      return 0;
+    case BLKBSZGET:
+    case BLKBSZSET:
+      return blk_ioctl (Inode->i_rdev, Request, Argument);
+
     case BLKRRPART:
       /* Re-Read Partition Table. */
       if (!capable(CAP_SYS_ADMIN)) return -EACCES;
diff -u --recursive --new-file v2.4.9/linux/drivers/block/Makefile linux/drivers/block/Makefile
--- v2.4.9/linux/drivers/block/Makefile	Fri Dec 29 14:07:21 2000
+++ linux/drivers/block/Makefile	Sun Sep  9 12:00:55 2001
@@ -10,7 +10,7 @@
 
 O_TARGET := block.o
 
-export-objs	:= ll_rw_blk.o blkpg.o loop.o DAC960.o
+export-objs	:= ll_rw_blk.o blkpg.o loop.o DAC960.o genhd.o
 
 obj-y	:= ll_rw_blk.o blkpg.o genhd.o elevator.o
 
diff -u --recursive --new-file v2.4.9/linux/drivers/block/acsi.c linux/drivers/block/acsi.c
--- v2.4.9/linux/drivers/block/acsi.c	Mon Aug 27 12:41:40 2001
+++ linux/drivers/block/acsi.c	Sun Sep  9 16:27:47 2001
@@ -1386,16 +1386,14 @@
 extern struct block_device_operations acsi_fops;
 
 static struct gendisk acsi_gendisk = {
-	MAJOR_NR,		/* Major number */	
-	"ad",			/* Major name */
-	4,			/* Bits to shift to get real from partition */
-	1 << 4,			/* Number of partitions per real */
-	acsi_part,		/* hd struct */
-	acsi_sizes,		/* block sizes */
-	0,			/* number */
-	(void *)acsi_info,	/* internal */
-	NULL,			/* next */
-	&acsi_fops,		/* file operations */
+	major:		MAJOR_NR,
+	major_name:	"ad",
+	minor_shift:	4,
+	max_p:		1 << 4,
+	part:		acsi_part,
+	sizes:		acsi_sizes,
+	real_devices:	(void *)acsi_info,
+	fops:		&acsi_fops,
 };
 	
 #define MAX_SCSI_DEVICE_CODE 10
@@ -1792,8 +1790,7 @@
 	
 	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
 	read_ahead[MAJOR_NR] = 8;		/* 8 sector (4kB) read-ahead */
-	acsi_gendisk.next = gendisk_head;
-	gendisk_head = &acsi_gendisk;
+	add_gendisk(&acsi_gendisk);
 
 #ifdef CONFIG_ATARI_SLM
 	err = slm_init();
@@ -1817,8 +1814,6 @@
 
 void cleanup_module(void)
 {
-	struct gendisk ** gdp;
-
 	del_timer( &acsi_timer );
 	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
 	atari_stram_free( acsi_buffer );
@@ -1826,13 +1821,7 @@
 	if (devfs_unregister_blkdev( MAJOR_NR, "ad" ) != 0)
 		printk( KERN_ERR "acsi: cleanup_module failed\n");
 
-	for (gdp = &gendisk_head; *gdp; gdp = &((*gdp)->next))
-		if (*gdp == &acsi_gendisk)
-			break;
-	if (!*gdp)
-		printk( KERN_ERR "acsi: entry in disk chain missing!\n" );
-	else
-		*gdp = (*gdp)->next;
+	del_gendisk(&acsi_gendisk);
 }
 #endif
 
diff -u --recursive --new-file v2.4.9/linux/drivers/block/blkpg.c linux/drivers/block/blkpg.c
--- v2.4.9/linux/drivers/block/blkpg.c	Sun May 20 11:34:05 2001
+++ linux/drivers/block/blkpg.c	Sat Sep  8 12:02:32 2001
@@ -54,17 +54,6 @@
  * Note that several drives may have the same major.
  */
 
-/* a linear search, superfluous when dev is a pointer */
-static struct gendisk *get_gendisk(kdev_t dev) {
-	struct gendisk *g;
-	int m = MAJOR(dev);
-
-	for (g = gendisk_head; g; g = g->next)
-		if (g->major == m)
-			break;
-	return g;
-}
-
 /*
  * Add a partition.
  *
@@ -273,6 +262,29 @@
 		case BLKELVSET:
 			return blkelvset_ioctl(&blk_get_queue(dev)->elevator,
 					       (blkelv_ioctl_arg_t *) arg);
+
+		case BLKBSZGET:
+			/* get the logical block size (cf. BLKSSZGET) */
+			intval = BLOCK_SIZE;
+			if (blksize_size[MAJOR(dev)])
+				intval = blksize_size[MAJOR(dev)][MINOR(dev)];
+			return put_user (intval, (int *) arg);
+
+		case BLKBSZSET:
+			/* set the logical block size */
+			if (!capable (CAP_SYS_ADMIN))
+				return -EACCES;
+			if (!dev || !arg)
+				return -EINVAL;
+			if (get_user (intval, (int *) arg))
+				return -EFAULT;
+			if (intval > PAGE_SIZE || intval < 512 ||
+			    (intval & (intval - 1)))
+				return -EINVAL;
+			if (is_mounted (dev) || is_swap_partition (dev))
+				return -EBUSY;
+			set_blocksize (dev, intval);
+			return 0;
 
 		default:
 			return -EINVAL;
diff -u --recursive --new-file v2.4.9/linux/drivers/block/cciss.c linux/drivers/block/cciss.c
--- v2.4.9/linux/drivers/block/cciss.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/block/cciss.c	Sat Sep  8 12:02:32 2001
@@ -406,6 +406,8 @@
 	case BLKRRPART:
 		return revalidate_logvol(inode->i_rdev, 1);
 	case BLKFLSBUF:
+	case BLKBSZSET:
+	case BLKBSZGET:
 	case BLKROSET:
 	case BLKROGET:
 	case BLKRASET:
@@ -1963,8 +1965,7 @@
 	hba[i]->gendisk.nr_real = hba[i]->num_luns;
 
 	/* Get on the disk list */ 
-	hba[i]->gendisk.next = gendisk_head;
-	gendisk_head = &(hba[i]->gendisk); 
+	add_gendisk(&(hba[i]->gendisk));
 
 	cciss_geninit(i);
 	for(j=0; j<NWD; j++)
@@ -1980,7 +1981,6 @@
 {
 	ctlr_info_t *tmp_ptr;
 	int i;
-	struct gendisk *g;
 
 	if (pdev->driver_data == NULL)
 	{
@@ -2005,19 +2005,8 @@
 	
 
 	/* remove it from the disk list */
-	if (gendisk_head == &(hba[i]->gendisk))
-	{
-		gendisk_head = hba[i]->gendisk.next;
-	} else
-	{
-		for(g=gendisk_head; g ; g=g->next)
-		{
-			if(g->next == &(hba[i]->gendisk))
-			{
-				g->next = hba[i]->gendisk.next;
-			}
-		}
-	}
+	del_gendisk(&(hba[i]->gendisk));
+
 	pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof(CommandList_struct), 
 		hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle);
 	pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof( ErrorInfo_struct),
diff -u --recursive --new-file v2.4.9/linux/drivers/block/cpqarray.c linux/drivers/block/cpqarray.c
--- v2.4.9/linux/drivers/block/cpqarray.c	Sun Aug 12 13:27:59 2001
+++ linux/drivers/block/cpqarray.c	Sat Sep  8 12:02:32 2001
@@ -311,7 +311,6 @@
 void cleanup_module(void)
 {
 	int i;
-	struct gendisk *g;
 	char buff[4]; 
 
 	for(i=0; i<nr_ctlr; i++) {
@@ -335,16 +334,7 @@
 			hba[i]->cmd_pool_dhandle);
 		kfree(hba[i]->cmd_pool_bits);
 
-		if (gendisk_head == &ida_gendisk[i]) {
-			gendisk_head = ida_gendisk[i].next;
-		} else {
-			for(g=gendisk_head; g; g=g->next) {
-				if (g->next == &ida_gendisk[i]) {
-					g->next = ida_gendisk[i].next;
-					break;
-				}
-			}
-		}
+		del_gendisk(&ida_gendisk[i]);
 	}
 	remove_proc_entry("cpqarray", proc_root_driver);
 	kfree(ida);
@@ -550,8 +540,7 @@
 		ida_gendisk[i].nr_real = 0; 
 	
 		/* Get on the disk list */
-		ida_gendisk[i].next = gendisk_head;
-		gendisk_head = &ida_gendisk[i];
+		add_gendisk(&ida_gendisk[i]);
 
 		init_timer(&hba[i]->timer);
 		hba[i]->timer.expires = jiffies + IDA_TIMER;
@@ -1266,6 +1255,8 @@
 	}	
 
 	case BLKFLSBUF:
+	case BLKBSZSET:
+	case BLKBSZGET:
 	case BLKROSET:
 	case BLKROGET:
 	case BLKRASET:
diff -u --recursive --new-file v2.4.9/linux/drivers/block/floppy.c linux/drivers/block/floppy.c
--- v2.4.9/linux/drivers/block/floppy.c	Sun Aug 12 13:27:59 2001
+++ linux/drivers/block/floppy.c	Fri Sep  7 09:28:38 2001
@@ -124,6 +124,11 @@
  * - s/suser/capable/
  */
 
+/*
+ * 2001/08/26 -- Paul Gortmaker - fix insmod oops on machines with no
+ * floppy controller (lingering task on list after module is gone... boom.)
+ */
+
 #define FLOPPY_SANITY_CHECK
 #undef  FLOPPY_SILENT_DCL_CLEAR
 
@@ -4144,7 +4149,7 @@
 	return 0;
 }
 
-static int have_no_fdc= -EIO;
+static int have_no_fdc= -ENODEV;
 
 
 int __init floppy_init(void)
@@ -4200,7 +4205,6 @@
 		del_timer(&fd_timeout);
 		blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
 		devfs_unregister_blkdev(MAJOR_NR,"fd");
-		del_timer(&fd_timeout);
 		return -EBUSY;
 	}
 
@@ -4259,9 +4263,7 @@
 	if (have_no_fdc) 
 	{
 		DPRINT("no floppy controllers found\n");
-		floppy_tq.routine = (void *)(void *) empty;
-		mark_bh(IMMEDIATE_BH);
-		schedule();
+		run_task_queue(&tq_immediate);
 		if (usage_count)
 			floppy_release_irq_and_dma();
 		blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
@@ -4472,6 +4474,7 @@
 MODULE_PARM(FLOPPY_DMA,"i");
 MODULE_AUTHOR("Alain L. Knaff");
 MODULE_SUPPORTED_DEVICE("fd");
+MODULE_LICENSE("GPL");
 
 #else
 
diff -u --recursive --new-file v2.4.9/linux/drivers/block/genhd.c linux/drivers/block/genhd.c
--- v2.4.9/linux/drivers/block/genhd.c	Wed Jul 25 17:10:19 2001
+++ linux/drivers/block/genhd.c	Sun Sep  9 12:00:55 2001
@@ -10,12 +10,137 @@
  *  (linux@arm.uk.linux.org)
  */
 
+/*
+ * TODO:  rip out the remaining init crap from this file  --hch
+ */
+
 #include <linux/config.h>
+#include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/genhd.h>
 #include <linux/kernel.h>
 #include <linux/blk.h>
 #include <linux/init.h>
+#include <linux/spinlock.h>
+
+
+static rwlock_t gendisk_lock;
+
+/*
+ * Global kernel list of partitioning information.
+ *
+ * XXX: you should _never_ access this directly.
+ *	the only reason this is exported is source compatiblity.
+ */
+/*static*/ struct gendisk *gendisk_head;
+
+EXPORT_SYMBOL(gendisk_head);
+
+
+/**
+ * add_gendisk - add partitioning information to kernel list
+ * @gp: per-device partitioning information
+ *
+ * This function registers the partitioning information in @gp
+ * with the kernel.
+ */
+void
+add_gendisk(struct gendisk *gp)
+{
+	write_lock(&gendisk_lock);
+	gp->next = gendisk_head;
+	gendisk_head = gp;
+	write_unlock(&gendisk_lock);
+}
+
+EXPORT_SYMBOL(add_gendisk);
+
+
+/**
+ * del_gendisk - remove partitioning information from kernel list
+ * @gp: per-device partitioning information
+ *
+ * This function unregisters the partitioning information in @gp
+ * with the kernel.
+ */
+void
+del_gendisk(struct gendisk *gp)
+{
+	struct gendisk **gpp;
+
+	write_lock(&gendisk_lock);
+	for (gpp = &gendisk_head; *gpp; gpp = &((*gpp)->next))
+		if (*gpp == gp)
+			break;
+	if (*gpp)
+		*gpp = (*gpp)->next;
+	write_unlock(&gendisk_lock);
+}
+
+EXPORT_SYMBOL(del_gendisk);
+
+
+/**
+ * get_gendisk - get partitioning information for a given device
+ * @dev: device to get partitioning information for
+ *
+ * This function gets the structure containing partitioning
+ * information for the given device @dev.
+ */
+struct gendisk *
+get_gendisk(kdev_t dev)
+{
+	struct gendisk *gp = NULL;
+	int maj = MAJOR(dev);
+
+	read_lock(&gendisk_lock);
+	for (gp = gendisk_head; gp; gp = gp->next)
+		if (gp->major == maj)
+			break;
+	read_unlock(&gendisk_lock);
+
+	return gp;
+}
+
+EXPORT_SYMBOL(get_gendisk);
+
+
+#ifdef CONFIG_PROC_FS
+int
+get_partition_list(char *page, char **start, off_t offset, int count)
+{
+	struct gendisk *gp;
+	char buf[64];
+	int len, n;
+
+	len = sprintf(page, "major minor  #blocks  name\n\n");
+	read_lock(&gendisk_lock);
+	for (gp = gendisk_head; gp; gp = gp->next) {
+		for (n = 0; n < (gp->nr_real << gp->minor_shift); n++) {
+			if (gp->part[n].nr_sects == 0)
+				continue;
+
+			len += snprintf(page + len, 63,
+					"%4d  %4d %10d %s\n",
+					gp->major, n, gp->sizes[n],
+					disk_name(gp, n, buf));
+			if (len < offset)
+				offset -= len, len = 0;
+			else if (len >= offset + count)
+				goto out;
+		}
+	}
+
+out:
+	read_unlock(&gendisk_lock);
+	*start = page + offset;
+	len -= offset;
+	if (len < 0)
+		len = 0;
+	return len > count ? count : len;
+}
+#endif
+
 
 extern int blk_dev_init(void);
 #ifdef CONFIG_BLK_DEV_DAC960
@@ -33,6 +158,7 @@
 
 int __init device_init(void)
 {
+	rwlock_init(&gendisk_lock);
 	blk_dev_init();
 	sti();
 #ifdef CONFIG_I2O
diff -u --recursive --new-file v2.4.9/linux/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c
--- v2.4.9/linux/drivers/block/ll_rw_blk.c	Sun Aug 12 13:27:59 2001
+++ linux/drivers/block/ll_rw_blk.c	Sat Sep  8 12:00:46 2001
@@ -131,7 +131,7 @@
 	return max_sectors[MAJOR(dev)][MINOR(dev)];
 }
 
-inline request_queue_t *__blk_get_queue(kdev_t dev)
+inline request_queue_t *blk_get_queue(kdev_t dev)
 {
 	struct blk_dev_struct *bdev = blk_dev + MAJOR(dev);
 
@@ -141,22 +141,6 @@
 		return &blk_dev[MAJOR(dev)].request_queue;
 }
 
-/*
- * NOTE: the device-specific queue() functions
- * have to be atomic!
- */
-request_queue_t *blk_get_queue(kdev_t dev)
-{
-	request_queue_t *ret;
-	unsigned long flags;
-
-	spin_lock_irqsave(&io_request_lock,flags);
-	ret = __blk_get_queue(dev);
-	spin_unlock_irqrestore(&io_request_lock,flags);
-
-	return ret;
-}
-
 static int __blk_cleanup_queue(struct list_head *head)
 {
 	struct request *rq;
@@ -1272,7 +1256,6 @@
 EXPORT_SYMBOL(end_that_request_last);
 EXPORT_SYMBOL(blk_init_queue);
 EXPORT_SYMBOL(blk_get_queue);
-EXPORT_SYMBOL(__blk_get_queue);
 EXPORT_SYMBOL(blk_cleanup_queue);
 EXPORT_SYMBOL(blk_queue_headactive);
 EXPORT_SYMBOL(blk_queue_make_request);
diff -u --recursive --new-file v2.4.9/linux/drivers/block/loop.c linux/drivers/block/loop.c
--- v2.4.9/linux/drivers/block/loop.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/block/loop.c	Sat Sep  1 11:01:28 2001
@@ -62,6 +62,7 @@
 #include <linux/major.h>
 #include <linux/wait.h>
 #include <linux/blk.h>
+#include <linux/blkpg.h>
 #include <linux/init.h>
 #include <linux/devfs_fs_kernel.h>
 #include <linux/smp_lock.h>
@@ -853,6 +854,10 @@
 			break;
 		}
 		err = put_user(loop_sizes[lo->lo_number] << 1, (long *) arg);
+		break;
+	case BLKBSZGET:
+	case BLKBSZSET:
+		err = blk_ioctl(inode->i_rdev, cmd, arg);
 		break;
 	default:
 		err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL;
diff -u --recursive --new-file v2.4.9/linux/drivers/block/paride/pd.c linux/drivers/block/paride/pd.c
--- v2.4.9/linux/drivers/block/paride/pd.c	Sat Apr 28 11:27:53 2001
+++ linux/drivers/block/paride/pd.c	Sun Sep  9 16:27:47 2001
@@ -343,16 +343,13 @@
 extern struct block_device_operations pd_fops;
 
 static struct gendisk pd_gendisk = {
-        PD_MAJOR,       /* Major number */
-        PD_NAME,        /* Major name */
-        PD_BITS,        /* Bits to shift to get real from partition */
-        PD_PARTNS,      /* Number of partitions per real */
-        pd_hd,          /* hd struct */
-        pd_sizes,       /* block sizes */
-        0,              /* number */
-        NULL,           /* internal */
-        NULL,           /* next */
-	&pd_fops,       /* block device operations */
+	major:		PD_MAJOR,
+	major_name:	PD_NAME,
+	minor_shift:	PD_BITS,
+	max_p:		PD_PARTNS,
+	part:		pd_hd,
+	sizes:		pd_sizes,
+	fops:		&pd_fops,
 };
 
 static struct block_device_operations pd_fops = {
@@ -455,8 +452,7 @@
         
 	pd_gendisk.major = major;
 	pd_gendisk.major_name = name;
-	pd_gendisk.next = gendisk_head;
-	gendisk_head = &pd_gendisk;
+	add_gendisk(&pd_gendisk);
 
 	for(i=0;i<PD_DEVS;i++) pd_blocksizes[i] = 1024;
 	blksize_size[MAJOR_NR] = pd_blocksizes;
@@ -642,12 +638,7 @@
 	int unit;
 
         devfs_unregister_blkdev(MAJOR_NR,name);
-        for(gdp=&gendisk_head;*gdp;gdp=&((*gdp)->next))
-                if (*gdp == &pd_gendisk) break;
-        if (*gdp) *gdp = (*gdp)->next;
-
-	for (unit=0;unit<PD_UNITS;unit++) 
-	   if (PD.present) pi_release(PI);
+	del_gendisk(&pd_gendisk);
 }
 
 #endif
diff -u --recursive --new-file v2.4.9/linux/drivers/block/paride/ppc6lnx.c linux/drivers/block/paride/ppc6lnx.c
--- v2.4.9/linux/drivers/block/paride/ppc6lnx.c	Fri Apr  6 10:42:55 2001
+++ linux/drivers/block/paride/ppc6lnx.c	Fri Sep  7 09:28:38 2001
@@ -108,28 +108,11 @@
 static u8 ppc6_rd_data_byte(PPC *ppc);
 static u8 ppc6_rd_port(PPC *ppc, u8 port);
 static void ppc6_wr_port(PPC *ppc, u8 port, u8 data);
-static u8 ppc6_rd_reg(PPC *ppc, u8 reg);
-static void ppc6_wr_reg(PPC *ppc, u8 reg, u8 data);
-static u8 ppc6_version(PPC *ppc);
 static void ppc6_rd_data_blk(PPC *ppc, u8 *data, long count);
 static void ppc6_wait_for_fifo(PPC *ppc);
 static void ppc6_wr_data_blk(PPC *ppc, u8 *data, long count);
 static void ppc6_rd_port16_blk(PPC *ppc, u8 port, u8 *data, long length);
-static u16 ppc6_rd_port16(PPC *ppc, u8 port);
-static void ppc6_wr_port16(PPC *ppc, u8 port, u16 data);
 static void ppc6_wr_port16_blk(PPC *ppc, u8 port, u8 *data, long length);
-static u8 ppc6_rd_eeprom_reg(PPC *ppc);
-static void ppc6_wr_eeprom_reg(PPC *ppc, u8 data);
-static void ppc6_eeprom_start(PPC *ppc);
-static void ppc6_eeprom_end(PPC *ppc);
-static void ppc6_set_cs(PPC *ppc);
-static void ppc6_reset_cs(PPC *ppc);
-static u8 ppc6_rd_eeprom_bit(PPC *ppc);
-static void ppc6_eeprom_ready_wait(PPC *ppc);
-static void ppc6_wr_eeprom_bit(PPC *ppc, u8 bit);
-static u16 ppc6_eeprom_read(PPC *ppc, u8 addr);
-static u8 ppc6_irq_test(PPC *ppc);
-static u8 ppc6_rd_extout(PPC *ppc);
 static void ppc6_wr_extout(PPC *ppc, u8 regdata);
 static int ppc6_open(PPC *ppc);
 static void ppc6_close(PPC *ppc);
@@ -304,7 +287,7 @@
 
 static u8 ppc6_rd_data_byte(PPC *ppc)
 {
-	u8 data;
+	u8 data = 0;
 
 	switch(ppc->mode)
 	{
@@ -393,33 +376,6 @@
 
 //***************************************************************************
 
-static u8 ppc6_rd_reg(PPC *ppc, u8 reg)
-{
-	ppc6_send_cmd(ppc,(u8)(reg | ACCESS_REG | ACCESS_READ));
-
-	return(ppc6_rd_data_byte(ppc));
-}
-
-//***************************************************************************
-
-static void ppc6_wr_reg(PPC *ppc, u8 reg, u8 data)
-{
-	ppc6_send_cmd(ppc,(u8)(reg | ACCESS_REG | ACCESS_WRITE));
-
-	ppc6_wr_data_byte(ppc, data);
-}
-
-//***************************************************************************
-
-static u8 ppc6_version(PPC *ppc)
-{
-	ppc6_send_cmd(ppc,(REG_VERSION | ACCESS_REG | ACCESS_READ));
-
-	return(ppc6_rd_data_byte(ppc) & 0x3F);
-}
-
-//***************************************************************************
-
 static void ppc6_rd_data_blk(PPC *ppc, u8 *data, long count)
 {
 	switch(ppc->mode)
@@ -708,44 +664,6 @@
 
 //***************************************************************************
 
-static u16 ppc6_rd_port16(PPC *ppc, u8 port)
-{
-	u16 data;
-
-	ppc6_send_cmd(ppc, (CMD_PREFIX_SET | PREFIX_IO16));
-
-	ppc6_send_cmd(ppc, (u8)(port | ACCESS_PORT | ACCESS_READ));
-
-	data = ppc6_rd_data_byte(ppc);
-
-	ppc6_send_cmd(ppc, (u8)(port | ACCESS_PORT | ACCESS_READ));
-
-	data += (u16)ppc6_rd_data_byte(ppc) << 8;
-
-	ppc6_send_cmd(ppc, (CMD_PREFIX_RESET | PREFIX_IO16));
-
-	return(data);
-}
-
-//***************************************************************************
-
-static void ppc6_wr_port16(PPC *ppc, u8 port, u16 data)
-{
-	ppc6_send_cmd(ppc, (CMD_PREFIX_SET | PREFIX_IO16));
-
-	ppc6_send_cmd(ppc, (u8)(port | ACCESS_PORT | ACCESS_WRITE));
-
-	ppc6_wr_data_byte(ppc, (u8)data);
-
-	ppc6_send_cmd(ppc, (u8)(port | ACCESS_PORT | ACCESS_WRITE));
-
-	ppc6_wr_data_byte(ppc, (u8)(data >> 8));
-
-	ppc6_send_cmd(ppc, (CMD_PREFIX_RESET | PREFIX_IO16));
-}
-
-//***************************************************************************
-
 static void ppc6_wr_port16_blk(PPC *ppc, u8 port, u8 *data, long length)
 {
 	length = length << 1;
@@ -762,148 +680,6 @@
 	ppc6_wr_data_blk(ppc, data, length);
 
 	ppc6_send_cmd(ppc, (CMD_PREFIX_RESET | PREFIX_IO16 | PREFIX_BLK));
-}
-
-//***************************************************************************
-
-static u8 ppc6_rd_eeprom_reg(PPC *ppc)
-{
-	ppc6_send_cmd(ppc, (REG_EEPROM | ACCESS_REG | ACCESS_READ));
-
-	return(ppc6_rd_data_byte(ppc));
-}
-
-//***************************************************************************
-
-static void ppc6_wr_eeprom_reg(PPC *ppc, u8 data)
-{
-	ppc6_send_cmd(ppc, (REG_EEPROM | ACCESS_REG | ACCESS_WRITE));
-
-	ppc6_wr_data_byte(ppc, data);
-}
-
-//***************************************************************************
-
-static void ppc6_eeprom_start(PPC *ppc)
-{
-	ppc6_wr_eeprom_reg(ppc, EEPROM_EN);
-}
-
-//***************************************************************************
-
-static void ppc6_eeprom_end(PPC *ppc)
-{
-	ppc6_wr_eeprom_reg(ppc, 0);
-}
-
-//***************************************************************************
-
-static void ppc6_set_cs(PPC *ppc)
-{
-	ppc6_wr_eeprom_reg(ppc, (u8)(ppc6_rd_eeprom_reg(ppc) | EEPROM_CS));
-}
-
-//***************************************************************************
-
-static void ppc6_reset_cs(PPC *ppc)
-{
-	ppc6_wr_eeprom_reg(ppc, (u8)(ppc6_rd_eeprom_reg(ppc) & ~EEPROM_CS));
-}
-
-//***************************************************************************
-
-static u8 ppc6_rd_eeprom_bit(PPC *ppc)
-{
-	ppc6_send_cmd(ppc, (REG_STATUS | ACCESS_REG | ACCESS_READ));
-
-	if (ppc6_rd_data_byte(ppc) & STATUS_EEPROM_DO)
-		return(1);
-	else
-		return(0);
-}
-
-//***************************************************************************
-
-static void ppc6_eeprom_ready_wait(PPC *ppc)
-{
-	ppc6_set_cs(ppc);
-
-	while(ppc6_rd_eeprom_bit(ppc));
-
-	ppc6_reset_cs(ppc);
-}
-
-//***************************************************************************
-
-static void ppc6_wr_eeprom_bit(PPC *ppc, u8 bit)
-{
-	u8 eereg;
-
-	eereg = ppc6_rd_eeprom_reg(ppc);
-
-	eereg &= ~(EEPROM_SK | EEPROM_DI);
-
-	if (bit & 1)
-		eereg |= EEPROM_DI;
-
-	ppc6_wr_eeprom_reg(ppc, eereg);
-
-	eereg |= EEPROM_SK;
-
-	ppc6_wr_eeprom_reg(ppc, eereg);
-
-	eereg &= ~EEPROM_SK;
-
-	ppc6_wr_eeprom_reg(ppc, eereg);
-}
-
-//***************************************************************************
-
-static u16 ppc6_eeprom_read(PPC *ppc, u8 addr)
-{
-	int i;
-	u16 data;
-
-	ppc6_set_cs(ppc);
-
-	ppc6_wr_eeprom_bit(ppc, 1); // Start bit
-
-	ppc6_wr_eeprom_bit(ppc, 1); // opcode 10 (read)
-	ppc6_wr_eeprom_bit(ppc, 0);
-
-	for(i=0; i<6; i++)
-		ppc6_wr_eeprom_bit(ppc, (u8)((addr >> (5 - i)) & 1));
-
-	data = 0;
-
-	for(i=0; i<16; i++)
-	{
-		ppc6_wr_eeprom_bit(ppc,0);
-
-		data = (data << 1) | ppc6_rd_eeprom_bit(ppc);
-	}
-
-	ppc6_reset_cs(ppc);
-
-	return(data);
-}
-
-//***************************************************************************
-
-static u8 ppc6_irq_test(PPC *ppc)
-{
-	ppc6_send_cmd(ppc,(REG_STATUS | ACCESS_REG | ACCESS_READ));
-
-	return(ppc6_rd_data_byte(ppc) & STATUS_IRQA);
-}
-
-//***************************************************************************
-
-static u8 ppc6_rd_extout(PPC *ppc)
-{
-	ppc6_send_cmd(ppc,(REG_VERSION | ACCESS_REG | ACCESS_READ));
-
-	return((ppc6_rd_data_byte(ppc) & 0xC0) >> 6);
 }
 
 //***************************************************************************
diff -u --recursive --new-file v2.4.9/linux/drivers/block/ps2esdi.c linux/drivers/block/ps2esdi.c
--- v2.4.9/linux/drivers/block/ps2esdi.c	Wed Jul 25 17:10:19 2001
+++ linux/drivers/block/ps2esdi.c	Sun Sep  9 18:59:43 2001
@@ -157,16 +157,14 @@
 
 static struct gendisk ps2esdi_gendisk =
 {
-	MAJOR_NR,		/* Major number */
-	"ed",			/* Major name */
-	6,			/* Bits to shift to get real from partition */
-	1 << 6,			/* Number of partitions per real disk */
-	ps2esdi,		/* hd struct */
-	ps2esdi_sizes,		/* block sizes */
-	0,			/* number */
-	(void *) ps2esdi_info,	/* internal */
-	NULL,			/* next */
-	&ps2esdi_fops,          /* file operations */
+	major:		MAJOR_NR,
+	major_name:	"ed",
+	minor_shift:	6,
+	max_p:		1 << 6,
+	part:		ps2esdi,
+	sizes:		ps2esdi_sizes,
+	real_devices:	(void *)ps2esdi_info,
+	fops:		&ps2esdi_fops,
 };
 
 /* initialization routine called by ll_rw_blk.c   */
@@ -184,8 +182,7 @@
 	read_ahead[MAJOR_NR] = 8;	/* 8 sector (4kB) read ahead */
 
 	/* some minor housekeeping - setup the global gendisk structure */
-	ps2esdi_gendisk.next = gendisk_head;
-	gendisk_head = &ps2esdi_gendisk;
+	add_gendisk(&ps2esdi_gendisk);
 	ps2esdi_geninit();
 	return 0;
 }				/* ps2esdi_init */
@@ -223,15 +220,15 @@
 void
 cleanup_module(void)
 {
-	if(ps2esdi_slot)
-	{
+	if(ps2esdi_slot) {
 		mca_mark_as_unused(ps2esdi_slot);
 		mca_set_adapter_procfn(ps2esdi_slot, NULL, NULL);
 	}
 	release_region(io_base, 4);
 	free_dma(dma_arb_level);
-  	free_irq(PS2ESDI_IRQ, NULL)
+  	free_irq(PS2ESDI_IRQ, NULL);
 	devfs_unregister_blkdev(MAJOR_NR, "ed");
+	del_gendisk(&ps2esdi_gendisk);
 	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
 }
 #endif /* MODULE */
@@ -1127,6 +1124,8 @@
 		case BLKRASET:
 		case BLKRAGET:
 		case BLKFLSBUF:
+		case BLKBSZGET:
+		case BLKBSZSET:
 		case BLKPG:
 			return blk_ioctl(inode->i_rdev, cmd, arg);
 		}
diff -u --recursive --new-file v2.4.9/linux/drivers/block/rd.c linux/drivers/block/rd.c
--- v2.4.9/linux/drivers/block/rd.c	Wed Jul 25 17:10:19 2001
+++ linux/drivers/block/rd.c	Sun Sep  9 16:40:38 2001
@@ -100,7 +100,7 @@
 static int rd_blocksizes[NUM_RAMDISKS];		/* Size of 1024 byte blocks :)  */
 static int rd_kbsize[NUM_RAMDISKS];		/* Size in blocks of 1024 bytes */
 static devfs_handle_t devfs_handle;
-static struct inode *rd_inode[NUM_RAMDISKS];	/* Protected device inodes */
+static struct block_device *rd_bdev[NUM_RAMDISKS];/* Protected device data */
 
 /*
  * Parameters for the boot-loading of the RAM disk.  These are set by
@@ -259,7 +259,7 @@
 			/* special: we want to release the ramdisk memory,
 			   it's not like with the other blockdevices where
 			   this ioctl only flushes away the buffer cache. */
-			if ((atomic_read(&inode->i_bdev->bd_openers) > 2))
+			if ((atomic_read(&rd_bdev[minor]->bd_openers) > 2))
 				return -EBUSY;
 			destroy_buffers(inode->i_rdev);
 			rd_blocksizes[minor] = 0;
@@ -305,7 +305,6 @@
 	lock_kernel();
 	if (!--initrd_users) {
 		blkdev_put(inode->i_bdev, BDEV_FILE);
-		iput(inode);
 		free_initrd_mem(initrd_start, initrd_end);
 		initrd_start = 0;
 	}
@@ -324,8 +323,10 @@
 
 static int rd_open(struct inode * inode, struct file * filp)
 {
+	int unit = DEVICE_NR(inode->i_rdev);
+
 #ifdef CONFIG_BLK_DEV_INITRD
-	if (DEVICE_NR(inode->i_rdev) == INITRD_MINOR) {
+	if (unit == INITRD_MINOR) {
 		if (!initrd_start) return -ENODEV;
 		initrd_users++;
 		filp->f_op = &initrd_fops;
@@ -333,16 +334,15 @@
 	}
 #endif
 
-	if (DEVICE_NR(inode->i_rdev) >= NUM_RAMDISKS)
+	if (unit >= NUM_RAMDISKS)
 		return -ENXIO;
 
 	/*
 	 * Immunize device against invalidate_buffers() and prune_icache().
 	 */
-	if (rd_inode[DEVICE_NR(inode->i_rdev)] == NULL) {
-		if (!inode->i_bdev) return -ENXIO;
-		if ((rd_inode[DEVICE_NR(inode->i_rdev)] = igrab(inode)) != NULL)
-			atomic_inc(&rd_inode[DEVICE_NR(inode->i_rdev)]->i_bdev->bd_openers);
+	if (rd_bdev[unit] == NULL) {
+		rd_bdev[unit] = bdget(kdev_t_to_nr(inode->i_rdev));
+		atomic_inc(&rd_bdev[unit]->bd_openers);
 	}
 
 	MOD_INC_USE_COUNT;
@@ -369,12 +369,11 @@
 	int i;
 
 	for (i = 0 ; i < NUM_RAMDISKS; i++) {
-		if (rd_inode[i]) {
-			/* withdraw invalidate_buffers() and prune_icache() immunity */
-			atomic_dec(&rd_inode[i]->i_bdev->bd_openers);
-			/* remove stale pointer to module address space */
-			rd_inode[i]->i_bdev->bd_op = NULL;
-			iput(rd_inode[i]);
+		struct block_device *bdev = rd_bdev[i];
+		rd_bdev[i] = NULL;
+		if (bdev) {
+			blkdev_put(bdev, BDEV_FILE);
+			bdput(bdev);
 		}
 		destroy_buffers(MKDEV(MAJOR_NR, i));
 	}
diff -u --recursive --new-file v2.4.9/linux/drivers/block/xd.c linux/drivers/block/xd.c
--- v2.4.9/linux/drivers/block/xd.c	Thu May 24 15:14:08 2001
+++ linux/drivers/block/xd.c	Sun Sep  9 16:27:47 2001
@@ -126,17 +126,16 @@
 extern struct block_device_operations xd_fops;
 
 static struct gendisk xd_gendisk = {
-	MAJOR_NR,	/* Major number */
-	"xd",		/* Major name */
-	6,		/* Bits to shift to get real from partition */
-	1 << 6,		/* Number of partitions per real */
-	xd_struct,	/* hd struct */
-	xd_sizes,	/* block sizes */
-	0,		/* number */
-	(void *) xd_info,	/* internal */
-	NULL,		/* next */
-	&xd_fops,	/* file operations */
+	major:		MAJOR_NR,
+	major_name:	"xd",
+	minor_shift:	6,
+	max_p:		1 << 6,
+	part:		xd_struct,
+	sizes:		xd_sizes,
+	real_devices:	(void *)xd_info,
+	fops:		&xd_fops,
 };
+
 static struct block_device_operations xd_fops = {
 	open:		xd_open,
 	release:	xd_release,
@@ -173,8 +172,7 @@
 	devfs_handle = devfs_mk_dir (NULL, xd_gendisk.major_name, NULL);
 	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
 	read_ahead[MAJOR_NR] = 8;	/* 8 sector (4kB) read ahead */
-	xd_gendisk.next = gendisk_head;
-	gendisk_head = &xd_gendisk;
+	add_gendisk(&xd_gendisk);
 	xd_geninit();
 
 	return 0;
@@ -1112,18 +1110,12 @@
 
 static void xd_done (void)
 {
-	struct gendisk ** gdp;
-	
 	blksize_size[MAJOR_NR] = NULL;
 	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
 	blk_size[MAJOR_NR] = NULL;
 	hardsect_size[MAJOR_NR] = NULL;
 	read_ahead[MAJOR_NR] = 0;
-	for (gdp = &gendisk_head; *gdp; gdp = &((*gdp)->next))
-		if (*gdp == &xd_gendisk)
-			break;
-	if (*gdp)
-		*gdp = (*gdp)->next;
+	del_gendisk(&xd_gendisk);
 	release_region(xd_iobase,4);
 }
 
diff -u --recursive --new-file v2.4.9/linux/drivers/bluetooth/Config.in linux/drivers/bluetooth/Config.in
--- v2.4.9/linux/drivers/bluetooth/Config.in	Tue Jul  3 17:08:19 2001
+++ linux/drivers/bluetooth/Config.in	Fri Sep  7 09:28:38 2001
@@ -3,6 +3,6 @@
 
 dep_tristate 'HCI USB driver' CONFIG_BLUEZ_HCIUSB $CONFIG_BLUEZ $CONFIG_USB
 dep_tristate 'HCI UART driver' CONFIG_BLUEZ_HCIUART $CONFIG_BLUEZ
-dep_tristate 'HCI EMU (virtual device) driver' CONFIG_BLUEZ_HCIEMU $CONFIG_BLUEZ
+dep_tristate 'HCI VHCI virtual HCI device driver' CONFIG_BLUEZ_HCIVHCI $CONFIG_BLUEZ
 
 endmenu
diff -u --recursive --new-file v2.4.9/linux/drivers/bluetooth/Makefile linux/drivers/bluetooth/Makefile
--- v2.4.9/linux/drivers/bluetooth/Makefile	Tue Jul  3 17:08:19 2001
+++ linux/drivers/bluetooth/Makefile	Fri Sep  7 09:28:38 2001
@@ -6,6 +6,6 @@
 
 obj-$(CONFIG_BLUEZ_HCIUSB)	+= hci_usb.o
 obj-$(CONFIG_BLUEZ_HCIUART)	+= hci_uart.o
-obj-$(CONFIG_BLUEZ_HCIEMU)	+= hci_emu.o
+obj-$(CONFIG_BLUEZ_HCIVHCI)	+= hci_vhci.o
 
 include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.9/linux/drivers/bluetooth/hci_emu.c linux/drivers/bluetooth/hci_emu.c
--- v2.4.9/linux/drivers/bluetooth/hci_emu.c	Mon Aug 27 12:41:40 2001
+++ linux/drivers/bluetooth/hci_emu.c	Wed Dec 31 16:00:00 1969
@@ -1,330 +0,0 @@
-/* 
-   BlueZ - Bluetooth protocol stack for Linux
-   Copyright (C) 2000-2001 Qualcomm Incorporated
-
-   Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License version 2 as
-   published by the Free Software Foundation;
-
-   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
-   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
-   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
-   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
-   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
-   SOFTWARE IS DISCLAIMED.
-*/
-
-/*
- * BlueZ HCI virtual device driver.
- *
- * $Id: hci_emu.c,v 1.1 2001/06/01 08:12:10 davem Exp $ 
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/poll.h>
-#include <linux/fcntl.h>
-#include <linux/init.h>
-#include <linux/random.h>
-
-#include <linux/skbuff.h>
-#include <linux/miscdevice.h>
-
-#include <asm/system.h>
-#include <asm/uaccess.h>
-
-#include <net/bluetooth/bluetooth.h>
-#include <net/bluetooth/bluez.h>
-#include <net/bluetooth/hci_core.h>
-#include <net/bluetooth/hci_emu.h>
-
-/* HCI device part */
-
-int hci_emu_open(struct hci_dev *hdev)
-{
-	hdev->flags |= HCI_RUNNING;
-	return 0;
-}
-
-int hci_emu_flush(struct hci_dev *hdev)
-{
-	struct hci_emu_struct *hci_emu = (struct hci_emu_struct *) hdev->driver_data;
-	bluez_skb_queue_purge(&hci_emu->readq);
-	return 0;
-}
-
-int hci_emu_close(struct hci_dev *hdev)
-{
-	hdev->flags &= ~HCI_RUNNING;
-	hci_emu_flush(hdev);
-	return 0;
-}
-
-int hci_emu_send_frame(struct sk_buff *skb)
-{
-	struct hci_dev* hdev = (struct hci_dev *) skb->dev;
-	struct hci_emu_struct *hci_emu;
-
-	if (!hdev) {
-		ERR("Frame for uknown device (hdev=NULL)");
-		return -ENODEV;
-	}
-
-	if (!(hdev->flags & HCI_RUNNING))
-		return -EBUSY;
-
-	hci_emu = (struct hci_emu_struct *) hdev->driver_data;
-
-	memcpy(skb_push(skb, 1), &skb->pkt_type, 1);
-	skb_queue_tail(&hci_emu->readq, skb);
-
-	if (hci_emu->flags & HCI_EMU_FASYNC)
-		kill_fasync(&hci_emu->fasync, SIGIO, POLL_IN);
-	wake_up_interruptible(&hci_emu->read_wait);
-
-	return 0;
-}
-
-/* Character device part */
-
-/* Poll */
-static unsigned int hci_emu_chr_poll(struct file *file, poll_table * wait)
-{  
-	struct hci_emu_struct *hci_emu = (struct hci_emu_struct *) file->private_data;
-
-	poll_wait(file, &hci_emu->read_wait, wait);
- 
-	if (skb_queue_len(&hci_emu->readq))
-		return POLLIN | POLLRDNORM;
-
-	return POLLOUT | POLLWRNORM;
-}
-
-/* Get packet from user space buffer(already verified) */
-static __inline__ ssize_t hci_emu_get_user(struct hci_emu_struct *hci_emu, const char *buf, size_t count)
-{
-	struct sk_buff *skb;
-
-	if (count > HCI_EMU_MAX_FRAME)
-		return -EINVAL;
-
-	if (!(skb = bluez_skb_alloc(count, GFP_KERNEL)))
-		return -ENOMEM;
-	
-	copy_from_user(skb_put(skb, count), buf, count); 
-
-	skb->dev = (void *) &hci_emu->hdev;
-	skb->pkt_type = *((__u8 *) skb->data);
-	skb_pull(skb, 1);
-
-	hci_recv_frame(skb);
-
-	return count;
-} 
-
-/* Write */
-static ssize_t hci_emu_chr_write(struct file * file, const char * buf, 
-			     size_t count, loff_t *pos)
-{
-	struct hci_emu_struct *hci_emu = (struct hci_emu_struct *) file->private_data;
-
-	if (verify_area(VERIFY_READ, buf, count))
-		return -EFAULT;
-
-	return hci_emu_get_user(hci_emu, buf, count);
-}
-
-/* Put packet to user space buffer(already verified) */
-static __inline__ ssize_t hci_emu_put_user(struct hci_emu_struct *hci_emu,
-				       struct sk_buff *skb, char *buf, int count)
-{
-	int len = count, total = 0;
-	char *ptr = buf;
-
-	len = MIN(skb->len, len); 
-	copy_to_user(ptr, skb->data, len); 
-	total += len;
-
-	hci_emu->hdev.stat.byte_tx += len;
-	switch (skb->pkt_type) {
-		case HCI_COMMAND_PKT:
-			hci_emu->hdev.stat.cmd_tx++;
-			break;
-
-		case HCI_ACLDATA_PKT:
-			hci_emu->hdev.stat.acl_tx++;
-			break;
-
-		case HCI_SCODATA_PKT:
-			hci_emu->hdev.stat.cmd_tx++;
-			break;
-	};
-
-	return total;
-}
-
-/* Read */
-static ssize_t hci_emu_chr_read(struct file * file, char * buf, size_t count, loff_t *pos)
-{
-	struct hci_emu_struct *hci_emu = (struct hci_emu_struct *) file->private_data;
-	DECLARE_WAITQUEUE(wait, current);
-	struct sk_buff *skb;
-	ssize_t ret = 0;
-
-	add_wait_queue(&hci_emu->read_wait, &wait);
-	while (count) {
-		current->state = TASK_INTERRUPTIBLE;
-
-		/* Read frames from device queue */
-		if (!(skb = skb_dequeue(&hci_emu->readq))) {
-			if (file->f_flags & O_NONBLOCK) {
-				ret = -EAGAIN;
-				break;
-			}
-			if (signal_pending(current)) {
-				ret = -ERESTARTSYS;
-				break;
-			}
-
-			/* Nothing to read, let's sleep */
-			schedule();
-			continue;
-		}
-
-		if (!verify_area(VERIFY_WRITE, buf, count))
-			ret = hci_emu_put_user(hci_emu, skb, buf, count);
-		else
-			ret = -EFAULT;
-
-		bluez_skb_free(skb);
-		break;
-	}
-
-	current->state = TASK_RUNNING;
-	remove_wait_queue(&hci_emu->read_wait, &wait);
-
-	return ret;
-}
-
-static int hci_emu_chr_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-	return -EINVAL;
-}
-
-static int hci_emu_chr_fasync(int fd, struct file *file, int on)
-{
-	struct hci_emu_struct *hci_emu = (struct hci_emu_struct *) file->private_data;
-	int ret;
-
-	if ((ret = fasync_helper(fd, file, on, &hci_emu->fasync)) < 0)
-		return ret; 
- 
-	if (on)
-		hci_emu->flags |= HCI_EMU_FASYNC;
-	else 
-		hci_emu->flags &= ~HCI_EMU_FASYNC;
-
-	return 0;
-}
-
-static int hci_emu_chr_open(struct inode *inode, struct file * file)
-{
-	struct hci_emu_struct *hci_emu = NULL; 
-	struct hci_dev *hdev;
-
-	if (!(hci_emu = kmalloc(sizeof(struct hci_emu_struct), GFP_KERNEL)))
-		return -ENOMEM;
-
-	memset(hci_emu, 0, sizeof(struct hci_emu_struct));
-
-	skb_queue_head_init(&hci_emu->readq);
-	init_waitqueue_head(&hci_emu->read_wait);
-
-	/* Initialize and register HCI device */
-	hdev = &hci_emu->hdev;
-
-	hdev->type = HCI_EMU;
-	hdev->driver_data = hci_emu;
-
-	hdev->open  = hci_emu_open;
-	hdev->close = hci_emu_close;
-	hdev->flush = hci_emu_flush;
-	hdev->send  = hci_emu_send_frame;
-
-	if (hci_register_dev(hdev) < 0) {
-		kfree(hci_emu);
-		return -EBUSY;
-	}
-
-	file->private_data = hci_emu;
-	return 0;   
-}
-
-static int hci_emu_chr_close(struct inode *inode, struct file *file)
-{
-	struct hci_emu_struct *hci_emu = (struct hci_emu_struct *) file->private_data;
-
-	if (hci_unregister_dev(&hci_emu->hdev) < 0) {
-		ERR("Can't unregister HCI device %s", hci_emu->hdev.name);
-	}
-
-	kfree(hci_emu);
-	file->private_data = NULL;
-
-	return 0;
-}
-
-static struct file_operations hci_emu_fops = {
-	owner:	THIS_MODULE,	
-	llseek:	no_llseek,
-	read:	hci_emu_chr_read,
-	write:	hci_emu_chr_write,
-	poll:	hci_emu_chr_poll,
-	ioctl:	hci_emu_chr_ioctl,
-	open:	hci_emu_chr_open,
-	release:hci_emu_chr_close,
-	fasync:	hci_emu_chr_fasync		
-};
-
-static struct miscdevice hci_emu_miscdev=
-{
-        HCI_EMU_MINOR,
-        "hci_emu",
-        &hci_emu_fops
-};
-
-int __init hci_emu_init(void)
-{
-	INF("BlueZ HCI EMU driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",  
-		BLUEZ_VER);
-	INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-
-	if (misc_register(&hci_emu_miscdev)) {
-		ERR("Can't register misc device %d\n", HCI_EMU_MINOR);
-		return -EIO;
-	}
-
-	return 0;
-}
-
-void hci_emu_cleanup(void)
-{
-	misc_deregister(&hci_emu_miscdev);
-}
-
-module_init(hci_emu_init);
-module_exit(hci_emu_cleanup);
diff -u --recursive --new-file v2.4.9/linux/drivers/bluetooth/hci_uart.c linux/drivers/bluetooth/hci_uart.c
--- v2.4.9/linux/drivers/bluetooth/hci_uart.c	Mon Aug 27 12:41:40 2001
+++ linux/drivers/bluetooth/hci_uart.c	Fri Sep  7 09:28:38 2001
@@ -25,8 +25,9 @@
 /*
  * BlueZ HCI UART driver.
  *
- * $Id: hci_uart.c,v 1.1 2001/06/01 08:12:10 davem Exp $    
+ * $Id: hci_uart.c,v 1.5 2001/07/05 18:42:44 maxk Exp $    
  */
+#define VERSION "1.0"
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -84,7 +85,7 @@
 	DBG("hdev %p tty %p", hdev, tty);
 
 	/* Drop TX queue */
-	bluez_skb_queue_purge(&n_hci->txq);
+	skb_queue_purge(&n_hci->txq);
 
 	/* Flush any pending characters in the driver and discipline. */
 	if (tty->ldisc.flush_buffer)
@@ -139,7 +140,7 @@
 
 		if (len == skb->len) {
 			/* Full frame was sent */
-			bluez_skb_free(skb);
+			kfree_skb(skb);
 		} else {
 			/* Subtract sent part and requeue  */
 			skb_pull(skb, len);
@@ -334,7 +335,7 @@
 		hci_recv_frame(n_hci->rx_skb);
 	} else if (len > room) {
 		ERR("Data length is to large");
-		bluez_skb_free(n_hci->rx_skb);
+		kfree_skb(n_hci->rx_skb);
 		n_hci->hdev.stat.err_rx++;
 	} else {
 		n_hci->rx_state = WAIT_DATA;
@@ -356,7 +357,7 @@
 	hci_sco_hdr   *sh;
 	register int len, type, dlen;
 
-	DBG("count %d state %d rx_count %d", count, n_hci->rx_state, n_hci->rx_count);
+	DBG("count %d state %ld rx_count %ld", count, n_hci->rx_state, n_hci->rx_count);
 
 	n_hci->hdev.stat.byte_rx += count;
 
@@ -441,7 +442,7 @@
 		ptr++; count--;
 
 		/* Allocate packet */
-		if (!(n_hci->rx_skb = bluez_skb_alloc(HCI_MAX_READ, GFP_ATOMIC))) {
+		if (!(n_hci->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
 			ERR("Can't allocate mem for new packet");
 
 			n_hci->rx_state = WAIT_PACKET_TYPE;
@@ -536,7 +537,7 @@
 	int err;
 
 	INF("BlueZ HCI UART driver ver %s Copyright (C) 2000,2001 Qualcomm Inc", 
-		BLUEZ_VER);
+		VERSION);
 	INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
 
 	/* Register the tty discipline */
@@ -573,3 +574,7 @@
 
 module_init(n_hci_init);
 module_exit(n_hci_cleanup);
+
+MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
+MODULE_DESCRIPTION("BlueZ HCI UART driver ver " VERSION);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.9/linux/drivers/bluetooth/hci_usb.c linux/drivers/bluetooth/hci_usb.c
--- v2.4.9/linux/drivers/bluetooth/hci_usb.c	Mon Aug 27 12:41:40 2001
+++ linux/drivers/bluetooth/hci_usb.c	Fri Sep  7 09:28:38 2001
@@ -28,8 +28,9 @@
  *    Copyright (c) 2000 Greg Kroah-Hartman        <greg@kroah.com>
  *    Copyright (c) 2000 Mark Douglas Corner       <mcorner@umich.edu>
  *
- * $Id: hci_usb.c,v 1.1 2001/06/01 08:12:10 davem Exp $    
+ * $Id: hci_usb.c,v 1.5 2001/07/05 18:42:44 maxk Exp $    
  */
+#define VERSION "1.0"
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -106,7 +107,7 @@
 		usb_free_urb(husb->write_urb);
 
 	if (husb->intr_skb)
-		bluez_skb_free(husb->intr_skb);
+		kfree_skb(husb->intr_skb);
 }
 
 /* ------- Interface to HCI layer ------ */
@@ -139,8 +140,8 @@
 	DBG("%s", hdev->name);
 
 	/* Drop TX queues */
-	bluez_skb_queue_purge(&husb->tx_ctrl_q);
-	bluez_skb_queue_purge(&husb->tx_write_q);
+	skb_queue_purge(&husb->tx_ctrl_q);
+	skb_queue_purge(&husb->tx_write_q);
 
 	return 0;
 }
@@ -173,7 +174,7 @@
 		goto done;
 
 	if (hci_usb_ctrl_msg(husb, skb)){
-		bluez_skb_free(skb);
+		kfree_skb(skb);
 		goto done;
 	}
 
@@ -271,7 +272,7 @@
 		DBG("%s ctrl status: %d", hdev->name, urb->status);
 
 	clear_bit(HCI_TX_CTRL, &husb->tx_state);
-	bluez_skb_free(skb);
+	kfree_skb(skb);
 
 	/* Wake up device */
 	hci_usb_ctrl_wakeup(husb);
@@ -294,7 +295,7 @@
 		DBG("%s bulk write status: %d", hdev->name, urb->status);
 
 	clear_bit(HCI_TX_WRITE, &husb->tx_state);
-	bluez_skb_free(skb);
+	kfree_skb(skb);
 
 	/* Wake up device */
 	hci_usb_write_wakeup(husb);
@@ -352,7 +353,7 @@
 		if (count > husb->intr_count) {
 			ERR("%s bad frame len %d (expected %d)", husb->hdev.name, count, husb->intr_count);
 
-			bluez_skb_free(skb);
+			kfree_skb(skb);
 			husb->intr_skb = NULL;
 			husb->intr_count = 0;
 			return;
@@ -563,7 +564,7 @@
 
 	ep = bulk_in_ep;
 	pipe = usb_rcvbulkpipe(udev, ep->bEndpointAddress);
-	size = HCI_USB_MAX_READ;
+	size = HCI_MAX_FRAME_SIZE;
 
 	if (!(buf = kmalloc(size, GFP_KERNEL))) {
 		ERR("Can't allocate: read buffer");
@@ -652,7 +653,7 @@
 	int err;
 
 	INF("BlueZ HCI USB driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",  
-		BLUEZ_VER);
+		VERSION);
 	INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
 
 	if ((err = usb_register(&hci_usb_driver)) < 0)
@@ -668,3 +669,7 @@
 
 module_init(hci_usb_init);
 module_exit(hci_usb_cleanup);
+
+MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
+MODULE_DESCRIPTION("BlueZ HCI USB driver ver " VERSION);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.9/linux/drivers/bluetooth/hci_vhci.c linux/drivers/bluetooth/hci_vhci.c
--- v2.4.9/linux/drivers/bluetooth/hci_vhci.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/bluetooth/hci_vhci.c	Fri Sep  7 09:28:38 2001
@@ -0,0 +1,340 @@
+/* 
+   BlueZ - Bluetooth protocol stack for Linux
+   Copyright (C) 2000-2001 Qualcomm Incorporated
+
+   Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License version 2 as
+   published by the Free Software Foundation;
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
+   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
+   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
+   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
+   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
+   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
+   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
+   SOFTWARE IS DISCLAIMED.
+*/
+
+/*
+ * BlueZ HCI virtual device driver.
+ *
+ * $Id: hci_vhci.c,v 1.3 2001/08/03 04:19:50 maxk Exp $ 
+ */
+#define VERSION "1.0"
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/poll.h>
+#include <linux/fcntl.h>
+#include <linux/init.h>
+#include <linux/random.h>
+
+#include <linux/skbuff.h>
+#include <linux/miscdevice.h>
+
+#include <asm/system.h>
+#include <asm/uaccess.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/bluez.h>
+#include <net/bluetooth/hci_core.h>
+#include <net/bluetooth/hci_vhci.h>
+
+/* HCI device part */
+
+int hci_vhci_open(struct hci_dev *hdev)
+{
+	hdev->flags |= HCI_RUNNING;
+	return 0;
+}
+
+int hci_vhci_flush(struct hci_dev *hdev)
+{
+	struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) hdev->driver_data;
+	skb_queue_purge(&hci_vhci->readq);
+	return 0;
+}
+
+int hci_vhci_close(struct hci_dev *hdev)
+{
+	hdev->flags &= ~HCI_RUNNING;
+	hci_vhci_flush(hdev);
+	return 0;
+}
+
+int hci_vhci_send_frame(struct sk_buff *skb)
+{
+	struct hci_dev* hdev = (struct hci_dev *) skb->dev;
+	struct hci_vhci_struct *hci_vhci;
+
+	if (!hdev) {
+		ERR("Frame for uknown device (hdev=NULL)");
+		return -ENODEV;
+	}
+
+	if (!(hdev->flags & HCI_RUNNING))
+		return -EBUSY;
+
+	hci_vhci = (struct hci_vhci_struct *) hdev->driver_data;
+
+	memcpy(skb_push(skb, 1), &skb->pkt_type, 1);
+	skb_queue_tail(&hci_vhci->readq, skb);
+
+	if (hci_vhci->flags & VHCI_FASYNC)
+		kill_fasync(&hci_vhci->fasync, SIGIO, POLL_IN);
+	wake_up_interruptible(&hci_vhci->read_wait);
+
+	return 0;
+}
+
+/* Character device part */
+
+/* Poll */
+static unsigned int hci_vhci_chr_poll(struct file *file, poll_table * wait)
+{  
+	struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) file->private_data;
+
+	poll_wait(file, &hci_vhci->read_wait, wait);
+ 
+	if (skb_queue_len(&hci_vhci->readq))
+		return POLLIN | POLLRDNORM;
+
+	return POLLOUT | POLLWRNORM;
+}
+
+/* Get packet from user space buffer(already verified) */
+static inline ssize_t hci_vhci_get_user(struct hci_vhci_struct *hci_vhci, const char *buf, size_t count)
+{
+	struct sk_buff *skb;
+
+	if (count > HCI_MAX_FRAME_SIZE)
+		return -EINVAL;
+
+	if (!(skb = bluez_skb_alloc(count, GFP_KERNEL)))
+		return -ENOMEM;
+	
+	copy_from_user(skb_put(skb, count), buf, count); 
+
+	skb->dev = (void *) &hci_vhci->hdev;
+	skb->pkt_type = *((__u8 *) skb->data);
+	skb_pull(skb, 1);
+
+	hci_recv_frame(skb);
+
+	return count;
+} 
+
+/* Write */
+static ssize_t hci_vhci_chr_write(struct file * file, const char * buf, 
+			     size_t count, loff_t *pos)
+{
+	struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) file->private_data;
+
+	if (verify_area(VERIFY_READ, buf, count))
+		return -EFAULT;
+
+	return hci_vhci_get_user(hci_vhci, buf, count);
+}
+
+/* Put packet to user space buffer(already verified) */
+static inline ssize_t hci_vhci_put_user(struct hci_vhci_struct *hci_vhci,
+				       struct sk_buff *skb, char *buf, int count)
+{
+	int len = count, total = 0;
+	char *ptr = buf;
+
+	len = MIN(skb->len, len); 
+	copy_to_user(ptr, skb->data, len); 
+	total += len;
+
+	hci_vhci->hdev.stat.byte_tx += len;
+	switch (skb->pkt_type) {
+		case HCI_COMMAND_PKT:
+			hci_vhci->hdev.stat.cmd_tx++;
+			break;
+
+		case HCI_ACLDATA_PKT:
+			hci_vhci->hdev.stat.acl_tx++;
+			break;
+
+		case HCI_SCODATA_PKT:
+			hci_vhci->hdev.stat.cmd_tx++;
+			break;
+	};
+
+	return total;
+}
+
+/* Read */
+static ssize_t hci_vhci_chr_read(struct file * file, char * buf, size_t count, loff_t *pos)
+{
+	struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) file->private_data;
+	DECLARE_WAITQUEUE(wait, current);
+	struct sk_buff *skb;
+	ssize_t ret = 0;
+
+	add_wait_queue(&hci_vhci->read_wait, &wait);
+	while (count) {
+		current->state = TASK_INTERRUPTIBLE;
+
+		/* Read frames from device queue */
+		if (!(skb = skb_dequeue(&hci_vhci->readq))) {
+			if (file->f_flags & O_NONBLOCK) {
+				ret = -EAGAIN;
+				break;
+			}
+			if (signal_pending(current)) {
+				ret = -ERESTARTSYS;
+				break;
+			}
+
+			/* Nothing to read, let's sleep */
+			schedule();
+			continue;
+		}
+
+		if (!verify_area(VERIFY_WRITE, buf, count))
+			ret = hci_vhci_put_user(hci_vhci, skb, buf, count);
+		else
+			ret = -EFAULT;
+
+		kfree_skb(skb);
+		break;
+	}
+
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&hci_vhci->read_wait, &wait);
+
+	return ret;
+}
+
+static loff_t hci_vhci_chr_lseek(struct file * file, loff_t offset, int origin)
+{
+	return -ESPIPE;
+}
+
+static int hci_vhci_chr_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+	return -EINVAL;
+}
+
+static int hci_vhci_chr_fasync(int fd, struct file *file, int on)
+{
+	struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) file->private_data;
+	int ret;
+
+	if ((ret = fasync_helper(fd, file, on, &hci_vhci->fasync)) < 0)
+		return ret; 
+ 
+	if (on)
+		hci_vhci->flags |= VHCI_FASYNC;
+	else 
+		hci_vhci->flags &= ~VHCI_FASYNC;
+
+	return 0;
+}
+
+static int hci_vhci_chr_open(struct inode *inode, struct file * file)
+{
+	struct hci_vhci_struct *hci_vhci = NULL; 
+	struct hci_dev *hdev;
+
+	if (!(hci_vhci = kmalloc(sizeof(struct hci_vhci_struct), GFP_KERNEL)))
+		return -ENOMEM;
+
+	memset(hci_vhci, 0, sizeof(struct hci_vhci_struct));
+
+	skb_queue_head_init(&hci_vhci->readq);
+	init_waitqueue_head(&hci_vhci->read_wait);
+
+	/* Initialize and register HCI device */
+	hdev = &hci_vhci->hdev;
+
+	hdev->type = HCI_VHCI;
+	hdev->driver_data = hci_vhci;
+
+	hdev->open  = hci_vhci_open;
+	hdev->close = hci_vhci_close;
+	hdev->flush = hci_vhci_flush;
+	hdev->send  = hci_vhci_send_frame;
+
+	if (hci_register_dev(hdev) < 0) {
+		kfree(hci_vhci);
+		return -EBUSY;
+	}
+
+	file->private_data = hci_vhci;
+	return 0;   
+}
+
+static int hci_vhci_chr_close(struct inode *inode, struct file *file)
+{
+	struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) file->private_data;
+
+	if (hci_unregister_dev(&hci_vhci->hdev) < 0) {
+		ERR("Can't unregister HCI device %s", hci_vhci->hdev.name);
+	}
+
+	kfree(hci_vhci);
+	file->private_data = NULL;
+
+	return 0;
+}
+
+static struct file_operations hci_vhci_fops = {
+	owner:	THIS_MODULE,	
+	llseek:	hci_vhci_chr_lseek,
+	read:	hci_vhci_chr_read,
+	write:	hci_vhci_chr_write,
+	poll:	hci_vhci_chr_poll,
+	ioctl:	hci_vhci_chr_ioctl,
+	open:	hci_vhci_chr_open,
+	release:hci_vhci_chr_close,
+	fasync:	hci_vhci_chr_fasync		
+};
+
+static struct miscdevice hci_vhci_miscdev=
+{
+        VHCI_MINOR,
+        "hci_vhci",
+        &hci_vhci_fops
+};
+
+int __init hci_vhci_init(void)
+{
+	INF("BlueZ VHCI driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",  
+		VERSION);
+	INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
+
+	if (misc_register(&hci_vhci_miscdev)) {
+		ERR("Can't register misc device %d\n", VHCI_MINOR);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+void hci_vhci_cleanup(void)
+{
+	misc_deregister(&hci_vhci_miscdev);
+}
+
+module_init(hci_vhci_init);
+module_exit(hci_vhci_cleanup);
+
+MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
+MODULE_DESCRIPTION("BlueZ VHCI driver ver " VERSION);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.9/linux/drivers/cdrom/aztcd.c linux/drivers/cdrom/aztcd.c
--- v2.4.9/linux/drivers/cdrom/aztcd.c	Thu Oct 26 23:35:47 2000
+++ linux/drivers/cdrom/aztcd.c	Sun Sep  9 10:43:02 2001
@@ -167,7 +167,7 @@
 
 #include <linux/version.h>
 
-#define MAJOR_NR AZTECH_CDROM_MAJOR 
+#define MAJOR_NR AZTECH_CDROM_MAJOR
 
 #include <linux/blk.h>
 #include "aztcd.h"
@@ -185,19 +185,13 @@
 #include <linux/major.h>
 #include <linux/devfs_fs_kernel.h>
 
-#ifndef AZT_KERNEL_PRIOR_2_1
 #include <linux/init.h>
-#endif
 
 #include <asm/system.h>
 #include <asm/io.h>
 
-#ifdef AZT_KERNEL_PRIOR_2_1
-#include <asm/segment.h>
-#else
 #include <asm/uaccess.h>
-static int aztcd_blocksizes[1] = {2048};
-#endif
+static int aztcd_blocksizes[1] = { 2048 };
 
 
 /*###########################################################################
@@ -206,7 +200,7 @@
 */
 #define SET_TIMER(func, jifs)   delay_timer.expires = jiffies + (jifs); \
                                 delay_timer.function = (void *) (func); \
-                                add_timer(&delay_timer); 
+                                add_timer(&delay_timer);
 
 #define CLEAR_TIMER             del_timer(&delay_timer);
 
@@ -219,17 +213,17 @@
 #define SWITCH_IDE_SLAVE  outb_p(0xa0,azt_port+6); \
 	                  outb_p(0x10,azt_port+6); \
 	                  outb_p(0x00,azt_port+7); \
-	                  outb_p(0x10,azt_port+6); 
+	                  outb_p(0x10,azt_port+6);
 #define SWITCH_IDE_MASTER outb_p(0xa0,azt_port+6);
 
 
 #if 0
 #define AZT_TEST
-#define AZT_TEST1 /* <int-..> */
-#define AZT_TEST2 /* do_aztcd_request */
-#define AZT_TEST3 /* AZT_S_state */
-#define AZT_TEST4 /* QUICK_LOOP-counter */
-#define AZT_TEST5 /* port(1) state */
+#define AZT_TEST1		/* <int-..> */
+#define AZT_TEST2		/* do_aztcd_request */
+#define AZT_TEST3		/* AZT_S_state */
+#define AZT_TEST4		/* QUICK_LOOP-counter */
+#define AZT_TEST5		/* port(1) state */
 #define AZT_DEBUG
 #define AZT_DEBUG_MULTISESSION
 #endif
@@ -243,30 +237,23 @@
 
 #define READ_TIMEOUT 3000
 
-#define azt_port aztcd  /*needed for the modutils*/
-
-#ifndef AZT_KERNEL_PRIOR_2_1 
-#define  memcpy_fromfs copy_from_user
-#define  memcpy_tofs   copy_to_user
-#endif
+#define azt_port aztcd		/*needed for the modutils */
 
 /*##########################################################################
   Type Definitions
   ##########################################################################
 */
-enum azt_state_e 
-{ AZT_S_IDLE,    /* 0 */
-  AZT_S_START,   /* 1 */
-  AZT_S_MODE,    /* 2 */
-  AZT_S_READ,    /* 3 */
-  AZT_S_DATA,    /* 4 */
-  AZT_S_STOP,    /* 5 */
-  AZT_S_STOPPING /* 6 */
+enum azt_state_e { AZT_S_IDLE,	/* 0 */
+	AZT_S_START,		/* 1 */
+	AZT_S_MODE,		/* 2 */
+	AZT_S_READ,		/* 3 */
+	AZT_S_DATA,		/* 4 */
+	AZT_S_STOP,		/* 5 */
+	AZT_S_STOPPING		/* 6 */
 };
-enum azt_read_modes 
-{ AZT_MODE_0,     /*read mode for audio disks, not supported by Aztech firmware*/
-  AZT_MODE_1,     /*read mode for normal CD-ROMs*/
-  AZT_MODE_2      /*read mode for XA CD-ROMs*/
+enum azt_read_modes { AZT_MODE_0,	/*read mode for audio disks, not supported by Aztech firmware */
+	AZT_MODE_1,		/*read mode for normal CD-ROMs */
+	AZT_MODE_2		/*read mode for XA CD-ROMs */
 };
 
 /*##########################################################################
@@ -275,20 +262,20 @@
 */
 static int aztPresent = 0;
 
-static volatile int azt_transfer_is_active=0;
+static volatile int azt_transfer_is_active = 0;
 
-static char azt_buf[CD_FRAMESIZE_RAW*AZT_BUF_SIZ];/*buffer for block size conversion*/
+static char azt_buf[CD_FRAMESIZE_RAW * AZT_BUF_SIZ];	/*buffer for block size conversion */
 #if AZT_PRIVATE_IOCTLS
-static char buf[CD_FRAMESIZE_RAW];              /*separate buffer for the ioctls*/
+static char buf[CD_FRAMESIZE_RAW];	/*separate buffer for the ioctls */
 #endif
 
 static volatile int azt_buf_bn[AZT_BUF_SIZ], azt_next_bn;
 static volatile int azt_buf_in, azt_buf_out = -1;
-static volatile int azt_error=0;
-static int azt_open_count=0;
+static volatile int azt_error = 0;
+static int azt_open_count = 0;
 static volatile enum azt_state_e azt_state = AZT_S_IDLE;
 #ifdef AZT_TEST3
-static volatile enum azt_state_e azt_state_old = AZT_S_STOP;  
+static volatile enum azt_state_e azt_state_old = AZT_S_STOP;
 static volatile int azt_st_old = 0;
 #endif
 static volatile enum azt_read_modes azt_read_mode = AZT_MODE_1;
@@ -298,15 +285,13 @@
 
 static int azt_port = AZT_BASE_ADDR;
 
-#ifndef AZT_KERNEL_PRIOR_2_1
 MODULE_PARM(azt_port, "i");
-#endif
 
 static int azt_port_auto[16] = AZT_BASE_AUTO;
 
-static char  azt_cont = 0;
-static char  azt_init_end = 0;
-static char  azt_auto_eject = AZT_AUTO_EJECT;
+static char azt_cont = 0;
+static char azt_init_end = 0;
+static char azt_auto_eject = AZT_AUTO_EJECT;
 
 static int AztTimeout, AztTries;
 static DECLARE_WAIT_QUEUE_HEAD(azt_waitq);
@@ -316,7 +301,7 @@
 static struct azt_Toc Toc[MAX_TRACKS];
 static struct azt_Play_msf azt_Play;
 
-static int  aztAudioStatus = CDROM_AUDIO_NO_STATUS;
+static int aztAudioStatus = CDROM_AUDIO_NO_STATUS;
 static char aztDiskChanged = 1;
 static char aztTocUpToDate = 0;
 
@@ -329,54 +314,51 @@
   ###########################################################################
 */
 /* CDROM Drive Low Level I/O Functions */
-void        op_ok(void);
-void        pa_ok(void);
-void        sten_low(void);
-void        dten_low(void);
-void        statusAzt(void);
+void op_ok(void);
+void pa_ok(void);
+void sten_low(void);
+void dten_low(void);
+void statusAzt(void);
 static void aztStatTimer(void);
 
 /* CDROM Drive Command Functions */
-static int  aztSendCmd(int cmd);
-static int  sendAztCmd(int cmd, struct azt_Play_msf *params);
-static int  aztSeek(struct azt_Play_msf *params);
-static int  aztSetDiskType(int type);
-static int  aztStatus(void);
-static int  getAztStatus(void);
-static int  aztPlay(struct azt_Play_msf *arg);
+static int aztSendCmd(int cmd);
+static int sendAztCmd(int cmd, struct azt_Play_msf *params);
+static int aztSeek(struct azt_Play_msf *params);
+static int aztSetDiskType(int type);
+static int aztStatus(void);
+static int getAztStatus(void);
+static int aztPlay(struct azt_Play_msf *arg);
 static void aztCloseDoor(void);
 static void aztLockDoor(void);
 static void aztUnlockDoor(void);
-static int  aztGetValue(unsigned char *result);
-static int  aztGetQChannelInfo(struct azt_Toc *qp);
-static int  aztUpdateToc(void);
-static int  aztGetDiskInfo(void);
-#if AZT_MULTISESSION 
- static int aztGetMultiDiskInfo(void);
+static int aztGetValue(unsigned char *result);
+static int aztGetQChannelInfo(struct azt_Toc *qp);
+static int aztUpdateToc(void);
+static int aztGetDiskInfo(void);
+#if AZT_MULTISESSION
+static int aztGetMultiDiskInfo(void);
 #endif
-static int  aztGetToc(int multi);
+static int aztGetToc(int multi);
 
 /* Kernel Interface Functions */
-static int  check_aztcd_media_change(kdev_t full_dev);
-static int  aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg);
+static int check_aztcd_media_change(kdev_t full_dev);
+static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
+		       unsigned long arg);
 static void azt_transfer(void);
 static void do_aztcd_request(request_queue_t *);
 static void azt_invalidate_buffers(void);
-int         aztcd_open(struct inode *ip, struct file *fp);
+int aztcd_open(struct inode *ip, struct file *fp);
 
-#ifdef AZT_KERNEL_PRIOR_2_1
-static void aztcd_release(struct inode * inode, struct file * file);
-#else
-static int  aztcd_release(struct inode * inode, struct file * file);
-#endif
+static int aztcd_release(struct inode *inode, struct file *file);
 
-int       aztcd_init(void);
+int aztcd_init(void);
 
 static struct block_device_operations azt_fops = {
-	open:			aztcd_open,
-	release:		aztcd_release,
-	ioctl:			aztcd_ioctl,
-	check_media_change:	check_aztcd_media_change,
+	open:aztcd_open,
+	release:aztcd_release,
+	ioctl:aztcd_ioctl,
+	check_media_change:check_aztcd_media_change,
 };
 
 /* Aztcd State Machine: Controls Drive Operating State */
@@ -386,7 +368,7 @@
 static void azt_hsg2msf(long hsg, struct msf *msf);
 static long azt_msf2hsg(struct msf *mp);
 static void azt_bin2bcd(unsigned char *p);
-static int  azt_bcd2bin(unsigned char bcd);
+static int azt_bcd2bin(unsigned char bcd);
 
 /*##########################################################################
   CDROM Drive Low Level I/O Functions
@@ -397,53 +379,64 @@
 /* Wait for OP_OK = drive answers with AFL_OP_OK after receiving a command*/
 # define OP_OK op_ok()
 void op_ok(void)
-{ aztTimeOutCount=0; 
-  do { aztIndatum=inb(DATA_PORT);
-       aztTimeOutCount++;
-       if (aztTimeOutCount>=AZT_TIMEOUT)
-	{ printk("aztcd: Error Wait OP_OK\n");
-	  break;
-	}
-     } while (aztIndatum!=AFL_OP_OK);
+{
+	aztTimeOutCount = 0;
+	do {
+		aztIndatum = inb(DATA_PORT);
+		aztTimeOutCount++;
+		if (aztTimeOutCount >= AZT_TIMEOUT) {
+			printk("aztcd: Error Wait OP_OK\n");
+			break;
+		}
+	} while (aztIndatum != AFL_OP_OK);
 }
 
 /* Wait for PA_OK = drive answers with AFL_PA_OK after receiving parameters*/
 # define PA_OK pa_ok()
 void pa_ok(void)
-{ aztTimeOutCount=0; 
-  do { aztIndatum=inb(DATA_PORT);
-       aztTimeOutCount++;
-       if (aztTimeOutCount>=AZT_TIMEOUT)
-	{ printk("aztcd: Error Wait PA_OK\n");
-	  break;
-	}
-     } while (aztIndatum!=AFL_PA_OK);
+{
+	aztTimeOutCount = 0;
+	do {
+		aztIndatum = inb(DATA_PORT);
+		aztTimeOutCount++;
+		if (aztTimeOutCount >= AZT_TIMEOUT) {
+			printk("aztcd: Error Wait PA_OK\n");
+			break;
+		}
+	} while (aztIndatum != AFL_PA_OK);
 }
-     
+
 /* Wait for STEN=Low = handshake signal 'AFL_.._OK available or command executed*/
 # define STEN_LOW  sten_low()
 void sten_low(void)
-{ aztTimeOutCount=0; 
-  do { aztIndatum=inb(STATUS_PORT);
-       aztTimeOutCount++;
-       if (aztTimeOutCount>=AZT_TIMEOUT)
-	{ if (azt_init_end) printk("aztcd: Error Wait STEN_LOW commands:%x\n",aztCmd);
-	  break;
-	}
-     } while (aztIndatum&AFL_STATUS);
+{
+	aztTimeOutCount = 0;
+	do {
+		aztIndatum = inb(STATUS_PORT);
+		aztTimeOutCount++;
+		if (aztTimeOutCount >= AZT_TIMEOUT) {
+			if (azt_init_end)
+				printk
+				    ("aztcd: Error Wait STEN_LOW commands:%x\n",
+				     aztCmd);
+			break;
+		}
+	} while (aztIndatum & AFL_STATUS);
 }
 
 /* Wait for DTEN=Low = handshake signal 'Data available'*/
 # define DTEN_LOW dten_low()
 void dten_low(void)
-{ aztTimeOutCount=0; 
-  do { aztIndatum=inb(STATUS_PORT);
-       aztTimeOutCount++;
-       if (aztTimeOutCount>=AZT_TIMEOUT)
-	{ printk("aztcd: Error Wait DTEN_OK\n");
-	  break;
-	}
-     } while (aztIndatum&AFL_DATA);
+{
+	aztTimeOutCount = 0;
+	do {
+		aztIndatum = inb(STATUS_PORT);
+		aztTimeOutCount++;
+		if (aztTimeOutCount >= AZT_TIMEOUT) {
+			printk("aztcd: Error Wait DTEN_OK\n");
+			break;
+		}
+	} while (aztIndatum & AFL_DATA);
 }
 
 /* 
@@ -452,25 +445,29 @@
 */
 #define STEN_LOW_WAIT   statusAzt()
 void statusAzt(void)
-{ AztTimeout = AZT_STATUS_DELAY;
-  SET_TIMER(aztStatTimer, HZ/100); 
-  sleep_on(&azt_waitq);
-  if (AztTimeout <= 0) printk("aztcd: Error Wait STEN_LOW_WAIT command:%x\n",aztCmd);
-  return;
+{
+	AztTimeout = AZT_STATUS_DELAY;
+	SET_TIMER(aztStatTimer, HZ / 100);
+	sleep_on(&azt_waitq);
+	if (AztTimeout <= 0)
+		printk("aztcd: Error Wait STEN_LOW_WAIT command:%x\n",
+		       aztCmd);
+	return;
 }
 
 static void aztStatTimer(void)
-{ if (!(inb(STATUS_PORT) & AFL_STATUS))
-     { wake_up(&azt_waitq);
-       return;
-     }
-  AztTimeout--;
-  if (AztTimeout <= 0)
-     { wake_up(&azt_waitq);
-       printk("aztcd: Error aztStatTimer: Timeout\n");
-       return;
-     }
-  SET_TIMER(aztStatTimer, HZ/100);
+{
+	if (!(inb(STATUS_PORT) & AFL_STATUS)) {
+		wake_up(&azt_waitq);
+		return;
+	}
+	AztTimeout--;
+	if (AztTimeout <= 0) {
+		wake_up(&azt_waitq);
+		printk("aztcd: Error aztStatTimer: Timeout\n");
+		return;
+	}
+	SET_TIMER(aztStatTimer, HZ / 100);
 }
 
 /*##########################################################################
@@ -481,111 +478,125 @@
  * Send a single command, return -1 on error, else 0
 */
 static int aztSendCmd(int cmd)
-{  unsigned char data;
-   int retry;
+{
+	unsigned char data;
+	int retry;
 
 #ifdef AZT_DEBUG
-   printk("aztcd: Executing command %x\n",cmd);
+	printk("aztcd: Executing command %x\n", cmd);
 #endif
 
-   if ((azt_port==0x1f0)||(azt_port==0x170))  
-      SWITCH_IDE_SLAVE; /*switch IDE interface to slave configuration*/
-   
-   aztCmd=cmd;
-   outb(POLLED,MODE_PORT);
-   do { if (inb(STATUS_PORT)&AFL_STATUS) break;
-	inb(DATA_PORT);    /* if status left from last command, read and */
-      } while (1);         /* discard it */
-   do { if (inb(STATUS_PORT)&AFL_DATA) break;
-	inb(DATA_PORT);    /* if data left from last command, read and */
-      } while (1);         /* discard it */
-   for (retry=0;retry<AZT_RETRY_ATTEMPTS;retry++)
-     { outb((unsigned char) cmd,CMD_PORT);
-       STEN_LOW;
-       data=inb(DATA_PORT);
-       if (data==AFL_OP_OK)
-	 { return 0;}           /*OP_OK?*/
-       if (data==AFL_OP_ERR)
-	 { STEN_LOW;
-	   data=inb(DATA_PORT);
-	   printk("### Error 1 aztcd: aztSendCmd %x  Error Code %x\n",cmd,data);
-	 }
-     }
-   if (retry>=AZT_RETRY_ATTEMPTS)
-     { printk("### Error 2 aztcd: aztSendCmd %x \n",cmd);
-       azt_error=0xA5;
-     }
-   RETURNM("aztSendCmd",-1);
+	if ((azt_port == 0x1f0) || (azt_port == 0x170))
+		SWITCH_IDE_SLAVE;	/*switch IDE interface to slave configuration */
+
+	aztCmd = cmd;
+	outb(POLLED, MODE_PORT);
+	do {
+		if (inb(STATUS_PORT) & AFL_STATUS)
+			break;
+		inb(DATA_PORT);	/* if status left from last command, read and */
+	} while (1);		/* discard it */
+	do {
+		if (inb(STATUS_PORT) & AFL_DATA)
+			break;
+		inb(DATA_PORT);	/* if data left from last command, read and */
+	} while (1);		/* discard it */
+	for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
+		outb((unsigned char) cmd, CMD_PORT);
+		STEN_LOW;
+		data = inb(DATA_PORT);
+		if (data == AFL_OP_OK) {
+			return 0;
+		}		/*OP_OK? */
+		if (data == AFL_OP_ERR) {
+			STEN_LOW;
+			data = inb(DATA_PORT);
+			printk
+			    ("### Error 1 aztcd: aztSendCmd %x  Error Code %x\n",
+			     cmd, data);
+		}
+	}
+	if (retry >= AZT_RETRY_ATTEMPTS) {
+		printk("### Error 2 aztcd: aztSendCmd %x \n", cmd);
+		azt_error = 0xA5;
+	}
+	RETURNM("aztSendCmd", -1);
 }
 
 /*
  * Send a play or read command to the drive, return -1 on error, else 0
 */
 static int sendAztCmd(int cmd, struct azt_Play_msf *params)
-{  unsigned char data;
-   int retry;
+{
+	unsigned char data;
+	int retry;
 
 #ifdef AZT_DEBUG
-   printk("aztcd: play start=%02x:%02x:%02x  end=%02x:%02x:%02x\n", \
-	   params->start.min, params->start.sec, params->start.frame, \
-	   params->end.min,   params->end.sec,   params->end.frame);
-#endif   
-   for (retry=0;retry<AZT_RETRY_ATTEMPTS;retry++)
-     { aztSendCmd(cmd);
-       outb(params -> start.min,CMD_PORT);
-       outb(params -> start.sec,CMD_PORT);
-       outb(params -> start.frame,CMD_PORT);
-       outb(params -> end.min,CMD_PORT);
-       outb(params -> end.sec,CMD_PORT);
-       outb(params -> end.frame,CMD_PORT);
-       STEN_LOW;
-       data=inb(DATA_PORT);
-       if (data==AFL_PA_OK)
-	 { return 0;}           /*PA_OK ?*/
-       if (data==AFL_PA_ERR)
-	 { STEN_LOW;
-	   data=inb(DATA_PORT);
-	   printk("### Error 1 aztcd: sendAztCmd %x  Error Code %x\n",cmd,data);
-	 }
-     }
-   if (retry>=AZT_RETRY_ATTEMPTS)
-     { printk("### Error 2 aztcd: sendAztCmd %x\n ",cmd);
-       azt_error=0xA5;
-     }
-   RETURNM("sendAztCmd",-1);
+	printk("aztcd: play start=%02x:%02x:%02x  end=%02x:%02x:%02x\n",
+	       params->start.min, params->start.sec, params->start.frame,
+	       params->end.min, params->end.sec, params->end.frame);
+#endif
+	for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
+		aztSendCmd(cmd);
+		outb(params->start.min, CMD_PORT);
+		outb(params->start.sec, CMD_PORT);
+		outb(params->start.frame, CMD_PORT);
+		outb(params->end.min, CMD_PORT);
+		outb(params->end.sec, CMD_PORT);
+		outb(params->end.frame, CMD_PORT);
+		STEN_LOW;
+		data = inb(DATA_PORT);
+		if (data == AFL_PA_OK) {
+			return 0;
+		}		/*PA_OK ? */
+		if (data == AFL_PA_ERR) {
+			STEN_LOW;
+			data = inb(DATA_PORT);
+			printk
+			    ("### Error 1 aztcd: sendAztCmd %x  Error Code %x\n",
+			     cmd, data);
+		}
+	}
+	if (retry >= AZT_RETRY_ATTEMPTS) {
+		printk("### Error 2 aztcd: sendAztCmd %x\n ", cmd);
+		azt_error = 0xA5;
+	}
+	RETURNM("sendAztCmd", -1);
 }
 
 /*
  * Send a seek command to the drive, return -1 on error, else 0
 */
 static int aztSeek(struct azt_Play_msf *params)
-{  unsigned char data;
-   int retry;
+{
+	unsigned char data;
+	int retry;
 
 #ifdef AZT_DEBUG
-   printk("aztcd: aztSeek %02x:%02x:%02x\n", \
-	   params->start.min, params->start.sec, params->start.frame);
-#endif   
-   for (retry=0;retry<AZT_RETRY_ATTEMPTS;retry++)
-     { aztSendCmd(ACMD_SEEK);
-       outb(params -> start.min,CMD_PORT);
-       outb(params -> start.sec,CMD_PORT);
-       outb(params -> start.frame,CMD_PORT);
-       STEN_LOW;
-       data=inb(DATA_PORT);
-       if (data==AFL_PA_OK)
-	 { return 0;}           /*PA_OK ?*/
-       if (data==AFL_PA_ERR)
-	 { STEN_LOW;
-	   data=inb(DATA_PORT);
-	   printk("### Error 1 aztcd: aztSeek\n");
-	 }
-     }
-   if (retry>=AZT_RETRY_ATTEMPTS)
-     { printk("### Error 2 aztcd: aztSeek\n ");
-       azt_error=0xA5;
-     }
-   RETURNM("aztSeek",-1);
+	printk("aztcd: aztSeek %02x:%02x:%02x\n",
+	       params->start.min, params->start.sec, params->start.frame);
+#endif
+	for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
+		aztSendCmd(ACMD_SEEK);
+		outb(params->start.min, CMD_PORT);
+		outb(params->start.sec, CMD_PORT);
+		outb(params->start.frame, CMD_PORT);
+		STEN_LOW;
+		data = inb(DATA_PORT);
+		if (data == AFL_PA_OK) {
+			return 0;
+		}		/*PA_OK ? */
+		if (data == AFL_PA_ERR) {
+			STEN_LOW;
+			data = inb(DATA_PORT);
+			printk("### Error 1 aztcd: aztSeek\n");
+		}
+	}
+	if (retry >= AZT_RETRY_ATTEMPTS) {
+		printk("### Error 2 aztcd: aztSeek\n ");
+		azt_error = 0xA5;
+	}
+	RETURNM("aztSeek", -1);
 }
 
 /* Send a Set Disk Type command
@@ -593,79 +604,86 @@
    dent on which mode is set ???
 */
 static int aztSetDiskType(int type)
-{  unsigned char data;
-   int retry;
+{
+	unsigned char data;
+	int retry;
 
 #ifdef AZT_DEBUG
-   printk("aztcd: set disk type command: type= %i\n",type);
+	printk("aztcd: set disk type command: type= %i\n", type);
 #endif
-   for (retry=0;retry<AZT_RETRY_ATTEMPTS;retry++)
-     { aztSendCmd(ACMD_SET_DISK_TYPE);
-       outb(type,CMD_PORT);
-       STEN_LOW;
-       data=inb(DATA_PORT);
-       if (data==AFL_PA_OK)     /*PA_OK ?*/
-	 { azt_read_mode=type;
-	   return 0;            
-	 }  
-       if (data==AFL_PA_ERR)
-	 { STEN_LOW;
-	   data=inb(DATA_PORT);
-	   printk("### Error 1 aztcd: aztSetDiskType %x Error Code %x\n",type,data);
-	 }
-     }
-   if (retry>=AZT_RETRY_ATTEMPTS)
-     { printk("### Error 2 aztcd: aztSetDiskType %x\n ",type);
-       azt_error=0xA5;
-     }
-   RETURNM("aztSetDiskType",-1);
+	for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
+		aztSendCmd(ACMD_SET_DISK_TYPE);
+		outb(type, CMD_PORT);
+		STEN_LOW;
+		data = inb(DATA_PORT);
+		if (data == AFL_PA_OK) {	/*PA_OK ? */
+			azt_read_mode = type;
+			return 0;
+		}
+		if (data == AFL_PA_ERR) {
+			STEN_LOW;
+			data = inb(DATA_PORT);
+			printk
+			    ("### Error 1 aztcd: aztSetDiskType %x Error Code %x\n",
+			     type, data);
+		}
+	}
+	if (retry >= AZT_RETRY_ATTEMPTS) {
+		printk("### Error 2 aztcd: aztSetDiskType %x\n ", type);
+		azt_error = 0xA5;
+	}
+	RETURNM("aztSetDiskType", -1);
 }
 
 
 /* used in azt_poll to poll the status, expects another program to issue a 
  * ACMD_GET_STATUS directly before 
  */
-static int aztStatus(void)  
-{       int st;
+static int aztStatus(void)
+{
+	int st;
 /*	int i;
 
 	i = inb(STATUS_PORT) & AFL_STATUS;    is STEN=0?    ???
 	if (!i)
-*/      STEN_LOW;
-        if (aztTimeOutCount<AZT_TIMEOUT)	
-	{   	st = inb(DATA_PORT) & 0xFF;
+*/ STEN_LOW;
+	if (aztTimeOutCount < AZT_TIMEOUT) {
+		st = inb(DATA_PORT) & 0xFF;
 		return st;
-	}
-	else
-		RETURNM("aztStatus",-1);
+	} else
+		RETURNM("aztStatus", -1);
 }
 
 /*
  * Get the drive status
  */
 static int getAztStatus(void)
-{       int st;
+{
+	int st;
 
-	if (aztSendCmd(ACMD_GET_STATUS)) RETURNM("getAztStatus 1",-1);
+	if (aztSendCmd(ACMD_GET_STATUS))
+		RETURNM("getAztStatus 1", -1);
 	STEN_LOW;
 	st = inb(DATA_PORT) & 0xFF;
 #ifdef AZT_DEBUG
-	printk("aztcd: Status = %x\n",st);
+	printk("aztcd: Status = %x\n", st);
 #endif
-	if ((st == 0xFF)||(st&AST_CMD_CHECK))
-	 { printk("aztcd: AST_CMD_CHECK error or no status available\n");
-	   return -1;
-	 }
-
-	if (((st&AST_MODE_BITS)!=AST_BUSY) && (aztAudioStatus == CDROM_AUDIO_PLAY))
-	   /* XXX might be an error? look at q-channel? */
-	   aztAudioStatus = CDROM_AUDIO_COMPLETED;
-
-	if ((st & AST_DSK_CHG)||(st & AST_NOT_READY))
-	 { aztDiskChanged = 1;
-	   aztTocUpToDate = 0;
-	   aztAudioStatus = CDROM_AUDIO_NO_STATUS;
-	 }
+	if ((st == 0xFF) || (st & AST_CMD_CHECK)) {
+		printk
+		    ("aztcd: AST_CMD_CHECK error or no status available\n");
+		return -1;
+	}
+
+	if (((st & AST_MODE_BITS) != AST_BUSY)
+	    && (aztAudioStatus == CDROM_AUDIO_PLAY))
+		/* XXX might be an error? look at q-channel? */
+		aztAudioStatus = CDROM_AUDIO_COMPLETED;
+
+	if ((st & AST_DSK_CHG) || (st & AST_NOT_READY)) {
+		aztDiskChanged = 1;
+		aztTocUpToDate = 0;
+		aztAudioStatus = CDROM_AUDIO_NO_STATUS;
+	}
 	return st;
 }
 
@@ -674,7 +692,9 @@
  * Send a 'Play' command and get the status.  Use only from the top half.
  */
 static int aztPlay(struct azt_Play_msf *arg)
-{       if (sendAztCmd(ACMD_PLAY_AUDIO, arg) < 0) RETURNM("aztPlay",-1);
+{
+	if (sendAztCmd(ACMD_PLAY_AUDIO, arg) < 0)
+		RETURNM("aztPlay", -1);
 	return 0;
 }
 
@@ -685,27 +705,27 @@
  */
 static void aztCloseDoor(void)
 {
-  aztSendCmd(ACMD_CLOSE);
-  STEN_LOW;
-  return;
+	aztSendCmd(ACMD_CLOSE);
+	STEN_LOW;
+	return;
 }
 
 static void aztLockDoor(void)
 {
 #if AZT_ALLOW_TRAY_LOCK
-  aztSendCmd(ACMD_LOCK);
-  STEN_LOW;
+	aztSendCmd(ACMD_LOCK);
+	STEN_LOW;
 #endif
-  return;
+	return;
 }
 
 static void aztUnlockDoor(void)
 {
 #if AZT_ALLOW_TRAY_LOCK
-  aztSendCmd(ACMD_UNLOCK);
-  STEN_LOW;
+	aztSendCmd(ACMD_UNLOCK);
+	STEN_LOW;
 #endif
-  return;
+	return;
 }
 
 /*
@@ -714,11 +734,12 @@
  * be issued with aztSendCmd() directly before
  */
 static int aztGetValue(unsigned char *result)
-{       int s;
+{
+	int s;
 
 	STEN_LOW;
-	if (aztTimeOutCount>=AZT_TIMEOUT)
-	{       printk("aztcd: aztGetValue timeout\n");
+	if (aztTimeOutCount >= AZT_TIMEOUT) {
+		printk("aztcd: aztGetValue timeout\n");
 		return -1;
 	}
 	s = inb(DATA_PORT) & 0xFF;
@@ -731,42 +752,55 @@
  * table of contents.
  */
 int aztGetQChannelInfo(struct azt_Toc *qp)
-{       unsigned char notUsed;
+{
+	unsigned char notUsed;
 	int st;
 
 #ifdef AZT_DEBUG
-	printk("aztcd: starting aztGetQChannelInfo  Time:%li\n",jiffies);
+	printk("aztcd: starting aztGetQChannelInfo  Time:%li\n", jiffies);
 #endif
-	if ((st=getAztStatus())==-1)        RETURNM("aztGetQChannelInfo 1",-1);
-	if (aztSendCmd(ACMD_GET_Q_CHANNEL)) RETURNM("aztGetQChannelInfo 2",-1);
-	/*STEN_LOW_WAIT; ??? Dosemu0.60's cdrom.c does not like STEN_LOW_WAIT here*/
-	if (aztGetValue(&notUsed)) RETURNM("aztGetQChannelInfo 3",-1); /*??? Nullbyte einlesen*/
-	if ((st&AST_MODE_BITS)==AST_INITIAL)
-	 { qp->ctrl_addr=0;      /* when audio stop ACMD_GET_Q_CHANNEL returns */
-	   qp->track=0;          /* only one byte with Aztech drives */
-	   qp->pointIndex=0;
-	   qp->trackTime.min=0;
-	   qp->trackTime.sec=0;
-	   qp->trackTime.frame=0;
-	   qp->diskTime.min=0;
-	   qp->diskTime.sec=0;
-	   qp->diskTime.frame=0;
-	   return 0;  
-	 }
-	else
-	 { if (aztGetValue(&qp -> ctrl_addr) < 0)       RETURNM("aztGetQChannelInfo 4",-1);
-	   if (aztGetValue(&qp -> track) < 0)           RETURNM("aztGetQChannelInfo 4",-1);
-	   if (aztGetValue(&qp -> pointIndex) < 0)      RETURNM("aztGetQChannelInfo 4",-1);
-	   if (aztGetValue(&qp -> trackTime.min) < 0)   RETURNM("aztGetQChannelInfo 4",-1);
-	   if (aztGetValue(&qp -> trackTime.sec) < 0)   RETURNM("aztGetQChannelInfo 4",-1);
-	   if (aztGetValue(&qp -> trackTime.frame) < 0) RETURNM("aztGetQChannelInfo 4",-1);
-	   if (aztGetValue(&notUsed) < 0)               RETURNM("aztGetQChannelInfo 4",-1);
-	   if (aztGetValue(&qp -> diskTime.min) < 0)    RETURNM("aztGetQChannelInfo 4",-1);
-	   if (aztGetValue(&qp -> diskTime.sec) < 0)    RETURNM("aztGetQChannelInfo 4",-1);
-	   if (aztGetValue(&qp -> diskTime.frame) < 0)  RETURNM("aztGetQChannelInfo 4",-1);
-	 }
+	if ((st = getAztStatus()) == -1)
+		RETURNM("aztGetQChannelInfo 1", -1);
+	if (aztSendCmd(ACMD_GET_Q_CHANNEL))
+		RETURNM("aztGetQChannelInfo 2", -1);
+	/*STEN_LOW_WAIT; ??? Dosemu0.60's cdrom.c does not like STEN_LOW_WAIT here */
+	if (aztGetValue(&notUsed))
+		RETURNM("aztGetQChannelInfo 3", -1);	/*??? Nullbyte einlesen */
+	if ((st & AST_MODE_BITS) == AST_INITIAL) {
+		qp->ctrl_addr = 0;	/* when audio stop ACMD_GET_Q_CHANNEL returns */
+		qp->track = 0;	/* only one byte with Aztech drives */
+		qp->pointIndex = 0;
+		qp->trackTime.min = 0;
+		qp->trackTime.sec = 0;
+		qp->trackTime.frame = 0;
+		qp->diskTime.min = 0;
+		qp->diskTime.sec = 0;
+		qp->diskTime.frame = 0;
+		return 0;
+	} else {
+		if (aztGetValue(&qp->ctrl_addr) < 0)
+			RETURNM("aztGetQChannelInfo 4", -1);
+		if (aztGetValue(&qp->track) < 0)
+			RETURNM("aztGetQChannelInfo 4", -1);
+		if (aztGetValue(&qp->pointIndex) < 0)
+			RETURNM("aztGetQChannelInfo 4", -1);
+		if (aztGetValue(&qp->trackTime.min) < 0)
+			RETURNM("aztGetQChannelInfo 4", -1);
+		if (aztGetValue(&qp->trackTime.sec) < 0)
+			RETURNM("aztGetQChannelInfo 4", -1);
+		if (aztGetValue(&qp->trackTime.frame) < 0)
+			RETURNM("aztGetQChannelInfo 4", -1);
+		if (aztGetValue(&notUsed) < 0)
+			RETURNM("aztGetQChannelInfo 4", -1);
+		if (aztGetValue(&qp->diskTime.min) < 0)
+			RETURNM("aztGetQChannelInfo 4", -1);
+		if (aztGetValue(&qp->diskTime.sec) < 0)
+			RETURNM("aztGetQChannelInfo 4", -1);
+		if (aztGetValue(&qp->diskTime.frame) < 0)
+			RETURNM("aztGetQChannelInfo 4", -1);
+	}
 #ifdef AZT_DEBUG
-	printk("aztcd: exiting aztGetQChannelInfo  Time:%li\n",jiffies);
+	printk("aztcd: exiting aztGetQChannelInfo  Time:%li\n", jiffies);
 #endif
 	return 0;
 }
@@ -775,11 +809,12 @@
  * Read the table of contents (TOC) and TOC header if necessary
  */
 static int aztUpdateToc()
-{       int st;
+{
+	int st;
 
 #ifdef AZT_DEBUG
-	printk("aztcd: starting aztUpdateToc  Time:%li\n",jiffies);
-#endif  
+	printk("aztcd: starting aztUpdateToc  Time:%li\n", jiffies);
+#endif
 	if (aztTocUpToDate)
 		return 0;
 
@@ -789,57 +824,63 @@
 	if (aztGetToc(0) < 0)
 		return -EIO;
 
-        /*audio disk detection
-          with my Aztech drive there is no audio status bit, so I use the copy
-          protection bit of the first track. If this track is copy protected 
-          (copy bit = 0), I assume, it's an audio  disk. Strange, but works ??? */
-        if (!(Toc[DiskInfo.first].ctrl_addr & 0x40)) 
-           DiskInfo.audio=1;
-        else 
-           DiskInfo.audio=0;
-
-        /* XA detection */
-	if (! DiskInfo.audio) 
-	   { azt_Play.start.min   = 0;  /*XA detection only seems to work*/
-             azt_Play.start.sec   = 2;  /*when we play a track*/
-	     azt_Play.start.frame = 0;
-	     azt_Play.end.min     = 0;
-	     azt_Play.end.sec     = 0;
-	     azt_Play.end.frame   = 1;
-	     if (sendAztCmd(ACMD_PLAY_READ, &azt_Play)) return -1;
-	     DTEN_LOW;
-	     for (st=0;st<CD_FRAMESIZE;st++) inb(DATA_PORT);
-           } 
-        DiskInfo.xa = getAztStatus() & AST_MODE;
-        if (DiskInfo.xa) 
-           { printk("aztcd: XA support experimental - mail results to Werner.Zimmermann@fht-esslingen.de\n");
-           }
-        
-        /*multisession detection
-          support for multisession CDs is done automatically with Aztech drives,
-          we don't have to take care about TOC redirection; if we want the isofs
-          to take care about redirection, we have to set AZT_MULTISESSION to 1*/
-        DiskInfo.multi=0;
+	/*audio disk detection
+	   with my Aztech drive there is no audio status bit, so I use the copy
+	   protection bit of the first track. If this track is copy protected 
+	   (copy bit = 0), I assume, it's an audio  disk. Strange, but works ??? */
+	if (!(Toc[DiskInfo.first].ctrl_addr & 0x40))
+		DiskInfo.audio = 1;
+	else
+		DiskInfo.audio = 0;
+
+	/* XA detection */
+	if (!DiskInfo.audio) {
+		azt_Play.start.min = 0;	/*XA detection only seems to work */
+		azt_Play.start.sec = 2;	/*when we play a track */
+		azt_Play.start.frame = 0;
+		azt_Play.end.min = 0;
+		azt_Play.end.sec = 0;
+		azt_Play.end.frame = 1;
+		if (sendAztCmd(ACMD_PLAY_READ, &azt_Play))
+			return -1;
+		DTEN_LOW;
+		for (st = 0; st < CD_FRAMESIZE; st++)
+			inb(DATA_PORT);
+	}
+	DiskInfo.xa = getAztStatus() & AST_MODE;
+	if (DiskInfo.xa) {
+		printk
+		    ("aztcd: XA support experimental - mail results to Werner.Zimmermann@fht-esslingen.de\n");
+	}
+
+	/*multisession detection
+	   support for multisession CDs is done automatically with Aztech drives,
+	   we don't have to take care about TOC redirection; if we want the isofs
+	   to take care about redirection, we have to set AZT_MULTISESSION to 1 */
+	DiskInfo.multi = 0;
 #if AZT_MULTISESSION
-  	if (DiskInfo.xa) 
-  	   { aztGetMultiDiskInfo(); /*here Disk.Info.multi is set*/
-  	   }
-#endif
-        if (DiskInfo.multi)
-           { DiskInfo.lastSession.min  = Toc[DiskInfo.next].diskTime.min;
-	     DiskInfo.lastSession.sec  = Toc[DiskInfo.next].diskTime.sec;
-             DiskInfo.lastSession.frame= Toc[DiskInfo.next].diskTime.frame;
-             printk("aztcd: Multisession support experimental\n");
-           }
-        else
-           { DiskInfo.lastSession.min  = Toc[DiskInfo.first].diskTime.min;
-	     DiskInfo.lastSession.sec  = Toc[DiskInfo.first].diskTime.sec;
-             DiskInfo.lastSession.frame= Toc[DiskInfo.first].diskTime.frame;
-           }
+	if (DiskInfo.xa) {
+		aztGetMultiDiskInfo();	/*here Disk.Info.multi is set */
+	}
+#endif
+	if (DiskInfo.multi) {
+		DiskInfo.lastSession.min = Toc[DiskInfo.next].diskTime.min;
+		DiskInfo.lastSession.sec = Toc[DiskInfo.next].diskTime.sec;
+		DiskInfo.lastSession.frame =
+		    Toc[DiskInfo.next].diskTime.frame;
+		printk("aztcd: Multisession support experimental\n");
+	} else {
+		DiskInfo.lastSession.min =
+		    Toc[DiskInfo.first].diskTime.min;
+		DiskInfo.lastSession.sec =
+		    Toc[DiskInfo.first].diskTime.sec;
+		DiskInfo.lastSession.frame =
+		    Toc[DiskInfo.first].diskTime.frame;
+	}
 
 	aztTocUpToDate = 1;
 #ifdef AZT_DEBUG
-	printk("aztcd: exiting aztUpdateToc  Time:%li\n",jiffies);
+	printk("aztcd: exiting aztUpdateToc  Time:%li\n", jiffies);
 #endif
 	return 0;
 }
@@ -849,56 +890,58 @@
  * track
  */
 static int aztGetDiskInfo()
-{ int limit;
-  unsigned char test;
-  struct azt_Toc qInfo;
-
-#ifdef AZT_DEBUG
-  printk("aztcd: starting aztGetDiskInfo  Time:%li\n",jiffies);
-#endif
-  if (aztSendCmd(ACMD_SEEK_TO_LEADIN)) RETURNM("aztGetDiskInfo 1",-1);
-  STEN_LOW_WAIT;
-  test=0;
-  for (limit=300;limit>0;limit--)
-   {  if (aztGetQChannelInfo(&qInfo)<0) RETURNM("aztGetDiskInfo 2",-1);
-      if (qInfo.pointIndex==0xA0)   /*Number of FirstTrack*/
-	{ DiskInfo.first = qInfo.diskTime.min;
-	  DiskInfo.first = azt_bcd2bin(DiskInfo.first);
-	  test=test|0x01;
-	}
-      if (qInfo.pointIndex==0xA1)   /*Number of LastTrack*/
-	{ DiskInfo.last  = qInfo.diskTime.min;
-	  DiskInfo.last  = azt_bcd2bin(DiskInfo.last);
-	  test=test|0x02;
-	}
-      if (qInfo.pointIndex==0xA2)   /*DiskLength*/
-	{ DiskInfo.diskLength.min=qInfo.diskTime.min;
-	  DiskInfo.diskLength.sec=qInfo.diskTime.sec;
-	  DiskInfo.diskLength.frame=qInfo.diskTime.frame;
-	  test=test|0x04;
-	}
-      if ((qInfo.pointIndex==DiskInfo.first)&&(test&0x01))   /*StartTime of First Track*/
-	{ DiskInfo.firstTrack.min=qInfo.diskTime.min;
-	  DiskInfo.firstTrack.sec=qInfo.diskTime.sec;
-	  DiskInfo.firstTrack.frame=qInfo.diskTime.frame;
-	  test=test|0x08;
-	}
-      if (test==0x0F) break;
-   }
-#ifdef AZT_DEBUG
-  printk ("aztcd: exiting aztGetDiskInfo  Time:%li\n",jiffies);
-  printk("Disk Info: first %d last %d length %02X:%02X.%02X dez  first %02X:%02X.%02X dez\n",
-  	  DiskInfo.first,
-	  DiskInfo.last,
-	  DiskInfo.diskLength.min,
-	  DiskInfo.diskLength.sec,
-	  DiskInfo.diskLength.frame,
-	  DiskInfo.firstTrack.min,
-	  DiskInfo.firstTrack.sec,
-	  DiskInfo.firstTrack.frame);
+{
+	int limit;
+	unsigned char test;
+	struct azt_Toc qInfo;
+
+#ifdef AZT_DEBUG
+	printk("aztcd: starting aztGetDiskInfo  Time:%li\n", jiffies);
+#endif
+	if (aztSendCmd(ACMD_SEEK_TO_LEADIN))
+		RETURNM("aztGetDiskInfo 1", -1);
+	STEN_LOW_WAIT;
+	test = 0;
+	for (limit = 300; limit > 0; limit--) {
+		if (aztGetQChannelInfo(&qInfo) < 0)
+			RETURNM("aztGetDiskInfo 2", -1);
+		if (qInfo.pointIndex == 0xA0) {	/*Number of FirstTrack */
+			DiskInfo.first = qInfo.diskTime.min;
+			DiskInfo.first = azt_bcd2bin(DiskInfo.first);
+			test = test | 0x01;
+		}
+		if (qInfo.pointIndex == 0xA1) {	/*Number of LastTrack */
+			DiskInfo.last = qInfo.diskTime.min;
+			DiskInfo.last = azt_bcd2bin(DiskInfo.last);
+			test = test | 0x02;
+		}
+		if (qInfo.pointIndex == 0xA2) {	/*DiskLength */
+			DiskInfo.diskLength.min = qInfo.diskTime.min;
+			DiskInfo.diskLength.sec = qInfo.diskTime.sec;
+			DiskInfo.diskLength.frame = qInfo.diskTime.frame;
+			test = test | 0x04;
+		}
+		if ((qInfo.pointIndex == DiskInfo.first) && (test & 0x01)) {	/*StartTime of First Track */
+			DiskInfo.firstTrack.min = qInfo.diskTime.min;
+			DiskInfo.firstTrack.sec = qInfo.diskTime.sec;
+			DiskInfo.firstTrack.frame = qInfo.diskTime.frame;
+			test = test | 0x08;
+		}
+		if (test == 0x0F)
+			break;
+	}
+#ifdef AZT_DEBUG
+	printk("aztcd: exiting aztGetDiskInfo  Time:%li\n", jiffies);
+	printk
+	    ("Disk Info: first %d last %d length %02X:%02X.%02X dez  first %02X:%02X.%02X dez\n",
+	     DiskInfo.first, DiskInfo.last, DiskInfo.diskLength.min,
+	     DiskInfo.diskLength.sec, DiskInfo.diskLength.frame,
+	     DiskInfo.firstTrack.min, DiskInfo.firstTrack.sec,
+	     DiskInfo.firstTrack.frame);
 #endif
-  if (test!=0x0F) return -1;
-  return 0;
+	if (test != 0x0F)
+		return -1;
+	return 0;
 }
 
 #if AZT_MULTISESSION
@@ -906,93 +949,105 @@
  * Get Multisession Disk Info
  */
 static int aztGetMultiDiskInfo(void)
-{ int limit, k=5;
-  unsigned char test;
-  struct azt_Toc qInfo;
-
-#ifdef AZT_DEBUG
-  printk("aztcd: starting aztGetMultiDiskInfo\n");
-#endif
-
-  do { azt_Play.start.min   = Toc[DiskInfo.last+1].diskTime.min;
-       azt_Play.start.sec   = Toc[DiskInfo.last+1].diskTime.sec;
-       azt_Play.start.frame = Toc[DiskInfo.last+1].diskTime.frame;
-       test=0;
-
-       for (limit=30;limit>0;limit--)   /*Seek for LeadIn of next session*/
-           { if (aztSeek(&azt_Play)) RETURNM("aztGetMultiDiskInfo 1",-1);
-             if (aztGetQChannelInfo(&qInfo)<0) RETURNM("aztGetMultiDiskInfo 2",-1);
-             if ((qInfo.track==0)&&(qInfo.pointIndex)) break;  /*LeadIn found*/
-             if ((azt_Play.start.sec+=10) > 59)
-                { azt_Play.start.sec=0;
-                  azt_Play.start.min++;
-                }
-           }
-       if (!limit) break;  /*Check, if a leadin track was found, if not we're
-                             at the end of the disk*/
+{
+	int limit, k = 5;
+	unsigned char test;
+	struct azt_Toc qInfo;
+
+#ifdef AZT_DEBUG
+	printk("aztcd: starting aztGetMultiDiskInfo\n");
+#endif
+
+	do {
+		azt_Play.start.min = Toc[DiskInfo.last + 1].diskTime.min;
+		azt_Play.start.sec = Toc[DiskInfo.last + 1].diskTime.sec;
+		azt_Play.start.frame =
+		    Toc[DiskInfo.last + 1].diskTime.frame;
+		test = 0;
+
+		for (limit = 30; limit > 0; limit--) {	/*Seek for LeadIn of next session */
+			if (aztSeek(&azt_Play))
+				RETURNM("aztGetMultiDiskInfo 1", -1);
+			if (aztGetQChannelInfo(&qInfo) < 0)
+				RETURNM("aztGetMultiDiskInfo 2", -1);
+			if ((qInfo.track == 0) && (qInfo.pointIndex))
+				break;	/*LeadIn found */
+			if ((azt_Play.start.sec += 10) > 59) {
+				azt_Play.start.sec = 0;
+				azt_Play.start.min++;
+			}
+		}
+		if (!limit)
+			break;	/*Check, if a leadin track was found, if not we're
+				   at the end of the disk */
 #ifdef AZT_DEBUG_MULTISESSION
-       printk("leadin found track %d  pointIndex %x  limit %d\n",qInfo.track,qInfo.pointIndex,limit);
+		printk("leadin found track %d  pointIndex %x  limit %d\n",
+		       qInfo.track, qInfo.pointIndex, limit);
 #endif
-       for (limit=300;limit>0;limit--)
-           { if (++azt_Play.start.frame>74)
-                { azt_Play.start.frame=0;
-                  if (azt_Play.start.sec > 59)
-                     { azt_Play.start.sec=0;
-                       azt_Play.start.min++;
-                     }
-                }     
-             if (aztSeek(&azt_Play)) RETURNM("aztGetMultiDiskInfo 3",-1);
-             if (aztGetQChannelInfo(&qInfo)<0) RETURNM("aztGetMultiDiskInfo 4",-1);
-             if (qInfo.pointIndex==0xA0)   /*Number of NextTrack*/
-	        { DiskInfo.next = qInfo.diskTime.min;
-	          DiskInfo.next = azt_bcd2bin(DiskInfo.next);
-	          test=test|0x01;
-	        }
-             if (qInfo.pointIndex==0xA1)   /*Number of LastTrack*/
-	 	{ DiskInfo.last  = qInfo.diskTime.min;
-	   	  DiskInfo.last  = azt_bcd2bin(DiskInfo.last);
-	   	  test=test|0x02;
-	 	}
-      	     if (qInfo.pointIndex==0xA2)   /*DiskLength*/
-	 	{ DiskInfo.diskLength.min  =qInfo.diskTime.min;
-	   	  DiskInfo.diskLength.sec  =qInfo.diskTime.sec;
-	   	  DiskInfo.diskLength.frame=qInfo.diskTime.frame;
-	  	  test=test|0x04;
-	 	}
-      	     if ((qInfo.pointIndex==DiskInfo.next)&&(test&0x01))   /*StartTime of Next Track*/
-		{ DiskInfo.nextSession.min=qInfo.diskTime.min;
-	  	  DiskInfo.nextSession.sec=qInfo.diskTime.sec;
-	  	  DiskInfo.nextSession.frame=qInfo.diskTime.frame;
-	  	  test=test|0x08;
+		for (limit = 300; limit > 0; limit--) {
+			if (++azt_Play.start.frame > 74) {
+				azt_Play.start.frame = 0;
+				if (azt_Play.start.sec > 59) {
+					azt_Play.start.sec = 0;
+					azt_Play.start.min++;
+				}
+			}
+			if (aztSeek(&azt_Play))
+				RETURNM("aztGetMultiDiskInfo 3", -1);
+			if (aztGetQChannelInfo(&qInfo) < 0)
+				RETURNM("aztGetMultiDiskInfo 4", -1);
+			if (qInfo.pointIndex == 0xA0) {	/*Number of NextTrack */
+				DiskInfo.next = qInfo.diskTime.min;
+				DiskInfo.next = azt_bcd2bin(DiskInfo.next);
+				test = test | 0x01;
+			}
+			if (qInfo.pointIndex == 0xA1) {	/*Number of LastTrack */
+				DiskInfo.last = qInfo.diskTime.min;
+				DiskInfo.last = azt_bcd2bin(DiskInfo.last);
+				test = test | 0x02;
+			}
+			if (qInfo.pointIndex == 0xA2) {	/*DiskLength */
+				DiskInfo.diskLength.min =
+				    qInfo.diskTime.min;
+				DiskInfo.diskLength.sec =
+				    qInfo.diskTime.sec;
+				DiskInfo.diskLength.frame =
+				    qInfo.diskTime.frame;
+				test = test | 0x04;
+			}
+			if ((qInfo.pointIndex == DiskInfo.next) && (test & 0x01)) {	/*StartTime of Next Track */
+				DiskInfo.nextSession.min =
+				    qInfo.diskTime.min;
+				DiskInfo.nextSession.sec =
+				    qInfo.diskTime.sec;
+				DiskInfo.nextSession.frame =
+				    qInfo.diskTime.frame;
+				test = test | 0x08;
+			}
+			if (test == 0x0F)
+				break;
 		}
-      	     if (test==0x0F) break;
-   	   }
 #ifdef AZT_DEBUG_MULTISESSION
-       printk ("MultiDisk Info: first %d next %d last %d length %02x:%02x.%02x dez  first %02x:%02x.%02x dez  next %02x:%02x.%02x dez\n",
-     		DiskInfo.first,
-		DiskInfo.next,
-		DiskInfo.last,
-		DiskInfo.diskLength.min,
-		DiskInfo.diskLength.sec,
-		DiskInfo.diskLength.frame,
-		DiskInfo.firstTrack.min,
-		DiskInfo.firstTrack.sec,
-		DiskInfo.firstTrack.frame,
-		DiskInfo.nextSession.min,
-		DiskInfo.nextSession.sec,
-		DiskInfo.nextSession.frame);
-#endif
-       if (test!=0x0F) 
-           break;
-       else 
-           DiskInfo.multi=1;   /*found TOC of more than one session*/
-       aztGetToc(1);
-     } while(--k);
+		printk
+		    ("MultiDisk Info: first %d next %d last %d length %02x:%02x.%02x dez  first %02x:%02x.%02x dez  next %02x:%02x.%02x dez\n",
+		     DiskInfo.first, DiskInfo.next, DiskInfo.last,
+		     DiskInfo.diskLength.min, DiskInfo.diskLength.sec,
+		     DiskInfo.diskLength.frame, DiskInfo.firstTrack.min,
+		     DiskInfo.firstTrack.sec, DiskInfo.firstTrack.frame,
+		     DiskInfo.nextSession.min, DiskInfo.nextSession.sec,
+		     DiskInfo.nextSession.frame);
+#endif
+		if (test != 0x0F)
+			break;
+		else
+			DiskInfo.multi = 1;	/*found TOC of more than one session */
+		aztGetToc(1);
+	} while (--k);
 
 #ifdef AZT_DEBUG
-  printk ("aztcd: exiting aztGetMultiDiskInfo  Time:%li\n",jiffies);
+	printk("aztcd: exiting aztGetMultiDiskInfo  Time:%li\n", jiffies);
 #endif
-  return 0;
+	return 0;
 }
 #endif
 
@@ -1000,75 +1055,81 @@
  * Read the table of contents (TOC)
  */
 static int aztGetToc(int multi)
-{ int i, px;
-  int limit;
-  struct azt_Toc qInfo;
-
-#ifdef AZT_DEBUG
-  printk("aztcd: starting aztGetToc  Time:%li\n",jiffies);
-#endif
-  if (!multi)
-     { for (i = 0; i < MAX_TRACKS; i++)
- 	    Toc[i].pointIndex = 0;
-       i = DiskInfo.last + 3;
-     }
-  else
-     { for (i = DiskInfo.next; i < MAX_TRACKS; i++)
-     	    Toc[i].pointIndex = 0; 
-       i = DiskInfo.last + 4 - DiskInfo.next;
-     }
+{
+	int i, px;
+	int limit;
+	struct azt_Toc qInfo;
+
+#ifdef AZT_DEBUG
+	printk("aztcd: starting aztGetToc  Time:%li\n", jiffies);
+#endif
+	if (!multi) {
+		for (i = 0; i < MAX_TRACKS; i++)
+			Toc[i].pointIndex = 0;
+		i = DiskInfo.last + 3;
+	} else {
+		for (i = DiskInfo.next; i < MAX_TRACKS; i++)
+			Toc[i].pointIndex = 0;
+		i = DiskInfo.last + 4 - DiskInfo.next;
+	}
 
 /*Is there a good reason to stop motor before TOC read?
   if (aztSendCmd(ACMD_STOP)) RETURNM("aztGetToc 1",-1);
       STEN_LOW_WAIT;
 */
 
-  if (!multi)
-     { azt_mode = 0x05;
-       if (aztSendCmd(ACMD_SEEK_TO_LEADIN)) RETURNM("aztGetToc 2",-1);
-       STEN_LOW_WAIT;
-     }
-  for (limit = 300; limit > 0; limit--)
-      { if (multi)
-           { if (++azt_Play.start.sec > 59)
-                { azt_Play.start.sec=0;
-                  azt_Play.start.min++;
-                }
-             if (aztSeek(&azt_Play)) RETURNM("aztGetToc 3",-1);
-           }
-	if (aztGetQChannelInfo(&qInfo) < 0)
-	    break;
-
-	px = azt_bcd2bin(qInfo.pointIndex);
-
-	if (px > 0 && px < MAX_TRACKS && qInfo.track == 0)
-  	    if (Toc[px].pointIndex == 0)
-	       { Toc[px] = qInfo;
-		 i--;
-	       }
-
-	if (i <= 0)
-	    break;
-      }
-
-  Toc[DiskInfo.last + 1].diskTime = DiskInfo.diskLength;
-  Toc[DiskInfo.last].trackTime    = DiskInfo.diskLength;
-
-#ifdef AZT_DEBUG_MULTISESSION 
-  printk("aztcd: exiting aztGetToc\n");
-  for (i = 1; i <= DiskInfo.last+1; i++)
-       printk("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X dez  %02X:%02X.%02X dez\n",
-               i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
-               Toc[i].trackTime.min, Toc[i].trackTime.sec, Toc[i].trackTime.frame,
-               Toc[i].diskTime.min, Toc[i].diskTime.sec, Toc[i].diskTime.frame);
-  for (i = 100; i < 103; i++)
-       printk("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X dez  %02X:%02X.%02X dez\n",
-               i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
-               Toc[i].trackTime.min, Toc[i].trackTime.sec, Toc[i].trackTime.frame,
-               Toc[i].diskTime.min, Toc[i].diskTime.sec, Toc[i].diskTime.frame);
+	if (!multi) {
+		azt_mode = 0x05;
+		if (aztSendCmd(ACMD_SEEK_TO_LEADIN))
+			RETURNM("aztGetToc 2", -1);
+		STEN_LOW_WAIT;
+	}
+	for (limit = 300; limit > 0; limit--) {
+		if (multi) {
+			if (++azt_Play.start.sec > 59) {
+				azt_Play.start.sec = 0;
+				azt_Play.start.min++;
+			}
+			if (aztSeek(&azt_Play))
+				RETURNM("aztGetToc 3", -1);
+		}
+		if (aztGetQChannelInfo(&qInfo) < 0)
+			break;
+
+		px = azt_bcd2bin(qInfo.pointIndex);
+
+		if (px > 0 && px < MAX_TRACKS && qInfo.track == 0)
+			if (Toc[px].pointIndex == 0) {
+				Toc[px] = qInfo;
+				i--;
+			}
+
+		if (i <= 0)
+			break;
+	}
+
+	Toc[DiskInfo.last + 1].diskTime = DiskInfo.diskLength;
+	Toc[DiskInfo.last].trackTime = DiskInfo.diskLength;
+
+#ifdef AZT_DEBUG_MULTISESSION
+	printk("aztcd: exiting aztGetToc\n");
+	for (i = 1; i <= DiskInfo.last + 1; i++)
+		printk
+		    ("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X dez  %02X:%02X.%02X dez\n",
+		     i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
+		     Toc[i].trackTime.min, Toc[i].trackTime.sec,
+		     Toc[i].trackTime.frame, Toc[i].diskTime.min,
+		     Toc[i].diskTime.sec, Toc[i].diskTime.frame);
+	for (i = 100; i < 103; i++)
+		printk
+		    ("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X dez  %02X:%02X.%02X dez\n",
+		     i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
+		     Toc[i].trackTime.min, Toc[i].trackTime.sec,
+		     Toc[i].trackTime.frame, Toc[i].diskTime.min,
+		     Toc[i].diskTime.sec, Toc[i].diskTime.frame);
 #endif
 
-  return limit > 0 ? 0 : -1;
+	return limit > 0 ? 0 : -1;
 }
 
 
@@ -1080,163 +1141,186 @@
 #ifndef MODULE
 static int __init aztcd_setup(char *str)
 {
-    int ints[4];
-    
-    (void)get_options(str, ARRAY_SIZE(ints), ints);
-    
-    if (ints[0] > 0)
-        azt_port = ints[1];
-    if (ints[1] > 1)
-        azt_cont = ints[2];
-    return 1;
+	int ints[4];
+
+	(void) get_options(str, ARRAY_SIZE(ints), ints);
+
+	if (ints[0] > 0)
+		azt_port = ints[1];
+	if (ints[1] > 1)
+		azt_cont = ints[2];
+	return 1;
 }
 
 __setup("aztcd=", aztcd_setup);
 
-#endif /* !MODULE */
+#endif				/* !MODULE */
 
 /* 
  * Checking if the media has been changed
 */
 static int check_aztcd_media_change(kdev_t full_dev)
-{ if (aztDiskChanged)          /* disk changed */
-     { aztDiskChanged=0;
-       return 1;
-     }
-  else
-       return 0;               /* no change */
+{
+	if (aztDiskChanged) {	/* disk changed */
+		aztDiskChanged = 0;
+		return 1;
+	} else
+		return 0;	/* no change */
 }
 
 /*
  * Kernel IO-controls
 */
-static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg)
-{       int i, st;
+static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
+		       unsigned long arg)
+{
+	int i;
 	struct azt_Toc qInfo;
 	struct cdrom_ti ti;
 	struct cdrom_tochdr tocHdr;
 	struct cdrom_msf msf;
 	struct cdrom_tocentry entry;
-	struct azt_Toc *tocPtr;            
+	struct azt_Toc *tocPtr;
 	struct cdrom_subchnl subchnl;
-        struct cdrom_volctrl volctrl;
+	struct cdrom_volctrl volctrl;
 
 #ifdef AZT_DEBUG
-	printk("aztcd: starting aztcd_ioctl - Command:%x   Time: %li\n",cmd, jiffies);
-        printk("aztcd Status %x\n", getAztStatus());
-#endif
-	if (!ip) RETURNM("aztcd_ioctl 1",-EINVAL);
-	if (getAztStatus()<0) RETURNM("aztcd_ioctl 2", -EIO);
-	if ((!aztTocUpToDate)||(aztDiskChanged))
-	{ if ((i=aztUpdateToc())<0) RETURNM("aztcd_ioctl 3", i); /* error reading TOC */
+	printk("aztcd: starting aztcd_ioctl - Command:%x   Time: %li\n",
+	       cmd, jiffies);
+	printk("aztcd Status %x\n", getAztStatus());
+#endif
+	if (!ip)
+		RETURNM("aztcd_ioctl 1", -EINVAL);
+	if (getAztStatus() < 0)
+		RETURNM("aztcd_ioctl 2", -EIO);
+	if ((!aztTocUpToDate) || (aztDiskChanged)) {
+		if ((i = aztUpdateToc()) < 0)
+			RETURNM("aztcd_ioctl 3", i);	/* error reading TOC */
 	}
 
-	switch (cmd)
-	{
-	case CDROMSTART:     /* Spin up the drive. Don't know, what to do,
-	                        at least close the tray */
-#if AZT_PRIVATE_IOCTLS 
-	        if (aztSendCmd(ACMD_CLOSE)) RETURNM("aztcd_ioctl 4",-1);
-	        STEN_LOW_WAIT;
+	switch (cmd) {
+	case CDROMSTART:	/* Spin up the drive. Don't know, what to do,
+				   at least close the tray */
+#if AZT_PRIVATE_IOCTLS
+		if (aztSendCmd(ACMD_CLOSE))
+			RETURNM("aztcd_ioctl 4", -1);
+		STEN_LOW_WAIT;
 #endif
 		break;
-	case CDROMSTOP:      /* Spin down the drive */
-		if (aztSendCmd(ACMD_STOP)) RETURNM("aztcd_ioctl 5",-1);
+	case CDROMSTOP:	/* Spin down the drive */
+		if (aztSendCmd(ACMD_STOP))
+			RETURNM("aztcd_ioctl 5", -1);
 		STEN_LOW_WAIT;
 		/* should we do anything if it fails? */
 		aztAudioStatus = CDROM_AUDIO_NO_STATUS;
 		break;
-	case CDROMPAUSE:     /* Pause the drive */
-                if (aztAudioStatus != CDROM_AUDIO_PLAY) return -EINVAL; 
-
-		if (aztGetQChannelInfo(&qInfo) < 0)
-		{ /* didn't get q channel info */
-		  aztAudioStatus = CDROM_AUDIO_NO_STATUS;
-		  RETURNM("aztcd_ioctl 7",0);
+	case CDROMPAUSE:	/* Pause the drive */
+		if (aztAudioStatus != CDROM_AUDIO_PLAY)
+			return -EINVAL;
+
+		if (aztGetQChannelInfo(&qInfo) < 0) {	/* didn't get q channel info */
+			aztAudioStatus = CDROM_AUDIO_NO_STATUS;
+			RETURNM("aztcd_ioctl 7", 0);
 		}
-		azt_Play.start = qInfo.diskTime;        /* remember restart point */
+		azt_Play.start = qInfo.diskTime;	/* remember restart point */
 
-		if (aztSendCmd(ACMD_PAUSE)) RETURNM("aztcd_ioctl 8",-1);
+		if (aztSendCmd(ACMD_PAUSE))
+			RETURNM("aztcd_ioctl 8", -1);
 		STEN_LOW_WAIT;
 		aztAudioStatus = CDROM_AUDIO_PAUSED;
 		break;
-	case CDROMRESUME:    /* Play it again, Sam */
-		if (aztAudioStatus != CDROM_AUDIO_PAUSED) return -EINVAL;
+	case CDROMRESUME:	/* Play it again, Sam */
+		if (aztAudioStatus != CDROM_AUDIO_PAUSED)
+			return -EINVAL;
 		/* restart the drive at the saved position. */
 		i = aztPlay(&azt_Play);
-		if (i < 0)
-		{ aztAudioStatus = CDROM_AUDIO_ERROR;
-		  return -EIO;
+		if (i < 0) {
+			aztAudioStatus = CDROM_AUDIO_ERROR;
+			return -EIO;
 		}
 		aztAudioStatus = CDROM_AUDIO_PLAY;
 		break;
-	case CDROMMULTISESSION: /*multisession support -- experimental*/
-	        { struct cdrom_multisession ms;
-#ifdef AZT_DEBUG
-   		  printk("aztcd ioctl MULTISESSION\n");
+	case CDROMMULTISESSION:	/*multisession support -- experimental */
+		{
+			struct cdrom_multisession ms;
+#ifdef AZT_DEBUG
+			printk("aztcd ioctl MULTISESSION\n");
+#endif
+			if (copy_from_user
+			    (&ms, (void *) arg,
+			     sizeof(struct cdrom_multisession)))
+				return -EFAULT;
+			if (ms.addr_format == CDROM_MSF) {
+				ms.addr.msf.minute =
+				    azt_bcd2bin(DiskInfo.lastSession.min);
+				ms.addr.msf.second =
+				    azt_bcd2bin(DiskInfo.lastSession.sec);
+				ms.addr.msf.frame =
+				    azt_bcd2bin(DiskInfo.lastSession.
+						frame);
+			} else if (ms.addr_format == CDROM_LBA)
+				ms.addr.lba =
+				    azt_msf2hsg(&DiskInfo.lastSession);
+			else
+				return -EINVAL;
+			ms.xa_flag = DiskInfo.xa;
+			if (copy_to_user
+			    ((void *) arg, &ms,
+			     sizeof(struct cdrom_multisession)))
+				return -EFAULT;
+#ifdef AZT_DEBUG
+			if (ms.addr_format == CDROM_MSF)
+				printk
+				    ("aztcd multisession xa:%d, msf:%02x:%02x.%02x [%02x:%02x.%02x])\n",
+				     ms.xa_flag, ms.addr.msf.minute,
+				     ms.addr.msf.second, ms.addr.msf.frame,
+				     DiskInfo.lastSession.min,
+				     DiskInfo.lastSession.sec,
+				     DiskInfo.lastSession.frame);
+			else
+				printk
+				    ("aztcd multisession %d, lba:0x%08x [%02x:%02x.%02x])\n",
+				     ms.xa_flag, ms.addr.lba,
+				     DiskInfo.lastSession.min,
+				     DiskInfo.lastSession.sec,
+				     DiskInfo.lastSession.frame);
 #endif
-		  st = verify_area(VERIFY_WRITE, (void*) arg, sizeof(struct cdrom_multisession));
-		  if (st) return st;
-		  memcpy_fromfs(&ms, (void*) arg, sizeof(struct cdrom_multisession));
-		  if (ms.addr_format == CDROM_MSF) 
-		     { ms.addr.msf.minute = azt_bcd2bin(DiskInfo.lastSession.min);
-		       ms.addr.msf.second = azt_bcd2bin(DiskInfo.lastSession.sec);
-		       ms.addr.msf.frame  = azt_bcd2bin(DiskInfo.lastSession.frame);
-		     } 
-		  else if (ms.addr_format == CDROM_LBA)
-		       ms.addr.lba = azt_msf2hsg(&DiskInfo.lastSession);
-		  else
-		       return -EINVAL;
-		  ms.xa_flag = DiskInfo.xa;
-	  	  memcpy_tofs((void*) arg, &ms, sizeof(struct cdrom_multisession));
-#ifdef AZT_DEBUG 
- 		  if (ms.addr_format == CDROM_MSF) 
-                      printk("aztcd multisession xa:%d, msf:%02x:%02x.%02x [%02x:%02x.%02x])\n",
-			      ms.xa_flag, ms.addr.msf.minute, ms.addr.msf.second, 
-			      ms.addr.msf.frame, DiskInfo.lastSession.min,
-			      DiskInfo.lastSession.sec, DiskInfo.lastSession.frame);
-		  else
-		      printk("aztcd multisession %d, lba:0x%08x [%02x:%02x.%02x])\n",
-			      ms.xa_flag, ms.addr.lba, DiskInfo.lastSession.min,
-			      DiskInfo.lastSession.sec, DiskInfo.lastSession.frame);
-#endif
-   		  return 0;
-		}
-	case CDROMPLAYTRKIND:     /* Play a track.  This currently ignores index. */
-		st = verify_area(VERIFY_READ, (void *) arg, sizeof ti);
-		if (st) return st;
-		memcpy_fromfs(&ti, (void *) arg, sizeof ti);
+			return 0;
+		}
+	case CDROMPLAYTRKIND:	/* Play a track.  This currently ignores index. */
+		if (copy_from_user(&ti, (void *) arg, sizeof ti))
+			return -EFAULT;
 		if (ti.cdti_trk0 < DiskInfo.first
-			|| ti.cdti_trk0 > DiskInfo.last
-			|| ti.cdti_trk1 < ti.cdti_trk0)
-		{ return -EINVAL;
+		    || ti.cdti_trk0 > DiskInfo.last
+		    || ti.cdti_trk1 < ti.cdti_trk0) {
+			return -EINVAL;
 		}
 		if (ti.cdti_trk1 > DiskInfo.last)
-		    ti.cdti_trk1 = DiskInfo.last;
+			ti.cdti_trk1 = DiskInfo.last;
 		azt_Play.start = Toc[ti.cdti_trk0].diskTime;
 		azt_Play.end = Toc[ti.cdti_trk1 + 1].diskTime;
 #ifdef AZT_DEBUG
-printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n",
-	azt_Play.start.min, azt_Play.start.sec, azt_Play.start.frame,
-	azt_Play.end.min, azt_Play.end.sec, azt_Play.end.frame);
+		printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n",
+		       azt_Play.start.min, azt_Play.start.sec,
+		       azt_Play.start.frame, azt_Play.end.min,
+		       azt_Play.end.sec, azt_Play.end.frame);
 #endif
 		i = aztPlay(&azt_Play);
-		if (i < 0)
-		{ aztAudioStatus = CDROM_AUDIO_ERROR;
-		  return -EIO;
+		if (i < 0) {
+			aztAudioStatus = CDROM_AUDIO_ERROR;
+			return -EIO;
 		}
 		aztAudioStatus = CDROM_AUDIO_PLAY;
 		break;
-	case CDROMPLAYMSF:   /* Play starting at the given MSF address. */
+	case CDROMPLAYMSF:	/* Play starting at the given MSF address. */
 /*              if (aztAudioStatus == CDROM_AUDIO_PLAY) 
 		{ if (aztSendCmd(ACMD_STOP)) RETURNM("aztcd_ioctl 9",-1);
 		  STEN_LOW;
 		  aztAudioStatus = CDROM_AUDIO_NO_STATUS;
 		}
 */
-		st = verify_area(VERIFY_READ, (void *) arg, sizeof msf);
-		if (st) return st;
-		memcpy_fromfs(&msf, (void *) arg, sizeof msf);
+		if (copy_from_user(&msf, (void *) arg, sizeof msf))
+			return -EFAULT;
 		/* convert to bcd */
 		azt_bin2bcd(&msf.cdmsf_min0);
 		azt_bin2bcd(&msf.cdmsf_sec0);
@@ -1251,171 +1335,190 @@
 		azt_Play.end.sec = msf.cdmsf_sec1;
 		azt_Play.end.frame = msf.cdmsf_frame1;
 #ifdef AZT_DEBUG
-printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n",
-azt_Play.start.min, azt_Play.start.sec, azt_Play.start.frame,
-azt_Play.end.min, azt_Play.end.sec, azt_Play.end.frame);
+		printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n",
+		       azt_Play.start.min, azt_Play.start.sec,
+		       azt_Play.start.frame, azt_Play.end.min,
+		       azt_Play.end.sec, azt_Play.end.frame);
 #endif
 		i = aztPlay(&azt_Play);
-		if (i < 0)
-		{ aztAudioStatus = CDROM_AUDIO_ERROR;
-		  return -EIO;
+		if (i < 0) {
+			aztAudioStatus = CDROM_AUDIO_ERROR;
+			return -EIO;
 		}
 		aztAudioStatus = CDROM_AUDIO_PLAY;
 		break;
 
-	case CDROMREADTOCHDR:        /* Read the table of contents header */
-		st = verify_area(VERIFY_WRITE, (void *) arg, sizeof tocHdr);
-		if (st) return st;
+	case CDROMREADTOCHDR:	/* Read the table of contents header */
 		tocHdr.cdth_trk0 = DiskInfo.first;
 		tocHdr.cdth_trk1 = DiskInfo.last;
-		memcpy_tofs((void *) arg, &tocHdr, sizeof tocHdr);
+		if (copy_to_user((void *) arg, &tocHdr, sizeof tocHdr))
+			return -EFAULT;
 		break;
-	case CDROMREADTOCENTRY:      /* Read an entry in the table of contents */
-		st = verify_area(VERIFY_WRITE, (void *) arg, sizeof entry);
-		if (st) return st;
-		memcpy_fromfs(&entry, (void *) arg, sizeof entry);
-		if ((!aztTocUpToDate)||aztDiskChanged) aztUpdateToc();
+	case CDROMREADTOCENTRY:	/* Read an entry in the table of contents */
+		if (copy_from_user(&entry, (void *) arg, sizeof entry))
+			return -EFAULT;
+		if ((!aztTocUpToDate) || aztDiskChanged)
+			aztUpdateToc();
 		if (entry.cdte_track == CDROM_LEADOUT)
-		  tocPtr = &Toc[DiskInfo.last + 1];
+			tocPtr = &Toc[DiskInfo.last + 1];
 		else if (entry.cdte_track > DiskInfo.last
-				|| entry.cdte_track < DiskInfo.first)
-		{ return -EINVAL;
-		}
-		else 
-		  tocPtr = &Toc[entry.cdte_track];
-		entry.cdte_adr = tocPtr -> ctrl_addr;
-		entry.cdte_ctrl = tocPtr -> ctrl_addr >> 4;
+			 || entry.cdte_track < DiskInfo.first) {
+			return -EINVAL;
+		} else
+			tocPtr = &Toc[entry.cdte_track];
+		entry.cdte_adr = tocPtr->ctrl_addr;
+		entry.cdte_ctrl = tocPtr->ctrl_addr >> 4;
 		if (entry.cdte_format == CDROM_LBA)
-		  entry.cdte_addr.lba = azt_msf2hsg(&tocPtr -> diskTime);
-		else if (entry.cdte_format == CDROM_MSF)
-		{ entry.cdte_addr.msf.minute = azt_bcd2bin(tocPtr -> diskTime.min);
-		  entry.cdte_addr.msf.second = azt_bcd2bin(tocPtr -> diskTime.sec);
-		  entry.cdte_addr.msf.frame  = azt_bcd2bin(tocPtr -> diskTime.frame);
+			entry.cdte_addr.lba =
+			    azt_msf2hsg(&tocPtr->diskTime);
+		else if (entry.cdte_format == CDROM_MSF) {
+			entry.cdte_addr.msf.minute =
+			    azt_bcd2bin(tocPtr->diskTime.min);
+			entry.cdte_addr.msf.second =
+			    azt_bcd2bin(tocPtr->diskTime.sec);
+			entry.cdte_addr.msf.frame =
+			    azt_bcd2bin(tocPtr->diskTime.frame);
+		} else {
+			return -EINVAL;
 		}
-		else
-		{ return -EINVAL;
-		}
-		memcpy_tofs((void *) arg, &entry, sizeof entry);
+		if (copy_to_user((void *) arg, &entry, sizeof entry))
+			return -EFAULT;
 		break;
-	case CDROMSUBCHNL:   /* Get subchannel info */
-		st = verify_area(VERIFY_WRITE, (void *) arg, sizeof(struct cdrom_subchnl));
-		if (st) { 
-#ifdef AZT_DEBUG
-		          printk("aztcd: exiting aztcd_ioctl - Error 1 - Command:%x\n",cmd);
-#endif
-		          return st;
-		        }  
-		memcpy_fromfs(&subchnl, (void *) arg, sizeof (struct cdrom_subchnl));
-		if (aztGetQChannelInfo(&qInfo) < 0)
-		if (st) { 
-#ifdef AZT_DEBUG
-		          printk("aztcd: exiting aztcd_ioctl - Error 3 - Command:%x\n",cmd);
+	case CDROMSUBCHNL:	/* Get subchannel info */
+		if (copy_from_user
+		    (&subchnl, (void *) arg, sizeof(struct cdrom_subchnl)))
+			return -EFAULT;
+		if (aztGetQChannelInfo(&qInfo) < 0) {
+#ifdef AZT_DEBUG
+			printk
+			    ("aztcd: exiting aztcd_ioctl - Error 3 - Command:%x\n",
+			     cmd);
 #endif
-     		  	  return -EIO;
-     		  	}  
+			return -EIO;
+		}
 		subchnl.cdsc_audiostatus = aztAudioStatus;
 		subchnl.cdsc_adr = qInfo.ctrl_addr;
 		subchnl.cdsc_ctrl = qInfo.ctrl_addr >> 4;
 		subchnl.cdsc_trk = azt_bcd2bin(qInfo.track);
 		subchnl.cdsc_ind = azt_bcd2bin(qInfo.pointIndex);
-		if (subchnl.cdsc_format == CDROM_LBA)
-		{ subchnl.cdsc_absaddr.lba = azt_msf2hsg(&qInfo.diskTime);
-		  subchnl.cdsc_reladdr.lba = azt_msf2hsg(&qInfo.trackTime);
-		}
-		else  /*default*/
-		{ subchnl.cdsc_format = CDROM_MSF;
-		  subchnl.cdsc_absaddr.msf.minute = azt_bcd2bin(qInfo.diskTime.min);
-		  subchnl.cdsc_absaddr.msf.second = azt_bcd2bin(qInfo.diskTime.sec);
-		  subchnl.cdsc_absaddr.msf.frame  = azt_bcd2bin(qInfo.diskTime.frame);
-		  subchnl.cdsc_reladdr.msf.minute = azt_bcd2bin(qInfo.trackTime.min);
-		  subchnl.cdsc_reladdr.msf.second = azt_bcd2bin(qInfo.trackTime.sec);
-		  subchnl.cdsc_reladdr.msf.frame  = azt_bcd2bin(qInfo.trackTime.frame);
+		if (subchnl.cdsc_format == CDROM_LBA) {
+			subchnl.cdsc_absaddr.lba =
+			    azt_msf2hsg(&qInfo.diskTime);
+			subchnl.cdsc_reladdr.lba =
+			    azt_msf2hsg(&qInfo.trackTime);
+		} else {	/*default */
+			subchnl.cdsc_format = CDROM_MSF;
+			subchnl.cdsc_absaddr.msf.minute =
+			    azt_bcd2bin(qInfo.diskTime.min);
+			subchnl.cdsc_absaddr.msf.second =
+			    azt_bcd2bin(qInfo.diskTime.sec);
+			subchnl.cdsc_absaddr.msf.frame =
+			    azt_bcd2bin(qInfo.diskTime.frame);
+			subchnl.cdsc_reladdr.msf.minute =
+			    azt_bcd2bin(qInfo.trackTime.min);
+			subchnl.cdsc_reladdr.msf.second =
+			    azt_bcd2bin(qInfo.trackTime.sec);
+			subchnl.cdsc_reladdr.msf.frame =
+			    azt_bcd2bin(qInfo.trackTime.frame);
 		}
-		memcpy_tofs((void *) arg, &subchnl, sizeof (struct cdrom_subchnl));
+		if (copy_to_user
+		    ((void *) arg, &subchnl, sizeof(struct cdrom_subchnl)))
+			return -EFAULT;
 		break;
-	case CDROMVOLCTRL:   /* Volume control 
-	 * With my Aztech CD268-01A volume control does not work, I can only
-	   turn the channels on (any value !=0) or off (value==0). Maybe it
-           works better with your drive */
-                st=verify_area(VERIFY_READ,(void *) arg, sizeof(volctrl));
-                if (st) return (st);
-                memcpy_fromfs(&volctrl,(char *) arg,sizeof(volctrl));
+	case CDROMVOLCTRL:	/* Volume control 
+				   * With my Aztech CD268-01A volume control does not work, I can only
+				   turn the channels on (any value !=0) or off (value==0). Maybe it
+				   works better with your drive */
+		if (copy_from_user
+		    (&volctrl, (char *) arg, sizeof(volctrl)))
+			return -EFAULT;
 		azt_Play.start.min = 0x21;
 		azt_Play.start.sec = 0x84;
 		azt_Play.start.frame = volctrl.channel0;
-		azt_Play.end.min =     volctrl.channel1;
-		azt_Play.end.sec =     volctrl.channel2;
-		azt_Play.end.frame =   volctrl.channel3;
-                sendAztCmd(ACMD_SET_VOLUME, &azt_Play);
-                STEN_LOW_WAIT;
-                break;
+		azt_Play.end.min = volctrl.channel1;
+		azt_Play.end.sec = volctrl.channel2;
+		azt_Play.end.frame = volctrl.channel3;
+		sendAztCmd(ACMD_SET_VOLUME, &azt_Play);
+		STEN_LOW_WAIT;
+		break;
 	case CDROMEJECT:
-                aztUnlockDoor(); /* Assume user knows what they're doing */
-	       /* all drives can at least stop! */
-		if (aztAudioStatus == CDROM_AUDIO_PLAY) 
-		{ if (aztSendCmd(ACMD_STOP)) RETURNM("azt_ioctl 10",-1);
-		  STEN_LOW_WAIT;
+		aztUnlockDoor();	/* Assume user knows what they're doing */
+		/* all drives can at least stop! */
+		if (aztAudioStatus == CDROM_AUDIO_PLAY) {
+			if (aztSendCmd(ACMD_STOP))
+				RETURNM("azt_ioctl 10", -1);
+			STEN_LOW_WAIT;
 		}
-		if (aztSendCmd(ACMD_EJECT)) RETURNM("azt_ioctl 11",-1);
+		if (aztSendCmd(ACMD_EJECT))
+			RETURNM("azt_ioctl 11", -1);
 		STEN_LOW_WAIT;
 		aztAudioStatus = CDROM_AUDIO_NO_STATUS;
 		break;
 	case CDROMEJECT_SW:
 		azt_auto_eject = (char) arg;
-		break;	
-        case CDROMRESET:
-        	outb(ACMD_SOFT_RESET,CMD_PORT);   /*send reset*/
-	        STEN_LOW;
-	        if (inb(DATA_PORT)!=AFL_OP_OK)    /*OP_OK?*/
-	          { printk("aztcd: AZTECH CD-ROM drive does not respond\n");
-                  }
-                break;
+		break;
+	case CDROMRESET:
+		outb(ACMD_SOFT_RESET, CMD_PORT);	/*send reset */
+		STEN_LOW;
+		if (inb(DATA_PORT) != AFL_OP_OK) {	/*OP_OK? */
+			printk
+			    ("aztcd: AZTECH CD-ROM drive does not respond\n");
+		}
+		break;
 /*Take care, the following code is not compatible with other CD-ROM drivers,
   use it at your own risk with cdplay.c. Set AZT_PRIVATE_IOCTLS to 0 in aztcd.h,
   if you do not want to use it!
-*/                  
-#if AZT_PRIVATE_IOCTLS 
-	case CDROMREADCOOKED: /*read data in mode 1 (2048 Bytes)*/
-	case CDROMREADRAW:    /*read data in mode 2 (2336 Bytes)*/
-		{ st = verify_area(VERIFY_WRITE, (void *) arg, sizeof buf);
-		  if (st) return st;
-		  memcpy_fromfs(&msf, (void *) arg, sizeof msf);
-		  /* convert to bcd */
-		  azt_bin2bcd(&msf.cdmsf_min0);
-		  azt_bin2bcd(&msf.cdmsf_sec0);
-		  azt_bin2bcd(&msf.cdmsf_frame0);
-		  msf.cdmsf_min1=0;
-		  msf.cdmsf_sec1=0;
-		  msf.cdmsf_frame1=1; /*read only one frame*/
-		  azt_Play.start.min = msf.cdmsf_min0;
-		  azt_Play.start.sec = msf.cdmsf_sec0;
-		  azt_Play.start.frame = msf.cdmsf_frame0;
-		  azt_Play.end.min = msf.cdmsf_min1;
-		  azt_Play.end.sec = msf.cdmsf_sec1;
-		  azt_Play.end.frame = msf.cdmsf_frame1;
-		  if (cmd==CDROMREADRAW)
-		  { if (DiskInfo.xa)
-		       { return -1;         /*XA Disks can't be read raw*/
-		       }
-		    else   
-		       { if (sendAztCmd(ACMD_PLAY_READ_RAW, &azt_Play)) return -1;
-		         DTEN_LOW;
-		         insb(DATA_PORT,buf,CD_FRAMESIZE_RAW);
-		         memcpy_tofs((void *) arg, &buf, CD_FRAMESIZE_RAW);
-		       }  
-		  }
-		  else /*CDROMREADCOOKED*/
-		  { if (sendAztCmd(ACMD_PLAY_READ, &azt_Play)) return -1;
-		    DTEN_LOW;
-		    insb(DATA_PORT,buf,CD_FRAMESIZE);
-		    memcpy_tofs((void *) arg, &buf, CD_FRAMESIZE);
-		  }
-		 } 
-                break;
-	case CDROMSEEK:    /*seek msf address*/
-		st = verify_area(VERIFY_READ,  (void *) arg, sizeof msf);
-		if (st) return st;
-		memcpy_fromfs(&msf, (void *) arg, sizeof msf);
+*/
+#if AZT_PRIVATE_IOCTLS
+	case CDROMREADCOOKED:	/*read data in mode 1 (2048 Bytes) */
+	case CDROMREADRAW:	/*read data in mode 2 (2336 Bytes) */
+		{
+			if (copy_from_user(&msf, (void *) arg, sizeof msf))
+				return -EFAULT;
+			/* convert to bcd */
+			azt_bin2bcd(&msf.cdmsf_min0);
+			azt_bin2bcd(&msf.cdmsf_sec0);
+			azt_bin2bcd(&msf.cdmsf_frame0);
+			msf.cdmsf_min1 = 0;
+			msf.cdmsf_sec1 = 0;
+			msf.cdmsf_frame1 = 1;	/*read only one frame */
+			azt_Play.start.min = msf.cdmsf_min0;
+			azt_Play.start.sec = msf.cdmsf_sec0;
+			azt_Play.start.frame = msf.cdmsf_frame0;
+			azt_Play.end.min = msf.cdmsf_min1;
+			azt_Play.end.sec = msf.cdmsf_sec1;
+			azt_Play.end.frame = msf.cdmsf_frame1;
+			if (cmd == CDROMREADRAW) {
+				if (DiskInfo.xa) {
+					return -1;	/*XA Disks can't be read raw */
+				} else {
+					if (sendAztCmd
+					    (ACMD_PLAY_READ_RAW,
+					     &azt_Play))
+						return -1;
+					DTEN_LOW;
+					insb(DATA_PORT, buf,
+					     CD_FRAMESIZE_RAW);
+					if (copy_to_user
+					    ((void *) arg, &buf,
+					     CD_FRAMESIZE_RAW))
+						return -EFAULT;
+				}
+			} else
+				/*CDROMREADCOOKED*/ {
+				if (sendAztCmd(ACMD_PLAY_READ, &azt_Play))
+					return -1;
+				DTEN_LOW;
+				insb(DATA_PORT, buf, CD_FRAMESIZE);
+				if (copy_to_user
+				    ((void *) arg, &buf, CD_FRAMESIZE))
+					return -EFAULT;
+				}
+		}
+		break;
+	case CDROMSEEK:	/*seek msf address */
+		if (copy_from_user(&msf, (void *) arg, sizeof msf))
+			return -EFAULT;
 		/* convert to bcd */
 		azt_bin2bcd(&msf.cdmsf_min0);
 		azt_bin2bcd(&msf.cdmsf_sec0);
@@ -1423,18 +1526,20 @@
 		azt_Play.start.min = msf.cdmsf_min0;
 		azt_Play.start.sec = msf.cdmsf_sec0;
 		azt_Play.start.frame = msf.cdmsf_frame0;
-		if (aztSeek(&azt_Play)) return -1;
-                break;
-#endif /*end of incompatible code*/       
-	case CDROMREADMODE1: /*set read data in mode 1*/
-                return aztSetDiskType(AZT_MODE_1);
-	case CDROMREADMODE2: /*set read data in mode 2*/
-                return aztSetDiskType(AZT_MODE_2);	    
+		if (aztSeek(&azt_Play))
+			return -1;
+		break;
+#endif				/*end of incompatible code */
+	case CDROMREADMODE1:	/*set read data in mode 1 */
+		return aztSetDiskType(AZT_MODE_1);
+	case CDROMREADMODE2:	/*set read data in mode 2 */
+		return aztSetDiskType(AZT_MODE_2);
 	default:
 		return -EINVAL;
 	}
 #ifdef AZT_DEBUG
-        printk("aztcd: exiting aztcd_ioctl Command:%x  Time:%li\n",cmd,jiffies);
+	printk("aztcd: exiting aztcd_ioctl Command:%x  Time:%li\n", cmd,
+	       jiffies);
 #endif
 	return 0;
 }
@@ -1444,131 +1549,139 @@
  * When Linux gets variable block sizes this will probably go away.
  */
 static void azt_transfer(void)
-{ 
+{
 #ifdef AZT_TEST
-  printk("aztcd: executing azt_transfer Time:%li\n",jiffies);
+	printk("aztcd: executing azt_transfer Time:%li\n", jiffies);
 #endif
-  if (CURRENT_VALID) {
-    while (CURRENT -> nr_sectors) {
-      int bn = CURRENT -> sector / 4;
-      int i;
-      for (i = 0; i < AZT_BUF_SIZ && azt_buf_bn[i] != bn; ++i)
-	;
-      if (i < AZT_BUF_SIZ) {
-	int offs = (i * 4 + (CURRENT -> sector & 3)) * 512;
-	int nr_sectors = 4 - (CURRENT -> sector & 3);
-	if (azt_buf_out != i) {
-	  azt_buf_out = i;
-	  if (azt_buf_bn[i] != bn) {
-	    azt_buf_out = -1;
-	    continue;
-	  }
-	}
-	if (nr_sectors > CURRENT -> nr_sectors)
-	  nr_sectors = CURRENT -> nr_sectors;
-	memcpy(CURRENT -> buffer, azt_buf + offs, nr_sectors * 512);
-	CURRENT -> nr_sectors -= nr_sectors;
-	CURRENT -> sector += nr_sectors;
-	CURRENT -> buffer += nr_sectors * 512;
-      } else {
-	azt_buf_out = -1;
-	break;
-      }
-    }
-  }
+	if (CURRENT_VALID) {
+		while (CURRENT->nr_sectors) {
+			int bn = CURRENT->sector / 4;
+			int i;
+			for (i = 0; i < AZT_BUF_SIZ && azt_buf_bn[i] != bn;
+			     ++i);
+			if (i < AZT_BUF_SIZ) {
+				int offs =
+				    (i * 4 + (CURRENT->sector & 3)) * 512;
+				int nr_sectors = 4 - (CURRENT->sector & 3);
+				if (azt_buf_out != i) {
+					azt_buf_out = i;
+					if (azt_buf_bn[i] != bn) {
+						azt_buf_out = -1;
+						continue;
+					}
+				}
+				if (nr_sectors > CURRENT->nr_sectors)
+					nr_sectors = CURRENT->nr_sectors;
+				memcpy(CURRENT->buffer, azt_buf + offs,
+				       nr_sectors * 512);
+				CURRENT->nr_sectors -= nr_sectors;
+				CURRENT->sector += nr_sectors;
+				CURRENT->buffer += nr_sectors * 512;
+			} else {
+				azt_buf_out = -1;
+				break;
+			}
+		}
+	}
 }
 
 static void do_aztcd_request(request_queue_t * q)
 {
 #ifdef AZT_TEST
-  printk(" do_aztcd_request(%ld+%ld) Time:%li\n", CURRENT -> sector, CURRENT -> nr_sectors,jiffies);
+	printk(" do_aztcd_request(%ld+%ld) Time:%li\n", CURRENT->sector,
+	       CURRENT->nr_sectors, jiffies);
 #endif
-  if (DiskInfo.audio) 
-    { printk("aztcd: Error, tried to mount an Audio CD\n");
-      end_request(0);
-      return;
-    }
-  azt_transfer_is_active = 1;
-  while (CURRENT_VALID) {
-    if (CURRENT->bh) {
-      if (!buffer_locked(CURRENT->bh))
-	panic(DEVICE_NAME ": block not locked");
-    }
-    azt_transfer();
-    if (CURRENT -> nr_sectors == 0) {
-      end_request(1);
-    } else {
-      azt_buf_out = -1;         /* Want to read a block not in buffer */
-      if (azt_state == AZT_S_IDLE) {
-	if ((!aztTocUpToDate)||aztDiskChanged) {
-	  if (aztUpdateToc() < 0) {
-	    while (CURRENT_VALID)
-	      end_request(0);
-	    break;
-	  }
-	}
-	azt_state = AZT_S_START;
-	AztTries = 5;
-	SET_TIMER(azt_poll, HZ/100);
-      }
-      break;
-    }
-  }
-  azt_transfer_is_active = 0;
+	if (DiskInfo.audio) {
+		printk("aztcd: Error, tried to mount an Audio CD\n");
+		end_request(0);
+		return;
+	}
+	azt_transfer_is_active = 1;
+	while (CURRENT_VALID) {
+		if (CURRENT->bh) {
+			if (!buffer_locked(CURRENT->bh))
+				panic(DEVICE_NAME ": block not locked");
+		}
+		azt_transfer();
+		if (CURRENT->nr_sectors == 0) {
+			end_request(1);
+		} else {
+			azt_buf_out = -1;	/* Want to read a block not in buffer */
+			if (azt_state == AZT_S_IDLE) {
+				if ((!aztTocUpToDate) || aztDiskChanged) {
+					if (aztUpdateToc() < 0) {
+						while (CURRENT_VALID)
+							end_request(0);
+						break;
+					}
+				}
+				azt_state = AZT_S_START;
+				AztTries = 5;
+				SET_TIMER(azt_poll, HZ / 100);
+			}
+			break;
+		}
+	}
+	azt_transfer_is_active = 0;
 #ifdef AZT_TEST2
-  printk("azt_next_bn:%x  azt_buf_in:%x azt_buf_out:%x  azt_buf_bn:%x\n", \
-	  azt_next_bn, azt_buf_in, azt_buf_out, azt_buf_bn[azt_buf_in]);
-  printk(" do_aztcd_request ends  Time:%li\n",jiffies);
+	printk
+	    ("azt_next_bn:%x  azt_buf_in:%x azt_buf_out:%x  azt_buf_bn:%x\n",
+	     azt_next_bn, azt_buf_in, azt_buf_out, azt_buf_bn[azt_buf_in]);
+	printk(" do_aztcd_request ends  Time:%li\n", jiffies);
 #endif
 }
 
 
 static void azt_invalidate_buffers(void)
-{ int i;
+{
+	int i;
 
 #ifdef AZT_DEBUG
-  printk("aztcd: executing azt_invalidate_buffers\n");
+	printk("aztcd: executing azt_invalidate_buffers\n");
 #endif
-  for (i = 0; i < AZT_BUF_SIZ; ++i)
-    azt_buf_bn[i] = -1;
-  azt_buf_out = -1;
+	for (i = 0; i < AZT_BUF_SIZ; ++i)
+		azt_buf_bn[i] = -1;
+	azt_buf_out = -1;
 }
 
 /*
  * Open the device special file.  Check that a disk is in.
  */
 int aztcd_open(struct inode *ip, struct file *fp)
-{       int st;
+{
+	int st;
 
 #ifdef AZT_DEBUG
 	printk("aztcd: starting aztcd_open\n");
 #endif
 
 	if (aztPresent == 0)
-		return -ENXIO;                  /* no hardware */
+		return -ENXIO;	/* no hardware */
 
-        MOD_INC_USE_COUNT;
+	MOD_INC_USE_COUNT;
+
+	if (!azt_open_count && azt_state == AZT_S_IDLE) {
+		azt_invalidate_buffers();
 
-	if (!azt_open_count && azt_state == AZT_S_IDLE) 
-	  { azt_invalidate_buffers();
+		st = getAztStatus();	/* check drive status */
+		if (st == -1)
+			goto err_out;	/* drive doesn't respond */
+
+		if (st & AST_DOOR_OPEN) {	/* close door, then get the status again. */
+			printk("aztcd: Door Open?\n");
+			aztCloseDoor();
+			st = getAztStatus();
+		}
+
+		if ((st & AST_NOT_READY) || (st & AST_DSK_CHG)) {	/*no disk in drive or changed */
+			printk
+			    ("aztcd: Disk Changed or No Disk in Drive?\n");
+			aztTocUpToDate = 0;
+		}
+		if (aztUpdateToc())
+			goto err_out;
 
-	    st = getAztStatus();                    /* check drive status */
-	    if (st == -1) goto err_out;              /* drive doesn't respond */
-
-            if (st & AST_DOOR_OPEN)
-               { /* close door, then get the status again. */
-	         printk("aztcd: Door Open?\n");
-                 aztCloseDoor();     
-                 st = getAztStatus();
-               }        
-
-	    if ((st & AST_NOT_READY) || (st & AST_DSK_CHG)) /*no disk in drive or changed*/
-	       { printk("aztcd: Disk Changed or No Disk in Drive?\n");
-                 aztTocUpToDate=0;
-               }
-            if (aztUpdateToc())	goto err_out;
-	       
-	  }
+	}
 	++azt_open_count;
 	aztLockDoor();
 
@@ -1577,7 +1690,7 @@
 #endif
 	return 0;
 
-err_out:
+      err_out:
 	MOD_DEC_USE_COUNT;
 	return -EIO;
 }
@@ -1586,29 +1699,22 @@
 /*
  * On close, we flush all azt blocks from the buffer cache.
  */
-#ifdef AZT_KERNEL_PRIOR_2_1
-static void aztcd_release(struct inode * inode, struct file * file)
-#else
-static int  aztcd_release(struct inode * inode, struct file * file)
-#endif
-{ 
+static int aztcd_release(struct inode *inode, struct file *file)
+{
 #ifdef AZT_DEBUG
-  printk("aztcd: executing aztcd_release\n");
-  printk("inode: %p, inode->i_rdev: %x    file: %p\n",inode,inode->i_rdev,file);
-#endif
-  MOD_DEC_USE_COUNT;
-  if (!--azt_open_count) {
-	azt_invalidate_buffers();
-	aztUnlockDoor();
-        if (azt_auto_eject)
-           aztSendCmd(ACMD_EJECT);
-        CLEAR_TIMER;
-  }
-#ifdef AZT_KERNEL_PRIOR_2_1
-  return;
-#else
-  return 0;
+	printk("aztcd: executing aztcd_release\n");
+	printk("inode: %p, inode->i_rdev: %x    file: %p\n", inode,
+	       inode->i_rdev, file);
 #endif
+	MOD_DEC_USE_COUNT;
+	if (!--azt_open_count) {
+		azt_invalidate_buffers();
+		aztUnlockDoor();
+		if (azt_auto_eject)
+			aztSendCmd(ACMD_EJECT);
+		CLEAR_TIMER;
+	}
+	return 0;
 }
 
 
@@ -1618,222 +1724,244 @@
  */
 
 int __init aztcd_init(void)
-{       long int count, max_count;
+{
+	long int count, max_count;
 	unsigned char result[50];
 	int st;
 	int i = 0;
 
-	if (azt_port == 0) 
-	{ printk("aztcd: no Aztech CD-ROM Initialization");
-          return -EIO;
+	if (azt_port == 0) {
+		printk("aztcd: no Aztech CD-ROM Initialization");
+		return -EIO;
 	}
 
-	printk("aztcd: AZTECH, ORCHID, OKANO, WEARNES, TXC, CyDROM CD-ROM Driver\n"); 
+	printk
+	    ("aztcd: AZTECH, ORCHID, OKANO, WEARNES, TXC, CyDROM CD-ROM Driver\n");
 	printk("aztcd: (C) 1994-98 W.Zimmermann\n");
-	if (azt_port == -1) 
-	{ printk("aztcd: KernelVersion=%s DriverVersion=%s For IDE/ATAPI-drives use ide-cd.c\n",UTS_RELEASE,AZT_VERSION);
+	if (azt_port == -1) {
+		printk
+		    ("aztcd: KernelVersion=%s DriverVersion=%s For IDE/ATAPI-drives use ide-cd.c\n",
+		     UTS_RELEASE, AZT_VERSION);
+	} else
+		printk
+		    ("aztcd: DriverVersion=%s BaseAddress=0x%x  For IDE/ATAPI-drives use ide-cd.c\n",
+		     AZT_VERSION, azt_port);
+	printk
+	    ("aztcd: If you have problems, read /usr/src/linux/Documentation/cdrom/aztcd\n");
+
+
+#ifdef AZT_SW32			/*CDROM connected to Soundwave32 card */
+	if ((0xFF00 & inw(AZT_SW32_ID_REG)) != 0x4500) {
+		printk
+		    ("aztcd: no Soundwave32 card detected at base:%x init:%x config:%x id:%x\n",
+		     AZT_SW32_BASE_ADDR, AZT_SW32_INIT,
+		     AZT_SW32_CONFIG_REG, AZT_SW32_ID_REG);
+		return -EIO;
+	} else {
+		printk(KERN_INFO
+		       "aztcd: Soundwave32 card detected at %x  Version %x\n",
+		       AZT_SW32_BASE_ADDR, inw(AZT_SW32_ID_REG));
+		outw(AZT_SW32_INIT, AZT_SW32_CONFIG_REG);
+		for (count = 0; count < 10000; count++);	/*delay a bit */
 	}
-        else
-	  printk("aztcd: DriverVersion=%s BaseAddress=0x%x  For IDE/ATAPI-drives use ide-cd.c\n",AZT_VERSION,azt_port);
-	printk("aztcd: If you have problems, read /usr/src/linux/Documentation/cdrom/aztcd\n");
-
- 
-#ifdef AZT_SW32   /*CDROM connected to Soundwave32 card*/
-        if ((0xFF00 & inw(AZT_SW32_ID_REG)) != 0x4500)
-           { printk("aztcd: no Soundwave32 card detected at base:%x init:%x config:%x id:%x\n",
-		 AZT_SW32_BASE_ADDR,AZT_SW32_INIT,AZT_SW32_CONFIG_REG,AZT_SW32_ID_REG);
-                 return -EIO;
-	   }
-        else                
-           { printk(KERN_INFO "aztcd: Soundwave32 card detected at %x  Version %x\n",
-	 	 AZT_SW32_BASE_ADDR, inw(AZT_SW32_ID_REG));
-	     outw(AZT_SW32_INIT,AZT_SW32_CONFIG_REG);
-	     for (count=0;count<10000;count++);          /*delay a bit*/    	 
-           }
-#endif	
+#endif
 
 	/* check for presence of drive */
 
-        if (azt_port == -1) 			/* autoprobing */
-        { for (i=0;(azt_port_auto[i]!=0)&&(i<16);i++)
-          { azt_port = azt_port_auto[i];
-            printk("aztcd: Autoprobing BaseAddress=0x%x \n",azt_port);
-            st = check_region(azt_port, 4);  /*proprietary interfaces need 4 bytes*/
-  	    if (st) continue;
-
-	    outb(POLLED,MODE_PORT);              
-	    inb(CMD_PORT);
-	    inb(CMD_PORT);
-	    outb(ACMD_GET_VERSION,CMD_PORT); /*Try to get version info*/
-
-            aztTimeOutCount=0;   
-  	    do { aztIndatum=inb(STATUS_PORT);
-	         aztTimeOutCount++; 
-	         if (aztTimeOutCount>=AZT_FAST_TIMEOUT) break; 
-	       } while (aztIndatum&AFL_STATUS); 
-	    if (inb(DATA_PORT)==AFL_OP_OK) 
-	      break;
-          }
-          if ((azt_port_auto[i]==0)||(i==16))  
-          { printk("aztcd: no AZTECH CD-ROM drive found\n");
-            return -EIO;
-          }
-        } 
-        else					/* no autoprobing */
-        { if ((azt_port==0x1f0)||(azt_port==0x170))  
-            st = check_region(azt_port, 8);  /*IDE-interfaces need 8 bytes*/
-          else
-            st = check_region(azt_port, 4);  /*proprietary interfaces need 4 bytes*/
-	  if (st) 
-	  { printk("aztcd: conflict, I/O port (%X) already used\n",azt_port);
-            return -EIO;
-	  }
-	
-          if ((azt_port==0x1f0)||(azt_port==0x170))  
-            SWITCH_IDE_SLAVE;  /*switch IDE interface to slave configuration*/
-        
-          outb(POLLED,MODE_PORT);              
-	  inb(CMD_PORT);
-	  inb(CMD_PORT);
-	  outb(ACMD_GET_VERSION,CMD_PORT); /*Try to get version info*/
-
-          aztTimeOutCount=0;   
-	  do { aztIndatum=inb(STATUS_PORT);
-	       aztTimeOutCount++; 
-	       if (aztTimeOutCount>=AZT_FAST_TIMEOUT) break; 
-	     } while (aztIndatum&AFL_STATUS); 
+	if (azt_port == -1) {	/* autoprobing */
+		for (i = 0; (azt_port_auto[i] != 0) && (i < 16); i++) {
+			azt_port = azt_port_auto[i];
+			printk("aztcd: Autoprobing BaseAddress=0x%x \n",
+			       azt_port);
+			st = check_region(azt_port, 4);	/*proprietary interfaces need 4 bytes */
+			if (st)
+				continue;
+
+			outb(POLLED, MODE_PORT);
+			inb(CMD_PORT);
+			inb(CMD_PORT);
+			outb(ACMD_GET_VERSION, CMD_PORT);	/*Try to get version info */
+
+			aztTimeOutCount = 0;
+			do {
+				aztIndatum = inb(STATUS_PORT);
+				aztTimeOutCount++;
+				if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
+					break;
+			} while (aztIndatum & AFL_STATUS);
+			if (inb(DATA_PORT) == AFL_OP_OK)
+				break;
+		}
+		if ((azt_port_auto[i] == 0) || (i == 16)) {
+			printk("aztcd: no AZTECH CD-ROM drive found\n");
+			return -EIO;
+		}
+	} else {		/* no autoprobing */
+		if ((azt_port == 0x1f0) || (azt_port == 0x170))
+			st = check_region(azt_port, 8);	/*IDE-interfaces need 8 bytes */
+		else
+			st = check_region(azt_port, 4);	/*proprietary interfaces need 4 bytes */
+		if (st) {
+			printk
+			    ("aztcd: conflict, I/O port (%X) already used\n",
+			     azt_port);
+			return -EIO;
+		}
 
-  	  if (inb(DATA_PORT)!=AFL_OP_OK) /*OP_OK? If not, reset and try again*/
-             { 
+		if ((azt_port == 0x1f0) || (azt_port == 0x170))
+			SWITCH_IDE_SLAVE;	/*switch IDE interface to slave configuration */
+
+		outb(POLLED, MODE_PORT);
+		inb(CMD_PORT);
+		inb(CMD_PORT);
+		outb(ACMD_GET_VERSION, CMD_PORT);	/*Try to get version info */
+
+		aztTimeOutCount = 0;
+		do {
+			aztIndatum = inb(STATUS_PORT);
+			aztTimeOutCount++;
+			if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
+				break;
+		} while (aztIndatum & AFL_STATUS);
+
+		if (inb(DATA_PORT) != AFL_OP_OK) {	/*OP_OK? If not, reset and try again */
 #ifndef MODULE
-               if (azt_cont!=0x79)   
-	          { printk("aztcd: no AZTECH CD-ROM drive found-Try boot parameter aztcd=<BaseAddress>,0x79\n");
-	            return -EIO;
-                  }
-#else        
-               if (0)
-                  {
-                  }
-#endif	     
-               else   
-       	          { printk("aztcd: drive reset - please wait\n");
-	            for (count=0;count<50;count++)
-	              { inb(STATUS_PORT);    /*removing all data from earlier tries*/
-	                inb(DATA_PORT);
-	              }
-	            outb(POLLED,MODE_PORT);          
-	            inb(CMD_PORT);
-	            inb(CMD_PORT);
-		    getAztStatus(); 		    /*trap errors*/
-	            outb(ACMD_SOFT_RESET,CMD_PORT); /*send reset*/
-	            STEN_LOW;
-	            if (inb(DATA_PORT)!=AFL_OP_OK)    /*OP_OK?*/
-	               { printk("aztcd: no AZTECH CD-ROM drive found\n");
-                         return -EIO;
-	               } 
-	            
-	            for (count = 0; count < AZT_TIMEOUT; count++)
-	            	barrier();	/* Stop gcc 2.96 being smart */
-	            
-	            if ((st=getAztStatus())==-1)
-	               { printk("aztcd: Drive Status Error Status=%x\n",st);
-                         return -EIO;
-	               }
-#ifdef AZT_DEBUG
-	            printk("aztcd: Status = %x\n",st);
-#endif
-	            outb(POLLED,MODE_PORT);            
-	            inb(CMD_PORT);
-	            inb(CMD_PORT);
-	            outb(ACMD_GET_VERSION,CMD_PORT); /*GetVersion*/
-	            STEN_LOW;
-	            OP_OK;
-	          } 
-             }
+			if (azt_cont != 0x79) {
+				printk
+				    ("aztcd: no AZTECH CD-ROM drive found-Try boot parameter aztcd=<BaseAddress>,0x79\n");
+				return -EIO;
+			}
+#else
+			if (0) {
+			}
+#endif
+			else {
+				printk
+				    ("aztcd: drive reset - please wait\n");
+				for (count = 0; count < 50; count++) {
+					inb(STATUS_PORT);	/*removing all data from earlier tries */
+					inb(DATA_PORT);
+				}
+				outb(POLLED, MODE_PORT);
+				inb(CMD_PORT);
+				inb(CMD_PORT);
+				getAztStatus();	/*trap errors */
+				outb(ACMD_SOFT_RESET, CMD_PORT);	/*send reset */
+				STEN_LOW;
+				if (inb(DATA_PORT) != AFL_OP_OK) {	/*OP_OK? */
+					printk
+					    ("aztcd: no AZTECH CD-ROM drive found\n");
+					return -EIO;
+				}
+
+				for (count = 0; count < AZT_TIMEOUT;
+				     count++)
+					barrier();	/* Stop gcc 2.96 being smart */
+
+				if ((st = getAztStatus()) == -1) {
+					printk
+					    ("aztcd: Drive Status Error Status=%x\n",
+					     st);
+					return -EIO;
+				}
+#ifdef AZT_DEBUG
+				printk("aztcd: Status = %x\n", st);
+#endif
+				outb(POLLED, MODE_PORT);
+				inb(CMD_PORT);
+				inb(CMD_PORT);
+				outb(ACMD_GET_VERSION, CMD_PORT);	/*GetVersion */
+				STEN_LOW;
+				OP_OK;
+			}
+		}
 	}
-	
-	azt_init_end=1;
+
+	azt_init_end = 1;
 	STEN_LOW;
-	result[0]=inb(DATA_PORT);        /*reading in a null byte???*/
-	for (count=1;count<50;count++)   /*Reading version string*/
-	 { aztTimeOutCount=0;            /*here we must implement STEN_LOW differently*/
-	   do { aztIndatum=inb(STATUS_PORT);/*because we want to exit by timeout*/
-		aztTimeOutCount++; 
-		if (aztTimeOutCount>=AZT_FAST_TIMEOUT) break; 
-	      } while (aztIndatum&AFL_STATUS); 
-	   if (aztTimeOutCount>=AZT_FAST_TIMEOUT) break;  /*all chars read?*/
-	   result[count]=inb(DATA_PORT);
-	 }
-	if (count>30) max_count=30;  /*print max.30 chars of the version string*/
-	else          max_count=count;
+	result[0] = inb(DATA_PORT);	/*reading in a null byte??? */
+	for (count = 1; count < 50; count++) {	/*Reading version string */
+		aztTimeOutCount = 0;	/*here we must implement STEN_LOW differently */
+		do {
+			aztIndatum = inb(STATUS_PORT);	/*because we want to exit by timeout */
+			aztTimeOutCount++;
+			if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
+				break;
+		} while (aztIndatum & AFL_STATUS);
+		if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
+			break;	/*all chars read? */
+		result[count] = inb(DATA_PORT);
+	}
+	if (count > 30)
+		max_count = 30;	/*print max.30 chars of the version string */
+	else
+		max_count = count;
 	printk(KERN_INFO "aztcd: FirmwareVersion=");
-	for (count=1;count<max_count;count++) printk("%c",result[count]);
+	for (count = 1; count < max_count; count++)
+		printk("%c", result[count]);
 	printk("<<>> ");
 
-	if ((result[1]=='A')&&(result[2]=='Z')&&(result[3]=='T'))
-	 { printk("AZTECH drive detected\n"); /*AZTECH*/    
-	 }
-	else if ((result[2]=='C')&&(result[3]=='D')&&(result[4]=='D'))
-	 { printk("ORCHID or WEARNES drive detected\n"); /*ORCHID or WEARNES*/
-	 }
-	else if ((result[1]==0x03)&&(result[2]=='5'))
-	 { printk("TXC or CyCDROM drive detected\n"); /*Conrad TXC, CyCDROM*/
-	 }
-	else                                             /*OTHERS or none*/
-	 { printk("\nunknown drive or firmware version detected\n");
-	   printk("aztcd may not run stable, if you want to try anyhow,\n");
-	   printk("boot with: aztcd=<BaseAddress>,0x79\n");
-	   if ((azt_cont!=0x79))     
-	     { printk("aztcd: FirmwareVersion=");
-	       for (count=1;count<5;count++) printk("%c",result[count]);
-	       printk("<<>> ");
-	       printk("Aborted\n");
-               return -EIO;
-	     }
-	 }
-	devfs_register (NULL, "aztcd", DEVFS_FL_DEFAULT, MAJOR_NR, 0,
-			S_IFBLK | S_IRUGO | S_IWUGO, &azt_fops, NULL);
-	if (devfs_register_blkdev(MAJOR_NR, "aztcd", &azt_fops) != 0)
-	{
+	if ((result[1] == 'A') && (result[2] == 'Z') && (result[3] == 'T')) {
+		printk("AZTECH drive detected\n");
+	/*AZTECH*/}
+		else if ((result[2] == 'C') && (result[3] == 'D')
+			 && (result[4] == 'D')) {
+		printk("ORCHID or WEARNES drive detected\n");	/*ORCHID or WEARNES */
+	} else if ((result[1] == 0x03) && (result[2] == '5')) {
+		printk("TXC or CyCDROM drive detected\n");	/*Conrad TXC, CyCDROM */
+	} else {		/*OTHERS or none */
+		printk("\nunknown drive or firmware version detected\n");
+		printk
+		    ("aztcd may not run stable, if you want to try anyhow,\n");
+		printk("boot with: aztcd=<BaseAddress>,0x79\n");
+		if ((azt_cont != 0x79)) {
+			printk("aztcd: FirmwareVersion=");
+			for (count = 1; count < 5; count++)
+				printk("%c", result[count]);
+			printk("<<>> ");
+			printk("Aborted\n");
+			return -EIO;
+		}
+	}
+	devfs_register(NULL, "aztcd", DEVFS_FL_DEFAULT, MAJOR_NR, 0,
+		       S_IFBLK | S_IRUGO | S_IWUGO, &azt_fops, NULL);
+	if (devfs_register_blkdev(MAJOR_NR, "aztcd", &azt_fops) != 0) {
 		printk("aztcd: Unable to get major %d for Aztech CD-ROM\n",
 		       MAJOR_NR);
-                return -EIO;
+		return -EIO;
 	}
 	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
-#ifndef AZT_KERNEL_PRIOR_2_1
 	blksize_size[MAJOR_NR] = aztcd_blocksizes;
-#endif
 	read_ahead[MAJOR_NR] = 4;
-	register_disk(NULL, MKDEV(MAJOR_NR,0), 1, &azt_fops, 0);
+	register_disk(NULL, MKDEV(MAJOR_NR, 0), 1, &azt_fops, 0);
+
+	if ((azt_port == 0x1f0) || (azt_port == 0x170))
+		request_region(azt_port, 8, "aztcd");	/*IDE-interface */
+	else
+		request_region(azt_port, 4, "aztcd");	/*proprietary interface */
 
-        if ((azt_port==0x1f0)||(azt_port==0x170))  
-	   request_region(azt_port, 8, "aztcd");  /*IDE-interface*/
-        else
-	   request_region(azt_port, 4, "aztcd");  /*proprietary interface*/
-        
 	azt_invalidate_buffers();
 	aztPresent = 1;
 	aztCloseDoor();
-        return (0);
+	return (0);
 }
 
 void __exit aztcd_exit(void)
 {
-  devfs_unregister(devfs_find_handle(NULL, "aztcd", 0, 0, DEVFS_SPECIAL_BLK,
-				     0));
-  if ((devfs_unregister_blkdev(MAJOR_NR, "aztcd") == -EINVAL))    
-    { printk("What's that: can't unregister aztcd\n");
-      return;
-    }
-  blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
-  if ((azt_port==0x1f0)||(azt_port==0x170))  
-    { SWITCH_IDE_MASTER;
-      release_region(azt_port,8);  /*IDE-interface*/
-    }
-  else
-      release_region(azt_port,4);  /*proprietary interface*/
-  printk(KERN_INFO "aztcd module released.\n");
-}   
+	devfs_unregister(devfs_find_handle
+			 (NULL, "aztcd", 0, 0, DEVFS_SPECIAL_BLK, 0));
+	if ((devfs_unregister_blkdev(MAJOR_NR, "aztcd") == -EINVAL)) {
+		printk("What's that: can't unregister aztcd\n");
+		return;
+	}
+	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
+	if ((azt_port == 0x1f0) || (azt_port == 0x170)) {
+		SWITCH_IDE_MASTER;
+		release_region(azt_port, 8);	/*IDE-interface */
+	} else
+		release_region(azt_port, 4);	/*proprietary interface */
+	printk(KERN_INFO "aztcd module released.\n");
+}
 
 #ifdef MODULE
 module_init(aztcd_init);
@@ -1846,405 +1974,485 @@
 */
 static void azt_poll(void)
 {
-    int st = 0;
-    int loop_ctl = 1;
-    int skip = 0;
-
-    if (azt_error) {                            
-	if (aztSendCmd(ACMD_GET_ERROR)) RETURN("azt_poll 1");
-	STEN_LOW;
-	azt_error=inb(DATA_PORT)&0xFF;
-	printk("aztcd: I/O error 0x%02x\n", azt_error);
-	azt_invalidate_buffers();
+	int st = 0;
+	int loop_ctl = 1;
+	int skip = 0;
+
+	if (azt_error) {
+		if (aztSendCmd(ACMD_GET_ERROR))
+			RETURN("azt_poll 1");
+		STEN_LOW;
+		azt_error = inb(DATA_PORT) & 0xFF;
+		printk("aztcd: I/O error 0x%02x\n", azt_error);
+		azt_invalidate_buffers();
 #ifdef WARN_IF_READ_FAILURE
-	if (AztTries == 5)
-	  printk("aztcd: Read of Block %d Failed - Maybe Audio Disk?\n", azt_next_bn);
-#endif
-	if (!AztTries--) {
-	  printk("aztcd: Read of Block %d Failed, Maybe Audio Disk? Giving up\n", azt_next_bn);
-	  if (azt_transfer_is_active) {
-	    AztTries = 0;
-	    loop_ctl = 0;
-	  }
-	  if (CURRENT_VALID)
-	    end_request(0);
-	  AztTries = 5;
-	}
-    azt_error = 0;
-    azt_state = AZT_S_STOP;
-    }
-
-    while (loop_ctl)
-    {
-      loop_ctl = 0;   /* each case must flip this back to 1 if we want
-			 to come back up here */
-      switch (azt_state) {
+		if (AztTries == 5)
+			printk
+			    ("aztcd: Read of Block %d Failed - Maybe Audio Disk?\n",
+			     azt_next_bn);
+#endif
+		if (!AztTries--) {
+			printk
+			    ("aztcd: Read of Block %d Failed, Maybe Audio Disk? Giving up\n",
+			     azt_next_bn);
+			if (azt_transfer_is_active) {
+				AztTries = 0;
+				loop_ctl = 0;
+			}
+			if (CURRENT_VALID)
+				end_request(0);
+			AztTries = 5;
+		}
+		azt_error = 0;
+		azt_state = AZT_S_STOP;
+	}
+
+	while (loop_ctl) {
+		loop_ctl = 0;	/* each case must flip this back to 1 if we want
+				   to come back up here */
+		switch (azt_state) {
 
-	case AZT_S_IDLE:
+		case AZT_S_IDLE:
 #ifdef AZT_TEST3
-	  if (azt_state!=azt_state_old) {
-	    azt_state_old=azt_state;
-	    printk("AZT_S_IDLE\n");
-	    }
+			if (azt_state != azt_state_old) {
+				azt_state_old = azt_state;
+				printk("AZT_S_IDLE\n");
+			}
 #endif
-	  return;
+			return;
 
-	case AZT_S_START:
+		case AZT_S_START:
 #ifdef AZT_TEST3
-	  if (azt_state!=azt_state_old) {
-	    azt_state_old=azt_state;
-	    printk("AZT_S_START\n");
-	  }
-#endif
-	  if(aztSendCmd(ACMD_GET_STATUS)) RETURN("azt_poll 2");  /*result will be checked by aztStatus() */
-	  azt_state = azt_mode == 1 ? AZT_S_READ : AZT_S_MODE;
-	  AztTimeout = 3000;
-	  break;
+			if (azt_state != azt_state_old) {
+				azt_state_old = azt_state;
+				printk("AZT_S_START\n");
+			}
+#endif
+			if (aztSendCmd(ACMD_GET_STATUS))
+				RETURN("azt_poll 2");	/*result will be checked by aztStatus() */
+			azt_state =
+			    azt_mode == 1 ? AZT_S_READ : AZT_S_MODE;
+			AztTimeout = 3000;
+			break;
 
-	case AZT_S_MODE:
+		case AZT_S_MODE:
 #ifdef AZT_TEST3
-	  if (azt_state!=azt_state_old) {
-	    azt_state_old=azt_state;
-	    printk("AZT_S_MODE\n");
-	  }
-#endif
-	  if (!skip) {
-	    if ((st = aztStatus()) != -1) {
-	      if ((st & AST_DSK_CHG)||(st & AST_NOT_READY)) {
-		aztDiskChanged = 1;
-		aztTocUpToDate = 0;
-		azt_invalidate_buffers();
-		end_request(0);
-		printk("aztcd: Disk Changed or Not Ready 1 - Unmount Disk!\n");
-	      }
-	    } else break;
-	  }
-	  skip = 0;
-
-	  if ((st & AST_DOOR_OPEN)||(st & AST_NOT_READY)) {
-	    aztDiskChanged = 1;
-	    aztTocUpToDate = 0;
-            printk("aztcd: Disk Changed or Not Ready 2 - Unmount Disk!\n");
-            end_request(0);
-	    printk((st & AST_DOOR_OPEN) ? "aztcd: door open\n" : "aztcd: disk removed\n");
-	    if (azt_transfer_is_active) {
-	      azt_state = AZT_S_START;
-	      loop_ctl = 1;   /* goto immediately */
-	      break;
-	    }
-	    azt_state = AZT_S_IDLE;
-	    while (CURRENT_VALID)
-	      end_request(0);
-	    return;
-	  }
-				
+			if (azt_state != azt_state_old) {
+				azt_state_old = azt_state;
+				printk("AZT_S_MODE\n");
+			}
+#endif
+			if (!skip) {
+				if ((st = aztStatus()) != -1) {
+					if ((st & AST_DSK_CHG)
+					    || (st & AST_NOT_READY)) {
+						aztDiskChanged = 1;
+						aztTocUpToDate = 0;
+						azt_invalidate_buffers();
+						end_request(0);
+						printk
+						    ("aztcd: Disk Changed or Not Ready 1 - Unmount Disk!\n");
+					}
+				} else
+					break;
+			}
+			skip = 0;
+
+			if ((st & AST_DOOR_OPEN) || (st & AST_NOT_READY)) {
+				aztDiskChanged = 1;
+				aztTocUpToDate = 0;
+				printk
+				    ("aztcd: Disk Changed or Not Ready 2 - Unmount Disk!\n");
+				end_request(0);
+				printk((st & AST_DOOR_OPEN) ?
+				       "aztcd: door open\n" :
+				       "aztcd: disk removed\n");
+				if (azt_transfer_is_active) {
+					azt_state = AZT_S_START;
+					loop_ctl = 1;	/* goto immediately */
+					break;
+				}
+				azt_state = AZT_S_IDLE;
+				while (CURRENT_VALID)
+					end_request(0);
+				return;
+			}
+
 /*	  if (aztSendCmd(ACMD_SET_MODE)) RETURN("azt_poll 3");
 	  outb(0x01, DATA_PORT);          
 	  PA_OK;
 	  STEN_LOW;
-*/        if (aztSendCmd(ACMD_GET_STATUS)) RETURN("azt_poll 4");
-	  STEN_LOW;
-	  azt_mode = 1;
-	  azt_state = AZT_S_READ;
-	  AztTimeout = 3000;
+*/
+			if (aztSendCmd(ACMD_GET_STATUS))
+				RETURN("azt_poll 4");
+			STEN_LOW;
+			azt_mode = 1;
+			azt_state = AZT_S_READ;
+			AztTimeout = 3000;
 
-	  break;
+			break;
 
 
-	case AZT_S_READ:
+		case AZT_S_READ:
 #ifdef AZT_TEST3
-	  if (azt_state!=azt_state_old)  {
-	    azt_state_old=azt_state;
-	    printk("AZT_S_READ\n");
-	  }
-#endif
-	  if (!skip) {
-	      if ((st = aztStatus()) != -1) {
-		if ((st & AST_DSK_CHG)||(st & AST_NOT_READY)) {
-		aztDiskChanged = 1;
-		aztTocUpToDate = 0;
-		azt_invalidate_buffers();
-		printk("aztcd: Disk Changed or Not Ready 3 - Unmount Disk!\n");
-                end_request(0);               
-		}
-	      } else break;
-	  } 
-	    
-	  skip = 0;
-	  if ((st & AST_DOOR_OPEN)||(st & AST_NOT_READY)) {
-	    aztDiskChanged = 1;
-	    aztTocUpToDate = 0;
-	    printk((st & AST_DOOR_OPEN) ? "aztcd: door open\n" : "aztcd: disk removed\n");
-	    if (azt_transfer_is_active) {
-	      azt_state = AZT_S_START;
-	      loop_ctl = 1;
-	      break;
-	    }
-	    azt_state = AZT_S_IDLE;
-	    while (CURRENT_VALID)
-	    end_request(0);
-	    return;
-	  }
-
-	  if (CURRENT_VALID) {
-	    struct azt_Play_msf msf;
-	    int i;
-	    azt_next_bn = CURRENT -> sector / 4;
-	    azt_hsg2msf(azt_next_bn, &msf.start);
-	    i = 0;
-	    /* find out in which track we are */
-	    while (azt_msf2hsg(&msf.start)>azt_msf2hsg(&Toc[++i].trackTime)) {};
-	    if (azt_msf2hsg(&msf.start)<azt_msf2hsg(&Toc[i].trackTime)-AZT_BUF_SIZ)
-               { azt_read_count=AZT_BUF_SIZ;  /*fast, because we read ahead*/
-               /*azt_read_count=CURRENT->nr_sectors;    slow, no read ahead*/
-               }
-	    else /* don't read beyond end of track */           
-#if AZT_MULTISESSION 
-               { azt_read_count=(azt_msf2hsg(&Toc[i].trackTime)/4)*4-azt_msf2hsg(&msf.start);  
-                 if (azt_read_count < 0) azt_read_count=0;
-		 if (azt_read_count > AZT_BUF_SIZ) azt_read_count=AZT_BUF_SIZ;
-                 printk("aztcd: warning - trying to read beyond end of track\n");
+			if (azt_state != azt_state_old) {
+				azt_state_old = azt_state;
+				printk("AZT_S_READ\n");
+			}
+#endif
+			if (!skip) {
+				if ((st = aztStatus()) != -1) {
+					if ((st & AST_DSK_CHG)
+					    || (st & AST_NOT_READY)) {
+						aztDiskChanged = 1;
+						aztTocUpToDate = 0;
+						azt_invalidate_buffers();
+						printk
+						    ("aztcd: Disk Changed or Not Ready 3 - Unmount Disk!\n");
+						end_request(0);
+					}
+				} else
+					break;
+			}
+
+			skip = 0;
+			if ((st & AST_DOOR_OPEN) || (st & AST_NOT_READY)) {
+				aztDiskChanged = 1;
+				aztTocUpToDate = 0;
+				printk((st & AST_DOOR_OPEN) ?
+				       "aztcd: door open\n" :
+				       "aztcd: disk removed\n");
+				if (azt_transfer_is_active) {
+					azt_state = AZT_S_START;
+					loop_ctl = 1;
+					break;
+				}
+				azt_state = AZT_S_IDLE;
+				while (CURRENT_VALID)
+					end_request(0);
+				return;
+			}
+
+			if (CURRENT_VALID) {
+				struct azt_Play_msf msf;
+				int i;
+				azt_next_bn = CURRENT->sector / 4;
+				azt_hsg2msf(azt_next_bn, &msf.start);
+				i = 0;
+				/* find out in which track we are */
+				while (azt_msf2hsg(&msf.start) >
+				       azt_msf2hsg(&Toc[++i].trackTime)) {
+				};
+				if (azt_msf2hsg(&msf.start) <
+				    azt_msf2hsg(&Toc[i].trackTime) -
+				    AZT_BUF_SIZ) {
+					azt_read_count = AZT_BUF_SIZ;	/*fast, because we read ahead */
+					/*azt_read_count=CURRENT->nr_sectors;    slow, no read ahead */
+				} else	/* don't read beyond end of track */
+#if AZT_MULTISESSION
+				{
+					azt_read_count =
+					    (azt_msf2hsg(&Toc[i].trackTime)
+					     / 4) * 4 -
+					    azt_msf2hsg(&msf.start);
+					if (azt_read_count < 0)
+						azt_read_count = 0;
+					if (azt_read_count > AZT_BUF_SIZ)
+						azt_read_count =
+						    AZT_BUF_SIZ;
+					printk
+					    ("aztcd: warning - trying to read beyond end of track\n");
 /*               printk("%i %i %li %li\n",i,azt_read_count,azt_msf2hsg(&msf.start),azt_msf2hsg(&Toc[i].trackTime));
-*/             }
+*/ }
 #else
-	       { azt_read_count=AZT_BUF_SIZ;
-	       }
-#endif
-	    msf.end.min = 0;
-	    msf.end.sec = 0;            
-	    msf.end.frame = azt_read_count ;/*Mitsumi here reads 0xffffff sectors*/
+				{
+					azt_read_count = AZT_BUF_SIZ;
+				}
+#endif
+				msf.end.min = 0;
+				msf.end.sec = 0;
+				msf.end.frame = azt_read_count;	/*Mitsumi here reads 0xffffff sectors */
 #ifdef AZT_TEST3
-	    printk("---reading msf-address %x:%x:%x  %x:%x:%x\n",msf.start.min,msf.start.sec,msf.start.frame,msf.end.min,msf.end.sec,msf.end.frame);
-	    printk("azt_next_bn:%x  azt_buf_in:%x azt_buf_out:%x  azt_buf_bn:%x\n", \
-		    azt_next_bn, azt_buf_in, azt_buf_out, azt_buf_bn[azt_buf_in]);
-#endif 
-            if (azt_read_mode==AZT_MODE_2)
-               { sendAztCmd(ACMD_PLAY_READ_RAW, &msf); /*XA disks in raw mode*/
-               }
-            else
-               { sendAztCmd(ACMD_PLAY_READ, &msf);     /*others in cooked mode*/
-               }
-	    azt_state = AZT_S_DATA;
-	    AztTimeout = READ_TIMEOUT;
-	  } else {
-	    azt_state = AZT_S_STOP;
-	    loop_ctl = 1;
-	    break;
-	  }
+				printk
+				    ("---reading msf-address %x:%x:%x  %x:%x:%x\n",
+				     msf.start.min, msf.start.sec,
+				     msf.start.frame, msf.end.min,
+				     msf.end.sec, msf.end.frame);
+				printk
+				    ("azt_next_bn:%x  azt_buf_in:%x azt_buf_out:%x  azt_buf_bn:%x\n",
+				     azt_next_bn, azt_buf_in, azt_buf_out,
+				     azt_buf_bn[azt_buf_in]);
+#endif
+				if (azt_read_mode == AZT_MODE_2) {
+					sendAztCmd(ACMD_PLAY_READ_RAW, &msf);	/*XA disks in raw mode */
+				} else {
+					sendAztCmd(ACMD_PLAY_READ, &msf);	/*others in cooked mode */
+				}
+				azt_state = AZT_S_DATA;
+				AztTimeout = READ_TIMEOUT;
+			} else {
+				azt_state = AZT_S_STOP;
+				loop_ctl = 1;
+				break;
+			}
 
-	  break;
+			break;
 
 
-	case AZT_S_DATA:
+		case AZT_S_DATA:
 #ifdef AZT_TEST3
-	  if (azt_state!=azt_state_old)  {
-	    azt_state_old=azt_state;
-	    printk("AZT_S_DATA\n");
-	  }
+			if (azt_state != azt_state_old) {
+				azt_state_old = azt_state;
+				printk("AZT_S_DATA\n");
+			}
 #endif
 
-	  st = inb(STATUS_PORT) & AFL_STATUSorDATA; 
+			st = inb(STATUS_PORT) & AFL_STATUSorDATA;
 
-	  switch (st) {
+			switch (st) {
 
-	    case AFL_DATA:
+			case AFL_DATA:
 #ifdef AZT_TEST3
-	      if (st!=azt_st_old)  {
-		azt_st_old=st; 
-		printk("---AFL_DATA st:%x\n",st);
-	      }
-#endif
-	      if (!AztTries--) {
-		printk("aztcd: Read of Block %d Failed, Maybe Audio Disk ? Giving up\n", azt_next_bn);
-		if (azt_transfer_is_active) {
-		  AztTries = 0;
-		  break;
-		}
-		if (CURRENT_VALID)
-		  end_request(0);
-		AztTries = 5;
-	      }
-	      azt_state = AZT_S_START;
-	      AztTimeout = READ_TIMEOUT;
-	      loop_ctl = 1;
-	      break;
+				if (st != azt_st_old) {
+					azt_st_old = st;
+					printk("---AFL_DATA st:%x\n", st);
+				}
+#endif
+				if (!AztTries--) {
+					printk
+					    ("aztcd: Read of Block %d Failed, Maybe Audio Disk ? Giving up\n",
+					     azt_next_bn);
+					if (azt_transfer_is_active) {
+						AztTries = 0;
+						break;
+					}
+					if (CURRENT_VALID)
+						end_request(0);
+					AztTries = 5;
+				}
+				azt_state = AZT_S_START;
+				AztTimeout = READ_TIMEOUT;
+				loop_ctl = 1;
+				break;
 
-	    case AFL_STATUSorDATA:
+			case AFL_STATUSorDATA:
 #ifdef AZT_TEST3
-	      if (st!=azt_st_old)  {
-		azt_st_old=st;
-		printk("---AFL_STATUSorDATA st:%x\n",st);
-	      }
+				if (st != azt_st_old) {
+					azt_st_old = st;
+					printk
+					    ("---AFL_STATUSorDATA st:%x\n",
+					     st);
+				}
 #endif
-	      break;
+				break;
 
-	    default:
+			default:
 #ifdef AZT_TEST3
-	      if (st!=azt_st_old)  {
-		azt_st_old=st;
-		printk("---default: st:%x\n",st);
-	      }
-#endif
-	      AztTries = 5;
-	      if (!CURRENT_VALID && azt_buf_in == azt_buf_out) {
-		azt_state = AZT_S_STOP;
-		loop_ctl = 1;
-		break;
-	      }
-	      if (azt_read_count<=0)
-		printk("aztcd: warning - try to read 0 frames\n");
-	      while (azt_read_count)      /*??? fast read ahead loop*/
-	       { azt_buf_bn[azt_buf_in] = -1;
-		 DTEN_LOW;                      /*??? unsolved problem, very
-						      seldom we get timeouts
-						      here, don't now the real
-						      reason. With my drive this
-						      sometimes also happens with
-						      Aztech's original driver under
-						      DOS. Is it a hardware bug? 
-						      I tried to recover from such
-						      situations here. Zimmermann*/
-		 if (aztTimeOutCount>=AZT_TIMEOUT) 
-		  { printk("read_count:%d CURRENT->nr_sectors:%ld azt_buf_in:%d\n", azt_read_count,CURRENT->nr_sectors,azt_buf_in);
-		    printk("azt_transfer_is_active:%x\n",azt_transfer_is_active);
-		    azt_read_count=0;
-		    azt_state = AZT_S_STOP;
-		    loop_ctl = 1;
-		    end_request(1);  /*should we have here (1) or (0)? */
-		  }
-		 else
-		  { if (azt_read_mode==AZT_MODE_2)
-		       { insb(DATA_PORT, azt_buf + CD_FRAMESIZE_RAW * azt_buf_in, CD_FRAMESIZE_RAW);
-		       }
-		    else
-		       { insb(DATA_PORT, azt_buf + CD_FRAMESIZE * azt_buf_in, CD_FRAMESIZE);
-                       }
-		    azt_read_count--;
+				if (st != azt_st_old) {
+					azt_st_old = st;
+					printk("---default: st:%x\n", st);
+				}
+#endif
+				AztTries = 5;
+				if (!CURRENT_VALID
+				    && azt_buf_in == azt_buf_out) {
+					azt_state = AZT_S_STOP;
+					loop_ctl = 1;
+					break;
+				}
+				if (azt_read_count <= 0)
+					printk
+					    ("aztcd: warning - try to read 0 frames\n");
+				while (azt_read_count) {	/*??? fast read ahead loop */
+					azt_buf_bn[azt_buf_in] = -1;
+					DTEN_LOW;	/*??? unsolved problem, very
+							   seldom we get timeouts
+							   here, don't now the real
+							   reason. With my drive this
+							   sometimes also happens with
+							   Aztech's original driver under
+							   DOS. Is it a hardware bug? 
+							   I tried to recover from such
+							   situations here. Zimmermann */
+					if (aztTimeOutCount >= AZT_TIMEOUT) {
+						printk
+						    ("read_count:%d CURRENT->nr_sectors:%ld azt_buf_in:%d\n",
+						     azt_read_count,
+						     CURRENT->nr_sectors,
+						     azt_buf_in);
+						printk
+						    ("azt_transfer_is_active:%x\n",
+						     azt_transfer_is_active);
+						azt_read_count = 0;
+						azt_state = AZT_S_STOP;
+						loop_ctl = 1;
+						end_request(1);	/*should we have here (1) or (0)? */
+					} else {
+						if (azt_read_mode ==
+						    AZT_MODE_2) {
+							insb(DATA_PORT,
+							     azt_buf +
+							     CD_FRAMESIZE_RAW
+							     * azt_buf_in,
+							     CD_FRAMESIZE_RAW);
+						} else {
+							insb(DATA_PORT,
+							     azt_buf +
+							     CD_FRAMESIZE *
+							     azt_buf_in,
+							     CD_FRAMESIZE);
+						}
+						azt_read_count--;
 #ifdef AZT_TEST3
-		    printk("AZT_S_DATA; ---I've read data- read_count: %d\n",azt_read_count);
-		    printk("azt_next_bn:%d  azt_buf_in:%d azt_buf_out:%d  azt_buf_bn:%d\n", \
-			 azt_next_bn, azt_buf_in, azt_buf_out, azt_buf_bn[azt_buf_in]);
-#endif
-		    azt_buf_bn[azt_buf_in] = azt_next_bn++;
-		    if (azt_buf_out == -1)
-		      azt_buf_out = azt_buf_in;
-		    azt_buf_in = azt_buf_in + 1 == AZT_BUF_SIZ ? 0 : azt_buf_in + 1;
-		  }
-	       }
-	      if (!azt_transfer_is_active) {
-		while (CURRENT_VALID) {
-		  azt_transfer();
-		  if (CURRENT -> nr_sectors == 0)
-		    end_request(1);
-		  else
-		    break;
-		}
-	      }
-
-	      if (CURRENT_VALID
-		&& (CURRENT -> sector / 4 < azt_next_bn ||
-		CURRENT -> sector / 4 > azt_next_bn + AZT_BUF_SIZ)) {
-		azt_state = AZT_S_STOP;
-		loop_ctl = 1;
-		break;
-	      }
-	      AztTimeout = READ_TIMEOUT;   
-	      if (azt_read_count==0) {
-		azt_state = AZT_S_STOP; 
-		loop_ctl = 1;
-		break;           
-	      } 
-	      break;
-	    }
-    break;
+						printk
+						    ("AZT_S_DATA; ---I've read data- read_count: %d\n",
+						     azt_read_count);
+						printk
+						    ("azt_next_bn:%d  azt_buf_in:%d azt_buf_out:%d  azt_buf_bn:%d\n",
+						     azt_next_bn,
+						     azt_buf_in,
+						     azt_buf_out,
+						     azt_buf_bn
+						     [azt_buf_in]);
+#endif
+						azt_buf_bn[azt_buf_in] =
+						    azt_next_bn++;
+						if (azt_buf_out == -1)
+							azt_buf_out =
+							    azt_buf_in;
+						azt_buf_in =
+						    azt_buf_in + 1 ==
+						    AZT_BUF_SIZ ? 0 :
+						    azt_buf_in + 1;
+					}
+				}
+				if (!azt_transfer_is_active) {
+					while (CURRENT_VALID) {
+						azt_transfer();
+						if (CURRENT->nr_sectors ==
+						    0)
+							end_request(1);
+						else
+							break;
+					}
+				}
+
+				if (CURRENT_VALID
+				    && (CURRENT->sector / 4 < azt_next_bn
+					|| CURRENT->sector / 4 >
+					azt_next_bn + AZT_BUF_SIZ)) {
+					azt_state = AZT_S_STOP;
+					loop_ctl = 1;
+					break;
+				}
+				AztTimeout = READ_TIMEOUT;
+				if (azt_read_count == 0) {
+					azt_state = AZT_S_STOP;
+					loop_ctl = 1;
+					break;
+				}
+				break;
+			}
+			break;
 
 
-	case AZT_S_STOP:
+		case AZT_S_STOP:
 #ifdef AZT_TEST3
-	  if (azt_state!=azt_state_old) {
-	    azt_state_old=azt_state;
-	    printk("AZT_S_STOP\n");
-	  }
-#endif
-	  if (azt_read_count!=0) printk("aztcd: discard data=%x frames\n",azt_read_count);
-	  while (azt_read_count!=0) {
-	    int i;
-	    if ( !(inb(STATUS_PORT) & AFL_DATA) ) {
-	      if (azt_read_mode==AZT_MODE_2)
-	         for (i=0; i<CD_FRAMESIZE_RAW; i++) inb(DATA_PORT);
-	      else   
-	         for (i=0; i<CD_FRAMESIZE; i++) inb(DATA_PORT);
-	    }
-	    azt_read_count--;
-	  }  
-	  if (aztSendCmd(ACMD_GET_STATUS)) RETURN("azt_poll 5");
-	  azt_state = AZT_S_STOPPING;
-	  AztTimeout = 1000;
-	  break;
+			if (azt_state != azt_state_old) {
+				azt_state_old = azt_state;
+				printk("AZT_S_STOP\n");
+			}
+#endif
+			if (azt_read_count != 0)
+				printk("aztcd: discard data=%x frames\n",
+				       azt_read_count);
+			while (azt_read_count != 0) {
+				int i;
+				if (!(inb(STATUS_PORT) & AFL_DATA)) {
+					if (azt_read_mode == AZT_MODE_2)
+						for (i = 0;
+						     i < CD_FRAMESIZE_RAW;
+						     i++)
+							inb(DATA_PORT);
+					else
+						for (i = 0;
+						     i < CD_FRAMESIZE; i++)
+							inb(DATA_PORT);
+				}
+				azt_read_count--;
+			}
+			if (aztSendCmd(ACMD_GET_STATUS))
+				RETURN("azt_poll 5");
+			azt_state = AZT_S_STOPPING;
+			AztTimeout = 1000;
+			break;
 
-	case AZT_S_STOPPING:
+		case AZT_S_STOPPING:
 #ifdef AZT_TEST3
-	  if (azt_state!=azt_state_old) {
-	    azt_state_old=azt_state;
-	    printk("AZT_S_STOPPING\n");
-	  }
-#endif
-
-	  if ((st = aztStatus()) == -1 && AztTimeout)
-	    break;
-
-	  if ((st != -1) && ((st & AST_DSK_CHG)||(st & AST_NOT_READY))) {
-	    aztDiskChanged = 1;
-	    aztTocUpToDate = 0;
-	    azt_invalidate_buffers();
-	    printk("aztcd: Disk Changed or Not Ready 4 - Unmount Disk!\n");
-	    end_request(0);
-	  }
-
+			if (azt_state != azt_state_old) {
+				azt_state_old = azt_state;
+				printk("AZT_S_STOPPING\n");
+			}
+#endif
+
+			if ((st = aztStatus()) == -1 && AztTimeout)
+				break;
+
+			if ((st != -1)
+			    && ((st & AST_DSK_CHG)
+				|| (st & AST_NOT_READY))) {
+				aztDiskChanged = 1;
+				aztTocUpToDate = 0;
+				azt_invalidate_buffers();
+				printk
+				    ("aztcd: Disk Changed or Not Ready 4 - Unmount Disk!\n");
+				end_request(0);
+			}
 
 #ifdef AZT_TEST3
-	  printk("CURRENT_VALID %d azt_mode %d\n",
-	     CURRENT_VALID, azt_mode);
+			printk("CURRENT_VALID %d azt_mode %d\n",
+			       CURRENT_VALID, azt_mode);
 #endif
 
-	  if (CURRENT_VALID) {
-	    if (st != -1) {
-	      if (azt_mode == 1) {
-		azt_state = AZT_S_READ;
-		loop_ctl = 1;
-		skip = 1;
-		break;
-	      } else {
-		azt_state = AZT_S_MODE;
-		loop_ctl = 1;
-		skip = 1;
-		break;
-	      }
-	    } else {
-	      azt_state = AZT_S_START;
-	      AztTimeout = 1;
-	    }
-	  } else {
-	    azt_state = AZT_S_IDLE;
-	    return;
-	  }
-	  break;
+			if (CURRENT_VALID) {
+				if (st != -1) {
+					if (azt_mode == 1) {
+						azt_state = AZT_S_READ;
+						loop_ctl = 1;
+						skip = 1;
+						break;
+					} else {
+						azt_state = AZT_S_MODE;
+						loop_ctl = 1;
+						skip = 1;
+						break;
+					}
+				} else {
+					azt_state = AZT_S_START;
+					AztTimeout = 1;
+				}
+			} else {
+				azt_state = AZT_S_IDLE;
+				return;
+			}
+			break;
+
+		default:
+			printk("aztcd: invalid state %d\n", azt_state);
+			return;
+		}		/* case */
+	}			/* while */
 
-	default:
-	  printk("aztcd: invalid state %d\n", azt_state);
-	  return;
-      }  /* case */
-    } /* while */
-  
-
-   if (!AztTimeout--) 
-    { printk("aztcd: timeout in state %d\n", azt_state);
-      azt_state = AZT_S_STOP;
-      if (aztSendCmd(ACMD_STOP)) RETURN("azt_poll 6"); 
-      STEN_LOW_WAIT;     
-    };
 
-  SET_TIMER(azt_poll, HZ/100);
+	if (!AztTimeout--) {
+		printk("aztcd: timeout in state %d\n", azt_state);
+		azt_state = AZT_S_STOP;
+		if (aztSendCmd(ACMD_STOP))
+			RETURN("azt_poll 6");
+		STEN_LOW_WAIT;
+	};
+
+	SET_TIMER(azt_poll, HZ / 100);
 }
 
 
@@ -2253,28 +2461,34 @@
   ###########################################################################
 */
 static void azt_hsg2msf(long hsg, struct msf *msf)
-{       hsg += 150;
-	msf -> min = hsg / 4500;
+{
+	hsg += 150;
+	msf->min = hsg / 4500;
 	hsg %= 4500;
-	msf -> sec = hsg / 75;
-	msf -> frame = hsg % 75;
+	msf->sec = hsg / 75;
+	msf->frame = hsg % 75;
 #ifdef AZT_DEBUG
-	if (msf->min  >=70) printk("aztcd: Error hsg2msf address Minutes\n");
-	if (msf->sec  >=60) printk("aztcd: Error hsg2msf address Seconds\n");
-	if (msf->frame>=75) printk("aztcd: Error hsg2msf address Frames\n");
-#endif
-	azt_bin2bcd(&msf -> min);           /* convert to BCD */
-	azt_bin2bcd(&msf -> sec);
-	azt_bin2bcd(&msf -> frame);
+	if (msf->min >= 70)
+		printk("aztcd: Error hsg2msf address Minutes\n");
+	if (msf->sec >= 60)
+		printk("aztcd: Error hsg2msf address Seconds\n");
+	if (msf->frame >= 75)
+		printk("aztcd: Error hsg2msf address Frames\n");
+#endif
+	azt_bin2bcd(&msf->min);	/* convert to BCD */
+	azt_bin2bcd(&msf->sec);
+	azt_bin2bcd(&msf->frame);
 }
 
 static long azt_msf2hsg(struct msf *mp)
-{ return azt_bcd2bin(mp -> frame) + azt_bcd2bin(mp -> sec) * 75
-		                  + azt_bcd2bin(mp -> min) * 4500 - CD_MSF_OFFSET;
+{
+	return azt_bcd2bin(mp->frame) + azt_bcd2bin(mp->sec) * 75
+	    + azt_bcd2bin(mp->min) * 4500 - CD_MSF_OFFSET;
 }
 
 static void azt_bin2bcd(unsigned char *p)
-{       int u, t;
+{
+	int u, t;
 
 	u = *p % 10;
 	t = *p / 10;
@@ -2282,5 +2496,9 @@
 }
 
 static int azt_bcd2bin(unsigned char bcd)
-{       return (bcd >> 4) * 10 + (bcd & 0xF);
+{
+	return (bcd >> 4) * 10 + (bcd & 0xF);
 }
+
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
diff -u --recursive --new-file v2.4.9/linux/drivers/cdrom/cdu31a.c linux/drivers/cdrom/cdu31a.c
--- v2.4.9/linux/drivers/cdrom/cdu31a.c	Fri Feb  9 11:30:22 2001
+++ linux/drivers/cdrom/cdu31a.c	Fri Sep  7 09:28:38 2001
@@ -179,7 +179,7 @@
 #define MAJOR_NR CDU31A_CDROM_MAJOR
 #include <linux/blk.h>
 
-#define CDU31A_READAHEAD 4  /* 128 sector, 64kB, 32 reads read-ahead */
+#define CDU31A_READAHEAD 4	/* 128 sector, 64kB, 32 reads read-ahead */
 #define CDU31A_MAX_CONSECUTIVE_ATTENTIONS 10
 
 #define DEBUG 0
@@ -192,25 +192,12 @@
 ** Default is polled and no DMA.  DMA is not recommended for double-speed
 ** drives.
 */
-static struct
-{
-   unsigned short base;         /* I/O Base Address */
-   short          int_num;      /* Interrupt Number (-1 means scan for it,
-                                   0 means don't use) */
-} cdu31a_addresses[] __initdata =
-{
-#if 0	/* No autoconfig any more. See Note at beginning
-	   of this file. */
-   { 0x340,     0 },    /* Standard configuration Sony Interface */
-   { 0x1f88,    0 },    /* Fusion CD-16 */
-   { 0x230,     0 },    /* SoundBlaster 16 card */
-   { 0x360,     0 },    /* Secondary standard Sony Interface */
-   { 0x320,     0 },    /* Secondary standard Sony Interface */
-   { 0x330,     0 },    /* Secondary standard Sony Interface */
-   { 0x634,     0 },    /* Sound FX SC400 */
-   { 0x654,     0 },    /* Sound FX SC400 */
-#endif
-   { 0 }
+static struct {
+	unsigned short base;	/* I/O Base Address */
+	short int_num;		/* Interrupt Number (-1 means scan for it,
+				   0 means don't use) */
+} cdu31a_addresses[] __initdata = {
+	{0}
 };
 
 static int handle_sony_cd_attention(void);
@@ -220,17 +207,16 @@
 /*static int scd_open(struct inode *inode, struct file *filp);*/
 static int scd_open(struct cdrom_device_info *, int);
 static void do_sony_cd_cmd(unsigned char cmd,
-                           unsigned char *params,
-                           unsigned int num_params,
-                           unsigned char *result_buffer,
-                           unsigned int *result_size);
-static void size_to_buf(unsigned int size,
-                        unsigned char *buf);
+			   unsigned char *params,
+			   unsigned int num_params,
+			   unsigned char *result_buffer,
+			   unsigned int *result_size);
+static void size_to_buf(unsigned int size, unsigned char *buf);
 
 /* Parameters for the read-ahead. */
-static unsigned int sony_next_block;      /* Next 512 byte block offset */
-static unsigned int sony_blocks_left = 0; /* Number of 512 byte blocks left
-                                             in the current read command. */
+static unsigned int sony_next_block;	/* Next 512 byte block offset */
+static unsigned int sony_blocks_left = 0;	/* Number of 512 byte blocks left
+						   in the current read command. */
 
 
 /* The base I/O address of the Sony Interface.  This is a variable (not a
@@ -252,48 +238,48 @@
 static volatile unsigned short sony_cd_fifost_reg;
 
 
-static int sony_spun_up = 0;               /* Has the drive been spun up? */
+static int sony_spun_up = 0;	/* Has the drive been spun up? */
 
-static int sony_speed = 0;                 /* Last wanted speed */
+static int sony_speed = 0;	/* Last wanted speed */
 
-static int sony_xa_mode = 0;               /* Is an XA disk in the drive
-					      and the drive a CDU31A? */
+static int sony_xa_mode = 0;	/* Is an XA disk in the drive
+				   and the drive a CDU31A? */
 
-static int sony_raw_data_mode = 1;         /* 1 if data tracks, 0 if audio.
-                                              For raw data reads. */
+static int sony_raw_data_mode = 1;	/* 1 if data tracks, 0 if audio.
+					   For raw data reads. */
 
-static unsigned int sony_usage = 0;        /* How many processes have the
-                                              drive open. */
+static unsigned int sony_usage = 0;	/* How many processes have the
+					   drive open. */
 
-static int sony_pas_init = 0;		   /* Initialize the Pro-Audio
-					      Spectrum card? */
+static int sony_pas_init = 0;	/* Initialize the Pro-Audio
+				   Spectrum card? */
 
-static struct s_sony_session_toc single_toc;  /* Holds the
-					         table of
-					         contents. */
+static struct s_sony_session_toc single_toc;	/* Holds the
+						   table of
+						   contents. */
 
-static struct s_all_sessions_toc sony_toc; /* entries gathered from all
-                                                sessions */
+static struct s_all_sessions_toc sony_toc;	/* entries gathered from all
+						   sessions */
 
-static int sony_toc_read = 0;		   /* Has the TOC been read for
-					      the drive? */
+static int sony_toc_read = 0;	/* Has the TOC been read for
+				   the drive? */
 
-static struct s_sony_subcode last_sony_subcode; /* Points to the last
-                                                   subcode address read */
+static struct s_sony_subcode last_sony_subcode;	/* Points to the last
+						   subcode address read */
 
-static volatile int sony_inuse = 0;  /* Is the drive in use?  Only one operation
-					at a time allowed */
+static volatile int sony_inuse = 0;	/* Is the drive in use?  Only one operation
+					   at a time allowed */
 
 static DECLARE_WAIT_QUEUE_HEAD(sony_wait);	/* Things waiting for the drive */
 
-static struct task_struct *has_cd_task = NULL;  /* The task that is currently
+static struct task_struct *has_cd_task = NULL;	/* The task that is currently
 						   using the CDROM drive, or
 						   NULL if none. */
 
-static int is_double_speed = 0; /* does the drive support double speed ? */
-static int is_a_cdu31a = 1;     /* Is the drive a CDU31A? */
+static int is_double_speed = 0;	/* does the drive support double speed ? */
+static int is_a_cdu31a = 1;	/* Is the drive a CDU31A? */
 
-static int is_auto_eject = 1;   /* Door has been locked? 1=No/0=Yes */
+static int is_auto_eject = 1;	/* Door has been locked? 1=No/0=Yes */
 
 /*
  * The audio status uses the values from read subchannel data as specified
@@ -319,7 +305,7 @@
    interrupts. */
 DECLARE_WAIT_QUEUE_HEAD(cdu31a_irq_wait);
 
-static int curr_control_reg = 0; /* Current value of the control register */
+static int curr_control_reg = 0;	/* Current value of the control register */
 
 /* A disk changed variable.  When a disk change is detected, it will
    all be set to TRUE.  As the upper layers ask for disk_changed status
@@ -348,25 +334,23 @@
  * This routine returns 1 if the disk has been changed since the last
  * check or 0 if it hasn't.
  */
-static int
-scd_disk_change(kdev_t full_dev)
+static int scd_disk_change(kdev_t full_dev)
 {
-   int retval;
+	int retval;
 
-   retval = disk_changed;
-   disk_changed = 0;
+	retval = disk_changed;
+	disk_changed = 0;
 
-   return retval;
+	return retval;
 }
 
 /*
  * Uniform cdrom interface function
  * report back, if disc has changed from time of last request.
  */
-static int
-scd_media_changed(struct cdrom_device_info *cdi, int disc_nr)
+static int scd_media_changed(struct cdrom_device_info *cdi, int disc_nr)
 {
-  return scd_disk_change(cdi->dev);
+	return scd_disk_change(cdi->dev);
 }
 
 /*
@@ -375,56 +359,51 @@
  */
 static int scd_drive_status(struct cdrom_device_info *cdi, int slot_nr)
 {
-  if (CDSL_CURRENT != slot_nr) {
-     /* we have no changer support */
-     return -EINVAL;
-  }
-  if (scd_spinup() == 0) {
-         sony_spun_up = 1;
-  }
-  return sony_spun_up ? CDS_DISC_OK : CDS_DRIVE_NOT_READY;
-}
-
-static inline void
-enable_interrupts(void)
-{
-   curr_control_reg |= (  SONY_ATTN_INT_EN_BIT
-                        | SONY_RES_RDY_INT_EN_BIT
-                        | SONY_DATA_RDY_INT_EN_BIT);
-   outb(curr_control_reg, sony_cd_control_reg);
-}
-
-static inline void
-disable_interrupts(void)
-{
-   curr_control_reg &= ~(  SONY_ATTN_INT_EN_BIT
-                         | SONY_RES_RDY_INT_EN_BIT
-                         | SONY_DATA_RDY_INT_EN_BIT);
-   outb(curr_control_reg, sony_cd_control_reg);
+	if (CDSL_CURRENT != slot_nr) {
+		/* we have no changer support */
+		return -EINVAL;
+	}
+	if (scd_spinup() == 0) {
+		sony_spun_up = 1;
+	}
+	return sony_spun_up ? CDS_DISC_OK : CDS_DRIVE_NOT_READY;
+}
+
+static inline void enable_interrupts(void)
+{
+	curr_control_reg |= (SONY_ATTN_INT_EN_BIT
+			     | SONY_RES_RDY_INT_EN_BIT
+			     | SONY_DATA_RDY_INT_EN_BIT);
+	outb(curr_control_reg, sony_cd_control_reg);
+}
+
+static inline void disable_interrupts(void)
+{
+	curr_control_reg &= ~(SONY_ATTN_INT_EN_BIT
+			      | SONY_RES_RDY_INT_EN_BIT
+			      | SONY_DATA_RDY_INT_EN_BIT);
+	outb(curr_control_reg, sony_cd_control_reg);
 }
 
 /*
  * Wait a little while (used for polling the drive).  If in initialization,
  * setting a timeout doesn't work, so just loop for a while.
  */
-static inline void
-sony_sleep(void)
+static inline void sony_sleep(void)
 {
-   unsigned long flags;
+	unsigned long flags;
 
-   if (cdu31a_irq <= 0)
-   {
-      current->state = TASK_INTERRUPTIBLE;
-      schedule_timeout(0);
-   }
-   else /* Interrupt driven */
-   {
-      save_flags(flags);
-      cli();
-      enable_interrupts();
-      interruptible_sleep_on(&cdu31a_irq_wait);
-      restore_flags(flags);
-   }
+	if (cdu31a_irq <= 0) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule_timeout(0);
+	} else {		/* Interrupt driven */
+
+		save_flags(flags);
+		cli();
+		enable_interrupts();
+		interruptible_sleep_on(&cdu31a_irq_wait);
+		restore_flags(flags);
+	}
 }
 
 
@@ -432,272 +411,276 @@
  * The following are convenience routine to read various status and set
  * various conditions in the drive.
  */
-static inline int
-is_attention(void)
+static inline int is_attention(void)
 {
-   return((inb(sony_cd_status_reg) & SONY_ATTN_BIT) != 0);
+	return ((inb(sony_cd_status_reg) & SONY_ATTN_BIT) != 0);
 }
 
-static inline int
-is_busy(void)
+static inline int is_busy(void)
 {
-   return((inb(sony_cd_status_reg) & SONY_BUSY_BIT) != 0);
+	return ((inb(sony_cd_status_reg) & SONY_BUSY_BIT) != 0);
 }
 
-static inline int
-is_data_ready(void)
+static inline int is_data_ready(void)
 {
-   return((inb(sony_cd_status_reg) & SONY_DATA_RDY_BIT) != 0);
+	return ((inb(sony_cd_status_reg) & SONY_DATA_RDY_BIT) != 0);
 }
 
-static inline int
-is_data_requested(void)
+static inline int is_data_requested(void)
 {
-   return((inb(sony_cd_status_reg) & SONY_DATA_REQUEST_BIT) != 0);
+	return ((inb(sony_cd_status_reg) & SONY_DATA_REQUEST_BIT) != 0);
 }
 
-static inline int
-is_result_ready(void)
+static inline int is_result_ready(void)
 {
-   return((inb(sony_cd_status_reg) & SONY_RES_RDY_BIT) != 0);
+	return ((inb(sony_cd_status_reg) & SONY_RES_RDY_BIT) != 0);
 }
 
-static inline int
-is_param_write_rdy(void)
+static inline int is_param_write_rdy(void)
 {
-   return((inb(sony_cd_fifost_reg) & SONY_PARAM_WRITE_RDY_BIT) != 0);
+	return ((inb(sony_cd_fifost_reg) & SONY_PARAM_WRITE_RDY_BIT) != 0);
 }
 
-static inline int
-is_result_reg_not_empty(void)
+static inline int is_result_reg_not_empty(void)
 {
-   return((inb(sony_cd_fifost_reg) & SONY_RES_REG_NOT_EMP_BIT) != 0);
+	return ((inb(sony_cd_fifost_reg) & SONY_RES_REG_NOT_EMP_BIT) != 0);
 }
 
-static inline void
-reset_drive(void)
+static inline void reset_drive(void)
 {
-   curr_control_reg = 0;
-   readahead_dataleft = 0;
-   sony_toc_read = 0;
-   outb(SONY_DRIVE_RESET_BIT, sony_cd_control_reg);
+	curr_control_reg = 0;
+	readahead_dataleft = 0;
+	sony_toc_read = 0;
+	outb(SONY_DRIVE_RESET_BIT, sony_cd_control_reg);
 }
 
 /*
  * Uniform cdrom interface function
  * reset drive and return when it is ready
  */
-static int scd_reset(struct cdrom_device_info * cdi)
+static int scd_reset(struct cdrom_device_info *cdi)
 {
-  int retry_count;
+	int retry_count;
 
-  reset_drive();
+	reset_drive();
 
-  retry_count = jiffies + SONY_RESET_TIMEOUT;
-  while (time_before(jiffies, retry_count) && (!is_attention()))
-  {
-     sony_sleep();
-  }
+	retry_count = jiffies + SONY_RESET_TIMEOUT;
+	while (time_before(jiffies, retry_count) && (!is_attention())) {
+		sony_sleep();
+	}
 
-  return 0;
+	return 0;
 }
 
-static inline void
-clear_attention(void)
+static inline void clear_attention(void)
 {
-   outb(curr_control_reg | SONY_ATTN_CLR_BIT, sony_cd_control_reg);
+	outb(curr_control_reg | SONY_ATTN_CLR_BIT, sony_cd_control_reg);
 }
 
-static inline void
-clear_result_ready(void)
+static inline void clear_result_ready(void)
 {
-   outb(curr_control_reg | SONY_RES_RDY_CLR_BIT, sony_cd_control_reg);
+	outb(curr_control_reg | SONY_RES_RDY_CLR_BIT, sony_cd_control_reg);
 }
 
-static inline void
-clear_data_ready(void)
+static inline void clear_data_ready(void)
 {
-   outb(curr_control_reg | SONY_DATA_RDY_CLR_BIT, sony_cd_control_reg);
+	outb(curr_control_reg | SONY_DATA_RDY_CLR_BIT,
+	     sony_cd_control_reg);
 }
 
-static inline void
-clear_param_reg(void)
+static inline void clear_param_reg(void)
 {
-   outb(curr_control_reg | SONY_PARAM_CLR_BIT, sony_cd_control_reg);
+	outb(curr_control_reg | SONY_PARAM_CLR_BIT, sony_cd_control_reg);
 }
 
-static inline unsigned char
-read_status_register(void)
+static inline unsigned char read_status_register(void)
 {
-   return(inb(sony_cd_status_reg));
+	return (inb(sony_cd_status_reg));
 }
 
-static inline unsigned char
-read_result_register(void)
+static inline unsigned char read_result_register(void)
 {
-   return(inb(sony_cd_result_reg));
+	return (inb(sony_cd_result_reg));
 }
 
-static inline unsigned char
-read_data_register(void)
+static inline unsigned char read_data_register(void)
 {
-   return(inb(sony_cd_read_reg));
+	return (inb(sony_cd_read_reg));
 }
 
-static inline void
-write_param(unsigned char param)
+static inline void write_param(unsigned char param)
 {
-   outb(param, sony_cd_param_reg);
+	outb(param, sony_cd_param_reg);
 }
 
-static inline void
-write_cmd(unsigned char cmd)
+static inline void write_cmd(unsigned char cmd)
 {
-   outb(curr_control_reg | SONY_RES_RDY_INT_EN_BIT, sony_cd_control_reg);
-   outb(cmd, sony_cd_cmd_reg);
+	outb(curr_control_reg | SONY_RES_RDY_INT_EN_BIT,
+	     sony_cd_control_reg);
+	outb(cmd, sony_cd_cmd_reg);
 }
 
-static void
-cdu31a_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static void cdu31a_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-   unsigned char val;
+	unsigned char val;
+
+	if (abort_read_started) {
+		/* We might be waiting for an abort to finish.  Don't
+		   disable interrupts yet, though, because we handle
+		   this one here. */
+		/* Clear out the result registers. */
+		while (is_result_reg_not_empty()) {
+			val = read_result_register();
+		}
+		clear_data_ready();
+		clear_result_ready();
 
-   if (abort_read_started)
-   {
-      /* We might be waiting for an abort to finish.  Don't
-         disable interrupts yet, though, because we handle
-         this one here. */
-      /* Clear out the result registers. */
-      while (is_result_reg_not_empty())
-      {
-         val = read_result_register();
-      }
-      clear_data_ready();
-      clear_result_ready();
-
-      /* Clear out the data */
-      while (is_data_requested())
-      {
-         val = read_data_register();
-      }
-      abort_read_started = 0;
-
-      /* If something was waiting, wake it up now. */
-      if (waitqueue_active(&cdu31a_irq_wait))
-      {
-         disable_interrupts();
-         wake_up(&cdu31a_irq_wait);
-      }
-   }
-   else if (waitqueue_active(&cdu31a_irq_wait))
-   {
-      disable_interrupts();
-      wake_up(&cdu31a_irq_wait);
-   }
-   else
-   {
-      disable_interrupts();
-      printk("CDU31A: Got an interrupt but nothing was waiting\n");
-   }
+		/* Clear out the data */
+		while (is_data_requested()) {
+			val = read_data_register();
+		}
+		abort_read_started = 0;
+
+		/* If something was waiting, wake it up now. */
+		if (waitqueue_active(&cdu31a_irq_wait)) {
+			disable_interrupts();
+			wake_up(&cdu31a_irq_wait);
+		}
+	} else if (waitqueue_active(&cdu31a_irq_wait)) {
+		disable_interrupts();
+		wake_up(&cdu31a_irq_wait);
+	} else {
+		disable_interrupts();
+		printk
+		    ("CDU31A: Got an interrupt but nothing was waiting\n");
+	}
 }
 
 /*
  * give more verbose error messages
  */
-static unsigned char *translate_error( unsigned char err_code )
+static unsigned char *translate_error(unsigned char err_code)
 {
-   static unsigned char errbuf[80];
+	static unsigned char errbuf[80];
 
-   switch (err_code) {
-     case 0x10: return "illegal command ";
-     case 0x11: return "illegal parameter ";
-
-     case 0x20: return "not loaded ";
-     case 0x21: return "no disc ";
-     case 0x22: return "not spinning ";
-     case 0x23: return "spinning ";
-     case 0x25: return "spindle servo ";
-     case 0x26: return "focus servo ";
-     case 0x29: return "eject mechanism ";
-     case 0x2a: return "audio playing ";
-     case 0x2c: return "emergency eject ";
-
-     case 0x30: return "focus ";
-     case 0x31: return "frame sync ";
-     case 0x32: return "subcode address ";
-     case 0x33: return "block sync ";
-     case 0x34: return "header address ";
-
-     case 0x40: return "illegal track read ";
-     case 0x41: return "mode 0 read ";
-     case 0x42: return "illegal mode read ";
-     case 0x43: return "illegal block size read ";
-     case 0x44: return "mode read ";
-     case 0x45: return "form read ";
-     case 0x46: return "leadout read ";
-     case 0x47: return "buffer overrun ";
-
-     case 0x53: return "unrecoverable CIRC ";
-     case 0x57: return "unrecoverable LECC ";
-
-     case 0x60: return "no TOC ";
-     case 0x61: return "invalid subcode data ";
-     case 0x63: return "focus on TOC read ";
-     case 0x64: return "frame sync on TOC read ";
-     case 0x65: return "TOC data ";
-
-     case 0x70: return "hardware failure ";
-     case 0x91: return "leadin ";
-     case 0x92: return "leadout ";
-     case 0x93: return "data track ";
-   }
-   sprintf(errbuf, "unknown 0x%02x ", err_code);
-   return errbuf;
+	switch (err_code) {
+	case 0x10:
+		return "illegal command ";
+	case 0x11:
+		return "illegal parameter ";
+
+	case 0x20:
+		return "not loaded ";
+	case 0x21:
+		return "no disc ";
+	case 0x22:
+		return "not spinning ";
+	case 0x23:
+		return "spinning ";
+	case 0x25:
+		return "spindle servo ";
+	case 0x26:
+		return "focus servo ";
+	case 0x29:
+		return "eject mechanism ";
+	case 0x2a:
+		return "audio playing ";
+	case 0x2c:
+		return "emergency eject ";
+
+	case 0x30:
+		return "focus ";
+	case 0x31:
+		return "frame sync ";
+	case 0x32:
+		return "subcode address ";
+	case 0x33:
+		return "block sync ";
+	case 0x34:
+		return "header address ";
+
+	case 0x40:
+		return "illegal track read ";
+	case 0x41:
+		return "mode 0 read ";
+	case 0x42:
+		return "illegal mode read ";
+	case 0x43:
+		return "illegal block size read ";
+	case 0x44:
+		return "mode read ";
+	case 0x45:
+		return "form read ";
+	case 0x46:
+		return "leadout read ";
+	case 0x47:
+		return "buffer overrun ";
+
+	case 0x53:
+		return "unrecoverable CIRC ";
+	case 0x57:
+		return "unrecoverable LECC ";
+
+	case 0x60:
+		return "no TOC ";
+	case 0x61:
+		return "invalid subcode data ";
+	case 0x63:
+		return "focus on TOC read ";
+	case 0x64:
+		return "frame sync on TOC read ";
+	case 0x65:
+		return "TOC data ";
+
+	case 0x70:
+		return "hardware failure ";
+	case 0x91:
+		return "leadin ";
+	case 0x92:
+		return "leadout ";
+	case 0x93:
+		return "data track ";
+	}
+	sprintf(errbuf, "unknown 0x%02x ", err_code);
+	return errbuf;
 }
 
 /*
  * Set the drive parameters so the drive will auto-spin-up when a
  * disk is inserted.
  */
-static void
-set_drive_params(int want_doublespeed)
+static void set_drive_params(int want_doublespeed)
 {
-   unsigned char res_reg[12];
-   unsigned int res_size;
-   unsigned char params[3];
-
-
-   params[0] = SONY_SD_AUTO_SPIN_DOWN_TIME;
-   params[1] = 0x00; /* Never spin down the drive. */
-   do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
-                  params,
-                  2,
-                  res_reg,
-                  &res_size);
-   if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
-   {
-      printk("  Unable to set spin-down time: 0x%2.2x\n", res_reg[1]);
-   }
-
-   params[0] = SONY_SD_MECH_CONTROL;
-   params[1] = SONY_AUTO_SPIN_UP_BIT; /* Set auto spin up */
-
-   if (is_auto_eject) params[1] |= SONY_AUTO_EJECT_BIT;
-   
-   if (is_double_speed && want_doublespeed)
-   {
-      params[1] |= SONY_DOUBLE_SPEED_BIT; /* Set the drive to double speed if 
-                                             possible */
-   }
-   do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
-                  params,
-                  2,
-                  res_reg,
-                  &res_size);
-   if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
-   {
-      printk("  Unable to set mechanical parameters: 0x%2.2x\n", res_reg[1]);
-   }
+	unsigned char res_reg[12];
+	unsigned int res_size;
+	unsigned char params[3];
+
+
+	params[0] = SONY_SD_AUTO_SPIN_DOWN_TIME;
+	params[1] = 0x00;	/* Never spin down the drive. */
+	do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
+		       params, 2, res_reg, &res_size);
+	if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
+		printk("  Unable to set spin-down time: 0x%2.2x\n",
+		       res_reg[1]);
+	}
+
+	params[0] = SONY_SD_MECH_CONTROL;
+	params[1] = SONY_AUTO_SPIN_UP_BIT;	/* Set auto spin up */
+
+	if (is_auto_eject)
+		params[1] |= SONY_AUTO_EJECT_BIT;
+
+	if (is_double_speed && want_doublespeed) {
+		params[1] |= SONY_DOUBLE_SPEED_BIT;	/* Set the drive to double speed if 
+							   possible */
+	}
+	do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
+		       params, 2, res_reg, &res_size);
+	if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
+		printk("  Unable to set mechanical parameters: 0x%2.2x\n",
+		       res_reg[1]);
+	}
 }
 
 /*
@@ -706,13 +689,13 @@
  */
 static int scd_select_speed(struct cdrom_device_info *cdi, int speed)
 {
-  if (speed == 0)
-    sony_speed = 1;
-  else 
-    sony_speed = speed - 1;
+	if (speed == 0)
+		sony_speed = 1;
+	else
+		sony_speed = speed - 1;
 
-  set_drive_params(sony_speed);
-  return 0;
+	set_drive_params(sony_speed);
+	return 0;
 }
 
 /*
@@ -721,77 +704,69 @@
  */
 static int scd_lock_door(struct cdrom_device_info *cdi, int lock)
 {
-   if (lock == 0 && sony_usage == 1)
-   {
-      /* Unlock the door, only if nobody is using the drive */
-      is_auto_eject = 1;
-   } else {
-      is_auto_eject = 0;
-   }
-   set_drive_params(sony_speed);
-   return 0;
+	if (lock == 0 && sony_usage == 1) {
+		/* Unlock the door, only if nobody is using the drive */
+		is_auto_eject = 1;
+	} else {
+		is_auto_eject = 0;
+	}
+	set_drive_params(sony_speed);
+	return 0;
 }
 
 /*
  * This code will reset the drive and attempt to restore sane parameters.
  */
-static void
-restart_on_error(void)
+static void restart_on_error(void)
 {
-   unsigned char res_reg[12];
-   unsigned int res_size;
-   unsigned int retry_count;
-
-
-   printk("cdu31a: Resetting drive on error\n");
-   reset_drive();
-   retry_count = jiffies + SONY_RESET_TIMEOUT;
-   while (time_before(jiffies, retry_count) && (!is_attention()))
-   {
-      sony_sleep();
-   }
-   set_drive_params(sony_speed);
-   do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
-   if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
-   {
-      printk("cdu31a: Unable to spin up drive: 0x%2.2x\n", res_reg[1]);
-   }
+	unsigned char res_reg[12];
+	unsigned int res_size;
+	unsigned int retry_count;
+
+
+	printk("cdu31a: Resetting drive on error\n");
+	reset_drive();
+	retry_count = jiffies + SONY_RESET_TIMEOUT;
+	while (time_before(jiffies, retry_count) && (!is_attention())) {
+		sony_sleep();
+	}
+	set_drive_params(sony_speed);
+	do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
+	if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
+		printk("cdu31a: Unable to spin up drive: 0x%2.2x\n",
+		       res_reg[1]);
+	}
 
-   current->state = TASK_INTERRUPTIBLE;
-   schedule_timeout(2*HZ);
+	current->state = TASK_INTERRUPTIBLE;
+	schedule_timeout(2 * HZ);
 
-   sony_get_toc();
+	sony_get_toc();
 }
 
 /*
  * This routine writes data to the parameter register.  Since this should
  * happen fairly fast, it is polled with no OS waits between.
  */
-static int
-write_params(unsigned char *params,
-             int num_params)
+static int write_params(unsigned char *params, int num_params)
 {
-   unsigned int retry_count;
+	unsigned int retry_count;
 
 
-   retry_count = SONY_READY_RETRIES;
-   while ((retry_count > 0) && (!is_param_write_rdy()))
-   {
-      retry_count--;
-   }
-   if (!is_param_write_rdy())
-   {
-      return -EIO;
-   }
-
-   while (num_params > 0)
-   {
-      write_param(*params);
-      params++;
-      num_params--;
-   }
+	retry_count = SONY_READY_RETRIES;
+	while ((retry_count > 0) && (!is_param_write_rdy())) {
+		retry_count--;
+	}
+	if (!is_param_write_rdy()) {
+		return -EIO;
+	}
+
+	while (num_params > 0) {
+		write_param(*params);
+		params++;
+		num_params--;
+	}
 
-   return 0;
+	return 0;
 }
 
 
@@ -802,134 +777,125 @@
  * the drive manual.
  */
 static void
-get_result(unsigned char *result_buffer,
-           unsigned int *result_size)
+get_result(unsigned char *result_buffer, unsigned int *result_size)
 {
-   unsigned char a, b;
-   int i;
-   unsigned int retry_count;
-
-
-   while (handle_sony_cd_attention())
-      ;
-   /* Wait for the result data to be ready */
-   retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
-   while (time_before(jiffies, retry_count) && (is_busy() || (!(is_result_ready()))))
-   {
-      sony_sleep();
-
-      while (handle_sony_cd_attention())
-         ;
-   }
-   if (is_busy() || (!(is_result_ready())))
-   {
-#if DEBUG
-      printk("CDU31A timeout out %d\n", __LINE__);
-#endif
-      result_buffer[0] = 0x20;
-      result_buffer[1] = SONY_TIMEOUT_OP_ERR;
-      *result_size = 2;
-      return;
-   }
-
-   /*
-    * Get the first two bytes.  This determines what else needs
-    * to be done.
-    */
-   clear_result_ready();
-   a = read_result_register();
-   *result_buffer = a;
-   result_buffer++;
-
-   /* Check for block error status result. */
-   if ((a & 0xf0) == 0x50)
-   {
-      *result_size = 1;
-      return;
-   }
-
-   b = read_result_register();
-   *result_buffer = b;
-   result_buffer++;
-   *result_size = 2;
-
-   /*
-    * 0x20 means an error occurred.  Byte 2 will have the error code.
-    * Otherwise, the command succeeded, byte 2 will have the count of
-    * how many more status bytes are coming.
-    *
-    * The result register can be read 10 bytes at a time, a wait for
-    * result ready to be asserted must be done between every 10 bytes.
-    */
-   if ((a & 0xf0) != 0x20)
-   {
-      if (b > 8)
-      {
-         for (i=0; i<8; i++)
-         {
-            *result_buffer = read_result_register();
-            result_buffer++;
-            (*result_size)++;
-         }
-         b = b - 8;
-
-         while (b > 10)
-         {
-            retry_count = SONY_READY_RETRIES;
-            while ((retry_count > 0) && (!is_result_ready()))
-            {
-               retry_count--;
-            }
-            if (!is_result_ready())
-            {
-#if DEBUG
-               printk("CDU31A timeout out %d\n", __LINE__);
-#endif
-               result_buffer[0] = 0x20;
-               result_buffer[1] = SONY_TIMEOUT_OP_ERR;
-               *result_size = 2;
-               return;
-            }
-
-            clear_result_ready();
-                                
-            for (i=0; i<10; i++)
-            {
-               *result_buffer = read_result_register();
-               result_buffer++;
-               (*result_size)++;
-            }
-            b = b - 10;
-         }
-
-         if (b > 0)
-         {
-            retry_count = SONY_READY_RETRIES;
-            while ((retry_count > 0) && (!is_result_ready()))
-            {
-               retry_count--;
-            }
-            if (!is_result_ready())
-            {
-#if DEBUG
-               printk("CDU31A timeout out %d\n", __LINE__);
-#endif
-               result_buffer[0] = 0x20;
-               result_buffer[1] = SONY_TIMEOUT_OP_ERR;
-               *result_size = 2;
-               return;
-            }
-         }
-      }
-
-      while (b > 0)
-      {
-         *result_buffer = read_result_register();
-         result_buffer++;
-         (*result_size)++;
-         b--;
-      }
-   }
+	unsigned char a, b;
+	int i;
+	unsigned int retry_count;
+
+
+	while (handle_sony_cd_attention());
+	/* Wait for the result data to be ready */
+	retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
+	while (time_before(jiffies, retry_count)
+	       && (is_busy() || (!(is_result_ready())))) {
+		sony_sleep();
+
+		while (handle_sony_cd_attention());
+	}
+	if (is_busy() || (!(is_result_ready()))) {
+#if DEBUG
+		printk("CDU31A timeout out %d\n", __LINE__);
+#endif
+		result_buffer[0] = 0x20;
+		result_buffer[1] = SONY_TIMEOUT_OP_ERR;
+		*result_size = 2;
+		return;
+	}
+
+	/*
+	 * Get the first two bytes.  This determines what else needs
+	 * to be done.
+	 */
+	clear_result_ready();
+	a = read_result_register();
+	*result_buffer = a;
+	result_buffer++;
+
+	/* Check for block error status result. */
+	if ((a & 0xf0) == 0x50) {
+		*result_size = 1;
+		return;
+	}
+
+	b = read_result_register();
+	*result_buffer = b;
+	result_buffer++;
+	*result_size = 2;
+
+	/*
+	 * 0x20 means an error occurred.  Byte 2 will have the error code.
+	 * Otherwise, the command succeeded, byte 2 will have the count of
+	 * how many more status bytes are coming.
+	 *
+	 * The result register can be read 10 bytes at a time, a wait for
+	 * result ready to be asserted must be done between every 10 bytes.
+	 */
+	if ((a & 0xf0) != 0x20) {
+		if (b > 8) {
+			for (i = 0; i < 8; i++) {
+				*result_buffer = read_result_register();
+				result_buffer++;
+				(*result_size)++;
+			}
+			b = b - 8;
+
+			while (b > 10) {
+				retry_count = SONY_READY_RETRIES;
+				while ((retry_count > 0)
+				       && (!is_result_ready())) {
+					retry_count--;
+				}
+				if (!is_result_ready()) {
+#if DEBUG
+					printk("CDU31A timeout out %d\n",
+					       __LINE__);
+#endif
+					result_buffer[0] = 0x20;
+					result_buffer[1] =
+					    SONY_TIMEOUT_OP_ERR;
+					*result_size = 2;
+					return;
+				}
+
+				clear_result_ready();
+
+				for (i = 0; i < 10; i++) {
+					*result_buffer =
+					    read_result_register();
+					result_buffer++;
+					(*result_size)++;
+				}
+				b = b - 10;
+			}
+
+			if (b > 0) {
+				retry_count = SONY_READY_RETRIES;
+				while ((retry_count > 0)
+				       && (!is_result_ready())) {
+					retry_count--;
+				}
+				if (!is_result_ready()) {
+#if DEBUG
+					printk("CDU31A timeout out %d\n",
+					       __LINE__);
+#endif
+					result_buffer[0] = 0x20;
+					result_buffer[1] =
+					    SONY_TIMEOUT_OP_ERR;
+					*result_size = 2;
+					return;
+				}
+			}
+		}
+
+		while (b > 0) {
+			*result_buffer = read_result_register();
+			result_buffer++;
+			(*result_size)++;
+			b--;
+		}
+	}
 }
 
 /*
@@ -939,95 +905,81 @@
  */
 static void
 do_sony_cd_cmd(unsigned char cmd,
-               unsigned char *params,
-               unsigned int num_params,
-               unsigned char *result_buffer,
-               unsigned int *result_size)
-{
-   unsigned int retry_count;
-   int num_retries;
-   int recursive_call;
-   unsigned long flags;
-
-
-   save_flags(flags);
-   cli();
-   if (current != has_cd_task) /* Allow recursive calls to this routine */
-   {
-      while (sony_inuse)
-      {
-         interruptible_sleep_on(&sony_wait);
-         if (signal_pending(current))
-         {
-            result_buffer[0] = 0x20;
-            result_buffer[1] = SONY_SIGNAL_OP_ERR;
-            *result_size = 2;
-            restore_flags(flags);
-            return;
-         }
-      }
-      sony_inuse = 1;
-      has_cd_task = current;
-      recursive_call = 0;
-   }
-   else
-   {
-      recursive_call = 1;
-   }
+	       unsigned char *params,
+	       unsigned int num_params,
+	       unsigned char *result_buffer, unsigned int *result_size)
+{
+	unsigned int retry_count;
+	int num_retries;
+	int recursive_call;
+	unsigned long flags;
+
+
+	save_flags(flags);
+	cli();
+	if (current != has_cd_task) {	/* Allow recursive calls to this routine */
+		while (sony_inuse) {
+			interruptible_sleep_on(&sony_wait);
+			if (signal_pending(current)) {
+				result_buffer[0] = 0x20;
+				result_buffer[1] = SONY_SIGNAL_OP_ERR;
+				*result_size = 2;
+				restore_flags(flags);
+				return;
+			}
+		}
+		sony_inuse = 1;
+		has_cd_task = current;
+		recursive_call = 0;
+	} else {
+		recursive_call = 1;
+	}
 
-   num_retries = 0;
+	num_retries = 0;
 retry_cd_operation:
 
-   while (handle_sony_cd_attention())
-      ;
+	while (handle_sony_cd_attention());
+
+	sti();
 
-   sti();
-   
-   retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
-   while (time_before(jiffies, retry_count) && (is_busy()))
-   {
-      sony_sleep();
-      
-      while (handle_sony_cd_attention())
-         ;
-   }
-   if (is_busy())
-   {
-#if DEBUG
-      printk("CDU31A timeout out %d\n", __LINE__);
-#endif
-      result_buffer[0] = 0x20;
-      result_buffer[1] = SONY_TIMEOUT_OP_ERR;
-      *result_size = 2;
-   }
-   else
-   {
-      clear_result_ready();
-      clear_param_reg();
-
-      write_params(params, num_params);
-      write_cmd(cmd);
-
-      get_result(result_buffer, result_size);
-   }
-
-   if (   ((result_buffer[0] & 0xf0) == 0x20)
-       && (num_retries < MAX_CDU31A_RETRIES))
-   {
-      num_retries++;
-      current->state = TASK_INTERRUPTIBLE;
-      schedule_timeout(HZ/10);  /* Wait .1 seconds on retries */
-      goto retry_cd_operation;
-   }
-
-   if (!recursive_call)
-   {
-      has_cd_task = NULL;
-      sony_inuse = 0;
-      wake_up_interruptible(&sony_wait);
-   }
+	retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
+	while (time_before(jiffies, retry_count) && (is_busy())) {
+		sony_sleep();
+
+		while (handle_sony_cd_attention());
+	}
+	if (is_busy()) {
+#if DEBUG
+		printk("CDU31A timeout out %d\n", __LINE__);
+#endif
+		result_buffer[0] = 0x20;
+		result_buffer[1] = SONY_TIMEOUT_OP_ERR;
+		*result_size = 2;
+	} else {
+		clear_result_ready();
+		clear_param_reg();
+
+		write_params(params, num_params);
+		write_cmd(cmd);
+
+		get_result(result_buffer, result_size);
+	}
+
+	if (((result_buffer[0] & 0xf0) == 0x20)
+	    && (num_retries < MAX_CDU31A_RETRIES)) {
+		num_retries++;
+		current->state = TASK_INTERRUPTIBLE;
+		schedule_timeout(HZ / 10);	/* Wait .1 seconds on retries */
+		goto retry_cd_operation;
+	}
+
+	if (!recursive_call) {
+		has_cd_task = NULL;
+		sony_inuse = 0;
+		wake_up_interruptible(&sony_wait);
+	}
 
-   restore_flags(flags);
+	restore_flags(flags);
 }
 
 
@@ -1040,120 +992,114 @@
  * a 0), and returns a 0 if it happens too many times.  This will help
  * prevent a lockup.
  */
-static int
-handle_sony_cd_attention(void)
+static int handle_sony_cd_attention(void)
 {
-   unsigned char atten_code;
-   static int num_consecutive_attentions = 0;
-   volatile int val;
+	unsigned char atten_code;
+	static int num_consecutive_attentions = 0;
+	volatile int val;
 
 
 #if 0*DEBUG
-   printk("Entering handle_sony_cd_attention\n");
+	printk("Entering handle_sony_cd_attention\n");
 #endif
-   if (is_attention())
-   {
-      if (num_consecutive_attentions > CDU31A_MAX_CONSECUTIVE_ATTENTIONS)
-      {
-         printk("cdu31a: Too many consecutive attentions: %d\n",
-                num_consecutive_attentions);
-         num_consecutive_attentions = 0;
-#if DEBUG
-         printk("Leaving handle_sony_cd_attention at %d\n", __LINE__);
-#endif
-         return(0);
-      }
-
-      clear_attention();
-      atten_code = read_result_register();
-
-      switch (atten_code)
-      {
-       /* Someone changed the CD.  Mark it as changed */
-      case SONY_MECH_LOADED_ATTN:
-         disk_changed = 1;
-	 sony_toc_read = 0;
-         sony_audio_status = CDROM_AUDIO_NO_STATUS;
-         sony_blocks_left = 0;
-         break;
-
-      case SONY_SPIN_DOWN_COMPLETE_ATTN:
-         /* Mark the disk as spun down. */
-         sony_spun_up = 0;
-         break;
-
-      case SONY_AUDIO_PLAY_DONE_ATTN:
-         sony_audio_status = CDROM_AUDIO_COMPLETED;
-         read_subcode();
-         break;
-
-      case SONY_EJECT_PUSHED_ATTN:
-         if (is_auto_eject)
-         {
-            sony_audio_status = CDROM_AUDIO_INVALID;
-         }
-         break;
-
-      case SONY_LEAD_IN_ERR_ATTN:
-      case SONY_LEAD_OUT_ERR_ATTN:
-      case SONY_DATA_TRACK_ERR_ATTN:
-      case SONY_AUDIO_PLAYBACK_ERR_ATTN:
-         sony_audio_status = CDROM_AUDIO_ERROR;
-         break;
-      }
-
-      num_consecutive_attentions++;
-#if DEBUG
-      printk("Leaving handle_sony_cd_attention at %d\n", __LINE__);
-#endif
-      return(1);
-   }
-   else if (abort_read_started)
-   {
-      while (is_result_reg_not_empty())
-      {
-         val = read_result_register();
-      }
-      clear_data_ready();
-      clear_result_ready();
-      /* Clear out the data */
-      while (is_data_requested())
-      {
-         val = read_data_register();
-      }
-      abort_read_started = 0;
+	if (is_attention()) {
+		if (num_consecutive_attentions >
+		    CDU31A_MAX_CONSECUTIVE_ATTENTIONS) {
+			printk
+			    ("cdu31a: Too many consecutive attentions: %d\n",
+			     num_consecutive_attentions);
+			num_consecutive_attentions = 0;
+#if DEBUG
+			printk("Leaving handle_sony_cd_attention at %d\n",
+			       __LINE__);
+#endif
+			return (0);
+		}
+
+		clear_attention();
+		atten_code = read_result_register();
+
+		switch (atten_code) {
+			/* Someone changed the CD.  Mark it as changed */
+		case SONY_MECH_LOADED_ATTN:
+			disk_changed = 1;
+			sony_toc_read = 0;
+			sony_audio_status = CDROM_AUDIO_NO_STATUS;
+			sony_blocks_left = 0;
+			break;
+
+		case SONY_SPIN_DOWN_COMPLETE_ATTN:
+			/* Mark the disk as spun down. */
+			sony_spun_up = 0;
+			break;
+
+		case SONY_AUDIO_PLAY_DONE_ATTN:
+			sony_audio_status = CDROM_AUDIO_COMPLETED;
+			read_subcode();
+			break;
+
+		case SONY_EJECT_PUSHED_ATTN:
+			if (is_auto_eject) {
+				sony_audio_status = CDROM_AUDIO_INVALID;
+			}
+			break;
+
+		case SONY_LEAD_IN_ERR_ATTN:
+		case SONY_LEAD_OUT_ERR_ATTN:
+		case SONY_DATA_TRACK_ERR_ATTN:
+		case SONY_AUDIO_PLAYBACK_ERR_ATTN:
+			sony_audio_status = CDROM_AUDIO_ERROR;
+			break;
+		}
+
+		num_consecutive_attentions++;
+#if DEBUG
+		printk("Leaving handle_sony_cd_attention at %d\n",
+		       __LINE__);
+#endif
+		return (1);
+	} else if (abort_read_started) {
+		while (is_result_reg_not_empty()) {
+			val = read_result_register();
+		}
+		clear_data_ready();
+		clear_result_ready();
+		/* Clear out the data */
+		while (is_data_requested()) {
+			val = read_data_register();
+		}
+		abort_read_started = 0;
 #if DEBUG
-      printk("Leaving handle_sony_cd_attention at %d\n", __LINE__);
+		printk("Leaving handle_sony_cd_attention at %d\n",
+		       __LINE__);
 #endif
-      return(1);
-   }
+		return (1);
+	}
 
-   num_consecutive_attentions = 0;
+	num_consecutive_attentions = 0;
 #if 0*DEBUG
-   printk("Leaving handle_sony_cd_attention at %d\n", __LINE__);
+	printk("Leaving handle_sony_cd_attention at %d\n", __LINE__);
 #endif
-   return(0);
+	return (0);
 }
 
 
 /* Convert from an integer 0-99 to BCD */
-static inline unsigned int
-int_to_bcd(unsigned int val)
+static inline unsigned int int_to_bcd(unsigned int val)
 {
-   int retval;
+	int retval;
 
 
-   retval = (val / 10) << 4;
-   retval = retval | val % 10;
-   return(retval);
+	retval = (val / 10) << 4;
+	retval = retval | val % 10;
+	return (retval);
 }
 
 
 /* Convert from BCD to an integer from 0-99 */
-static unsigned int
-bcd_to_int(unsigned int bcd)
+static unsigned int bcd_to_int(unsigned int bcd)
 {
-   return((((bcd >> 4) & 0x0f) * 10) + (bcd & 0x0f));
+	return ((((bcd >> 4) & 0x0f) * 10) + (bcd & 0x0f));
 }
 
 
@@ -1161,32 +1107,30 @@
  * Convert a logical sector value (like the OS would want to use for
  * a block device) to an MSF format.
  */
-static void
-log_to_msf(unsigned int log, unsigned char *msf)
+static void log_to_msf(unsigned int log, unsigned char *msf)
 {
-   log = log + LOG_START_OFFSET;
-   msf[0] = int_to_bcd(log / 4500);
-   log = log % 4500;
-   msf[1] = int_to_bcd(log / 75);
-   msf[2] = int_to_bcd(log % 75);
+	log = log + LOG_START_OFFSET;
+	msf[0] = int_to_bcd(log / 4500);
+	log = log % 4500;
+	msf[1] = int_to_bcd(log / 75);
+	msf[2] = int_to_bcd(log % 75);
 }
 
 
 /*
  * Convert an MSF format to a logical sector.
  */
-static unsigned int
-msf_to_log(unsigned char *msf)
+static unsigned int msf_to_log(unsigned char *msf)
 {
-   unsigned int log;
+	unsigned int log;
 
 
-   log = msf[2];
-   log += msf[1] * 75;
-   log += msf[0] * 4500;
-   log = log - LOG_START_OFFSET;
+	log = msf[2];
+	log += msf[1] * 75;
+	log += msf[0] * 4500;
+	log = log - LOG_START_OFFSET;
 
-   return log;
+	return log;
 }
 
 
@@ -1194,14 +1138,12 @@
  * Take in integer size value and put it into a buffer like
  * the drive would want to see a number-of-sector value.
  */
-static void
-size_to_buf(unsigned int size,
-            unsigned char *buf)
+static void size_to_buf(unsigned int size, unsigned char *buf)
 {
-   buf[0] = size / 65536;
-   size = size % 65536;
-   buf[1] = size / 256;
-   buf[2] = size % 256;
+	buf[0] = size / 65536;
+	size = size % 65536;
+	buf[1] = size / 256;
+	buf[2] = size % 256;
 }
 
 /* Starts a read operation. Returns 0 on success and 1 on failure. 
@@ -1211,430 +1153,380 @@
    operation if the requested sector is not the next one from the
    drive. */
 static int
-start_request(unsigned int sector,
-              unsigned int nsect,
-              int          read_nsect_only)
-{
-   unsigned char params[6];
-   unsigned int read_size;
-   unsigned int retry_count;
-
-
-#if DEBUG
-   printk("Entering start_request\n");
-#endif
-   log_to_msf(sector, params);
-   /* If requested, read exactly what was asked. */
-   if (read_nsect_only)
-   {
-      read_size = nsect;
-   }
-   /*
-    * If the full read-ahead would go beyond the end of the media, trim
-    * it back to read just till the end of the media.
-    */
-   else if ((sector + nsect) >= sony_toc.lead_out_start_lba)
-   {
-      read_size = sony_toc.lead_out_start_lba - sector;
-   }
-   /* Read the full readahead amount. */
-   else
-   {
-      read_size = CDU31A_READAHEAD / 4;
-   }
-   size_to_buf(read_size, &params[3]);
-
-   /*
-    * Clear any outstanding attentions and wait for the drive to
-    * complete any pending operations.
-    */
-   while (handle_sony_cd_attention())
-      ;
-
-   retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
-   while (time_before(jiffies, retry_count) && (is_busy()))
-   {
-      sony_sleep();
-      
-      while (handle_sony_cd_attention())
-         ;
-   }
-
-   if (is_busy())
-   {
-      printk("CDU31A: Timeout while waiting to issue command\n");
-#if DEBUG
-      printk("Leaving start_request at %d\n", __LINE__);
-#endif
-      return(1);
-   }
-   else
-   {
-      /* Issue the command */
-      clear_result_ready();
-      clear_param_reg();
-
-      write_params(params, 6);
-      write_cmd(SONY_READ_BLKERR_STAT_CMD);
-
-      sony_blocks_left = read_size * 4;
-      sony_next_block = sector * 4;
-      readahead_dataleft = 0;
-      readahead_bad = 0;
+start_request(unsigned int sector, unsigned int nsect, int read_nsect_only)
+{
+	unsigned char params[6];
+	unsigned int read_size;
+	unsigned int retry_count;
+
+
+#if DEBUG
+	printk("Entering start_request\n");
+#endif
+	log_to_msf(sector, params);
+	/* If requested, read exactly what was asked. */
+	if (read_nsect_only) {
+		read_size = nsect;
+	}
+	/*
+	 * If the full read-ahead would go beyond the end of the media, trim
+	 * it back to read just till the end of the media.
+	 */
+	else if ((sector + nsect) >= sony_toc.lead_out_start_lba) {
+		read_size = sony_toc.lead_out_start_lba - sector;
+	}
+	/* Read the full readahead amount. */
+	else {
+		read_size = CDU31A_READAHEAD / 4;
+	}
+	size_to_buf(read_size, &params[3]);
+
+	/*
+	 * Clear any outstanding attentions and wait for the drive to
+	 * complete any pending operations.
+	 */
+	while (handle_sony_cd_attention());
+
+	retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
+	while (time_before(jiffies, retry_count) && (is_busy())) {
+		sony_sleep();
+
+		while (handle_sony_cd_attention());
+	}
+
+	if (is_busy()) {
+		printk("CDU31A: Timeout while waiting to issue command\n");
+#if DEBUG
+		printk("Leaving start_request at %d\n", __LINE__);
+#endif
+		return (1);
+	} else {
+		/* Issue the command */
+		clear_result_ready();
+		clear_param_reg();
+
+		write_params(params, 6);
+		write_cmd(SONY_READ_BLKERR_STAT_CMD);
+
+		sony_blocks_left = read_size * 4;
+		sony_next_block = sector * 4;
+		readahead_dataleft = 0;
+		readahead_bad = 0;
 #if DEBUG
-      printk("Leaving start_request at %d\n", __LINE__);
+		printk("Leaving start_request at %d\n", __LINE__);
 #endif
-      return(0);
-   }
+		return (0);
+	}
 #if DEBUG
-   printk("Leaving start_request at %d\n", __LINE__);
+	printk("Leaving start_request at %d\n", __LINE__);
 #endif
 }
 
 /* Abort a pending read operation.  Clear all the drive status and
    readahead variables. */
-static void
-abort_read(void)
+static void abort_read(void)
 {
-   unsigned char result_reg[2];
-   int           result_size;
-   volatile int  val;
-
-
-   do_sony_cd_cmd(SONY_ABORT_CMD, NULL, 0, result_reg, &result_size);
-   if ((result_reg[0] & 0xf0) == 0x20)
-   {
-      printk("CDU31A: Error aborting read, %s error\n",
-             translate_error(
-             result_reg[1]));
-   }
-
-   while (is_result_reg_not_empty())
-   {
-      val = read_result_register();
-   }
-   clear_data_ready();
-   clear_result_ready();
-   /* Clear out the data */
-   while (is_data_requested())
-   {
-      val = read_data_register();
-   }
-
-   sony_blocks_left = 0;
-   readahead_dataleft = 0;
-   readahead_bad = 0;
+	unsigned char result_reg[2];
+	int result_size;
+	volatile int val;
+
+
+	do_sony_cd_cmd(SONY_ABORT_CMD, NULL, 0, result_reg, &result_size);
+	if ((result_reg[0] & 0xf0) == 0x20) {
+		printk("CDU31A: Error aborting read, %s error\n",
+		       translate_error(result_reg[1]));
+	}
+
+	while (is_result_reg_not_empty()) {
+		val = read_result_register();
+	}
+	clear_data_ready();
+	clear_result_ready();
+	/* Clear out the data */
+	while (is_data_requested()) {
+		val = read_data_register();
+	}
+
+	sony_blocks_left = 0;
+	readahead_dataleft = 0;
+	readahead_bad = 0;
 }
 
 /* Called when the timer times out.  This will abort the
    pending read operation. */
-static void
-handle_abort_timeout(unsigned long data)
+static void handle_abort_timeout(unsigned long data)
 {
-   unsigned long flags;
+	unsigned long flags;
 
 #if DEBUG
-   printk("Entering handle_abort_timeout\n");
+	printk("Entering handle_abort_timeout\n");
 #endif
-   save_flags(flags);
-   cli();
-   /* If it is in use, ignore it. */
-   if (!sony_inuse)
-   {
-      /* We can't use abort_read(), because it will sleep
-         or schedule in the timer interrupt.  Just start
-         the operation, finish it on the next access to
-         the drive. */
-      clear_result_ready();
-      clear_param_reg();
-      write_cmd(SONY_ABORT_CMD);
-
-      sony_blocks_left = 0;
-      readahead_dataleft = 0;
-      readahead_bad = 0;
-      abort_read_started = 1;
-   }
-   restore_flags(flags);
+	save_flags(flags);
+	cli();
+	/* If it is in use, ignore it. */
+	if (!sony_inuse) {
+		/* We can't use abort_read(), because it will sleep
+		   or schedule in the timer interrupt.  Just start
+		   the operation, finish it on the next access to
+		   the drive. */
+		clear_result_ready();
+		clear_param_reg();
+		write_cmd(SONY_ABORT_CMD);
+
+		sony_blocks_left = 0;
+		readahead_dataleft = 0;
+		readahead_bad = 0;
+		abort_read_started = 1;
+	}
+	restore_flags(flags);
 #if DEBUG
-   printk("Leaving handle_abort_timeout\n");
+	printk("Leaving handle_abort_timeout\n");
 #endif
 }
 
 /* Actually get data and status from the drive. */
 static void
-input_data(char         *buffer,
-           unsigned int bytesleft,
-           unsigned int nblocks,
-           unsigned int offset,
-           unsigned int skip)
-{
-   int i;
-   volatile unsigned char val;
+input_data(char *buffer,
+	   unsigned int bytesleft,
+	   unsigned int nblocks, unsigned int offset, unsigned int skip)
+{
+	int i;
+	volatile unsigned char val;
 
 
 #if DEBUG
-   printk("Entering input_data\n");
-#endif
-   /* If an XA disk on a CDU31A, skip the first 12 bytes of data from
-      the disk.  The real data is after that. */
-   if (sony_xa_mode)
-   {
-      for(i=0; i<CD_XA_HEAD; i++)
-      {
-         val = read_data_register();
-      }
-   }
-
-   clear_data_ready();
-
-   if (bytesleft == 2048) /* 2048 byte direct buffer transfer */
-   {
-      insb(sony_cd_read_reg, buffer, 2048);
-      readahead_dataleft = 0;
-   }
-   else
-   {
-      /* If the input read did not align with the beginning of the block,
-	 skip the necessary bytes. */
-      if (skip != 0)
-      {
-         insb(sony_cd_read_reg, readahead_buffer, skip);
-      }
-
-      /* Get the data into the buffer. */
-      insb(sony_cd_read_reg, &buffer[offset], bytesleft);
-
-      /* Get the rest of the data into the readahead buffer at the
-	 proper location. */
-      readahead_dataleft = (2048 - skip) - bytesleft;
-      insb(sony_cd_read_reg,
-           readahead_buffer + bytesleft,
-           readahead_dataleft);
-   }
-   sony_blocks_left -= nblocks;
-   sony_next_block += nblocks; 
-
-   /* If an XA disk, we have to clear out the rest of the unused
-      error correction data. */
-   if (sony_xa_mode)
-   {
-      for(i=0; i<CD_XA_TAIL; i++)
-      {
-         val = read_data_register();
-      }
-   }
+	printk("Entering input_data\n");
+#endif
+	/* If an XA disk on a CDU31A, skip the first 12 bytes of data from
+	   the disk.  The real data is after that. */
+	if (sony_xa_mode) {
+		for (i = 0; i < CD_XA_HEAD; i++) {
+			val = read_data_register();
+		}
+	}
+
+	clear_data_ready();
+
+	if (bytesleft == 2048) {	/* 2048 byte direct buffer transfer */
+		insb(sony_cd_read_reg, buffer, 2048);
+		readahead_dataleft = 0;
+	} else {
+		/* If the input read did not align with the beginning of the block,
+		   skip the necessary bytes. */
+		if (skip != 0) {
+			insb(sony_cd_read_reg, readahead_buffer, skip);
+		}
+
+		/* Get the data into the buffer. */
+		insb(sony_cd_read_reg, &buffer[offset], bytesleft);
+
+		/* Get the rest of the data into the readahead buffer at the
+		   proper location. */
+		readahead_dataleft = (2048 - skip) - bytesleft;
+		insb(sony_cd_read_reg,
+		     readahead_buffer + bytesleft, readahead_dataleft);
+	}
+	sony_blocks_left -= nblocks;
+	sony_next_block += nblocks;
+
+	/* If an XA disk, we have to clear out the rest of the unused
+	   error correction data. */
+	if (sony_xa_mode) {
+		for (i = 0; i < CD_XA_TAIL; i++) {
+			val = read_data_register();
+		}
+	}
 #if DEBUG
-   printk("Leaving input_data at %d\n", __LINE__);
+	printk("Leaving input_data at %d\n", __LINE__);
 #endif
 }
 
 /* read data from the drive.  Note the nsect must be <= 4. */
 static void
-read_data_block(char          *buffer,
-                unsigned int  block,
-                unsigned int  nblocks,
-                unsigned char res_reg[],
-                int           *res_size)
-{
-   unsigned int retry_count;
-   unsigned int bytesleft;
-   unsigned int offset;
-   unsigned int skip;
-
-
-#if DEBUG
-   printk("Entering read_data_block\n");
-#endif
-
-   res_reg[0] = 0;
-   res_reg[1] = 0;
-   *res_size = 0;
-   bytesleft = nblocks * 512;
-   offset = 0;
-
-   /* If the data in the read-ahead does not match the block offset,
-      then fix things up. */
-   if (((block % 4) * 512) != ((2048 - readahead_dataleft) % 2048))
-   {
-      sony_next_block += block % 4;
-      sony_blocks_left -= block % 4;
-      skip = (block % 4) * 512;
-   }
-   else
-   {
-      skip = 0;
-   }
-
-   /* We have readahead data in the buffer, get that first before we
-      decide if a read is necessary. */
-   if (readahead_dataleft != 0)
-   {
-      if (bytesleft > readahead_dataleft)
-      {
-	 /* The readahead will not fill the requested buffer, but
-	    get the data out of the readahead into the buffer. */
-         memcpy(buffer,
-                readahead_buffer + (2048 - readahead_dataleft),
-                readahead_dataleft);
-         readahead_dataleft = 0;
-         bytesleft -= readahead_dataleft;
-         offset += readahead_dataleft;
-      }
-      else
-      {
-	 /* The readahead will fill the whole buffer, get the data
-	    and return. */
-         memcpy(buffer,
-                readahead_buffer + (2048 - readahead_dataleft),
-                bytesleft);
-         readahead_dataleft -= bytesleft;
-         bytesleft = 0;
-         sony_blocks_left -= nblocks;
-         sony_next_block += nblocks;
-
-	 /* If the data in the readahead is bad, return an error so the
-	    driver will abort the buffer. */
-         if (readahead_bad)
-         {
-            res_reg[0] = 0x20;
-            res_reg[1] = SONY_BAD_DATA_ERR;
-            *res_size = 2;
-         }
-
-         if (readahead_dataleft == 0)
-         {
-            readahead_bad = 0;
-         }
-
-         /* Final transfer is done for read command, get final result. */
-         if (sony_blocks_left == 0)
-         {
-            get_result(res_reg, res_size);
-         }
-#if DEBUG
-         printk("Leaving read_data_block at %d\n", __LINE__);
-#endif
-         return;
-      }
-   }
-
-   /* Wait for the drive to tell us we have something */
-   retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
-   while (time_before(jiffies, retry_count) && !(is_data_ready()))
-   {
-      while (handle_sony_cd_attention())
-         ;
-
-      sony_sleep();
-   }
-   if (!(is_data_ready()))
-   {
-      if (is_result_ready())
-      {
-         get_result(res_reg, res_size);
-         if ((res_reg[0] & 0xf0) != 0x20)
-         {
-            printk("CDU31A: Got result that should have been error: %d\n",
-                   res_reg[0]);
-            res_reg[0] = 0x20;
-            res_reg[1] = SONY_BAD_DATA_ERR;
-            *res_size = 2;
-         }
-         abort_read();
-      }
-      else
-      {
-#if DEBUG
-         printk("CDU31A timeout out %d\n", __LINE__);
-#endif
-         res_reg[0] = 0x20;
-         res_reg[1] = SONY_TIMEOUT_OP_ERR;
-         *res_size = 2;
-         abort_read();
-      }
-   }
-   else
-   {
-      input_data(buffer, bytesleft, nblocks, offset, skip);
-
-      /* Wait for the status from the drive. */
-      retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
-      while (time_before(jiffies, retry_count) && !(is_result_ready()))
-      {
-         while (handle_sony_cd_attention())
-            ;
-
-         sony_sleep();
-      }
-
-      if (!is_result_ready())
-      {
-#if DEBUG
-         printk("CDU31A timeout out %d\n", __LINE__);
-#endif
-         res_reg[0] = 0x20;
-         res_reg[1] = SONY_TIMEOUT_OP_ERR;
-         *res_size = 2;
-         abort_read();
-      }
-      else
-      {
-         get_result(res_reg, res_size);
-
-	 /* If we got a buffer status, handle that. */
-         if ((res_reg[0] & 0xf0) == 0x50)
-         {
-
-            if (   (res_reg[0] == SONY_NO_CIRC_ERR_BLK_STAT)
-                || (res_reg[0] == SONY_NO_LECC_ERR_BLK_STAT)
-                || (res_reg[0] == SONY_RECOV_LECC_ERR_BLK_STAT))
-            {
-	       /* The data was successful, but if data was read from
-		  the readahead  and it was bad, set the whole
-		  buffer as bad. */
-               if (readahead_bad)
-               {
-                  readahead_bad = 0;
-                  res_reg[0] = 0x20;
-                  res_reg[1] = SONY_BAD_DATA_ERR;
-                  *res_size = 2;
-               }
-            }
-            else
-            {
-               printk("CDU31A: Data block error: 0x%x\n", res_reg[0]);
-               res_reg[0] = 0x20;
-               res_reg[1] = SONY_BAD_DATA_ERR;
-               *res_size = 2;
-
-               /* Data is in the readahead buffer but an error was returned.
-                  Make sure future requests don't use the data. */
-               if (bytesleft != 2048)
-               {
-                  readahead_bad = 1;
-               }
-            }
-
-            /* Final transfer is done for read command, get final result. */
-            if (sony_blocks_left == 0)
-            {
-               get_result(res_reg, res_size);
-            }
-         }
-         else if ((res_reg[0] & 0xf0) != 0x20)
-         {
-            /* The drive gave me bad status, I don't know what to do.
-               Reset the driver and return an error. */
-            printk("CDU31A: Invalid block status: 0x%x\n", res_reg[0]);
-            restart_on_error();
-            res_reg[0] = 0x20;
-            res_reg[1] = SONY_BAD_DATA_ERR;
-            *res_size = 2;
-         }
-      }
-   }
+read_data_block(char *buffer,
+		unsigned int block,
+		unsigned int nblocks,
+		unsigned char res_reg[], int *res_size)
+{
+	unsigned int retry_count;
+	unsigned int bytesleft;
+	unsigned int offset;
+	unsigned int skip;
+
+
+#if DEBUG
+	printk("Entering read_data_block\n");
+#endif
+
+	res_reg[0] = 0;
+	res_reg[1] = 0;
+	*res_size = 0;
+	bytesleft = nblocks * 512;
+	offset = 0;
+
+	/* If the data in the read-ahead does not match the block offset,
+	   then fix things up. */
+	if (((block % 4) * 512) != ((2048 - readahead_dataleft) % 2048)) {
+		sony_next_block += block % 4;
+		sony_blocks_left -= block % 4;
+		skip = (block % 4) * 512;
+	} else {
+		skip = 0;
+	}
+
+	/* We have readahead data in the buffer, get that first before we
+	   decide if a read is necessary. */
+	if (readahead_dataleft != 0) {
+		if (bytesleft > readahead_dataleft) {
+			/* The readahead will not fill the requested buffer, but
+			   get the data out of the readahead into the buffer. */
+			memcpy(buffer,
+			       readahead_buffer + (2048 -
+						   readahead_dataleft),
+			       readahead_dataleft);
+			readahead_dataleft = 0;
+			bytesleft -= readahead_dataleft;
+			offset += readahead_dataleft;
+		} else {
+			/* The readahead will fill the whole buffer, get the data
+			   and return. */
+			memcpy(buffer,
+			       readahead_buffer + (2048 -
+						   readahead_dataleft),
+			       bytesleft);
+			readahead_dataleft -= bytesleft;
+			bytesleft = 0;
+			sony_blocks_left -= nblocks;
+			sony_next_block += nblocks;
+
+			/* If the data in the readahead is bad, return an error so the
+			   driver will abort the buffer. */
+			if (readahead_bad) {
+				res_reg[0] = 0x20;
+				res_reg[1] = SONY_BAD_DATA_ERR;
+				*res_size = 2;
+			}
+
+			if (readahead_dataleft == 0) {
+				readahead_bad = 0;
+			}
+
+			/* Final transfer is done for read command, get final result. */
+			if (sony_blocks_left == 0) {
+				get_result(res_reg, res_size);
+			}
+#if DEBUG
+			printk("Leaving read_data_block at %d\n",
+			       __LINE__);
+#endif
+			return;
+		}
+	}
+
+	/* Wait for the drive to tell us we have something */
+	retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
+	while (time_before(jiffies, retry_count) && !(is_data_ready())) {
+		while (handle_sony_cd_attention());
+
+		sony_sleep();
+	}
+	if (!(is_data_ready())) {
+		if (is_result_ready()) {
+			get_result(res_reg, res_size);
+			if ((res_reg[0] & 0xf0) != 0x20) {
+				printk
+				    ("CDU31A: Got result that should have been error: %d\n",
+				     res_reg[0]);
+				res_reg[0] = 0x20;
+				res_reg[1] = SONY_BAD_DATA_ERR;
+				*res_size = 2;
+			}
+			abort_read();
+		} else {
+#if DEBUG
+			printk("CDU31A timeout out %d\n", __LINE__);
+#endif
+			res_reg[0] = 0x20;
+			res_reg[1] = SONY_TIMEOUT_OP_ERR;
+			*res_size = 2;
+			abort_read();
+		}
+	} else {
+		input_data(buffer, bytesleft, nblocks, offset, skip);
+
+		/* Wait for the status from the drive. */
+		retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
+		while (time_before(jiffies, retry_count)
+		       && !(is_result_ready())) {
+			while (handle_sony_cd_attention());
+
+			sony_sleep();
+		}
+
+		if (!is_result_ready()) {
+#if DEBUG
+			printk("CDU31A timeout out %d\n", __LINE__);
+#endif
+			res_reg[0] = 0x20;
+			res_reg[1] = SONY_TIMEOUT_OP_ERR;
+			*res_size = 2;
+			abort_read();
+		} else {
+			get_result(res_reg, res_size);
+
+			/* If we got a buffer status, handle that. */
+			if ((res_reg[0] & 0xf0) == 0x50) {
+
+				if ((res_reg[0] ==
+				     SONY_NO_CIRC_ERR_BLK_STAT)
+				    || (res_reg[0] ==
+					SONY_NO_LECC_ERR_BLK_STAT)
+				    || (res_reg[0] ==
+					SONY_RECOV_LECC_ERR_BLK_STAT)) {
+					/* The data was successful, but if data was read from
+					   the readahead  and it was bad, set the whole
+					   buffer as bad. */
+					if (readahead_bad) {
+						readahead_bad = 0;
+						res_reg[0] = 0x20;
+						res_reg[1] =
+						    SONY_BAD_DATA_ERR;
+						*res_size = 2;
+					}
+				} else {
+					printk
+					    ("CDU31A: Data block error: 0x%x\n",
+					     res_reg[0]);
+					res_reg[0] = 0x20;
+					res_reg[1] = SONY_BAD_DATA_ERR;
+					*res_size = 2;
+
+					/* Data is in the readahead buffer but an error was returned.
+					   Make sure future requests don't use the data. */
+					if (bytesleft != 2048) {
+						readahead_bad = 1;
+					}
+				}
+
+				/* Final transfer is done for read command, get final result. */
+				if (sony_blocks_left == 0) {
+					get_result(res_reg, res_size);
+				}
+			} else if ((res_reg[0] & 0xf0) != 0x20) {
+				/* The drive gave me bad status, I don't know what to do.
+				   Reset the driver and return an error. */
+				printk
+				    ("CDU31A: Invalid block status: 0x%x\n",
+				     res_reg[0]);
+				restart_on_error();
+				res_reg[0] = 0x20;
+				res_reg[1] = SONY_BAD_DATA_ERR;
+				*res_size = 2;
+			}
+		}
+	}
 #if DEBUG
-   printk("Leaving read_data_block at %d\n", __LINE__);
+	printk("Leaving read_data_block at %d\n", __LINE__);
 #endif
 }
 
@@ -1646,230 +1538,215 @@
  * uses 1024 byte blocks and the drive uses 2048 byte blocks.  Since most
  * data access on a CD is done sequentially, this saves a lot of operations.
  */
-static void
-do_cdu31a_request(request_queue_t * q)
+static void do_cdu31a_request(request_queue_t * q)
 {
-   int block;
-   int nblock;
-   unsigned char res_reg[12];
-   unsigned int res_size;
-   int num_retries;
-   unsigned long flags;
-
-
-#if DEBUG
-         printk("Entering do_cdu31a_request\n");
-#endif
-
-   /* 
-    * Make sure no one else is using the driver; wait for them
-    * to finish if it is so.
-    */
-   save_flags(flags);
-   cli();
-   while (sony_inuse)
-   {
-      interruptible_sleep_on(&sony_wait);
-      if (signal_pending(current))
-      {
-         restore_flags(flags);
-         if (!QUEUE_EMPTY && CURRENT->rq_status != RQ_INACTIVE)
-         {
-            end_request(0);
-         }
-         restore_flags(flags);
-#if DEBUG
-         printk("Leaving do_cdu31a_request at %d\n", __LINE__);
-#endif
-         return;
-      }
-   }
-   sony_inuse = 1;
-   has_cd_task = current;
-
-   /* Get drive status before doing anything. */
-   while (handle_sony_cd_attention())
-      ;
-
-   /* Make sure we have a valid TOC. */
-   sony_get_toc(); 
-
-   spin_unlock_irq(&io_request_lock);
-
-   /* Make sure the timer is cancelled. */
-   del_timer(&cdu31a_abort_timer);
-
-   while (1)
-   {
-cdu31a_request_startover:
-      /*
-       * The beginning here is stolen from the hard disk driver.  I hope
-       * it's right.
-       */
-      if (QUEUE_EMPTY || CURRENT->rq_status == RQ_INACTIVE)
-      {
-         goto end_do_cdu31a_request;
-      }
-
-      if (!sony_spun_up)
-      {
-         scd_spinup();
-      }
-
-      /* I don't use INIT_REQUEST because it calls return, which would
-         return without unlocking the device.  It shouldn't matter,
-         but just to be safe... */
-      if (MAJOR(CURRENT->rq_dev) != MAJOR_NR)
-      {
-	 panic(DEVICE_NAME ": request list destroyed");
-      }
-      if (CURRENT->bh)
-      {
-	 if (!buffer_locked(CURRENT->bh))
-         {
-	    panic(DEVICE_NAME ": block not locked");
-         }
-      }
-
-      block = CURRENT->sector;
-      nblock = CURRENT->nr_sectors;
-
-      if (!sony_toc_read)
-      {
-	 printk("CDU31A: TOC not read\n");
-	 end_request(0);
-	 goto cdu31a_request_startover;
-      }
-
-      switch(CURRENT->cmd)
-      {
-      case READ:
-         /*
-          * If the block address is invalid or the request goes beyond the end of
-          * the media, return an error.
-          */
+	int block;
+	int nblock;
+	unsigned char res_reg[12];
+	unsigned int res_size;
+	int num_retries;
+	unsigned long flags;
+
+
+#if DEBUG
+	printk("Entering do_cdu31a_request\n");
+#endif
+
+	/* 
+	 * Make sure no one else is using the driver; wait for them
+	 * to finish if it is so.
+	 */
+	save_flags(flags);
+	cli();
+	while (sony_inuse) {
+		interruptible_sleep_on(&sony_wait);
+		if (signal_pending(current)) {
+			restore_flags(flags);
+			if (!QUEUE_EMPTY
+			    && CURRENT->rq_status != RQ_INACTIVE) {
+				end_request(0);
+			}
+			restore_flags(flags);
+#if DEBUG
+			printk("Leaving do_cdu31a_request at %d\n",
+			       __LINE__);
+#endif
+			return;
+		}
+	}
+	sony_inuse = 1;
+	has_cd_task = current;
+
+	/* Get drive status before doing anything. */
+	while (handle_sony_cd_attention());
+
+	/* Make sure we have a valid TOC. */
+	sony_get_toc();
+
+	spin_unlock_irq(&io_request_lock);
+
+	/* Make sure the timer is cancelled. */
+	del_timer(&cdu31a_abort_timer);
+
+	while (1) {
+	      cdu31a_request_startover:
+		/*
+		 * The beginning here is stolen from the hard disk driver.  I hope
+		 * it's right.
+		 */
+		if (QUEUE_EMPTY || CURRENT->rq_status == RQ_INACTIVE) {
+			goto end_do_cdu31a_request;
+		}
+
+		if (!sony_spun_up) {
+			scd_spinup();
+		}
+
+		/* I don't use INIT_REQUEST because it calls return, which would
+		   return without unlocking the device.  It shouldn't matter,
+		   but just to be safe... */
+		if (MAJOR(CURRENT->rq_dev) != MAJOR_NR) {
+			panic(DEVICE_NAME ": request list destroyed");
+		}
+		if (CURRENT->bh) {
+			if (!buffer_locked(CURRENT->bh)) {
+				panic(DEVICE_NAME ": block not locked");
+			}
+		}
+
+		block = CURRENT->sector;
+		nblock = CURRENT->nr_sectors;
+
+		if (!sony_toc_read) {
+			printk("CDU31A: TOC not read\n");
+			end_request(0);
+			goto cdu31a_request_startover;
+		}
+
+		switch (CURRENT->cmd) {
+		case READ:
+			/*
+			 * If the block address is invalid or the request goes beyond the end of
+			 * the media, return an error.
+			 */
 #if 0
-	 if ((block / 4) < sony_toc.start_track_lba)
-	 {
-            printk("CDU31A: Request before beginning of media\n");
-            end_request(0);
-            goto cdu31a_request_startover;
-	 }
-#endif
-         if ((block / 4) >= sony_toc.lead_out_start_lba)
-         {
-            printk("CDU31A: Request past end of media\n");
-            end_request(0);
-            goto cdu31a_request_startover;
-         }
-         if (((block + nblock) / 4) >= sony_toc.lead_out_start_lba)
-         {
-            printk("CDU31A: Request past end of media\n");
-            end_request(0);
-            goto cdu31a_request_startover;
-         }
-
-         num_retries = 0;
-
-try_read_again:
-         while (handle_sony_cd_attention())
-            ;
-
-         if (!sony_toc_read)
-         {
-	    printk("CDU31A: TOC not read\n");
-	    end_request(0);
-	    goto cdu31a_request_startover;
-         }
-
-	 /* If no data is left to be read from the drive, start the
-	    next request. */
-         if (sony_blocks_left == 0)
-         {
-            if (start_request(block / 4, CDU31A_READAHEAD / 4, 0))
-            {
-               end_request(0);
-               goto cdu31a_request_startover;
-            }
-         }
-	 /* If the requested block is not the next one waiting in
-	    the driver, abort the current operation and start a
-	    new one. */
-         else if (block != sony_next_block)
-         {
-#if DEBUG
-            printk("CDU31A Warning: Read for block %d, expected %d\n",
-                   block,
-                   sony_next_block);
-#endif
-            abort_read();
-            if (!sony_toc_read)
-            {
-	       printk("CDU31A: TOC not read\n");
-	       end_request(0);
-               goto cdu31a_request_startover;
-            }
-            if (start_request(block / 4, CDU31A_READAHEAD / 4, 0))
-            {
-               printk("CDU31a: start request failed\n");
-               end_request(0);
-               goto cdu31a_request_startover;
-            }
-         }
-
-         read_data_block(CURRENT->buffer, block, nblock, res_reg, &res_size);
-         if (res_reg[0] == 0x20)
-         {
-            if (num_retries > MAX_CDU31A_RETRIES)
-            {
-               end_request(0);
-               goto cdu31a_request_startover;
-            }
-
-            num_retries++;
-            if (res_reg[1] == SONY_NOT_SPIN_ERR)
-            {
-               do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
-            }
-            else
-            {
-               printk("CDU31A: %s error for block %d, nblock %d\n", translate_error(res_reg[1]), block, nblock);
-            }
-            goto try_read_again;
-         }
-         else
-         {
-            end_request(1);
-         }
-         break;
-            
-      case WRITE:
-         end_request(0);
-         break;
-            
-      default:
-         panic("CDU31A: Unknown cmd");
-      }
-   }
+			if ((block / 4) < sony_toc.start_track_lba) {
+				printk
+				    ("CDU31A: Request before beginning of media\n");
+				end_request(0);
+				goto cdu31a_request_startover;
+			}
+#endif
+			if ((block / 4) >= sony_toc.lead_out_start_lba) {
+				printk
+				    ("CDU31A: Request past end of media\n");
+				end_request(0);
+				goto cdu31a_request_startover;
+			}
+			if (((block + nblock) / 4) >=
+			    sony_toc.lead_out_start_lba) {
+				printk
+				    ("CDU31A: Request past end of media\n");
+				end_request(0);
+				goto cdu31a_request_startover;
+			}
+
+			num_retries = 0;
+
+		      try_read_again:
+			while (handle_sony_cd_attention());
+
+			if (!sony_toc_read) {
+				printk("CDU31A: TOC not read\n");
+				end_request(0);
+				goto cdu31a_request_startover;
+			}
+
+			/* If no data is left to be read from the drive, start the
+			   next request. */
+			if (sony_blocks_left == 0) {
+				if (start_request
+				    (block / 4, CDU31A_READAHEAD / 4, 0)) {
+					end_request(0);
+					goto cdu31a_request_startover;
+				}
+			}
+			/* If the requested block is not the next one waiting in
+			   the driver, abort the current operation and start a
+			   new one. */
+			else if (block != sony_next_block) {
+#if DEBUG
+				printk
+				    ("CDU31A Warning: Read for block %d, expected %d\n",
+				     block, sony_next_block);
+#endif
+				abort_read();
+				if (!sony_toc_read) {
+					printk("CDU31A: TOC not read\n");
+					end_request(0);
+					goto cdu31a_request_startover;
+				}
+				if (start_request
+				    (block / 4, CDU31A_READAHEAD / 4, 0)) {
+					printk
+					    ("CDU31a: start request failed\n");
+					end_request(0);
+					goto cdu31a_request_startover;
+				}
+			}
+
+			read_data_block(CURRENT->buffer, block, nblock,
+					res_reg, &res_size);
+			if (res_reg[0] == 0x20) {
+				if (num_retries > MAX_CDU31A_RETRIES) {
+					end_request(0);
+					goto cdu31a_request_startover;
+				}
+
+				num_retries++;
+				if (res_reg[1] == SONY_NOT_SPIN_ERR) {
+					do_sony_cd_cmd(SONY_SPIN_UP_CMD,
+						       NULL, 0, res_reg,
+						       &res_size);
+				} else {
+					printk
+					    ("CDU31A: %s error for block %d, nblock %d\n",
+					     translate_error(res_reg[1]),
+					     block, nblock);
+				}
+				goto try_read_again;
+			} else {
+				end_request(1);
+			}
+			break;
+
+		case WRITE:
+			end_request(0);
+			break;
+
+		default:
+			panic("CDU31A: Unknown cmd");
+		}
+	}
 
-end_do_cdu31a_request:
-   spin_lock_irq(&io_request_lock);
+      end_do_cdu31a_request:
+	spin_lock_irq(&io_request_lock);
 #if 0
-   /* After finished, cancel any pending operations. */
-   abort_read();
+	/* After finished, cancel any pending operations. */
+	abort_read();
 #else
-   /* Start a timer to time out after a while to disable
-      the read. */
-   cdu31a_abort_timer.expires = jiffies + 2*HZ; /* Wait 2 seconds */
-   add_timer(&cdu31a_abort_timer);
+	/* Start a timer to time out after a while to disable
+	   the read. */
+	cdu31a_abort_timer.expires = jiffies + 2 * HZ;	/* Wait 2 seconds */
+	add_timer(&cdu31a_abort_timer);
 #endif
 
-   has_cd_task = NULL;
-   sony_inuse = 0;
-   wake_up_interruptible(&sony_wait);
-   restore_flags(flags);
+	has_cd_task = NULL;
+	sony_inuse = 0;
+	wake_up_interruptible(&sony_wait);
+	restore_flags(flags);
 #if DEBUG
-   printk("Leaving do_cdu31a_request at %d\n", __LINE__);
+	printk("Leaving do_cdu31a_request at %d\n", __LINE__);
 #endif
 }
 
@@ -1878,356 +1755,473 @@
  * Read the table of contents from the drive and set up TOC if
  * successful.
  */
-static void
-sony_get_toc(void)
+static void sony_get_toc(void)
 {
-   unsigned char res_reg[2];
-   unsigned int res_size;
-   unsigned char parms[1];
-   int session;
-   int num_spin_ups;
-   int totaltracks = 0;
-   int mint = 99;
-   int maxt = 0;
-
-#if DEBUG
-   printk("Entering sony_get_toc\n");
-#endif
-
-   num_spin_ups = 0;
-   if (!sony_toc_read)
-   {
-respinup_on_gettoc:
-      /* Ignore the result, since it might error if spinning already. */
-      do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
-
-      do_sony_cd_cmd(SONY_READ_TOC_CMD, NULL, 0, res_reg, &res_size);
-
-      /* The drive sometimes returns error 0.  I don't know why, but ignore
-         it.  It seems to mean the drive has already done the operation. */
-      if ((res_size < 2) || ((res_reg[0] != 0) && (res_reg[1] != 0)))
-      {
-         /* If the drive is already playing, it's ok.  */
-         if ((res_reg[1] == SONY_AUDIO_PLAYING_ERR) || (res_reg[1] == 0))
-         {
-            goto gettoc_drive_spinning;
-         }
-
-         /* If the drive says it is not spun up (even though we just did it!)
-            then retry the operation at least a few times. */
-         if (   (res_reg[1] == SONY_NOT_SPIN_ERR)
-             && (num_spin_ups < MAX_CDU31A_RETRIES))
-         {
-            num_spin_ups++;
-            goto respinup_on_gettoc;
-         }
-
-         printk("cdu31a: Error reading TOC: %x %s\n",
-                res_reg[0], translate_error(res_reg[1]));
-	 return;
-      }
-
-gettoc_drive_spinning:
-
-      /* The idea here is we keep asking for sessions until the command
-	 fails.  Then we know what the last valid session on the disk is.
-	 No need to check session 0, since session 0 is the same as session
-         1; the command returns different information if you give it 0. 
-        */
-#if DEBUG
-      memset(&sony_toc, 0x0e, sizeof(sony_toc));
-      memset(&single_toc, 0x0f, sizeof(single_toc));
-#endif
-      session = 1;
-      while (1)
-      {
+	unsigned char res_reg[2];
+	unsigned int res_size;
+	unsigned char parms[1];
+	int session;
+	int num_spin_ups;
+	int totaltracks = 0;
+	int mint = 99;
+	int maxt = 0;
+
+#if DEBUG
+	printk("Entering sony_get_toc\n");
+#endif
+
+	num_spin_ups = 0;
+	if (!sony_toc_read) {
+	      respinup_on_gettoc:
+		/* Ignore the result, since it might error if spinning already. */
+		do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
+			       &res_size);
+
+		do_sony_cd_cmd(SONY_READ_TOC_CMD, NULL, 0, res_reg,
+			       &res_size);
+
+		/* The drive sometimes returns error 0.  I don't know why, but ignore
+		   it.  It seems to mean the drive has already done the operation. */
+		if ((res_size < 2)
+		    || ((res_reg[0] != 0) && (res_reg[1] != 0))) {
+			/* If the drive is already playing, it's ok.  */
+			if ((res_reg[1] == SONY_AUDIO_PLAYING_ERR)
+			    || (res_reg[1] == 0)) {
+				goto gettoc_drive_spinning;
+			}
+
+			/* If the drive says it is not spun up (even though we just did it!)
+			   then retry the operation at least a few times. */
+			if ((res_reg[1] == SONY_NOT_SPIN_ERR)
+			    && (num_spin_ups < MAX_CDU31A_RETRIES)) {
+				num_spin_ups++;
+				goto respinup_on_gettoc;
+			}
+
+			printk("cdu31a: Error reading TOC: %x %s\n",
+			       res_reg[0], translate_error(res_reg[1]));
+			return;
+		}
+
+	      gettoc_drive_spinning:
+
+		/* The idea here is we keep asking for sessions until the command
+		   fails.  Then we know what the last valid session on the disk is.
+		   No need to check session 0, since session 0 is the same as session
+		   1; the command returns different information if you give it 0. 
+		 */
+#if DEBUG
+		memset(&sony_toc, 0x0e, sizeof(sony_toc));
+		memset(&single_toc, 0x0f, sizeof(single_toc));
+#endif
+		session = 1;
+		while (1) {
 /* This seems to slow things down enough to make it work.  This
  * appears to be a problem in do_sony_cd_cmd.  This printk seems 
  * to address the symptoms...  -Erik */
 #if 1
-         printk("cdu31a: Trying session %d\n", session);
+			printk("cdu31a: Trying session %d\n", session);
 #endif
-	 parms[0] = session;
-	 do_sony_cd_cmd(SONY_READ_TOC_SPEC_CMD,
-			parms,
-			1, 
-			res_reg,
-			&res_size);
-
-#if DEBUG
-         printk("%2.2x %2.2x\n", res_reg[0], res_reg[1]);
-#endif
-
-	 if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
-	 {
-	    /* An error reading the TOC, this must be past the last session. */
-	     if (session == 1)
-		    printk("Yikes! Couldn't read any sessions!");
-	    break;
-         }
-#if DEBUG
-         printk("Reading session %d\n", session);
-#endif
-
-         parms[0] = session;
-         do_sony_cd_cmd(SONY_REQ_TOC_DATA_SPEC_CMD,
-		     parms,
-		     1, 
-		     (unsigned char *) &single_toc, 
-		     &res_size);
-         if ((res_size < 2) || ((single_toc.exec_status[0] & 0xf0) == 0x20))
-         {
-            printk("cdu31a: Error reading session %d: %x %s\n",
-                session,
-                single_toc.exec_status[0],
-                translate_error(single_toc.exec_status[1]));
-	    /* An error reading the TOC.  Return without sony_toc_read
-	       set. */
-	    return;
-         }
-#if DEBUG
-      printk("add0 %01x, con0 %01x, poi0 %02x, 1st trk %d, dsktyp %x, dum0 %x\n",
-              single_toc.address0, single_toc.control0, single_toc.point0,
-              bcd_to_int(single_toc.first_track_num), single_toc.disk_type, single_toc.dummy0);
-      printk("add1 %01x, con1 %01x, poi1 %02x, lst trk %d, dummy1 %x, dum2 %x\n",
-              single_toc.address1, single_toc.control1, single_toc.point1,
-              bcd_to_int(single_toc.last_track_num), single_toc.dummy1, single_toc.dummy2);
-      printk("add2 %01x, con2 %01x, poi2 %02x leadout start min %d, sec %d, frame %d\n",
-              single_toc.address2, single_toc.control2, single_toc.point2,
-              bcd_to_int(single_toc.lead_out_start_msf[0]),
-              bcd_to_int(single_toc.lead_out_start_msf[1]),
-              bcd_to_int(single_toc.lead_out_start_msf[2]));
-      if (res_size > 18 && single_toc.pointb0 > 0xaf)
-      printk("addb0 %01x, conb0 %01x, poib0 %02x, nextsession min %d, sec %d, frame %d\n"
-             "#mode5_ptrs %02d, max_start_outer_leadout_msf min %d, sec %d, frame %d\n",
-              single_toc.addressb0, single_toc.controlb0, single_toc.pointb0,
-              bcd_to_int(single_toc.next_poss_prog_area_msf[0]),
-              bcd_to_int(single_toc.next_poss_prog_area_msf[1]),
-              bcd_to_int(single_toc.next_poss_prog_area_msf[2]),
-              single_toc.num_mode_5_pointers,
-              bcd_to_int(single_toc.max_start_outer_leadout_msf[0]),
-              bcd_to_int(single_toc.max_start_outer_leadout_msf[1]),
-              bcd_to_int(single_toc.max_start_outer_leadout_msf[2]));
-      if (res_size > 27 && single_toc.pointb1 > 0xaf)
-      printk("addb1 %01x, conb1 %01x, poib1 %02x, %x %x %x %x #skipint_ptrs %d, #skiptrkassign %d %x\n",
-              single_toc.addressb1, single_toc.controlb1, single_toc.pointb1,
-              single_toc.dummyb0_1[0],
-              single_toc.dummyb0_1[1],
-              single_toc.dummyb0_1[2],
-              single_toc.dummyb0_1[3],
-              single_toc.num_skip_interval_pointers,
-              single_toc.num_skip_track_assignments,
-              single_toc.dummyb0_2);
-      if (res_size > 36 && single_toc.pointb2 > 0xaf)
-      printk("addb2 %01x, conb2 %01x, poib2 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
-              single_toc.addressb2, single_toc.controlb2, single_toc.pointb2,
-              single_toc.tracksb2[0],
-              single_toc.tracksb2[1],
-              single_toc.tracksb2[2],
-              single_toc.tracksb2[3],
-              single_toc.tracksb2[4],
-              single_toc.tracksb2[5],
-              single_toc.tracksb2[6]);
-      if (res_size > 45 && single_toc.pointb3 > 0xaf)
-      printk("addb3 %01x, conb3 %01x, poib3 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
-              single_toc.addressb3, single_toc.controlb3, single_toc.pointb3,
-              single_toc.tracksb3[0],
-              single_toc.tracksb3[1],
-              single_toc.tracksb3[2],
-              single_toc.tracksb3[3],
-              single_toc.tracksb3[4],
-              single_toc.tracksb3[5],
-              single_toc.tracksb3[6]);
-      if (res_size > 54 && single_toc.pointb4 > 0xaf)
-      printk("addb4 %01x, conb4 %01x, poib4 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
-              single_toc.addressb4, single_toc.controlb4, single_toc.pointb4,
-              single_toc.tracksb4[0],
-              single_toc.tracksb4[1],
-              single_toc.tracksb4[2],
-              single_toc.tracksb4[3],
-              single_toc.tracksb4[4],
-              single_toc.tracksb4[5],
-              single_toc.tracksb4[6]);
-      if (res_size > 63 && single_toc.pointc0 > 0xaf)
-      printk("addc0 %01x, conc0 %01x, poic0 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
-              single_toc.addressc0, single_toc.controlc0, single_toc.pointc0,
-              single_toc.dummyc0[0],
-              single_toc.dummyc0[1],
-              single_toc.dummyc0[2],
-              single_toc.dummyc0[3],
-              single_toc.dummyc0[4],
-              single_toc.dummyc0[5],
-              single_toc.dummyc0[6]);
+			parms[0] = session;
+			do_sony_cd_cmd(SONY_READ_TOC_SPEC_CMD,
+				       parms, 1, res_reg, &res_size);
+
+#if DEBUG
+			printk("%2.2x %2.2x\n", res_reg[0], res_reg[1]);
+#endif
+
+			if ((res_size < 2)
+			    || ((res_reg[0] & 0xf0) == 0x20)) {
+				/* An error reading the TOC, this must be past the last session. */
+				if (session == 1)
+					printk
+					    ("Yikes! Couldn't read any sessions!");
+				break;
+			}
+#if DEBUG
+			printk("Reading session %d\n", session);
+#endif
+
+			parms[0] = session;
+			do_sony_cd_cmd(SONY_REQ_TOC_DATA_SPEC_CMD,
+				       parms,
+				       1,
+				       (unsigned char *) &single_toc,
+				       &res_size);
+			if ((res_size < 2)
+			    || ((single_toc.exec_status[0] & 0xf0) ==
+				0x20)) {
+				printk
+				    ("cdu31a: Error reading session %d: %x %s\n",
+				     session, single_toc.exec_status[0],
+				     translate_error(single_toc.
+						     exec_status[1]));
+				/* An error reading the TOC.  Return without sony_toc_read
+				   set. */
+				return;
+			}
+#if DEBUG
+			printk
+			    ("add0 %01x, con0 %01x, poi0 %02x, 1st trk %d, dsktyp %x, dum0 %x\n",
+			     single_toc.address0, single_toc.control0,
+			     single_toc.point0,
+			     bcd_to_int(single_toc.first_track_num),
+			     single_toc.disk_type, single_toc.dummy0);
+			printk
+			    ("add1 %01x, con1 %01x, poi1 %02x, lst trk %d, dummy1 %x, dum2 %x\n",
+			     single_toc.address1, single_toc.control1,
+			     single_toc.point1,
+			     bcd_to_int(single_toc.last_track_num),
+			     single_toc.dummy1, single_toc.dummy2);
+			printk
+			    ("add2 %01x, con2 %01x, poi2 %02x leadout start min %d, sec %d, frame %d\n",
+			     single_toc.address2, single_toc.control2,
+			     single_toc.point2,
+			     bcd_to_int(single_toc.lead_out_start_msf[0]),
+			     bcd_to_int(single_toc.lead_out_start_msf[1]),
+			     bcd_to_int(single_toc.lead_out_start_msf[2]));
+			if (res_size > 18 && single_toc.pointb0 > 0xaf)
+				printk
+				    ("addb0 %01x, conb0 %01x, poib0 %02x, nextsession min %d, sec %d, frame %d\n"
+				     "#mode5_ptrs %02d, max_start_outer_leadout_msf min %d, sec %d, frame %d\n",
+				     single_toc.addressb0,
+				     single_toc.controlb0,
+				     single_toc.pointb0,
+				     bcd_to_int(single_toc.
+						next_poss_prog_area_msf
+						[0]),
+				     bcd_to_int(single_toc.
+						next_poss_prog_area_msf
+						[1]),
+				     bcd_to_int(single_toc.
+						next_poss_prog_area_msf
+						[2]),
+				     single_toc.num_mode_5_pointers,
+				     bcd_to_int(single_toc.
+						max_start_outer_leadout_msf
+						[0]),
+				     bcd_to_int(single_toc.
+						max_start_outer_leadout_msf
+						[1]),
+				     bcd_to_int(single_toc.
+						max_start_outer_leadout_msf
+						[2]));
+			if (res_size > 27 && single_toc.pointb1 > 0xaf)
+				printk
+				    ("addb1 %01x, conb1 %01x, poib1 %02x, %x %x %x %x #skipint_ptrs %d, #skiptrkassign %d %x\n",
+				     single_toc.addressb1,
+				     single_toc.controlb1,
+				     single_toc.pointb1,
+				     single_toc.dummyb0_1[0],
+				     single_toc.dummyb0_1[1],
+				     single_toc.dummyb0_1[2],
+				     single_toc.dummyb0_1[3],
+				     single_toc.num_skip_interval_pointers,
+				     single_toc.num_skip_track_assignments,
+				     single_toc.dummyb0_2);
+			if (res_size > 36 && single_toc.pointb2 > 0xaf)
+				printk
+				    ("addb2 %01x, conb2 %01x, poib2 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
+				     single_toc.addressb2,
+				     single_toc.controlb2,
+				     single_toc.pointb2,
+				     single_toc.tracksb2[0],
+				     single_toc.tracksb2[1],
+				     single_toc.tracksb2[2],
+				     single_toc.tracksb2[3],
+				     single_toc.tracksb2[4],
+				     single_toc.tracksb2[5],
+				     single_toc.tracksb2[6]);
+			if (res_size > 45 && single_toc.pointb3 > 0xaf)
+				printk
+				    ("addb3 %01x, conb3 %01x, poib3 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
+				     single_toc.addressb3,
+				     single_toc.controlb3,
+				     single_toc.pointb3,
+				     single_toc.tracksb3[0],
+				     single_toc.tracksb3[1],
+				     single_toc.tracksb3[2],
+				     single_toc.tracksb3[3],
+				     single_toc.tracksb3[4],
+				     single_toc.tracksb3[5],
+				     single_toc.tracksb3[6]);
+			if (res_size > 54 && single_toc.pointb4 > 0xaf)
+				printk
+				    ("addb4 %01x, conb4 %01x, poib4 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
+				     single_toc.addressb4,
+				     single_toc.controlb4,
+				     single_toc.pointb4,
+				     single_toc.tracksb4[0],
+				     single_toc.tracksb4[1],
+				     single_toc.tracksb4[2],
+				     single_toc.tracksb4[3],
+				     single_toc.tracksb4[4],
+				     single_toc.tracksb4[5],
+				     single_toc.tracksb4[6]);
+			if (res_size > 63 && single_toc.pointc0 > 0xaf)
+				printk
+				    ("addc0 %01x, conc0 %01x, poic0 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
+				     single_toc.addressc0,
+				     single_toc.controlc0,
+				     single_toc.pointc0,
+				     single_toc.dummyc0[0],
+				     single_toc.dummyc0[1],
+				     single_toc.dummyc0[2],
+				     single_toc.dummyc0[3],
+				     single_toc.dummyc0[4],
+				     single_toc.dummyc0[5],
+				     single_toc.dummyc0[6]);
 #endif
 #undef DEBUG
 #define DEBUG 0
 
-      sony_toc.lead_out_start_msf[0] = bcd_to_int(single_toc.lead_out_start_msf[0]);
-      sony_toc.lead_out_start_msf[1] = bcd_to_int(single_toc.lead_out_start_msf[1]);
-      sony_toc.lead_out_start_msf[2] = bcd_to_int(single_toc.lead_out_start_msf[2]);
-      sony_toc.lead_out_start_lba = single_toc.lead_out_start_lba =
-                    msf_to_log(sony_toc.lead_out_start_msf);
-
-      /* For points that do not exist, move the data over them
-	 to the right location. */
-      if (single_toc.pointb0 != 0xb0)
-      {
-	 memmove(((char *) &single_toc) + 27,
-		 ((char *) &single_toc) + 18,
-		 res_size - 18);
-	 res_size += 9;
-      }
-      else if (res_size > 18) {
-        sony_toc.lead_out_start_msf[0] = bcd_to_int(single_toc.max_start_outer_leadout_msf[0]);
-        sony_toc.lead_out_start_msf[1] = bcd_to_int(single_toc.max_start_outer_leadout_msf[1]);
-        sony_toc.lead_out_start_msf[2] = bcd_to_int(single_toc.max_start_outer_leadout_msf[2]);
-        sony_toc.lead_out_start_lba = msf_to_log(sony_toc.lead_out_start_msf);
-      }
-      if (single_toc.pointb1 != 0xb1)
-      {
-	 memmove(((char *) &single_toc) + 36,
-		((char *) &single_toc) + 27,
-		res_size - 27);
-	 res_size += 9;
-      }
-      if (single_toc.pointb2 != 0xb2)
-      {
-	 memmove(((char *) &single_toc) + 45,
-		((char *) &single_toc) + 36,
-		res_size - 36);
-	 res_size += 9;
-      }
-      if (single_toc.pointb3 != 0xb3)
-      {
-	 memmove(((char *) &single_toc) + 54,
-		((char *) &single_toc) + 45,
-		res_size - 45);
-	 res_size += 9;
-      }
-      if (single_toc.pointb4 != 0xb4)
-      {
-	 memmove(((char *) &single_toc) + 63,
-		((char *) &single_toc) + 54,
-		res_size - 54);
-	 res_size += 9;
-      }
-      if (single_toc.pointc0 != 0xc0)
-      {
-	 memmove(((char *) &single_toc) + 72,
-		((char *) &single_toc) + 63,
-		res_size - 63);
-	 res_size += 9;
-      }
-
-#if DEBUG
-      printk("start track lba %u,  leadout start lba %u\n",
-              single_toc.start_track_lba, single_toc.lead_out_start_lba);
-      { int i;
-        for (i = 0; i < 1 + bcd_to_int(single_toc.last_track_num)
-                          - bcd_to_int(single_toc.first_track_num); i++) {
-          printk("trk %02d: add 0x%01x, con 0x%01x,  track %02d, start min %02d, sec %02d, frame %02d\n",
-                 i, single_toc.tracks[i].address, single_toc.tracks[i].control,
-                 bcd_to_int(single_toc.tracks[i].track),
-                 bcd_to_int(single_toc.tracks[i].track_start_msf[0]),
-                 bcd_to_int(single_toc.tracks[i].track_start_msf[1]),
-                 bcd_to_int(single_toc.tracks[i].track_start_msf[2]));
-          if (mint > bcd_to_int(single_toc.tracks[i].track))
-            mint = bcd_to_int(single_toc.tracks[i].track);
-          if (maxt < bcd_to_int(single_toc.tracks[i].track))
-            maxt = bcd_to_int(single_toc.tracks[i].track);
-        }
-        printk("min track number %d,   max track number %d\n", mint, maxt);
-      }
-#endif
-
-         /* prepare a special table of contents for a CD-I disc. They don't have one. */
-         if (single_toc.disk_type == 0x10 &&
-             single_toc.first_track_num == 2 &&
-             single_toc.last_track_num == 2 /* CD-I */)
-         {
-            sony_toc.tracks[totaltracks].address = 1;
-	    sony_toc.tracks[totaltracks].control = 4; /* force data tracks */
-            sony_toc.tracks[totaltracks].track = 1;
-            sony_toc.tracks[totaltracks].track_start_msf[0] = 0;
-            sony_toc.tracks[totaltracks].track_start_msf[1] = 2;
-            sony_toc.tracks[totaltracks].track_start_msf[2] = 0;
-            mint = maxt = 1;
-            totaltracks++;
-         } else
-         /* gather track entries from this session */
-         { int i;
-	   for (i = 0; i < 1 + bcd_to_int(single_toc.last_track_num)
-                          - bcd_to_int(single_toc.first_track_num); i++, totaltracks++) {
-             sony_toc.tracks[totaltracks].address = single_toc.tracks[i].address;
-             sony_toc.tracks[totaltracks].control = single_toc.tracks[i].control;
-             sony_toc.tracks[totaltracks].track = bcd_to_int(single_toc.tracks[i].track);
-             sony_toc.tracks[totaltracks].track_start_msf[0] = 
-                  bcd_to_int(single_toc.tracks[i].track_start_msf[0]);
-             sony_toc.tracks[totaltracks].track_start_msf[1] = 
-                  bcd_to_int(single_toc.tracks[i].track_start_msf[1]);
-             sony_toc.tracks[totaltracks].track_start_msf[2] = 
-                  bcd_to_int(single_toc.tracks[i].track_start_msf[2]);
-             if (i == 0)
-               single_toc.start_track_lba = msf_to_log(sony_toc.tracks[totaltracks].track_start_msf);
-             if (mint > sony_toc.tracks[totaltracks].track)
-               mint = sony_toc.tracks[totaltracks].track;
-             if (maxt < sony_toc.tracks[totaltracks].track)
-               maxt = sony_toc.tracks[totaltracks].track;
-           }
-         }
-         sony_toc.first_track_num = mint;
-         sony_toc.last_track_num = maxt;
-         /* Disk type of last session wins. For example:
-            CD-Extra has disk type 0 for the first session, so
-            a dumb HiFi CD player thinks it is a plain audio CD.
-	    We are interested in the disk type of the last session,
-            which is 0x20 (XA) for CD-Extra, so we can access the
-            data track ... */
-         sony_toc.disk_type = single_toc.disk_type;
-         sony_toc.sessions = session;
-
-         /* don't believe everything :-) */
-         if (session == 1)
-            single_toc.start_track_lba = 0;
-         sony_toc.start_track_lba = single_toc.start_track_lba;
-
-         if (session > 1 && single_toc.pointb0 == 0xb0 &&
-             sony_toc.lead_out_start_lba == single_toc.lead_out_start_lba)
-	 {
-            break;
-         }
-
-         /* Let's not get carried away... */
-         if (session > 40)
-         {
-            printk("cdu31a: too many sessions: %d\n", session);
-            break;
-         }
-         session++;
-      }
-      sony_toc.track_entries = totaltracks;
-      /* add one entry for the LAST track with track number CDROM_LEADOUT */ 
-      sony_toc.tracks[totaltracks].address = single_toc.address2;
-      sony_toc.tracks[totaltracks].control = single_toc.control2;
-      sony_toc.tracks[totaltracks].track = CDROM_LEADOUT;
-      sony_toc.tracks[totaltracks].track_start_msf[0] = 
-             sony_toc.lead_out_start_msf[0];
-      sony_toc.tracks[totaltracks].track_start_msf[1] = 
-             sony_toc.lead_out_start_msf[1];
-      sony_toc.tracks[totaltracks].track_start_msf[2] = 
-             sony_toc.lead_out_start_msf[2];
+			sony_toc.lead_out_start_msf[0] =
+			    bcd_to_int(single_toc.lead_out_start_msf[0]);
+			sony_toc.lead_out_start_msf[1] =
+			    bcd_to_int(single_toc.lead_out_start_msf[1]);
+			sony_toc.lead_out_start_msf[2] =
+			    bcd_to_int(single_toc.lead_out_start_msf[2]);
+			sony_toc.lead_out_start_lba =
+			    single_toc.lead_out_start_lba =
+			    msf_to_log(sony_toc.lead_out_start_msf);
+
+			/* For points that do not exist, move the data over them
+			   to the right location. */
+			if (single_toc.pointb0 != 0xb0) {
+				memmove(((char *) &single_toc) + 27,
+					((char *) &single_toc) + 18,
+					res_size - 18);
+				res_size += 9;
+			} else if (res_size > 18) {
+				sony_toc.lead_out_start_msf[0] =
+				    bcd_to_int(single_toc.
+					       max_start_outer_leadout_msf
+					       [0]);
+				sony_toc.lead_out_start_msf[1] =
+				    bcd_to_int(single_toc.
+					       max_start_outer_leadout_msf
+					       [1]);
+				sony_toc.lead_out_start_msf[2] =
+				    bcd_to_int(single_toc.
+					       max_start_outer_leadout_msf
+					       [2]);
+				sony_toc.lead_out_start_lba =
+				    msf_to_log(sony_toc.
+					       lead_out_start_msf);
+			}
+			if (single_toc.pointb1 != 0xb1) {
+				memmove(((char *) &single_toc) + 36,
+					((char *) &single_toc) + 27,
+					res_size - 27);
+				res_size += 9;
+			}
+			if (single_toc.pointb2 != 0xb2) {
+				memmove(((char *) &single_toc) + 45,
+					((char *) &single_toc) + 36,
+					res_size - 36);
+				res_size += 9;
+			}
+			if (single_toc.pointb3 != 0xb3) {
+				memmove(((char *) &single_toc) + 54,
+					((char *) &single_toc) + 45,
+					res_size - 45);
+				res_size += 9;
+			}
+			if (single_toc.pointb4 != 0xb4) {
+				memmove(((char *) &single_toc) + 63,
+					((char *) &single_toc) + 54,
+					res_size - 54);
+				res_size += 9;
+			}
+			if (single_toc.pointc0 != 0xc0) {
+				memmove(((char *) &single_toc) + 72,
+					((char *) &single_toc) + 63,
+					res_size - 63);
+				res_size += 9;
+			}
+#if DEBUG
+			printk
+			    ("start track lba %u,  leadout start lba %u\n",
+			     single_toc.start_track_lba,
+			     single_toc.lead_out_start_lba);
+			{
+				int i;
+				for (i = 0;
+				     i <
+				     1 +
+				     bcd_to_int(single_toc.last_track_num)
+				     -
+				     bcd_to_int(single_toc.
+						first_track_num); i++) {
+					printk
+					    ("trk %02d: add 0x%01x, con 0x%01x,  track %02d, start min %02d, sec %02d, frame %02d\n",
+					     i,
+					     single_toc.tracks[i].address,
+					     single_toc.tracks[i].control,
+					     bcd_to_int(single_toc.
+							tracks[i].track),
+					     bcd_to_int(single_toc.
+							tracks[i].
+							track_start_msf
+							[0]),
+					     bcd_to_int(single_toc.
+							tracks[i].
+							track_start_msf
+							[1]),
+					     bcd_to_int(single_toc.
+							tracks[i].
+							track_start_msf
+							[2]));
+					if (mint >
+					    bcd_to_int(single_toc.
+						       tracks[i].track))
+						mint =
+						    bcd_to_int(single_toc.
+							       tracks[i].
+							       track);
+					if (maxt <
+					    bcd_to_int(single_toc.
+						       tracks[i].track))
+						maxt =
+						    bcd_to_int(single_toc.
+							       tracks[i].
+							       track);
+				}
+				printk
+				    ("min track number %d,   max track number %d\n",
+				     mint, maxt);
+			}
+#endif
+
+			/* prepare a special table of contents for a CD-I disc. They don't have one. */
+			if (single_toc.disk_type == 0x10 &&
+			    single_toc.first_track_num == 2 &&
+			    single_toc.last_track_num == 2 /* CD-I */ ) {
+				sony_toc.tracks[totaltracks].address = 1;
+				sony_toc.tracks[totaltracks].control = 4;	/* force data tracks */
+				sony_toc.tracks[totaltracks].track = 1;
+				sony_toc.tracks[totaltracks].
+				    track_start_msf[0] = 0;
+				sony_toc.tracks[totaltracks].
+				    track_start_msf[1] = 2;
+				sony_toc.tracks[totaltracks].
+				    track_start_msf[2] = 0;
+				mint = maxt = 1;
+				totaltracks++;
+			} else
+				/* gather track entries from this session */
+			{
+				int i;
+				for (i = 0;
+				     i <
+				     1 +
+				     bcd_to_int(single_toc.last_track_num)
+				     -
+				     bcd_to_int(single_toc.
+						first_track_num);
+				     i++, totaltracks++) {
+					sony_toc.tracks[totaltracks].
+					    address =
+					    single_toc.tracks[i].address;
+					sony_toc.tracks[totaltracks].
+					    control =
+					    single_toc.tracks[i].control;
+					sony_toc.tracks[totaltracks].
+					    track =
+					    bcd_to_int(single_toc.
+						       tracks[i].track);
+					sony_toc.tracks[totaltracks].
+					    track_start_msf[0] =
+					    bcd_to_int(single_toc.
+						       tracks[i].
+						       track_start_msf[0]);
+					sony_toc.tracks[totaltracks].
+					    track_start_msf[1] =
+					    bcd_to_int(single_toc.
+						       tracks[i].
+						       track_start_msf[1]);
+					sony_toc.tracks[totaltracks].
+					    track_start_msf[2] =
+					    bcd_to_int(single_toc.
+						       tracks[i].
+						       track_start_msf[2]);
+					if (i == 0)
+						single_toc.
+						    start_track_lba =
+						    msf_to_log(sony_toc.
+							       tracks
+							       [totaltracks].
+							       track_start_msf);
+					if (mint >
+					    sony_toc.tracks[totaltracks].
+					    track)
+						mint =
+						    sony_toc.
+						    tracks[totaltracks].
+						    track;
+					if (maxt <
+					    sony_toc.tracks[totaltracks].
+					    track)
+						maxt =
+						    sony_toc.
+						    tracks[totaltracks].
+						    track;
+				}
+			}
+			sony_toc.first_track_num = mint;
+			sony_toc.last_track_num = maxt;
+			/* Disk type of last session wins. For example:
+			   CD-Extra has disk type 0 for the first session, so
+			   a dumb HiFi CD player thinks it is a plain audio CD.
+			   We are interested in the disk type of the last session,
+			   which is 0x20 (XA) for CD-Extra, so we can access the
+			   data track ... */
+			sony_toc.disk_type = single_toc.disk_type;
+			sony_toc.sessions = session;
+
+			/* don't believe everything :-) */
+			if (session == 1)
+				single_toc.start_track_lba = 0;
+			sony_toc.start_track_lba =
+			    single_toc.start_track_lba;
+
+			if (session > 1 && single_toc.pointb0 == 0xb0 &&
+			    sony_toc.lead_out_start_lba ==
+			    single_toc.lead_out_start_lba) {
+				break;
+			}
+
+			/* Let's not get carried away... */
+			if (session > 40) {
+				printk("cdu31a: too many sessions: %d\n",
+				       session);
+				break;
+			}
+			session++;
+		}
+		sony_toc.track_entries = totaltracks;
+		/* add one entry for the LAST track with track number CDROM_LEADOUT */
+		sony_toc.tracks[totaltracks].address = single_toc.address2;
+		sony_toc.tracks[totaltracks].control = single_toc.control2;
+		sony_toc.tracks[totaltracks].track = CDROM_LEADOUT;
+		sony_toc.tracks[totaltracks].track_start_msf[0] =
+		    sony_toc.lead_out_start_msf[0];
+		sony_toc.tracks[totaltracks].track_start_msf[1] =
+		    sony_toc.lead_out_start_msf[1];
+		sony_toc.tracks[totaltracks].track_start_msf[2] =
+		    sony_toc.lead_out_start_msf[2];
 
-      sony_toc_read = 1;
+		sony_toc_read = 1;
 #undef DEBUG
 #if DEBUG
-   printk("Disk session %d, start track: %d, stop track: %d\n",
-	  session,
-	  single_toc.start_track_lba,
-	  single_toc.lead_out_start_lba);
+		printk
+		    ("Disk session %d, start track: %d, stop track: %d\n",
+		     session, single_toc.start_track_lba,
+		     single_toc.lead_out_start_lba);
 #endif
-   }
+	}
 #if DEBUG
-   printk("Leaving sony_get_toc\n");
+	printk("Leaving sony_get_toc\n");
 #endif
 }
 
@@ -2236,74 +2230,76 @@
  * Uniform cdrom interface function
  * return multisession offset and sector information
  */
-static int scd_get_last_session(struct cdrom_device_info *cdi, 
-                                struct cdrom_multisession *ms_info)
+static int scd_get_last_session(struct cdrom_device_info *cdi,
+				struct cdrom_multisession *ms_info)
 {
-   if (ms_info == NULL)
-      return 1;
+	if (ms_info == NULL)
+		return 1;
 
-   if (!sony_toc_read)
-      sony_get_toc();
+	if (!sony_toc_read)
+		sony_get_toc();
 
-   ms_info->addr_format = CDROM_LBA;
-   ms_info->addr.lba    = sony_toc.start_track_lba;
-   ms_info->xa_flag     = sony_toc.disk_type == SONY_XA_DISK_TYPE ||
-                          sony_toc.disk_type == 0x10 /* CDI */;
+	ms_info->addr_format = CDROM_LBA;
+	ms_info->addr.lba = sony_toc.start_track_lba;
+	ms_info->xa_flag = sony_toc.disk_type == SONY_XA_DISK_TYPE ||
+	    sony_toc.disk_type == 0x10 /* CDI */ ;
 
-   return 0;
+	return 0;
 }
 
 /*
  * Search for a specific track in the table of contents.
  */
-static int
-find_track(int track)
+static int find_track(int track)
 {
-   int i;
+	int i;
 
-   for (i = 0; i <= sony_toc.track_entries; i++)
-   {
-      if (sony_toc.tracks[i].track == track)
-      {
-         return i;
-      }
-   }
+	for (i = 0; i <= sony_toc.track_entries; i++) {
+		if (sony_toc.tracks[i].track == track) {
+			return i;
+		}
+	}
 
-   return -1;
+	return -1;
 }
 
 
 /*
  * Read the subcode and put it in last_sony_subcode for future use.
  */
-static int
-read_subcode(void)
+static int read_subcode(void)
 {
-   unsigned int res_size;
+	unsigned int res_size;
 
 
-   do_sony_cd_cmd(SONY_REQ_SUBCODE_ADDRESS_CMD,
-                  NULL,
-                  0, 
-                  (unsigned char *) &last_sony_subcode, 
-                  &res_size);
-   if ((res_size < 2) || ((last_sony_subcode.exec_status[0] & 0xf0) == 0x20))
-   {
-      printk("Sony CDROM error %s (read_subcode)\n",
-             translate_error(last_sony_subcode.exec_status[1]));
-      return -EIO;
-   }
-
-   last_sony_subcode.track_num = bcd_to_int(last_sony_subcode.track_num);
-   last_sony_subcode.index_num = bcd_to_int(last_sony_subcode.index_num);
-   last_sony_subcode.abs_msf[0] = bcd_to_int(last_sony_subcode.abs_msf[0]);
-   last_sony_subcode.abs_msf[1] = bcd_to_int(last_sony_subcode.abs_msf[1]);
-   last_sony_subcode.abs_msf[2] = bcd_to_int(last_sony_subcode.abs_msf[2]);
-
-   last_sony_subcode.rel_msf[0] = bcd_to_int(last_sony_subcode.rel_msf[0]);
-   last_sony_subcode.rel_msf[1] = bcd_to_int(last_sony_subcode.rel_msf[1]);
-   last_sony_subcode.rel_msf[2] = bcd_to_int(last_sony_subcode.rel_msf[2]);
-   return 0;
+	do_sony_cd_cmd(SONY_REQ_SUBCODE_ADDRESS_CMD,
+		       NULL,
+		       0, (unsigned char *) &last_sony_subcode, &res_size);
+	if ((res_size < 2)
+	    || ((last_sony_subcode.exec_status[0] & 0xf0) == 0x20)) {
+		printk("Sony CDROM error %s (read_subcode)\n",
+		       translate_error(last_sony_subcode.exec_status[1]));
+		return -EIO;
+	}
+
+	last_sony_subcode.track_num =
+	    bcd_to_int(last_sony_subcode.track_num);
+	last_sony_subcode.index_num =
+	    bcd_to_int(last_sony_subcode.index_num);
+	last_sony_subcode.abs_msf[0] =
+	    bcd_to_int(last_sony_subcode.abs_msf[0]);
+	last_sony_subcode.abs_msf[1] =
+	    bcd_to_int(last_sony_subcode.abs_msf[1]);
+	last_sony_subcode.abs_msf[2] =
+	    bcd_to_int(last_sony_subcode.abs_msf[2]);
+
+	last_sony_subcode.rel_msf[0] =
+	    bcd_to_int(last_sony_subcode.rel_msf[0]);
+	last_sony_subcode.rel_msf[1] =
+	    bcd_to_int(last_sony_subcode.rel_msf[1]);
+	last_sony_subcode.rel_msf[2] =
+	    bcd_to_int(last_sony_subcode.rel_msf[2]);
+	return 0;
 }
 
 /*
@@ -2313,37 +2309,33 @@
 static int
 scd_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
 {
-   unsigned char resbuffer[2 + 14];
-   unsigned char *mcnp = mcn->medium_catalog_number;
-   unsigned char *resp = resbuffer + 3;
-   unsigned int res_size;
-
-   memset(mcn->medium_catalog_number, 0, 14);
-   do_sony_cd_cmd(SONY_REQ_UPC_EAN_CMD,
-                  NULL,
-                  0, 
-                  resbuffer,
-                  &res_size);
-   if ((res_size < 2) || ((resbuffer[0] & 0xf0) == 0x20))
-     ;
-   else {
-     /* packed bcd to single ASCII digits */
-     *mcnp++ = (*resp >> 4)     + '0'; 
-     *mcnp++ = (*resp++ & 0x0f) + '0'; 
-     *mcnp++ = (*resp >> 4)     + '0'; 
-     *mcnp++ = (*resp++ & 0x0f) + '0'; 
-     *mcnp++ = (*resp >> 4)     + '0'; 
-     *mcnp++ = (*resp++ & 0x0f) + '0'; 
-     *mcnp++ = (*resp >> 4)     + '0'; 
-     *mcnp++ = (*resp++ & 0x0f) + '0'; 
-     *mcnp++ = (*resp >> 4)     + '0'; 
-     *mcnp++ = (*resp++ & 0x0f) + '0'; 
-     *mcnp++ = (*resp >> 4)     + '0'; 
-     *mcnp++ = (*resp++ & 0x0f) + '0'; 
-     *mcnp++ = (*resp >> 4)     + '0'; 
-   }
-   *mcnp = '\0';
-   return 0;
+	unsigned char resbuffer[2 + 14];
+	unsigned char *mcnp = mcn->medium_catalog_number;
+	unsigned char *resp = resbuffer + 3;
+	unsigned int res_size;
+
+	memset(mcn->medium_catalog_number, 0, 14);
+	do_sony_cd_cmd(SONY_REQ_UPC_EAN_CMD,
+		       NULL, 0, resbuffer, &res_size);
+	if ((res_size < 2) || ((resbuffer[0] & 0xf0) == 0x20));
+	else {
+		/* packed bcd to single ASCII digits */
+		*mcnp++ = (*resp >> 4) + '0';
+		*mcnp++ = (*resp++ & 0x0f) + '0';
+		*mcnp++ = (*resp >> 4) + '0';
+		*mcnp++ = (*resp++ & 0x0f) + '0';
+		*mcnp++ = (*resp >> 4) + '0';
+		*mcnp++ = (*resp++ & 0x0f) + '0';
+		*mcnp++ = (*resp >> 4) + '0';
+		*mcnp++ = (*resp++ & 0x0f) + '0';
+		*mcnp++ = (*resp >> 4) + '0';
+		*mcnp++ = (*resp++ & 0x0f) + '0';
+		*mcnp++ = (*resp >> 4) + '0';
+		*mcnp++ = (*resp++ & 0x0f) + '0';
+		*mcnp++ = (*resp >> 4) + '0';
+	}
+	*mcnp = '\0';
+	return 0;
 }
 
 
@@ -2354,67 +2346,67 @@
  * already been stored, just use that.  The ioctl call wants things in decimal
  * (not BCD), so all the conversions are done.
  */
-static int
-sony_get_subchnl_info(struct cdrom_subchnl *schi)
+static int sony_get_subchnl_info(struct cdrom_subchnl *schi)
 {
-   /* Get attention stuff */
-   while (handle_sony_cd_attention())
-      ;
-
-   sony_get_toc();
-   if (!sony_toc_read)
-   {
-      return -EIO;
-   }
-
-   switch (sony_audio_status)
-   {
-   case CDROM_AUDIO_NO_STATUS:
-   case CDROM_AUDIO_PLAY:
-      if (read_subcode() < 0)
-      {
-         return -EIO;
-      }
-      break;
-
-   case CDROM_AUDIO_PAUSED:
-   case CDROM_AUDIO_COMPLETED:
-      break;
+	/* Get attention stuff */
+	while (handle_sony_cd_attention());
+
+	sony_get_toc();
+	if (!sony_toc_read) {
+		return -EIO;
+	}
+
+	switch (sony_audio_status) {
+	case CDROM_AUDIO_NO_STATUS:
+	case CDROM_AUDIO_PLAY:
+		if (read_subcode() < 0) {
+			return -EIO;
+		}
+		break;
+
+	case CDROM_AUDIO_PAUSED:
+	case CDROM_AUDIO_COMPLETED:
+		break;
 
 #if 0
-   case CDROM_AUDIO_NO_STATUS:
-      schi->cdsc_audiostatus = sony_audio_status;
-      return 0;
-      break;
-#endif
-   case CDROM_AUDIO_INVALID:
-   case CDROM_AUDIO_ERROR:
-   default:
-      return -EIO;
-   }
-
-   schi->cdsc_audiostatus = sony_audio_status;
-   schi->cdsc_adr = last_sony_subcode.address;
-   schi->cdsc_ctrl = last_sony_subcode.control;
-   schi->cdsc_trk = last_sony_subcode.track_num;
-   schi->cdsc_ind = last_sony_subcode.index_num;
-   if (schi->cdsc_format == CDROM_MSF)
-   {
-      schi->cdsc_absaddr.msf.minute = last_sony_subcode.abs_msf[0];
-      schi->cdsc_absaddr.msf.second = last_sony_subcode.abs_msf[1];
-      schi->cdsc_absaddr.msf.frame = last_sony_subcode.abs_msf[2];
-
-      schi->cdsc_reladdr.msf.minute = last_sony_subcode.rel_msf[0];
-      schi->cdsc_reladdr.msf.second = last_sony_subcode.rel_msf[1];
-      schi->cdsc_reladdr.msf.frame = last_sony_subcode.rel_msf[2];
-   }
-   else if (schi->cdsc_format == CDROM_LBA)
-   {
-      schi->cdsc_absaddr.lba = msf_to_log(last_sony_subcode.abs_msf);
-      schi->cdsc_reladdr.lba = msf_to_log(last_sony_subcode.rel_msf);
-   }
-   
-   return 0;
+	case CDROM_AUDIO_NO_STATUS:
+		schi->cdsc_audiostatus = sony_audio_status;
+		return 0;
+		break;
+#endif
+	case CDROM_AUDIO_INVALID:
+	case CDROM_AUDIO_ERROR:
+	default:
+		return -EIO;
+	}
+
+	schi->cdsc_audiostatus = sony_audio_status;
+	schi->cdsc_adr = last_sony_subcode.address;
+	schi->cdsc_ctrl = last_sony_subcode.control;
+	schi->cdsc_trk = last_sony_subcode.track_num;
+	schi->cdsc_ind = last_sony_subcode.index_num;
+	if (schi->cdsc_format == CDROM_MSF) {
+		schi->cdsc_absaddr.msf.minute =
+		    last_sony_subcode.abs_msf[0];
+		schi->cdsc_absaddr.msf.second =
+		    last_sony_subcode.abs_msf[1];
+		schi->cdsc_absaddr.msf.frame =
+		    last_sony_subcode.abs_msf[2];
+
+		schi->cdsc_reladdr.msf.minute =
+		    last_sony_subcode.rel_msf[0];
+		schi->cdsc_reladdr.msf.second =
+		    last_sony_subcode.rel_msf[1];
+		schi->cdsc_reladdr.msf.frame =
+		    last_sony_subcode.rel_msf[2];
+	} else if (schi->cdsc_format == CDROM_LBA) {
+		schi->cdsc_absaddr.lba =
+		    msf_to_log(last_sony_subcode.abs_msf);
+		schi->cdsc_reladdr.lba =
+		    msf_to_log(last_sony_subcode.rel_msf);
+	}
+
+	return 0;
 }
 
 /* Get audio data from the drive.  This is fairly complex because I
@@ -2422,782 +2414,756 @@
    then I just look for data.  I need to get the status immediately so
    the switch from audio to data tracks will happen quickly. */
 static void
-read_audio_data(char          *buffer,
-                unsigned char res_reg[],
-                int           *res_size)
-{
-   unsigned int retry_count;
-   int result_read;
-
-
-   res_reg[0] = 0;
-   res_reg[1] = 0;
-   *res_size = 0;
-   result_read = 0;
-
-   /* Wait for the drive to tell us we have something */
-   retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
-continue_read_audio_wait:
-   while (time_before(jiffies, retry_count) && !(is_data_ready())
-          && !(is_result_ready() || result_read))
-   {
-      while (handle_sony_cd_attention())
-         ;
-
-      sony_sleep();
-   }
-   if (!(is_data_ready()))
-   {
-      if (is_result_ready() && !result_read)
-      {
-         get_result(res_reg, res_size);
-
-         /* Read block status and continue waiting for data. */
-         if ((res_reg[0] & 0xf0) == 0x50)
-         {
-            result_read = 1;
-            goto continue_read_audio_wait;
-         }
-         /* Invalid data from the drive.  Shut down the operation. */
-         else if ((res_reg[0] & 0xf0) != 0x20)
-         {
-            printk("CDU31A: Got result that should have been error: %d\n",
-                   res_reg[0]);
-            res_reg[0] = 0x20;
-            res_reg[1] = SONY_BAD_DATA_ERR;
-            *res_size = 2;
-         }
-         abort_read();
-      }
-      else
-      {
-#if DEBUG
-         printk("CDU31A timeout out %d\n", __LINE__);
-#endif
-         res_reg[0] = 0x20;
-         res_reg[1] = SONY_TIMEOUT_OP_ERR;
-         *res_size = 2;
-         abort_read();
-      }
-   }
-   else
-   {
-      clear_data_ready();
-
-      /* If data block, then get 2340 bytes offset by 12. */
-      if (sony_raw_data_mode)
-      {
-         insb(sony_cd_read_reg, buffer + CD_XA_HEAD, CD_FRAMESIZE_RAW1);
-      }
-      else
-      {
-         /* Audio gets the whole 2352 bytes. */
-         insb(sony_cd_read_reg, buffer, CD_FRAMESIZE_RAW);
-      }
-
-      /* If I haven't already gotten the result, get it now. */
-      if (!result_read)
-      {
-         /* Wait for the drive to tell us we have something */
-         retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
-         while (time_before(jiffies, retry_count) && !(is_result_ready()))
-         {
-            while (handle_sony_cd_attention())
-               ;
-
-            sony_sleep();
-         }
-
-         if (!is_result_ready())
-         {
-#if DEBUG
-            printk("CDU31A timeout out %d\n", __LINE__);
-#endif
-            res_reg[0] = 0x20;
-            res_reg[1] = SONY_TIMEOUT_OP_ERR;
-            *res_size = 2;
-            abort_read();
-            return;
-         }
-         else
-         {
-            get_result(res_reg, res_size);
-         }
-      }
-
-      if ((res_reg[0] & 0xf0) == 0x50)
-      {
-         if (   (res_reg[0] == SONY_NO_CIRC_ERR_BLK_STAT)
-             || (res_reg[0] == SONY_NO_LECC_ERR_BLK_STAT)
-             || (res_reg[0] == SONY_RECOV_LECC_ERR_BLK_STAT)
-             || (res_reg[0] == SONY_NO_ERR_DETECTION_STAT))
-         {
-            /* Ok, nothing to do. */
-         }
-         else
-         {
-            printk("CDU31A: Data block error: 0x%x\n", res_reg[0]);
-            res_reg[0] = 0x20;
-            res_reg[1] = SONY_BAD_DATA_ERR;
-            *res_size = 2;
-         }
-      }
-      else if ((res_reg[0] & 0xf0) != 0x20)
-      {
-         /* The drive gave me bad status, I don't know what to do.
-            Reset the driver and return an error. */
-         printk("CDU31A: Invalid block status: 0x%x\n", res_reg[0]);
-         restart_on_error();
-         res_reg[0] = 0x20;
-         res_reg[1] = SONY_BAD_DATA_ERR;
-         *res_size = 2;
-      }
-   }
+read_audio_data(char *buffer, unsigned char res_reg[], int *res_size)
+{
+	unsigned int retry_count;
+	int result_read;
+
+
+	res_reg[0] = 0;
+	res_reg[1] = 0;
+	*res_size = 0;
+	result_read = 0;
+
+	/* Wait for the drive to tell us we have something */
+	retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
+      continue_read_audio_wait:
+	while (time_before(jiffies, retry_count) && !(is_data_ready())
+	       && !(is_result_ready() || result_read)) {
+		while (handle_sony_cd_attention());
+
+		sony_sleep();
+	}
+	if (!(is_data_ready())) {
+		if (is_result_ready() && !result_read) {
+			get_result(res_reg, res_size);
+
+			/* Read block status and continue waiting for data. */
+			if ((res_reg[0] & 0xf0) == 0x50) {
+				result_read = 1;
+				goto continue_read_audio_wait;
+			}
+			/* Invalid data from the drive.  Shut down the operation. */
+			else if ((res_reg[0] & 0xf0) != 0x20) {
+				printk
+				    ("CDU31A: Got result that should have been error: %d\n",
+				     res_reg[0]);
+				res_reg[0] = 0x20;
+				res_reg[1] = SONY_BAD_DATA_ERR;
+				*res_size = 2;
+			}
+			abort_read();
+		} else {
+#if DEBUG
+			printk("CDU31A timeout out %d\n", __LINE__);
+#endif
+			res_reg[0] = 0x20;
+			res_reg[1] = SONY_TIMEOUT_OP_ERR;
+			*res_size = 2;
+			abort_read();
+		}
+	} else {
+		clear_data_ready();
+
+		/* If data block, then get 2340 bytes offset by 12. */
+		if (sony_raw_data_mode) {
+			insb(sony_cd_read_reg, buffer + CD_XA_HEAD,
+			     CD_FRAMESIZE_RAW1);
+		} else {
+			/* Audio gets the whole 2352 bytes. */
+			insb(sony_cd_read_reg, buffer, CD_FRAMESIZE_RAW);
+		}
+
+		/* If I haven't already gotten the result, get it now. */
+		if (!result_read) {
+			/* Wait for the drive to tell us we have something */
+			retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
+			while (time_before(jiffies, retry_count)
+			       && !(is_result_ready())) {
+				while (handle_sony_cd_attention());
+
+				sony_sleep();
+			}
+
+			if (!is_result_ready()) {
+#if DEBUG
+				printk("CDU31A timeout out %d\n",
+				       __LINE__);
+#endif
+				res_reg[0] = 0x20;
+				res_reg[1] = SONY_TIMEOUT_OP_ERR;
+				*res_size = 2;
+				abort_read();
+				return;
+			} else {
+				get_result(res_reg, res_size);
+			}
+		}
+
+		if ((res_reg[0] & 0xf0) == 0x50) {
+			if ((res_reg[0] == SONY_NO_CIRC_ERR_BLK_STAT)
+			    || (res_reg[0] == SONY_NO_LECC_ERR_BLK_STAT)
+			    || (res_reg[0] == SONY_RECOV_LECC_ERR_BLK_STAT)
+			    || (res_reg[0] == SONY_NO_ERR_DETECTION_STAT)) {
+				/* Ok, nothing to do. */
+			} else {
+				printk("CDU31A: Data block error: 0x%x\n",
+				       res_reg[0]);
+				res_reg[0] = 0x20;
+				res_reg[1] = SONY_BAD_DATA_ERR;
+				*res_size = 2;
+			}
+		} else if ((res_reg[0] & 0xf0) != 0x20) {
+			/* The drive gave me bad status, I don't know what to do.
+			   Reset the driver and return an error. */
+			printk("CDU31A: Invalid block status: 0x%x\n",
+			       res_reg[0]);
+			restart_on_error();
+			res_reg[0] = 0x20;
+			res_reg[1] = SONY_BAD_DATA_ERR;
+			*res_size = 2;
+		}
+	}
 }
 
 /* Perform a raw data read.  This will automatically detect the
    track type and read the proper data (audio or data). */
-static int
-read_audio(struct cdrom_read_audio *ra)
+static int read_audio(struct cdrom_read_audio *ra)
 {
-   int retval;
-   unsigned char params[2];
-   unsigned char res_reg[12];
-   unsigned int res_size;
-   unsigned int cframe;
-   unsigned long flags;
-
-   /* 
-    * Make sure no one else is using the driver; wait for them
-    * to finish if it is so.
-    */
-   save_flags(flags);
-   cli();
-   while (sony_inuse)
-   {
-      interruptible_sleep_on(&sony_wait);
-      if (signal_pending(current))
-      {
-         restore_flags(flags);
-         return -EAGAIN;
-      }
-   }
-   sony_inuse = 1;
-   has_cd_task = current;
-   restore_flags(flags);
-
-   if (!sony_spun_up)
-   {
-     scd_spinup();
-   }
-
-   /* Set the drive to do raw operations. */
-   params[0] = SONY_SD_DECODE_PARAM;
-   params[1] = 0x06 | sony_raw_data_mode;
-   do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
-                  params,
-                  2,
-                  res_reg,
-                  &res_size);
-   if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
-   {
-      printk("CDU31A: Unable to set decode params: 0x%2.2x\n", res_reg[1]);
-      return -EIO;
-   }
-
-   /* From here down, we have to goto exit_read_audio instead of returning
-      because the drive parameters have to be set back to data before
-      return. */
-
-   retval = 0;
-   /* start_request clears out any readahead data, so it should be safe. */
-   if (start_request(ra->addr.lba, ra->nframes, 1))
-   {
-      retval = -EIO;
-      goto exit_read_audio;
-   }
-
-   /* For every requested frame. */
-   cframe = 0;
-   while (cframe < ra->nframes)
-   {
-      read_audio_data(readahead_buffer, res_reg, &res_size);
-      if ((res_reg[0] & 0xf0) == 0x20)
-      {
-         if (res_reg[1] == SONY_BAD_DATA_ERR)
-         {
-            printk("CDU31A: Data error on audio sector %d\n",
-                   ra->addr.lba + cframe);
-         }
-         else if (res_reg[1] == SONY_ILL_TRACK_R_ERR)
-         {
-            /* Illegal track type, change track types and start over. */
-            sony_raw_data_mode = (sony_raw_data_mode) ? 0 : 1;
-
-            /* Set the drive mode. */
-            params[0] = SONY_SD_DECODE_PARAM;
-            params[1] = 0x06 | sony_raw_data_mode;
-            do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
-                           params,
-                           2,
-                           res_reg,
-                           &res_size);
-            if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
-            {
-               printk("CDU31A: Unable to set decode params: 0x%2.2x\n", res_reg[1]);
-               retval = -EIO;
-               goto exit_read_audio;
-            }
-
-            /* Restart the request on the current frame. */
-            if (start_request(ra->addr.lba + cframe, ra->nframes - cframe, 1))
-            {
-               retval = -EIO;
-               goto exit_read_audio;
-            }
-
-            /* Don't go back to the top because don't want to get into
-               and infinite loop.  A lot of code gets duplicated, but
-               that's no big deal, I don't guess. */
-            read_audio_data(readahead_buffer, res_reg, &res_size);
-            if ((res_reg[0] & 0xf0) == 0x20)
-            {
-               if (res_reg[1] == SONY_BAD_DATA_ERR)
-               {
-                  printk("CDU31A: Data error on audio sector %d\n",
-                         ra->addr.lba + cframe);
-               }
-               else
-               {
-                  printk("CDU31A: Error reading audio data on sector %d: %s\n",
-                         ra->addr.lba + cframe,
-                         translate_error(res_reg[1]));
-                  retval = -EIO;
-                  goto exit_read_audio;
-               }
-            }
-            else
-            {
-               copy_to_user((char *) (ra->buf + (CD_FRAMESIZE_RAW * cframe)),
-                           (char *) readahead_buffer,
-                           CD_FRAMESIZE_RAW);
-            }
-         }
-         else
-         {
-            printk("CDU31A: Error reading audio data on sector %d: %s\n",
-                   ra->addr.lba + cframe,
-                   translate_error(res_reg[1]));
-            retval = -EIO;
-            goto exit_read_audio;
-         }
-      }
-      else
-      {
-         copy_to_user((char *) (ra->buf + (CD_FRAMESIZE_RAW * cframe)),
-                     (char *) readahead_buffer,
-                     CD_FRAMESIZE_RAW);
-      }
-
-      cframe++;
-   }
-
-   get_result(res_reg, &res_size);
-   if ((res_reg[0] & 0xf0) == 0x20)
-   {
-      printk("CDU31A: Error return from audio read: %s\n",
-             translate_error(res_reg[1]));
-      retval = -EIO;
-      goto exit_read_audio;
-   }
-
-exit_read_audio:
-
-   /* Set the drive mode back to the proper one for the disk. */
-   params[0] = SONY_SD_DECODE_PARAM;
-   if (!sony_xa_mode)
-   {
-      params[1] = 0x0f;
-   }
-   else
-   {
-      params[1] = 0x07;
-   }
-   do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
-                  params,
-                  2,
-                  res_reg,
-                  &res_size);
-   if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
-   {
-      printk("CDU31A: Unable to reset decode params: 0x%2.2x\n", res_reg[1]);
-      return -EIO;
-   }
-
-   has_cd_task = NULL;
-   sony_inuse = 0;
-   wake_up_interruptible(&sony_wait);
+	int retval;
+	unsigned char params[2];
+	unsigned char res_reg[12];
+	unsigned int res_size;
+	unsigned int cframe;
+	unsigned long flags;
+
+	/* 
+	 * Make sure no one else is using the driver; wait for them
+	 * to finish if it is so.
+	 */
+	save_flags(flags);
+	cli();
+	while (sony_inuse) {
+		interruptible_sleep_on(&sony_wait);
+		if (signal_pending(current)) {
+			restore_flags(flags);
+			return -EAGAIN;
+		}
+	}
+	sony_inuse = 1;
+	has_cd_task = current;
+	restore_flags(flags);
+
+	if (!sony_spun_up) {
+		scd_spinup();
+	}
+
+	/* Set the drive to do raw operations. */
+	params[0] = SONY_SD_DECODE_PARAM;
+	params[1] = 0x06 | sony_raw_data_mode;
+	do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
+		       params, 2, res_reg, &res_size);
+	if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
+		printk("CDU31A: Unable to set decode params: 0x%2.2x\n",
+		       res_reg[1]);
+		return -EIO;
+	}
+
+	/* From here down, we have to goto exit_read_audio instead of returning
+	   because the drive parameters have to be set back to data before
+	   return. */
+
+	retval = 0;
+	/* start_request clears out any readahead data, so it should be safe. */
+	if (start_request(ra->addr.lba, ra->nframes, 1)) {
+		retval = -EIO;
+		goto exit_read_audio;
+	}
+
+	/* For every requested frame. */
+	cframe = 0;
+	while (cframe < ra->nframes) {
+		read_audio_data(readahead_buffer, res_reg, &res_size);
+		if ((res_reg[0] & 0xf0) == 0x20) {
+			if (res_reg[1] == SONY_BAD_DATA_ERR) {
+				printk
+				    ("CDU31A: Data error on audio sector %d\n",
+				     ra->addr.lba + cframe);
+			} else if (res_reg[1] == SONY_ILL_TRACK_R_ERR) {
+				/* Illegal track type, change track types and start over. */
+				sony_raw_data_mode =
+				    (sony_raw_data_mode) ? 0 : 1;
+
+				/* Set the drive mode. */
+				params[0] = SONY_SD_DECODE_PARAM;
+				params[1] = 0x06 | sony_raw_data_mode;
+				do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
+					       params,
+					       2, res_reg, &res_size);
+				if ((res_size < 2)
+				    || ((res_reg[0] & 0xf0) == 0x20)) {
+					printk
+					    ("CDU31A: Unable to set decode params: 0x%2.2x\n",
+					     res_reg[1]);
+					retval = -EIO;
+					goto exit_read_audio;
+				}
+
+				/* Restart the request on the current frame. */
+				if (start_request
+				    (ra->addr.lba + cframe,
+				     ra->nframes - cframe, 1)) {
+					retval = -EIO;
+					goto exit_read_audio;
+				}
+
+				/* Don't go back to the top because don't want to get into
+				   and infinite loop.  A lot of code gets duplicated, but
+				   that's no big deal, I don't guess. */
+				read_audio_data(readahead_buffer, res_reg,
+						&res_size);
+				if ((res_reg[0] & 0xf0) == 0x20) {
+					if (res_reg[1] ==
+					    SONY_BAD_DATA_ERR) {
+						printk
+						    ("CDU31A: Data error on audio sector %d\n",
+						     ra->addr.lba +
+						     cframe);
+					} else {
+						printk
+						    ("CDU31A: Error reading audio data on sector %d: %s\n",
+						     ra->addr.lba + cframe,
+						     translate_error
+						     (res_reg[1]));
+						retval = -EIO;
+						goto exit_read_audio;
+					}
+				} else {
+					copy_to_user((char *) (ra->buf +
+							       (CD_FRAMESIZE_RAW
+								* cframe)),
+						     (char *)
+						     readahead_buffer,
+						     CD_FRAMESIZE_RAW);
+				}
+			} else {
+				printk
+				    ("CDU31A: Error reading audio data on sector %d: %s\n",
+				     ra->addr.lba + cframe,
+				     translate_error(res_reg[1]));
+				retval = -EIO;
+				goto exit_read_audio;
+			}
+		} else {
+			copy_to_user((char *) (ra->buf +
+					       (CD_FRAMESIZE_RAW *
+						cframe)),
+				     (char *) readahead_buffer,
+				     CD_FRAMESIZE_RAW);
+		}
+
+		cframe++;
+	}
+
+	get_result(res_reg, &res_size);
+	if ((res_reg[0] & 0xf0) == 0x20) {
+		printk("CDU31A: Error return from audio read: %s\n",
+		       translate_error(res_reg[1]));
+		retval = -EIO;
+		goto exit_read_audio;
+	}
+
+      exit_read_audio:
+
+	/* Set the drive mode back to the proper one for the disk. */
+	params[0] = SONY_SD_DECODE_PARAM;
+	if (!sony_xa_mode) {
+		params[1] = 0x0f;
+	} else {
+		params[1] = 0x07;
+	}
+	do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
+		       params, 2, res_reg, &res_size);
+	if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
+		printk("CDU31A: Unable to reset decode params: 0x%2.2x\n",
+		       res_reg[1]);
+		return -EIO;
+	}
+
+	has_cd_task = NULL;
+	sony_inuse = 0;
+	wake_up_interruptible(&sony_wait);
 
-   return(retval);
+	return (retval);
 }
 
 static int
 do_sony_cd_cmd_chk(const char *name,
-                   unsigned char cmd,
-                   unsigned char *params,
-                   unsigned int num_params,
-		   unsigned char *result_buffer,
-                   unsigned int *result_size)
-{      
-      do_sony_cd_cmd(cmd, params, num_params, result_buffer, result_size);
-      if ((*result_size < 2) || ((result_buffer[0] & 0xf0) == 0x20))
-      {
-         printk("Sony CDROM error %s (CDROM%s)\n", translate_error(result_buffer[1]), name);
-         return -EIO;
-      }
-      return 0;
+		   unsigned char cmd,
+		   unsigned char *params,
+		   unsigned int num_params,
+		   unsigned char *result_buffer, unsigned int *result_size)
+{
+	do_sony_cd_cmd(cmd, params, num_params, result_buffer,
+		       result_size);
+	if ((*result_size < 2) || ((result_buffer[0] & 0xf0) == 0x20)) {
+		printk("Sony CDROM error %s (CDROM%s)\n",
+		       translate_error(result_buffer[1]), name);
+		return -EIO;
+	}
+	return 0;
 }
- 
+
 /*
  * Uniform cdrom interface function
  * open the tray
  */
 static int scd_tray_move(struct cdrom_device_info *cdi, int position)
 {
-  if (position == 1 /* open tray */)
-  {
-    unsigned char res_reg[12];
-    unsigned int res_size;
-
-    do_sony_cd_cmd(SONY_AUDIO_STOP_CMD, NULL, 0, res_reg, &res_size);
-    do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg, &res_size);
-
-    sony_audio_status = CDROM_AUDIO_INVALID;
-    return do_sony_cd_cmd_chk("EJECT",SONY_EJECT_CMD, NULL, 0, res_reg, &res_size);
-  } else {
-    if (0 == scd_spinup())
-      sony_spun_up = 1;
-    return 0;
-  }
+	if (position == 1 /* open tray */ ) {
+		unsigned char res_reg[12];
+		unsigned int res_size;
+
+		do_sony_cd_cmd(SONY_AUDIO_STOP_CMD, NULL, 0, res_reg,
+			       &res_size);
+		do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg,
+			       &res_size);
+
+		sony_audio_status = CDROM_AUDIO_INVALID;
+		return do_sony_cd_cmd_chk("EJECT", SONY_EJECT_CMD, NULL, 0,
+					  res_reg, &res_size);
+	} else {
+		if (0 == scd_spinup())
+			sony_spun_up = 1;
+		return 0;
+	}
 }
 
 /*
  * The big ugly ioctl handler.
  */
 static int scd_audio_ioctl(struct cdrom_device_info *cdi,
-          unsigned int  cmd,
-          void * arg)
+			   unsigned int cmd, void *arg)
 {
-   unsigned char res_reg[12];
-   unsigned int res_size;
-   unsigned char params[7];
-   int i;
-
-
-   switch (cmd)
-   {
-   case CDROMSTART:     /* Spin up the drive */
-      return do_sony_cd_cmd_chk("START",SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
-      break;
-      
-   case CDROMSTOP:      /* Spin down the drive */
-      do_sony_cd_cmd(SONY_AUDIO_STOP_CMD, NULL, 0, res_reg, &res_size);
-
-      /*
-       * Spin the drive down, ignoring the error if the disk was
-       * already not spinning.
-       */
-      sony_audio_status = CDROM_AUDIO_NO_STATUS;
-      return do_sony_cd_cmd_chk("STOP",SONY_SPIN_DOWN_CMD, NULL, 0, res_reg, &res_size);
-
-   case CDROMPAUSE:     /* Pause the drive */
-      if(do_sony_cd_cmd_chk("PAUSE", SONY_AUDIO_STOP_CMD, NULL, 0, res_reg, &res_size))
-      	return -EIO;
-      /* Get the current position and save it for resuming */
-      if (read_subcode() < 0)
-      {
-         return -EIO;
-      }
-      cur_pos_msf[0] = last_sony_subcode.abs_msf[0];
-      cur_pos_msf[1] = last_sony_subcode.abs_msf[1];
-      cur_pos_msf[2] = last_sony_subcode.abs_msf[2];
-      sony_audio_status = CDROM_AUDIO_PAUSED;
-      return 0;
-      break;
-
-   case CDROMRESUME:    /* Start the drive after being paused */
-      if (sony_audio_status != CDROM_AUDIO_PAUSED)
-      {
-         return -EINVAL;
-      }
-      
-      do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
-      
-      /* Start the drive at the saved position. */
-      params[1] = int_to_bcd(cur_pos_msf[0]);
-      params[2] = int_to_bcd(cur_pos_msf[1]);
-      params[3] = int_to_bcd(cur_pos_msf[2]);
-      params[4] = int_to_bcd(final_pos_msf[0]);
-      params[5] = int_to_bcd(final_pos_msf[1]);
-      params[6] = int_to_bcd(final_pos_msf[2]);
-      params[0] = 0x03;
-      if(do_sony_cd_cmd_chk("RESUME",SONY_AUDIO_PLAYBACK_CMD, params, 7, res_reg, &res_size)<0)
-      	return -EIO;
-      sony_audio_status = CDROM_AUDIO_PLAY;
-      return 0;
-
-   case CDROMPLAYMSF:   /* Play starting at the given MSF address. */
-      do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
-      
-      /* The parameters are given in int, must be converted */
-      for (i=1; i<7; i++)
-      {
-         params[i] = int_to_bcd(((unsigned char *)arg)[i-1]);
-      }
-      params[0] = 0x03;
-      if(do_sony_cd_cmd_chk("PLAYMSF",SONY_AUDIO_PLAYBACK_CMD, params, 7, res_reg, &res_size)<0)
-      	return -EIO;
-      
-      /* Save the final position for pauses and resumes */
-      final_pos_msf[0] = bcd_to_int(params[4]);
-      final_pos_msf[1] = bcd_to_int(params[5]);
-      final_pos_msf[2] = bcd_to_int(params[6]);
-      sony_audio_status = CDROM_AUDIO_PLAY;
-      return 0;
-
-   case CDROMREADTOCHDR:        /* Read the table of contents header */
-      {
-         struct cdrom_tochdr *hdr;
-         
-         sony_get_toc();
-         if (!sony_toc_read)
-         {
-            return -EIO;
-         }
-         
-         hdr = (struct cdrom_tochdr *) arg;
-         hdr->cdth_trk0 = sony_toc.first_track_num;
-         hdr->cdth_trk1 = sony_toc.last_track_num;
-      }
-      return 0;
-
-   case CDROMREADTOCENTRY:      /* Read a given table of contents entry */
-      {
-         struct cdrom_tocentry *entry;
-         int track_idx;
-         unsigned char *msf_val = NULL;
-         
-         sony_get_toc();
-         if (!sony_toc_read)
-         {
-            return -EIO;
-         }
-         
-         entry = (struct cdrom_tocentry *) arg;
-         
-         track_idx = find_track(entry->cdte_track);
-         if (track_idx < 0)
-         {
-            return -EINVAL;
-         }
-            
-         entry->cdte_adr = sony_toc.tracks[track_idx].address;
-         entry->cdte_ctrl = sony_toc.tracks[track_idx].control;
-         msf_val = sony_toc.tracks[track_idx].track_start_msf;
-         
-         /* Logical buffer address or MSF format requested? */
-         if (entry->cdte_format == CDROM_LBA)
-         {
-            entry->cdte_addr.lba = msf_to_log(msf_val);
-         }
-         else if (entry->cdte_format == CDROM_MSF)
-         {
-            entry->cdte_addr.msf.minute = *msf_val;
-            entry->cdte_addr.msf.second = *(msf_val+1);
-            entry->cdte_addr.msf.frame = *(msf_val+2);
-         }
-      }
-      return 0;
-      break;
-
-   case CDROMPLAYTRKIND:     /* Play a track.  This currently ignores index. */
-      {
-         struct cdrom_ti *ti = (struct cdrom_ti *) arg;
-         int track_idx;
-         
-         sony_get_toc();
-         if (!sony_toc_read)
-         {
-            return -EIO;
-         }
-         
-         if (   (ti->cdti_trk0 < sony_toc.first_track_num)
-             || (ti->cdti_trk0 > sony_toc.last_track_num)
-             || (ti->cdti_trk1 < ti->cdti_trk0))
-         {
-            return -EINVAL;
-         }
-         
-         track_idx = find_track(ti->cdti_trk0);
-         if (track_idx < 0)
-         {
-            return -EINVAL;
-         }
-         params[1] = int_to_bcd(sony_toc.tracks[track_idx].track_start_msf[0]);
-         params[2] = int_to_bcd(sony_toc.tracks[track_idx].track_start_msf[1]);
-         params[3] = int_to_bcd(sony_toc.tracks[track_idx].track_start_msf[2]);
-         
-         /*
-          * If we want to stop after the last track, use the lead-out
-          * MSF to do that.
-          */
-         if (ti->cdti_trk1 >= sony_toc.last_track_num)
-         {
-            track_idx = find_track(CDROM_LEADOUT);
-         }
-         else
-         {
-            track_idx = find_track(ti->cdti_trk1+1);
-         }
-         if (track_idx < 0)
-         {
-            return -EINVAL;
-         }
-         params[4] = int_to_bcd(sony_toc.tracks[track_idx].track_start_msf[0]);
-         params[5] = int_to_bcd(sony_toc.tracks[track_idx].track_start_msf[1]);
-         params[6] = int_to_bcd(sony_toc.tracks[track_idx].track_start_msf[2]);
-         params[0] = 0x03;
-         
-         do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
-         
-         do_sony_cd_cmd(SONY_AUDIO_PLAYBACK_CMD, params, 7, res_reg, &res_size);
-         
-         if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
-         {
-            printk("Params: %x %x %x %x %x %x %x\n", params[0], params[1],
-                   params[2], params[3], params[4], params[5], params[6]);
-            printk("Sony CDROM error %s (CDROMPLAYTRKIND)\n", translate_error(res_reg[1]));
-            return -EIO;
-         }
-         
-         /* Save the final position for pauses and resumes */
-         final_pos_msf[0] = bcd_to_int(params[4]);
-         final_pos_msf[1] = bcd_to_int(params[5]);
-         final_pos_msf[2] = bcd_to_int(params[6]);
-         sony_audio_status = CDROM_AUDIO_PLAY;
-         return 0;
-      }
-     
-   case CDROMVOLCTRL:   /* Volume control.  What volume does this change, anyway? */
-      {
-         struct cdrom_volctrl *volctrl = (struct cdrom_volctrl *) arg;
-         
-         params[0] = SONY_SD_AUDIO_VOLUME;
-         params[1] = volctrl->channel0;
-         params[2] = volctrl->channel1;
-         return do_sony_cd_cmd_chk("VOLCTRL",SONY_SET_DRIVE_PARAM_CMD, params, 3, res_reg, &res_size);
-      }
-   case CDROMSUBCHNL:   /* Get subchannel info */
-      return sony_get_subchnl_info((struct cdrom_subchnl *)arg);
-
-   default:
-      return -EINVAL;
-   }
+	unsigned char res_reg[12];
+	unsigned int res_size;
+	unsigned char params[7];
+	int i;
+
+
+	switch (cmd) {
+	case CDROMSTART:	/* Spin up the drive */
+		return do_sony_cd_cmd_chk("START", SONY_SPIN_UP_CMD, NULL,
+					  0, res_reg, &res_size);
+		break;
+
+	case CDROMSTOP:	/* Spin down the drive */
+		do_sony_cd_cmd(SONY_AUDIO_STOP_CMD, NULL, 0, res_reg,
+			       &res_size);
+
+		/*
+		 * Spin the drive down, ignoring the error if the disk was
+		 * already not spinning.
+		 */
+		sony_audio_status = CDROM_AUDIO_NO_STATUS;
+		return do_sony_cd_cmd_chk("STOP", SONY_SPIN_DOWN_CMD, NULL,
+					  0, res_reg, &res_size);
+
+	case CDROMPAUSE:	/* Pause the drive */
+		if (do_sony_cd_cmd_chk
+		    ("PAUSE", SONY_AUDIO_STOP_CMD, NULL, 0, res_reg,
+		     &res_size))
+			return -EIO;
+		/* Get the current position and save it for resuming */
+		if (read_subcode() < 0) {
+			return -EIO;
+		}
+		cur_pos_msf[0] = last_sony_subcode.abs_msf[0];
+		cur_pos_msf[1] = last_sony_subcode.abs_msf[1];
+		cur_pos_msf[2] = last_sony_subcode.abs_msf[2];
+		sony_audio_status = CDROM_AUDIO_PAUSED;
+		return 0;
+		break;
+
+	case CDROMRESUME:	/* Start the drive after being paused */
+		if (sony_audio_status != CDROM_AUDIO_PAUSED) {
+			return -EINVAL;
+		}
+
+		do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
+			       &res_size);
+
+		/* Start the drive at the saved position. */
+		params[1] = int_to_bcd(cur_pos_msf[0]);
+		params[2] = int_to_bcd(cur_pos_msf[1]);
+		params[3] = int_to_bcd(cur_pos_msf[2]);
+		params[4] = int_to_bcd(final_pos_msf[0]);
+		params[5] = int_to_bcd(final_pos_msf[1]);
+		params[6] = int_to_bcd(final_pos_msf[2]);
+		params[0] = 0x03;
+		if (do_sony_cd_cmd_chk
+		    ("RESUME", SONY_AUDIO_PLAYBACK_CMD, params, 7, res_reg,
+		     &res_size) < 0)
+			return -EIO;
+		sony_audio_status = CDROM_AUDIO_PLAY;
+		return 0;
+
+	case CDROMPLAYMSF:	/* Play starting at the given MSF address. */
+		do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
+			       &res_size);
+
+		/* The parameters are given in int, must be converted */
+		for (i = 1; i < 7; i++) {
+			params[i] =
+			    int_to_bcd(((unsigned char *) arg)[i - 1]);
+		}
+		params[0] = 0x03;
+		if (do_sony_cd_cmd_chk
+		    ("PLAYMSF", SONY_AUDIO_PLAYBACK_CMD, params, 7,
+		     res_reg, &res_size) < 0)
+			return -EIO;
+
+		/* Save the final position for pauses and resumes */
+		final_pos_msf[0] = bcd_to_int(params[4]);
+		final_pos_msf[1] = bcd_to_int(params[5]);
+		final_pos_msf[2] = bcd_to_int(params[6]);
+		sony_audio_status = CDROM_AUDIO_PLAY;
+		return 0;
+
+	case CDROMREADTOCHDR:	/* Read the table of contents header */
+		{
+			struct cdrom_tochdr *hdr;
+
+			sony_get_toc();
+			if (!sony_toc_read) {
+				return -EIO;
+			}
+
+			hdr = (struct cdrom_tochdr *) arg;
+			hdr->cdth_trk0 = sony_toc.first_track_num;
+			hdr->cdth_trk1 = sony_toc.last_track_num;
+		}
+		return 0;
+
+	case CDROMREADTOCENTRY:	/* Read a given table of contents entry */
+		{
+			struct cdrom_tocentry *entry;
+			int track_idx;
+			unsigned char *msf_val = NULL;
+
+			sony_get_toc();
+			if (!sony_toc_read) {
+				return -EIO;
+			}
+
+			entry = (struct cdrom_tocentry *) arg;
+
+			track_idx = find_track(entry->cdte_track);
+			if (track_idx < 0) {
+				return -EINVAL;
+			}
+
+			entry->cdte_adr =
+			    sony_toc.tracks[track_idx].address;
+			entry->cdte_ctrl =
+			    sony_toc.tracks[track_idx].control;
+			msf_val =
+			    sony_toc.tracks[track_idx].track_start_msf;
+
+			/* Logical buffer address or MSF format requested? */
+			if (entry->cdte_format == CDROM_LBA) {
+				entry->cdte_addr.lba = msf_to_log(msf_val);
+			} else if (entry->cdte_format == CDROM_MSF) {
+				entry->cdte_addr.msf.minute = *msf_val;
+				entry->cdte_addr.msf.second =
+				    *(msf_val + 1);
+				entry->cdte_addr.msf.frame =
+				    *(msf_val + 2);
+			}
+		}
+		return 0;
+		break;
+
+	case CDROMPLAYTRKIND:	/* Play a track.  This currently ignores index. */
+		{
+			struct cdrom_ti *ti = (struct cdrom_ti *) arg;
+			int track_idx;
+
+			sony_get_toc();
+			if (!sony_toc_read) {
+				return -EIO;
+			}
+
+			if ((ti->cdti_trk0 < sony_toc.first_track_num)
+			    || (ti->cdti_trk0 > sony_toc.last_track_num)
+			    || (ti->cdti_trk1 < ti->cdti_trk0)) {
+				return -EINVAL;
+			}
+
+			track_idx = find_track(ti->cdti_trk0);
+			if (track_idx < 0) {
+				return -EINVAL;
+			}
+			params[1] =
+			    int_to_bcd(sony_toc.tracks[track_idx].
+				       track_start_msf[0]);
+			params[2] =
+			    int_to_bcd(sony_toc.tracks[track_idx].
+				       track_start_msf[1]);
+			params[3] =
+			    int_to_bcd(sony_toc.tracks[track_idx].
+				       track_start_msf[2]);
+
+			/*
+			 * If we want to stop after the last track, use the lead-out
+			 * MSF to do that.
+			 */
+			if (ti->cdti_trk1 >= sony_toc.last_track_num) {
+				track_idx = find_track(CDROM_LEADOUT);
+			} else {
+				track_idx = find_track(ti->cdti_trk1 + 1);
+			}
+			if (track_idx < 0) {
+				return -EINVAL;
+			}
+			params[4] =
+			    int_to_bcd(sony_toc.tracks[track_idx].
+				       track_start_msf[0]);
+			params[5] =
+			    int_to_bcd(sony_toc.tracks[track_idx].
+				       track_start_msf[1]);
+			params[6] =
+			    int_to_bcd(sony_toc.tracks[track_idx].
+				       track_start_msf[2]);
+			params[0] = 0x03;
+
+			do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
+				       &res_size);
+
+			do_sony_cd_cmd(SONY_AUDIO_PLAYBACK_CMD, params, 7,
+				       res_reg, &res_size);
+
+			if ((res_size < 2)
+			    || ((res_reg[0] & 0xf0) == 0x20)) {
+				printk("Params: %x %x %x %x %x %x %x\n",
+				       params[0], params[1], params[2],
+				       params[3], params[4], params[5],
+				       params[6]);
+				printk
+				    ("Sony CDROM error %s (CDROMPLAYTRKIND)\n",
+				     translate_error(res_reg[1]));
+				return -EIO;
+			}
+
+			/* Save the final position for pauses and resumes */
+			final_pos_msf[0] = bcd_to_int(params[4]);
+			final_pos_msf[1] = bcd_to_int(params[5]);
+			final_pos_msf[2] = bcd_to_int(params[6]);
+			sony_audio_status = CDROM_AUDIO_PLAY;
+			return 0;
+		}
+
+	case CDROMVOLCTRL:	/* Volume control.  What volume does this change, anyway? */
+		{
+			struct cdrom_volctrl *volctrl =
+			    (struct cdrom_volctrl *) arg;
+
+			params[0] = SONY_SD_AUDIO_VOLUME;
+			params[1] = volctrl->channel0;
+			params[2] = volctrl->channel1;
+			return do_sony_cd_cmd_chk("VOLCTRL",
+						  SONY_SET_DRIVE_PARAM_CMD,
+						  params, 3, res_reg,
+						  &res_size);
+		}
+	case CDROMSUBCHNL:	/* Get subchannel info */
+		return sony_get_subchnl_info((struct cdrom_subchnl *) arg);
+
+	default:
+		return -EINVAL;
+	}
 }
 
 static int scd_dev_ioctl(struct cdrom_device_info *cdi,
-          unsigned int  cmd,
-          unsigned long arg)
+			 unsigned int cmd, unsigned long arg)
 {
-   int i;
+	int i;
 
-   switch (cmd)
-   {
-   case CDROMREADAUDIO:      /* Read 2352 byte audio tracks and 2340 byte
-				 raw data tracks. */
-      {
-         struct cdrom_read_audio ra;
-
-
-         sony_get_toc();
-         if (!sony_toc_read)
-         {
-         	return -EIO;
-         }
-
-	 if(copy_from_user(&ra, (char *) arg, sizeof(ra)))
-	 	return -EFAULT;
-
-         if (ra.nframes == 0)
-         {
-         	return 0;
-         }
-
-         i=verify_area(VERIFY_WRITE, ra.buf, CD_FRAMESIZE_RAW * ra.nframes);
-         if(i<0)
-         	return i;
-
-         if (ra.addr_format == CDROM_LBA)
-         {
-            if (   (ra.addr.lba >= sony_toc.lead_out_start_lba)
-                || (ra.addr.lba + ra.nframes >= sony_toc.lead_out_start_lba))
-            {
-               return -EINVAL;
-            }
-         }
-         else if (ra.addr_format == CDROM_MSF)
-         {
-            if (   (ra.addr.msf.minute >= 75)
-                || (ra.addr.msf.second >= 60)
-                || (ra.addr.msf.frame >= 75))
-            {
-               return -EINVAL;
-            }
-
-            ra.addr.lba = (  (ra.addr.msf.minute * 4500)
-                           + (ra.addr.msf.second * 75)
-                           + ra.addr.msf.frame);
-            if (   (ra.addr.lba >= sony_toc.lead_out_start_lba)
-                || (ra.addr.lba + ra.nframes >= sony_toc.lead_out_start_lba))
-            {
-               return -EINVAL;
-            }
-
-            /* I know, this can go negative on an unsigned.  However,
-               the first thing done to the data is to add this value,
-               so this should compensate and allow direct msf access. */
-            ra.addr.lba -= LOG_START_OFFSET;
-         }
-         else
-         {
-            return -EINVAL;
-         }
-
-         return(read_audio(&ra));
-      }
-      return 0;
-      break;
-
-   default:
-      return -EINVAL;
-   }
+	switch (cmd) {
+	case CDROMREADAUDIO:	/* Read 2352 byte audio tracks and 2340 byte
+				   raw data tracks. */
+		{
+			struct cdrom_read_audio ra;
+
+
+			sony_get_toc();
+			if (!sony_toc_read) {
+				return -EIO;
+			}
+
+			if (copy_from_user(&ra, (char *) arg, sizeof(ra)))
+				return -EFAULT;
+
+			if (ra.nframes == 0) {
+				return 0;
+			}
+
+			i = verify_area(VERIFY_WRITE, ra.buf,
+					CD_FRAMESIZE_RAW * ra.nframes);
+			if (i < 0)
+				return i;
+
+			if (ra.addr_format == CDROM_LBA) {
+				if ((ra.addr.lba >=
+				     sony_toc.lead_out_start_lba)
+				    || (ra.addr.lba + ra.nframes >=
+					sony_toc.lead_out_start_lba)) {
+					return -EINVAL;
+				}
+			} else if (ra.addr_format == CDROM_MSF) {
+				if ((ra.addr.msf.minute >= 75)
+				    || (ra.addr.msf.second >= 60)
+				    || (ra.addr.msf.frame >= 75)) {
+					return -EINVAL;
+				}
+
+				ra.addr.lba = ((ra.addr.msf.minute * 4500)
+					       + (ra.addr.msf.second * 75)
+					       + ra.addr.msf.frame);
+				if ((ra.addr.lba >=
+				     sony_toc.lead_out_start_lba)
+				    || (ra.addr.lba + ra.nframes >=
+					sony_toc.lead_out_start_lba)) {
+					return -EINVAL;
+				}
+
+				/* I know, this can go negative on an unsigned.  However,
+				   the first thing done to the data is to add this value,
+				   so this should compensate and allow direct msf access. */
+				ra.addr.lba -= LOG_START_OFFSET;
+			} else {
+				return -EINVAL;
+			}
+
+			return (read_audio(&ra));
+		}
+		return 0;
+		break;
+
+	default:
+		return -EINVAL;
+	}
 }
 
 static int scd_spinup(void)
 {
-   unsigned char res_reg[12];
-   unsigned int res_size;
-   int num_spin_ups;
-
-   num_spin_ups = 0;
-
-respinup_on_open:
-   do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
-
-   /* The drive sometimes returns error 0.  I don't know why, but ignore
-      it.  It seems to mean the drive has already done the operation. */
-   if ((res_size < 2) || ((res_reg[0] != 0) && (res_reg[1] != 0)))
-   {
-      printk("Sony CDROM %s error (scd_open, spin up)\n", translate_error(res_reg[1]));
-      return 1;
-   }
-      
-   do_sony_cd_cmd(SONY_READ_TOC_CMD, NULL, 0, res_reg, &res_size);
-
-   /* The drive sometimes returns error 0.  I don't know why, but ignore
-      it.  It seems to mean the drive has already done the operation. */
-   if ((res_size < 2) || ((res_reg[0] != 0) && (res_reg[1] != 0)))
-   {
-      /* If the drive is already playing, it's ok.  */
-      if ((res_reg[1] == SONY_AUDIO_PLAYING_ERR) || (res_reg[1] == 0))
-      {
-         return 0;
-      }
-
-      /* If the drive says it is not spun up (even though we just did it!)
-         then retry the operation at least a few times. */
-      if (   (res_reg[1] == SONY_NOT_SPIN_ERR)
-          && (num_spin_ups < MAX_CDU31A_RETRIES))
-      {
-         num_spin_ups++;
-         goto respinup_on_open;
-      }
-
-      printk("Sony CDROM error %s (scd_open, read toc)\n", translate_error(res_reg[1]));
-      do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg, &res_size);
-      return 1;  
-   }
-   return 0;
+	unsigned char res_reg[12];
+	unsigned int res_size;
+	int num_spin_ups;
+
+	num_spin_ups = 0;
+
+      respinup_on_open:
+	do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
+
+	/* The drive sometimes returns error 0.  I don't know why, but ignore
+	   it.  It seems to mean the drive has already done the operation. */
+	if ((res_size < 2) || ((res_reg[0] != 0) && (res_reg[1] != 0))) {
+		printk("Sony CDROM %s error (scd_open, spin up)\n",
+		       translate_error(res_reg[1]));
+		return 1;
+	}
+
+	do_sony_cd_cmd(SONY_READ_TOC_CMD, NULL, 0, res_reg, &res_size);
+
+	/* The drive sometimes returns error 0.  I don't know why, but ignore
+	   it.  It seems to mean the drive has already done the operation. */
+	if ((res_size < 2) || ((res_reg[0] != 0) && (res_reg[1] != 0))) {
+		/* If the drive is already playing, it's ok.  */
+		if ((res_reg[1] == SONY_AUDIO_PLAYING_ERR)
+		    || (res_reg[1] == 0)) {
+			return 0;
+		}
+
+		/* If the drive says it is not spun up (even though we just did it!)
+		   then retry the operation at least a few times. */
+		if ((res_reg[1] == SONY_NOT_SPIN_ERR)
+		    && (num_spin_ups < MAX_CDU31A_RETRIES)) {
+			num_spin_ups++;
+			goto respinup_on_open;
+		}
+
+		printk("Sony CDROM error %s (scd_open, read toc)\n",
+		       translate_error(res_reg[1]));
+		do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg,
+			       &res_size);
+		return 1;
+	}
+	return 0;
 }
 
 /*
  * Open the drive for operations.  Spin the drive up and read the table of
  * contents if these have not already been done.
  */
-static int
-scd_open(struct cdrom_device_info *cdi, int openmode)
+static int scd_open(struct cdrom_device_info *cdi, int openmode)
 {
-   unsigned char res_reg[12];
-   unsigned int res_size;
-   unsigned char params[2];
-
-   MOD_INC_USE_COUNT;
-   if (sony_usage == 0)
-   {
-      if (scd_spinup() != 0) {
-         MOD_DEC_USE_COUNT;
-         return -EIO;
-      }
-      sony_get_toc();
-      if (!sony_toc_read)
-      {
-         do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg, &res_size);
-         MOD_DEC_USE_COUNT;
-         return -EIO;
-      }
-
-      /* For XA on the CDU31A only, we have to do special reads.
-         The CDU33A handles XA automagically. */
-      /* if (   (sony_toc.disk_type == SONY_XA_DISK_TYPE) */
-      if (   (sony_toc.disk_type != 0x00)
-          && (!is_double_speed))
-      {
-         params[0] = SONY_SD_DECODE_PARAM;
-         params[1] = 0x07;
-         do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
-                        params,
-                        2,
-                        res_reg,
-                        &res_size);
-         if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
-         {
-            printk("CDU31A: Unable to set XA params: 0x%2.2x\n", res_reg[1]);
-         }
-         sony_xa_mode = 1;
-      }
-      /* A non-XA disk.  Set the parms back if necessary. */
-      else if (sony_xa_mode)
-      {
-         params[0] = SONY_SD_DECODE_PARAM;
-         params[1] = 0x0f;
-         do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
-                        params,
-                        2,
-                        res_reg,
-                        &res_size);
-         if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
-         {
-            printk("CDU31A: Unable to reset XA params: 0x%2.2x\n", res_reg[1]);
-         }
-         sony_xa_mode = 0;
-      }
+	unsigned char res_reg[12];
+	unsigned int res_size;
+	unsigned char params[2];
+
+	MOD_INC_USE_COUNT;
+	if (sony_usage == 0) {
+		if (scd_spinup() != 0) {
+			MOD_DEC_USE_COUNT;
+			return -EIO;
+		}
+		sony_get_toc();
+		if (!sony_toc_read) {
+			do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0,
+				       res_reg, &res_size);
+			MOD_DEC_USE_COUNT;
+			return -EIO;
+		}
+
+		/* For XA on the CDU31A only, we have to do special reads.
+		   The CDU33A handles XA automagically. */
+		/* if (   (sony_toc.disk_type == SONY_XA_DISK_TYPE) */
+		if ((sony_toc.disk_type != 0x00)
+		    && (!is_double_speed)) {
+			params[0] = SONY_SD_DECODE_PARAM;
+			params[1] = 0x07;
+			do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
+				       params, 2, res_reg, &res_size);
+			if ((res_size < 2)
+			    || ((res_reg[0] & 0xf0) == 0x20)) {
+				printk
+				    ("CDU31A: Unable to set XA params: 0x%2.2x\n",
+				     res_reg[1]);
+			}
+			sony_xa_mode = 1;
+		}
+		/* A non-XA disk.  Set the parms back if necessary. */
+		else if (sony_xa_mode) {
+			params[0] = SONY_SD_DECODE_PARAM;
+			params[1] = 0x0f;
+			do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
+				       params, 2, res_reg, &res_size);
+			if ((res_size < 2)
+			    || ((res_reg[0] & 0xf0) == 0x20)) {
+				printk
+				    ("CDU31A: Unable to reset XA params: 0x%2.2x\n",
+				     res_reg[1]);
+			}
+			sony_xa_mode = 0;
+		}
 
-      sony_spun_up = 1;
-   }
+		sony_spun_up = 1;
+	}
 
-   sony_usage++;
+	sony_usage++;
 
-   return 0;
+	return 0;
 }
 
 
@@ -3205,114 +3171,109 @@
  * Close the drive.  Spin it down if no task is using it.  The spin
  * down will fail if playing audio, so audio play is OK.
  */
-static void
-scd_release(struct cdrom_device_info *cdi)
+static void scd_release(struct cdrom_device_info *cdi)
 {
-   if (sony_usage == 1)
-   {
-      unsigned char res_reg[12];
-      unsigned int  res_size;
-
-      do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg, &res_size);
-
-      sony_spun_up = 0;
-   }
-   sony_usage--;
-   MOD_DEC_USE_COUNT;
+	if (sony_usage == 1) {
+		unsigned char res_reg[12];
+		unsigned int res_size;
+
+		do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg,
+			       &res_size);
+
+		sony_spun_up = 0;
+	}
+	sony_usage--;
+	MOD_DEC_USE_COUNT;
 }
 
 static struct cdrom_device_ops scd_dops = {
-	open:			scd_open,
-	release:		scd_release,
-	drive_status:		scd_drive_status,
-	media_changed:		scd_media_changed,
-	tray_move:		scd_tray_move,
-	lock_door:		scd_lock_door,
-	select_speed:		scd_select_speed,
-	get_last_session:	scd_get_last_session,
-	get_mcn:		scd_get_mcn,
-	reset:			scd_reset,
-	audio_ioctl:		scd_audio_ioctl,
-	dev_ioctl:		scd_dev_ioctl,
-	capability:		CDC_OPEN_TRAY | CDC_CLOSE_TRAY | CDC_LOCK |
-				CDC_SELECT_SPEED | CDC_MULTI_SESSION | 
-				CDC_MULTI_SESSION | CDC_MCN |
-				CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO |
-				CDC_RESET | CDC_IOCTLS | CDC_DRIVE_STATUS,
-	n_minors:		1,
+	open:scd_open,
+	release:scd_release,
+	drive_status:scd_drive_status,
+	media_changed:scd_media_changed,
+	tray_move:scd_tray_move,
+	lock_door:scd_lock_door,
+	select_speed:scd_select_speed,
+	get_last_session:scd_get_last_session,
+	get_mcn:scd_get_mcn,
+	reset:scd_reset,
+	audio_ioctl:scd_audio_ioctl,
+	dev_ioctl:scd_dev_ioctl,
+	capability:CDC_OPEN_TRAY | CDC_CLOSE_TRAY | CDC_LOCK |
+	    CDC_SELECT_SPEED | CDC_MULTI_SESSION |
+	    CDC_MULTI_SESSION | CDC_MCN |
+	    CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO |
+	    CDC_RESET | CDC_IOCTLS | CDC_DRIVE_STATUS,
+	n_minors:1,
 };
 
 static struct cdrom_device_info scd_info = {
-	ops:		&scd_dops,
-	speed:		2,
-	capacity:	1,
-	name:		"cdu31a"
+	ops:&scd_dops,
+	speed:2,
+	capacity:1,
+	name:"cdu31a"
 };
 
 /* The different types of disc loading mechanisms supported */
-static const char *load_mech[] __initdata = { "caddy", "tray", "pop-up", "unknown" };
+static char *load_mech[] __initdata =
+    { "caddy", "tray", "pop-up", "unknown" };
 
-static void __init 
+static void __init
 get_drive_configuration(unsigned short base_io,
-                        unsigned char res_reg[],
-                        unsigned int *res_size)
+			unsigned char res_reg[], unsigned int *res_size)
 {
-   int retry_count;
+	int retry_count;
 
 
-   /* Set the base address */
-   cdu31a_port = base_io;
+	/* Set the base address */
+	cdu31a_port = base_io;
 
-   /* Set up all the register locations */
-   sony_cd_cmd_reg = cdu31a_port + SONY_CMD_REG_OFFSET;
-   sony_cd_param_reg = cdu31a_port + SONY_PARAM_REG_OFFSET;
-   sony_cd_write_reg = cdu31a_port + SONY_WRITE_REG_OFFSET;
-   sony_cd_control_reg = cdu31a_port + SONY_CONTROL_REG_OFFSET;
-   sony_cd_status_reg = cdu31a_port + SONY_STATUS_REG_OFFSET;
-   sony_cd_result_reg = cdu31a_port + SONY_RESULT_REG_OFFSET;
-   sony_cd_read_reg = cdu31a_port + SONY_READ_REG_OFFSET;
-   sony_cd_fifost_reg = cdu31a_port + SONY_FIFOST_REG_OFFSET;
-
-   /*
-    * Check to see if anything exists at the status register location.
-    * I don't know if this is a good way to check, but it seems to work
-    * ok for me.
-    */
-   if (read_status_register() != 0xff)
-   {
-      /*
-       * Reset the drive and wait for attention from it (to say it's reset).
-       * If you don't wait, the next operation will probably fail.
-       */
-      reset_drive();
-      retry_count = jiffies + SONY_RESET_TIMEOUT;
-      while (time_before(jiffies, retry_count) && (!is_attention()))
-      {
-         sony_sleep();
-      }
+	/* Set up all the register locations */
+	sony_cd_cmd_reg = cdu31a_port + SONY_CMD_REG_OFFSET;
+	sony_cd_param_reg = cdu31a_port + SONY_PARAM_REG_OFFSET;
+	sony_cd_write_reg = cdu31a_port + SONY_WRITE_REG_OFFSET;
+	sony_cd_control_reg = cdu31a_port + SONY_CONTROL_REG_OFFSET;
+	sony_cd_status_reg = cdu31a_port + SONY_STATUS_REG_OFFSET;
+	sony_cd_result_reg = cdu31a_port + SONY_RESULT_REG_OFFSET;
+	sony_cd_read_reg = cdu31a_port + SONY_READ_REG_OFFSET;
+	sony_cd_fifost_reg = cdu31a_port + SONY_FIFOST_REG_OFFSET;
+
+	/*
+	 * Check to see if anything exists at the status register location.
+	 * I don't know if this is a good way to check, but it seems to work
+	 * ok for me.
+	 */
+	if (read_status_register() != 0xff) {
+		/*
+		 * Reset the drive and wait for attention from it (to say it's reset).
+		 * If you don't wait, the next operation will probably fail.
+		 */
+		reset_drive();
+		retry_count = jiffies + SONY_RESET_TIMEOUT;
+		while (time_before(jiffies, retry_count)
+		       && (!is_attention())) {
+			sony_sleep();
+		}
 
 #if 0
-      /* If attention is never seen probably not a CDU31a present */
-      if (!is_attention())
-      {
-         res_reg[0] = 0x20;
-         return;
-      }
-#endif
-
-      /*
-       * Get the drive configuration.
-       */
-      do_sony_cd_cmd(SONY_REQ_DRIVE_CONFIG_CMD,
-                     NULL,
-                     0,
-                     (unsigned char *) res_reg,
-                     res_size);
-      return;
-   }
+		/* If attention is never seen probably not a CDU31a present */
+		if (!is_attention()) {
+			res_reg[0] = 0x20;
+			return;
+		}
+#endif
+
+		/*
+		 * Get the drive configuration.
+		 */
+		do_sony_cd_cmd(SONY_REQ_DRIVE_CONFIG_CMD,
+			       NULL,
+			       0, (unsigned char *) res_reg, res_size);
+		return;
+	}
 
-   /* Return an error */
-   res_reg[0] = 0x20;
+	/* Return an error */
+	res_reg[0] = 0x20;
 }
 
 #ifndef MODULE
@@ -3321,33 +3282,28 @@
  
  */
 
-static int __init cdu31a_setup(char *strings)	     
+static int __init cdu31a_setup(char *strings)
 {
-    int ints[4];
-    
-    (void)get_options(strings, ARRAY_SIZE(ints), ints);
-
-   if (ints[0] > 0)
-   {
-      cdu31a_port = ints[1];
-   }
-   if (ints[0] > 1)
-   {
-      cdu31a_irq = ints[2];
-   }
-   if ((strings != NULL) && (*strings != '\0'))
-   {
-      if (strcmp(strings, "PAS") == 0)
-      {
-	 sony_pas_init = 1;
-      }
-      else
-      {
-	 printk("CDU31A: Unknown interface type: %s\n", strings);
-      }
-   }
-   
-   return 1;
+	int ints[4];
+
+	(void) get_options(strings, ARRAY_SIZE(ints), ints);
+
+	if (ints[0] > 0) {
+		cdu31a_port = ints[1];
+	}
+	if (ints[0] > 1) {
+		cdu31a_irq = ints[2];
+	}
+	if ((strings != NULL) && (*strings != '\0')) {
+		if (strcmp(strings, "PAS") == 0) {
+			sony_pas_init = 1;
+		} else {
+			printk("CDU31A: Unknown interface type: %s\n",
+			       strings);
+		}
+	}
+
+	return 1;
 }
 
 __setup("cdu31a=", cdu31a_setup);
@@ -3359,223 +3315,204 @@
 /*
  * Initialize the driver.
  */
-int __init 
-cdu31a_init(void)
+int __init cdu31a_init(void)
 {
-   struct s_sony_drive_config drive_config;
-   unsigned int res_size;
-   char msg[255];
-   char buf[40];
-   int i;
-   int drive_found;
-   int tmp_irq;
-
-
-   /*
-    * According to Alex Freed (freed@europa.orion.adobe.com), this is
-    * required for the Fusion CD-16 package.  If the sound driver is
-    * loaded, it should work fine, but just in case...
-    *
-    * The following turn on the CD-ROM interface for a Fusion CD-16.
-    */
-   if (sony_pas_init)
-   {
-      outb(0xbc, 0x9a01);
-      outb(0xe2, 0x9a01);
-   }
-
-   drive_found = 0;
-
-   /* Setting the base I/O address to 0xffff will disable it. */
-   if (cdu31a_port == 0xffff)
-   {
-   }
-   else if (cdu31a_port != 0)
-   {
-      tmp_irq = cdu31a_irq; /* Need IRQ 0 because we can't sleep here. */
-      cdu31a_irq = 0;
-
-      get_drive_configuration(cdu31a_port,
-			      drive_config.exec_status,
-			      &res_size);
-      if ((res_size > 2) && ((drive_config.exec_status[0] & 0xf0) == 0x00))
-      {
-	 drive_found = 1;
-      }
-
-      cdu31a_irq = tmp_irq;
-   }
-   else
-   {
-      cdu31a_irq = 0;
-      i = 0;
-      while (   (cdu31a_addresses[i].base != 0)
-	     && (!drive_found))
-      {
-	 if (check_region(cdu31a_addresses[i].base, 4)) {
-	    i++;
-	    continue;
-	 }
-	 get_drive_configuration(cdu31a_addresses[i].base,
-				 drive_config.exec_status,
-				 &res_size);
-	 if ((res_size > 2) && ((drive_config.exec_status[0] & 0xf0) == 0x00))
-	 {
-	    drive_found = 1;
-	    cdu31a_irq = cdu31a_addresses[i].int_num;
-	 }
-	 else
-	 {
-	    i++;
-	 }
-      }
-   }
-
-   if (drive_found)
-   {
-      int deficiency=0;
-
-      request_region(cdu31a_port, 4,"cdu31a");
-      
-      if (devfs_register_blkdev(MAJOR_NR,"cdu31a",&cdrom_fops))
-      {
-	 printk("Unable to get major %d for CDU-31a\n", MAJOR_NR);
-         goto errout2;
-      }
-
-      if (SONY_HWC_DOUBLE_SPEED(drive_config))
-      {
-	 is_double_speed = 1;
-      }
-
-      tmp_irq = cdu31a_irq; /* Need IRQ 0 because we can't sleep here. */
-      cdu31a_irq = 0;
-
-      set_drive_params(sony_speed);
-
-      cdu31a_irq = tmp_irq;
-      
-      if (cdu31a_irq > 0)
-      {
-	 if (request_irq(cdu31a_irq, cdu31a_interrupt, SA_INTERRUPT, "cdu31a", NULL))
-	 {
-	    printk("Unable to grab IRQ%d for the CDU31A driver\n", cdu31a_irq);
-	    cdu31a_irq = 0;
-	 }
-      }
-      
-      sprintf(msg, "Sony I/F CDROM : %8.8s %16.16s %8.8s\n",
-	     drive_config.vendor_id,
-	     drive_config.product_id,
-	     drive_config.product_rev_level);
-      sprintf(buf, "  Capabilities: %s",
-	     load_mech[SONY_HWC_GET_LOAD_MECH(drive_config)]);
-      strcat(msg, buf);
-      if (SONY_HWC_AUDIO_PLAYBACK(drive_config))
-      {
-         strcat(msg, ", audio");
-      } else
-	 deficiency |= CDC_PLAY_AUDIO;
-      if (SONY_HWC_EJECT(drive_config))
-      {
-         strcat(msg, ", eject");
-      } else
-	 deficiency |= CDC_OPEN_TRAY;
-      if (SONY_HWC_LED_SUPPORT(drive_config))
-      {
-         strcat(msg, ", LED");
-      }
-      if (SONY_HWC_ELECTRIC_VOLUME(drive_config))
-      {
-         strcat(msg, ", elec. Vol");
-      }
-      if (SONY_HWC_ELECTRIC_VOLUME_CTL(drive_config))
-      {
-         strcat(msg, ", sep. Vol");
-      }
-      if (is_double_speed)
-      {
-         strcat(msg, ", double speed");
-      } else
-	 deficiency |= CDC_SELECT_SPEED;
-      if (cdu31a_irq > 0)
-      {
-	 sprintf(buf, ", irq %d", cdu31a_irq);
-         strcat(msg, buf);
-      }
-      strcat(msg, "\n");
-
-      is_a_cdu31a = strcmp("CD-ROM CDU31A", drive_config.product_id) == 0;
-
-      blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
-      read_ahead[MAJOR_NR] = CDU31A_READAHEAD;
-      cdu31a_block_size = 1024; /* 1kB default block size */
-      /* use 'mount -o block=2048' */
-      blksize_size[MAJOR_NR] = &cdu31a_block_size;
-      
-      init_timer(&cdu31a_abort_timer);
-      cdu31a_abort_timer.function = handle_abort_timeout;
-
-      scd_info.dev = MKDEV(MAJOR_NR,0);
-      scd_info.mask = deficiency;
-      strncpy(scd_info.name, "cdu31a", sizeof(scd_info.name));
-
-      if (register_cdrom(&scd_info))
-      {
-         goto errout0;
-      }
-   }
-
-
-   disk_changed = 1;
-   
-   if (drive_found)
-   {
-      return(0);
-   }
-   else
-   {
-      goto errout3;
-   }
-errout0:
-   printk("Unable to register CDU-31a with Uniform cdrom driver\n");
-   blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
-   if (devfs_unregister_blkdev(MAJOR_NR, "cdu31a"))    
-   {
-      printk("Can't unregister block device for cdu31a\n");
-   }
-errout2:
-   release_region(cdu31a_port,4);
-errout3:
-   return -EIO;
-}
-
-
-void __exit
-cdu31a_exit(void)
-{
-   if (unregister_cdrom(&scd_info))    
-   {
-      printk("Can't unregister cdu31a from Uniform cdrom driver\n");
-      return;
-   }
-   if ((devfs_unregister_blkdev(MAJOR_NR, "cdu31a") == -EINVAL))    
-   {
-      printk("Can't unregister cdu31a\n");
-      return;
-   }
-
-   blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
-
-   if (cdu31a_irq > 0)
-      free_irq(cdu31a_irq, NULL);
-
-   release_region(cdu31a_port,4);
-   printk(KERN_INFO "cdu31a module released.\n");
-}   
+	struct s_sony_drive_config drive_config;
+	unsigned int res_size;
+	char msg[255];
+	char buf[40];
+	int i;
+	int drive_found;
+	int tmp_irq;
+
+
+	/*
+	 * According to Alex Freed (freed@europa.orion.adobe.com), this is
+	 * required for the Fusion CD-16 package.  If the sound driver is
+	 * loaded, it should work fine, but just in case...
+	 *
+	 * The following turn on the CD-ROM interface for a Fusion CD-16.
+	 */
+	if (sony_pas_init) {
+		outb(0xbc, 0x9a01);
+		outb(0xe2, 0x9a01);
+	}
+
+	drive_found = 0;
+
+	/* Setting the base I/O address to 0xffff will disable it. */
+	if (cdu31a_port == 0xffff) {
+	} else if (cdu31a_port != 0) {
+		tmp_irq = cdu31a_irq;	/* Need IRQ 0 because we can't sleep here. */
+		cdu31a_irq = 0;
+
+		get_drive_configuration(cdu31a_port,
+					drive_config.exec_status,
+					&res_size);
+		if ((res_size > 2)
+		    && ((drive_config.exec_status[0] & 0xf0) == 0x00)) {
+			drive_found = 1;
+		}
+
+		cdu31a_irq = tmp_irq;
+	} else {
+		cdu31a_irq = 0;
+		i = 0;
+		while ((cdu31a_addresses[i].base != 0)
+		       && (!drive_found)) {
+			if (check_region(cdu31a_addresses[i].base, 4)) {
+				i++;
+				continue;
+			}
+			get_drive_configuration(cdu31a_addresses[i].base,
+						drive_config.exec_status,
+						&res_size);
+			if ((res_size > 2)
+			    && ((drive_config.exec_status[0] & 0xf0) ==
+				0x00)) {
+				drive_found = 1;
+				cdu31a_irq = cdu31a_addresses[i].int_num;
+			} else {
+				i++;
+			}
+		}
+	}
+
+	if (drive_found) {
+		int deficiency = 0;
+
+		request_region(cdu31a_port, 4, "cdu31a");
+
+		if (devfs_register_blkdev(MAJOR_NR, "cdu31a", &cdrom_fops)) {
+			printk("Unable to get major %d for CDU-31a\n",
+			       MAJOR_NR);
+			goto errout2;
+		}
+
+		if (SONY_HWC_DOUBLE_SPEED(drive_config)) {
+			is_double_speed = 1;
+		}
+
+		tmp_irq = cdu31a_irq;	/* Need IRQ 0 because we can't sleep here. */
+		cdu31a_irq = 0;
+
+		set_drive_params(sony_speed);
+
+		cdu31a_irq = tmp_irq;
+
+		if (cdu31a_irq > 0) {
+			if (request_irq
+			    (cdu31a_irq, cdu31a_interrupt, SA_INTERRUPT,
+			     "cdu31a", NULL)) {
+				printk
+				    ("Unable to grab IRQ%d for the CDU31A driver\n",
+				     cdu31a_irq);
+				cdu31a_irq = 0;
+			}
+		}
+
+		sprintf(msg, "Sony I/F CDROM : %8.8s %16.16s %8.8s\n",
+			drive_config.vendor_id,
+			drive_config.product_id,
+			drive_config.product_rev_level);
+		sprintf(buf, "  Capabilities: %s",
+			load_mech[SONY_HWC_GET_LOAD_MECH(drive_config)]);
+		strcat(msg, buf);
+		if (SONY_HWC_AUDIO_PLAYBACK(drive_config)) {
+			strcat(msg, ", audio");
+		} else
+			deficiency |= CDC_PLAY_AUDIO;
+		if (SONY_HWC_EJECT(drive_config)) {
+			strcat(msg, ", eject");
+		} else
+			deficiency |= CDC_OPEN_TRAY;
+		if (SONY_HWC_LED_SUPPORT(drive_config)) {
+			strcat(msg, ", LED");
+		}
+		if (SONY_HWC_ELECTRIC_VOLUME(drive_config)) {
+			strcat(msg, ", elec. Vol");
+		}
+		if (SONY_HWC_ELECTRIC_VOLUME_CTL(drive_config)) {
+			strcat(msg, ", sep. Vol");
+		}
+		if (is_double_speed) {
+			strcat(msg, ", double speed");
+		} else
+			deficiency |= CDC_SELECT_SPEED;
+		if (cdu31a_irq > 0) {
+			sprintf(buf, ", irq %d", cdu31a_irq);
+			strcat(msg, buf);
+		}
+		strcat(msg, "\n");
+
+		is_a_cdu31a =
+		    strcmp("CD-ROM CDU31A", drive_config.product_id) == 0;
+
+		blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR),
+			       DEVICE_REQUEST);
+		read_ahead[MAJOR_NR] = CDU31A_READAHEAD;
+		cdu31a_block_size = 1024;	/* 1kB default block size */
+		/* use 'mount -o block=2048' */
+		blksize_size[MAJOR_NR] = &cdu31a_block_size;
+
+		init_timer(&cdu31a_abort_timer);
+		cdu31a_abort_timer.function = handle_abort_timeout;
+
+		scd_info.dev = MKDEV(MAJOR_NR, 0);
+		scd_info.mask = deficiency;
+		strncpy(scd_info.name, "cdu31a", sizeof(scd_info.name));
+
+		if (register_cdrom(&scd_info)) {
+			goto errout0;
+		}
+	}
+
+
+	disk_changed = 1;
+
+	if (drive_found) {
+		return (0);
+	} else {
+		goto errout3;
+	}
+      errout0:
+	printk("Unable to register CDU-31a with Uniform cdrom driver\n");
+	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
+	if (devfs_unregister_blkdev(MAJOR_NR, "cdu31a")) {
+		printk("Can't unregister block device for cdu31a\n");
+	}
+      errout2:
+	release_region(cdu31a_port, 4);
+      errout3:
+	return -EIO;
+}
+
+
+void __exit cdu31a_exit(void)
+{
+	if (unregister_cdrom(&scd_info)) {
+		printk
+		    ("Can't unregister cdu31a from Uniform cdrom driver\n");
+		return;
+	}
+	if ((devfs_unregister_blkdev(MAJOR_NR, "cdu31a") == -EINVAL)) {
+		printk("Can't unregister cdu31a\n");
+		return;
+	}
+
+	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
+
+	if (cdu31a_irq > 0)
+		free_irq(cdu31a_irq, NULL);
+
+	release_region(cdu31a_port, 4);
+	printk(KERN_INFO "cdu31a module released.\n");
+}
 
 #ifdef MODULE
 module_init(cdu31a_init);
 #endif
 module_exit(cdu31a_exit);
 
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
diff -u --recursive --new-file v2.4.9/linux/drivers/cdrom/cm206.c linux/drivers/cdrom/cm206.c
--- v2.4.9/linux/drivers/cdrom/cm206.c	Fri Feb  9 11:30:22 2001
+++ linux/drivers/cdrom/cm206.c	Fri Sep  7 09:28:38 2001
@@ -178,7 +178,7 @@
  * David van Leeuwen, david@tm.tno.nl.  */
 #define REVISION "$Revision: 1.5 $"
 
-#include <linux/module.h>	
+#include <linux/module.h>
 
 #include <linux/errno.h>	/* These include what we really need */
 #include <linux/delay.h>
@@ -211,16 +211,19 @@
    address and interrupt request. It can be overridden by the boot 
    parameter `auto'.
 */
-static int auto_probe=1;	/* Yes, why not? */
+static int auto_probe = 1;	/* Yes, why not? */
 
 static int cm206_base = CM206_BASE;
-static int cm206_irq = CM206_IRQ; 
-static int cm206[2] = {0,0};	/* for compatible `insmod' parameter passing */
+static int cm206_irq = CM206_IRQ;
+#ifdef MODULE
+static int cm206[2] = { 0, 0 };	/* for compatible `insmod' parameter passing */
+#endif
 
 MODULE_PARM(cm206_base, "i");	/* base */
 MODULE_PARM(cm206_irq, "i");	/* irq */
 MODULE_PARM(cm206, "1-2i");	/* base,irq or irq,base */
 MODULE_PARM(auto_probe, "i");	/* auto probe base and irq */
+MODULE_LICENSE("GPL");
 
 #define POLLOOP 100		/* milliseconds */
 #define READ_AHEAD 1		/* defines private buffer, waste! */
@@ -233,7 +236,7 @@
 #define LINUX_BLOCK_SIZE 512	/* WHERE is this defined? */
 #define RAW_SECTOR_SIZE 2352	/* ok, is also defined in cdrom.h */
 #define ISO_SECTOR_SIZE 2048
-#define BLOCKS_ISO (ISO_SECTOR_SIZE/LINUX_BLOCK_SIZE) /* 4 */
+#define BLOCKS_ISO (ISO_SECTOR_SIZE/LINUX_BLOCK_SIZE)	/* 4 */
 #define CD_SYNC_HEAD 16		/* CD_SYNC + CD_HEAD */
 
 #ifdef STATISTICS		/* keep track of errors in counters */
@@ -254,88 +257,91 @@
 typedef unsigned char uch;	/* 8-bits */
 typedef unsigned short ush;	/* 16-bits */
 
-struct toc_struct{		/* private copy of Table of Contents */
-  uch track, fsm[3], q0;
+struct toc_struct {		/* private copy of Table of Contents */
+	uch track, fsm[3], q0;
 };
 
 static int cm206_blocksizes[1] = { 2048 };
 
 struct cm206_struct {
-  volatile ush intr_ds;		/* data status read on last interrupt */
-  volatile ush intr_ls;		/* uart line status read on last interrupt*/
-  volatile uch ur[UR_SIZE];	/* uart receive buffer fifo */
-  volatile uch ur_w, ur_r;	/* write/read buffer index */
-  volatile uch dsb, cc;	 /* drive status byte and condition (error) code */
-  int command;			/* command to be written to the uart */
-  int openfiles;
-  ush sector[READ_AHEAD*RAW_SECTOR_SIZE/2]; /* buffered cd-sector */
-  int sector_first, sector_last; /* range of these sectors */
-  wait_queue_head_t uart;	/* wait queues for interrupt */
-  wait_queue_head_t data;
-  struct timer_list timer;	/* time-out */
-  char timed_out;
-  signed char max_sectors;	/* number of sectors that fit in adapter mem */
-  char wait_back;		/* we're waiting for a background-read */
-  char background;		/* is a read going on in the background? */
-  int adapter_first;		/* if so, that's the starting sector */
-  int adapter_last;
-  char fifo_overflowed;
-  uch disc_status[7];		/* result of get_disc_status command */
+	volatile ush intr_ds;	/* data status read on last interrupt */
+	volatile ush intr_ls;	/* uart line status read on last interrupt */
+	volatile uch ur[UR_SIZE];	/* uart receive buffer fifo */
+	volatile uch ur_w, ur_r;	/* write/read buffer index */
+	volatile uch dsb, cc;	/* drive status byte and condition (error) code */
+	int command;		/* command to be written to the uart */
+	int openfiles;
+	ush sector[READ_AHEAD * RAW_SECTOR_SIZE / 2];	/* buffered cd-sector */
+	int sector_first, sector_last;	/* range of these sectors */
+	wait_queue_head_t uart;	/* wait queues for interrupt */
+	wait_queue_head_t data;
+	struct timer_list timer;	/* time-out */
+	char timed_out;
+	signed char max_sectors;	/* number of sectors that fit in adapter mem */
+	char wait_back;		/* we're waiting for a background-read */
+	char background;	/* is a read going on in the background? */
+	int adapter_first;	/* if so, that's the starting sector */
+	int adapter_last;
+	char fifo_overflowed;
+	uch disc_status[7];	/* result of get_disc_status command */
 #ifdef STATISTICS
-  int stats[NR_STATS];
-  int last_stat[NR_STATS];	/* `time' at which stat was stat */
-  int stat_counter;
-#endif  
-  struct toc_struct toc[101];	/* The whole table of contents + lead-out */
-  uch q[10];			/* Last read q-channel info */
-  uch audio_status[5];		/* last read position on pause */
-  uch media_changed;		/* record if media changed */
+	int stats[NR_STATS];
+	int last_stat[NR_STATS];	/* `time' at which stat was stat */
+	int stat_counter;
+#endif
+	struct toc_struct toc[101];	/* The whole table of contents + lead-out */
+	uch q[10];		/* Last read q-channel info */
+	uch audio_status[5];	/* last read position on pause */
+	uch media_changed;	/* record if media changed */
 };
 
 #define DISC_STATUS cd->disc_status[0]
 #define FIRST_TRACK cd->disc_status[1]
 #define LAST_TRACK cd->disc_status[2]
-#define PAUSED cd->audio_status[0] /* misuse this memory byte! */
+#define PAUSED cd->audio_status[0]	/* misuse this memory byte! */
 #define PLAY_TO cd->toc[0]	/* toc[0] records end-time in play */
 
-static struct cm206_struct * cd; /* the main memory structure */
+static struct cm206_struct *cd;	/* the main memory structure */
 
 /* First, we define some polling functions. These are actually
    only being used in the initialization. */
 
 void send_command_polled(int command)
 {
-  int loop=POLLOOP;
-  while (!(inw(r_line_status) & ls_transmitter_buffer_empty) && loop>0) {
-    mdelay(1);		/* one millisec delay */
-    --loop;
-  }
-  outw(command, r_uart_transmit);
+	int loop = POLLOOP;
+	while (!(inw(r_line_status) & ls_transmitter_buffer_empty)
+	       && loop > 0) {
+		mdelay(1);	/* one millisec delay */
+		--loop;
+	}
+	outw(command, r_uart_transmit);
 }
 
 uch receive_echo_polled(void)
 {
-  int loop=POLLOOP;
-  while (!(inw(r_line_status) & ls_receive_buffer_full) && loop>0) {
-    mdelay(1);
-    --loop;
-  }
-  return ((uch) inw(r_uart_receive));
+	int loop = POLLOOP;
+	while (!(inw(r_line_status) & ls_receive_buffer_full) && loop > 0) {
+		mdelay(1);
+		--loop;
+	}
+	return ((uch) inw(r_uart_receive));
 }
 
 uch send_receive_polled(int command)
 {
-  send_command_polled(command);
-  return receive_echo_polled();
+	send_command_polled(command);
+	return receive_echo_polled();
 }
 
-inline void clear_ur(void) {
-  if (cd->ur_r != cd->ur_w) {
-    debug(("Deleting bytes from fifo:"));
-    for(;cd->ur_r != cd->ur_w; cd->ur_r++, cd->ur_r %= UR_SIZE)
-      debug((" 0x%x", cd->ur[cd->ur_r]));
-    debug(("\n"));
-  }
+inline void clear_ur(void)
+{
+	if (cd->ur_r != cd->ur_w) {
+		debug(("Deleting bytes from fifo:"));
+		for (; cd->ur_r != cd->ur_w;
+		     cd->ur_r++, cd->ur_r %= UR_SIZE)
+			debug((" 0x%x", cd->ur[cd->ur_r]));
+		debug(("\n"));
+	}
 }
 
 /* The interrupt handler. When the cm260 generates an interrupt, very
@@ -351,252 +357,269 @@
    as there seems so reason for this to happen.
 */
 
-static void cm206_interrupt(int sig, void *dev_id, struct pt_regs * regs) 
+static void cm206_interrupt(int sig, void *dev_id, struct pt_regs *regs)
 /* you rang? */
 {
-  volatile ush fool;
-  cd->intr_ds = inw(r_data_status); /* resets data_ready, data_error,
-				       crc_error, sync_error, toc_ready 
-				       interrupts */
-  cd->intr_ls = inw(r_line_status); /* resets overrun bit */
-  debug(("Intr, 0x%x 0x%x, %d\n", cd->intr_ds, cd->intr_ls, cd->background));
-  if (cd->intr_ls & ls_attention) stats(attention);
-  /* receive buffer full? */
-  if (cd->intr_ls & ls_receive_buffer_full) {	
-    cd->ur[cd->ur_w] = inb(r_uart_receive); /* get order right! */
-    cd->intr_ls = inw(r_line_status); /* resets rbf interrupt */
-    debug(("receiving #%d: 0x%x\n", cd->ur_w, cd->ur[cd->ur_w]));
-    cd->ur_w++; cd->ur_w %= UR_SIZE;
-    if (cd->ur_w == cd->ur_r) debug(("cd->ur overflow!\n"));
-    if (waitqueue_active(&cd->uart) && cd->background < 2) { 
-      del_timer(&cd->timer);
-      wake_up_interruptible(&cd->uart);
-    }
-  }
-  /* data ready in fifo? */
-  else if (cd->intr_ds & ds_data_ready) { 
-    if (cd->background) ++cd->adapter_last;
-    if (waitqueue_active(&cd->data) && (cd->wait_back || !cd->background)) {
-      del_timer(&cd->timer);
-      wake_up_interruptible(&cd->data);
-    }
-    stats(data_ready);
-  }
-  /* ready to issue a write command? */
-  else if (cd->command && cd->intr_ls & ls_transmitter_buffer_empty) {
-    outw(dc_normal | (inw(r_data_status) & 0x7f), r_data_control);
-    outw(cd->command, r_uart_transmit);
-    cd->command=0;
-    if (!cd->background) wake_up_interruptible(&cd->uart);
-  }
-  /* now treat errors (at least, identify them for debugging) */
-  else if (cd->intr_ds & ds_fifo_overflow) {
-    debug(("Fifo overflow at sectors 0x%x\n", cd->sector_first));
-    fool = inw(r_fifo_output_buffer);	/* de-assert the interrupt */
-    cd->fifo_overflowed=1;	/* signal one word less should be read */
-    stats(fifo_overflow);
-  }
-  else if (cd->intr_ds & ds_data_error) {
-    debug(("Data error at sector 0x%x\n", cd->sector_first));
-    stats(data_error);
-  }
-  else if (cd->intr_ds & ds_crc_error) {
-    debug(("CRC error at sector 0x%x\n", cd->sector_first));
-    stats(crc_error);
-  }
-  else if (cd->intr_ds & ds_sync_error) {
-    debug(("Sync at sector 0x%x\n", cd->sector_first));
-    stats(sync_error);
-  }
-  else if (cd->intr_ds & ds_toc_ready) {
-    /* do something appropriate */
-  }
-  /* couldn't see why this interrupt, maybe due to init */
-  else {			
-    outw(dc_normal | READ_AHEAD, r_data_control);
-    stats(lost_intr);
-  }
-  if (cd->background && (cd->adapter_last-cd->adapter_first == cd->max_sectors
-			 || cd->fifo_overflowed))
-    mark_bh(CM206_BH);	/* issue a stop read command */
-  stats(interrupt);
+	volatile ush fool;
+	cd->intr_ds = inw(r_data_status);	/* resets data_ready, data_error,
+						   crc_error, sync_error, toc_ready 
+						   interrupts */
+	cd->intr_ls = inw(r_line_status);	/* resets overrun bit */
+	debug(("Intr, 0x%x 0x%x, %d\n", cd->intr_ds, cd->intr_ls,
+	       cd->background));
+	if (cd->intr_ls & ls_attention)
+		stats(attention);
+	/* receive buffer full? */
+	if (cd->intr_ls & ls_receive_buffer_full) {
+		cd->ur[cd->ur_w] = inb(r_uart_receive);	/* get order right! */
+		cd->intr_ls = inw(r_line_status);	/* resets rbf interrupt */
+		debug(("receiving #%d: 0x%x\n", cd->ur_w,
+		       cd->ur[cd->ur_w]));
+		cd->ur_w++;
+		cd->ur_w %= UR_SIZE;
+		if (cd->ur_w == cd->ur_r)
+			debug(("cd->ur overflow!\n"));
+		if (waitqueue_active(&cd->uart) && cd->background < 2) {
+			del_timer(&cd->timer);
+			wake_up_interruptible(&cd->uart);
+		}
+	}
+	/* data ready in fifo? */
+	else if (cd->intr_ds & ds_data_ready) {
+		if (cd->background)
+			++cd->adapter_last;
+		if (waitqueue_active(&cd->data)
+		    && (cd->wait_back || !cd->background)) {
+			del_timer(&cd->timer);
+			wake_up_interruptible(&cd->data);
+		}
+		stats(data_ready);
+	}
+	/* ready to issue a write command? */
+	else if (cd->command && cd->intr_ls & ls_transmitter_buffer_empty) {
+		outw(dc_normal | (inw(r_data_status) & 0x7f),
+		     r_data_control);
+		outw(cd->command, r_uart_transmit);
+		cd->command = 0;
+		if (!cd->background)
+			wake_up_interruptible(&cd->uart);
+	}
+	/* now treat errors (at least, identify them for debugging) */
+	else if (cd->intr_ds & ds_fifo_overflow) {
+		debug(("Fifo overflow at sectors 0x%x\n",
+		       cd->sector_first));
+		fool = inw(r_fifo_output_buffer);	/* de-assert the interrupt */
+		cd->fifo_overflowed = 1;	/* signal one word less should be read */
+		stats(fifo_overflow);
+	} else if (cd->intr_ds & ds_data_error) {
+		debug(("Data error at sector 0x%x\n", cd->sector_first));
+		stats(data_error);
+	} else if (cd->intr_ds & ds_crc_error) {
+		debug(("CRC error at sector 0x%x\n", cd->sector_first));
+		stats(crc_error);
+	} else if (cd->intr_ds & ds_sync_error) {
+		debug(("Sync at sector 0x%x\n", cd->sector_first));
+		stats(sync_error);
+	} else if (cd->intr_ds & ds_toc_ready) {
+		/* do something appropriate */
+	}
+	/* couldn't see why this interrupt, maybe due to init */
+	else {
+		outw(dc_normal | READ_AHEAD, r_data_control);
+		stats(lost_intr);
+	}
+	if (cd->background
+	    && (cd->adapter_last - cd->adapter_first == cd->max_sectors
+		|| cd->fifo_overflowed))
+		mark_bh(CM206_BH);	/* issue a stop read command */
+	stats(interrupt);
 }
 
 /* we have put the address of the wait queue in who */
 void cm206_timeout(unsigned long who)
 {
-  cd->timed_out = 1;
-  debug(("Timing out\n"));
-  wake_up_interruptible((wait_queue_head_t *)who);
+	cd->timed_out = 1;
+	debug(("Timing out\n"));
+	wake_up_interruptible((wait_queue_head_t *) who);
 }
 
 /* This function returns 1 if a timeout occurred, 0 if an interrupt
    happened */
-int sleep_or_timeout(wait_queue_head_t *wait, int timeout)
+int sleep_or_timeout(wait_queue_head_t * wait, int timeout)
 {
-  cd->timed_out=0;
-  cd->timer.data=(unsigned long) wait;
-  cd->timer.expires = jiffies + timeout;
-  add_timer(&cd->timer);
-  debug(("going to sleep\n"));
-  interruptible_sleep_on(wait);
-  del_timer(&cd->timer);
-  if (cd->timed_out) {
-    cd->timed_out = 0;
-    return 1;
-  }
-  else return 0;
+	cd->timed_out = 0;
+	cd->timer.data = (unsigned long) wait;
+	cd->timer.expires = jiffies + timeout;
+	add_timer(&cd->timer);
+	debug(("going to sleep\n"));
+	interruptible_sleep_on(wait);
+	del_timer(&cd->timer);
+	if (cd->timed_out) {
+		cd->timed_out = 0;
+		return 1;
+	} else
+		return 0;
 }
 
-void cm206_delay(int nr_jiffies) 
+void cm206_delay(int nr_jiffies)
 {
-  DECLARE_WAIT_QUEUE_HEAD(wait);
-  sleep_or_timeout(&wait, nr_jiffies);
+	DECLARE_WAIT_QUEUE_HEAD(wait);
+	sleep_or_timeout(&wait, nr_jiffies);
 }
 
 void send_command(int command)
 {
-  debug(("Sending 0x%x\n", command));
-  if (!(inw(r_line_status) & ls_transmitter_buffer_empty)) {
-    cd->command = command;
-    cli();			/* don't interrupt before sleep */
-    outw(dc_mask_sync_error | dc_no_stop_on_error | 
-	 (inw(r_data_status) & 0x7f), r_data_control);
-    /* interrupt routine sends command */
-    if (sleep_or_timeout(&cd->uart, UART_TIMEOUT)) {
-      debug(("Time out on write-buffer\n"));
-      stats(write_timeout);
-      outw(command, r_uart_transmit);
-    }
-    debug(("Write commmand delayed\n"));
-  }
-  else outw(command, r_uart_transmit);
+	debug(("Sending 0x%x\n", command));
+	if (!(inw(r_line_status) & ls_transmitter_buffer_empty)) {
+		cd->command = command;
+		cli();		/* don't interrupt before sleep */
+		outw(dc_mask_sync_error | dc_no_stop_on_error |
+		     (inw(r_data_status) & 0x7f), r_data_control);
+		/* interrupt routine sends command */
+		if (sleep_or_timeout(&cd->uart, UART_TIMEOUT)) {
+			debug(("Time out on write-buffer\n"));
+			stats(write_timeout);
+			outw(command, r_uart_transmit);
+		}
+		debug(("Write commmand delayed\n"));
+	} else
+		outw(command, r_uart_transmit);
 }
 
 uch receive_byte(int timeout)
 {
-  uch ret;
-  cli();
-  debug(("cli\n"));
-  ret = cd->ur[cd->ur_r];
-  if (cd->ur_r != cd->ur_w) {
-    sti();
-    debug(("returning #%d: 0x%x\n", cd->ur_r, cd->ur[cd->ur_r]));
-    cd->ur_r++; cd->ur_r %= UR_SIZE;
-    return ret;
-  } 
-  else if (sleep_or_timeout(&cd->uart, timeout)) { /* does sti() */
-    debug(("Time out on receive-buffer\n"));
+	uch ret;
+	cli();
+	debug(("cli\n"));
+	ret = cd->ur[cd->ur_r];
+	if (cd->ur_r != cd->ur_w) {
+		sti();
+		debug(("returning #%d: 0x%x\n", cd->ur_r,
+		       cd->ur[cd->ur_r]));
+		cd->ur_r++;
+		cd->ur_r %= UR_SIZE;
+		return ret;
+	} else if (sleep_or_timeout(&cd->uart, timeout)) {	/* does sti() */
+		debug(("Time out on receive-buffer\n"));
 #ifdef STATISTICS
-    if (timeout==UART_TIMEOUT) stats(receive_timeout) /* no `;'! */
-    else stats(dsb_timeout);
+		if (timeout == UART_TIMEOUT)
+			stats(receive_timeout)	/* no `;'! */
+			    else
+			stats(dsb_timeout);
 #endif
-    return 0xda;
-  }
-  ret = cd->ur[cd->ur_r];  
-  debug(("slept; returning #%d: 0x%x\n", cd->ur_r, cd->ur[cd->ur_r]));
-  cd->ur_r++; cd->ur_r %= UR_SIZE;
-  return ret;
+		return 0xda;
+	}
+	ret = cd->ur[cd->ur_r];
+	debug(("slept; returning #%d: 0x%x\n", cd->ur_r,
+	       cd->ur[cd->ur_r]));
+	cd->ur_r++;
+	cd->ur_r %= UR_SIZE;
+	return ret;
 }
 
 inline uch receive_echo(void)
 {
-  return receive_byte(UART_TIMEOUT);
+	return receive_byte(UART_TIMEOUT);
 }
 
 inline uch send_receive(int command)
 {
-  send_command(command);
-  return receive_echo();
+	send_command(command);
+	return receive_echo();
 }
 
 inline uch wait_dsb(void)
 {
-  return receive_byte(DSB_TIMEOUT);
+	return receive_byte(DSB_TIMEOUT);
 }
 
 int type_0_command(int command, int expect_dsb)
 {
-  int e;
-  clear_ur();
-  if (command != (e=send_receive(command))) {
-    debug(("command 0x%x echoed as 0x%x\n", command, e));
-    stats(echo);
-    return -1;
-  }
-  if (expect_dsb) {
-    cd->dsb = wait_dsb();	/* wait for command to finish */
-  }
-  return 0;
-}
-
-int type_1_command(int command, int bytes, uch * status) /* returns info */
-{
-  int i;
-  if (type_0_command(command,0)) return -1;
-  for(i=0; i<bytes; i++) 
-    status[i] = send_receive(c_gimme);
-  return 0;
-}  
+	int e;
+	clear_ur();
+	if (command != (e = send_receive(command))) {
+		debug(("command 0x%x echoed as 0x%x\n", command, e));
+		stats(echo);
+		return -1;
+	}
+	if (expect_dsb) {
+		cd->dsb = wait_dsb();	/* wait for command to finish */
+	}
+	return 0;
+}
+
+int type_1_command(int command, int bytes, uch * status)
+{				/* returns info */
+	int i;
+	if (type_0_command(command, 0))
+		return -1;
+	for (i = 0; i < bytes; i++)
+		status[i] = send_receive(c_gimme);
+	return 0;
+}
 
 /* This function resets the adapter card. We'd better not do this too
  * often, because it tends to generate `lost interrupts.' */
 void reset_cm260(void)
 {
-  outw(dc_normal | dc_initialize | READ_AHEAD, r_data_control);
-  udelay(10);			/* 3.3 mu sec minimum */
-  outw(dc_normal | READ_AHEAD, r_data_control);
+	outw(dc_normal | dc_initialize | READ_AHEAD, r_data_control);
+	udelay(10);		/* 3.3 mu sec minimum */
+	outw(dc_normal | READ_AHEAD, r_data_control);
 }
 
 /* fsm: frame-sec-min from linear address; one of many */
-void fsm(int lba, uch * fsm) 
+void fsm(int lba, uch * fsm)
 {
-  fsm[0] = lba % 75;
-  lba /= 75; lba += 2;
-  fsm[1] = lba % 60; fsm[2] = lba / 60;
+	fsm[0] = lba % 75;
+	lba /= 75;
+	lba += 2;
+	fsm[1] = lba % 60;
+	fsm[2] = lba / 60;
 }
 
-inline int fsm2lba(uch * fsm) 
+inline int fsm2lba(uch * fsm)
 {
-  return fsm[0] + 75*(fsm[1]-2 + 60*fsm[2]);
+	return fsm[0] + 75 * (fsm[1] - 2 + 60 * fsm[2]);
 }
 
 inline int f_s_m2lba(uch f, uch s, uch m)
 {
-  return f + 75*(s-2 + 60*m);
+	return f + 75 * (s - 2 + 60 * m);
 }
 
-int start_read(int start) 
+int start_read(int start)
 {
-  uch read_sector[4] = {c_read_data, };
-  int i, e;
+	uch read_sector[4] = { c_read_data, };
+	int i, e;
 
-  fsm(start, &read_sector[1]);
-  clear_ur();
-  for (i=0; i<4; i++) 
-    if (read_sector[i] != (e=send_receive(read_sector[i]))) {
-      debug(("read_sector: %x echoes %x\n", read_sector[i], e));
-      stats(echo);
-      if (e==0xff) {		/* this seems to happen often */
-	e = receive_echo();
-	debug(("Second try %x\n", e));
-	if (e!=read_sector[i]) return -1;
-      }
-    }
-  return 0;
+	fsm(start, &read_sector[1]);
+	clear_ur();
+	for (i = 0; i < 4; i++)
+		if (read_sector[i] != (e = send_receive(read_sector[i]))) {
+			debug(("read_sector: %x echoes %x\n",
+			       read_sector[i], e));
+			stats(echo);
+			if (e == 0xff) {	/* this seems to happen often */
+				e = receive_echo();
+				debug(("Second try %x\n", e));
+				if (e != read_sector[i])
+					return -1;
+			}
+		}
+	return 0;
 }
 
 int stop_read(void)
 {
-  int e;
-  type_0_command(c_stop,0);
-  if((e=receive_echo()) != 0xff) {
-    debug(("c_stop didn't send 0xff, but 0x%x\n", e));
-    stats(stop_0xff);
-    return -1;
-  }
-  return 0;
-}  
+	int e;
+	type_0_command(c_stop, 0);
+	if ((e = receive_echo()) != 0xff) {
+		debug(("c_stop didn't send 0xff, but 0x%x\n", e));
+		stats(stop_0xff);
+		return -1;
+	}
+	return 0;
+}
 
 /* This function starts to read sectors in adapter memory, the
    interrupt routine should stop the read. In fact, the bottom_half
@@ -605,12 +628,14 @@
 
 int read_background(int start, int reading)
 {
-  if (cd->background) return -1; /* can't do twice */
-  outw(dc_normal | BACK_AHEAD, r_data_control);
-  if (!reading && start_read(start)) return -2;
-  cd->adapter_first = cd->adapter_last = start; 
-  cd->background = 1;		/* flag a read is going on */
-  return 0;
+	if (cd->background)
+		return -1;	/* can't do twice */
+	outw(dc_normal | BACK_AHEAD, r_data_control);
+	if (!reading && start_read(start))
+		return -2;
+	cd->adapter_first = cd->adapter_last = start;
+	cd->background = 1;	/* flag a read is going on */
+	return 0;
 }
 
 #ifdef USE_INSW
@@ -618,12 +643,12 @@
 #else
 /* this routine implements insw(,,). There was a time i had the
    impression that there would be any difference in error-behaviour. */
-void transport_data(int port, ush * dest, int count) 
+void transport_data(int port, ush * dest, int count)
 {
-  int i;
-  ush * d;
-  for (i=0, d=dest; i<count; i++, d++) 
-    *d = inw(port);
+	int i;
+	ush *d;
+	for (i = 0, d = dest; i < count; i++, d++)
+		*d = inw(port);
 }
 #endif
 
@@ -631,33 +656,38 @@
 #define MAX_TRIES 100
 int read_sector(int start)
 {
-  int tries=0;
-  if (cd->background) {
-    cd->background=0;
-    cd->adapter_last = -1;	/* invalidate adapter memory */
-    stop_read();
-  }
-  cd->fifo_overflowed=0;
-  reset_cm260();		/* empty fifo etc. */
-  if (start_read(start)) return -1;
-  do {
-    if (sleep_or_timeout(&cd->data, DATA_TIMEOUT)) {
-      debug(("Read timed out sector 0x%x\n", start));
-      stats(read_timeout);
-      stop_read();
-      return -3;		
-    } 
-    tries++;
-  } while (cd->intr_ds & ds_fifo_empty && tries < MAX_TRIES);
-  if (tries>1) debug(("Took me some tries\n"))
-  else if (tries == MAX_TRIES) 
-    debug(("MAX_TRIES tries for read sector\n"));
-  transport_data(r_fifo_output_buffer, cd->sector, 
-		 READ_AHEAD*RAW_SECTOR_SIZE/2);
-  if (read_background(start+READ_AHEAD,1)) stats(read_background);
-  cd->sector_first = start; cd->sector_last = start+READ_AHEAD;
-  stats(read_restarted);
-  return 0;
+	int tries = 0;
+	if (cd->background) {
+		cd->background = 0;
+		cd->adapter_last = -1;	/* invalidate adapter memory */
+		stop_read();
+	}
+	cd->fifo_overflowed = 0;
+	reset_cm260();		/* empty fifo etc. */
+	if (start_read(start))
+		return -1;
+	do {
+		if (sleep_or_timeout(&cd->data, DATA_TIMEOUT)) {
+			debug(("Read timed out sector 0x%x\n", start));
+			stats(read_timeout);
+			stop_read();
+			return -3;
+		}
+		tries++;
+	} while (cd->intr_ds & ds_fifo_empty && tries < MAX_TRIES);
+	if (tries > 1)
+		debug(("Took me some tries\n"))
+		    else
+	if (tries == MAX_TRIES)
+		debug(("MAX_TRIES tries for read sector\n"));
+	transport_data(r_fifo_output_buffer, cd->sector,
+		       READ_AHEAD * RAW_SECTOR_SIZE / 2);
+	if (read_background(start + READ_AHEAD, 1))
+		stats(read_background);
+	cd->sector_first = start;
+	cd->sector_last = start + READ_AHEAD;
+	stats(read_restarted);
+	return 0;
 }
 
 /* The function of bottom-half is to send a stop command to the drive
@@ -672,43 +702,46 @@
 
 void cm206_bh(void)
 {
-  debug(("bh: %d\n", cd->background));
-  switch (cd->background) {
-  case 1:
-    stats(bh);
-    if (!(cd->intr_ls & ls_transmitter_buffer_empty)) {
-      cd->command = c_stop;
-      outw(dc_mask_sync_error | dc_no_stop_on_error | 
-	   (inw(r_data_status) & 0x7f), r_data_control);
-      cd->background=2;
-      break;			/* we'd better not time-out here! */
-    }
-    else outw(c_stop, r_uart_transmit);
-    /* fall into case 2: */
-  case 2:			
-    /* the write has been satisfied by interrupt routine */
-    cd->background=3;
-    break;
-  case 3:
-    if (cd->ur_r != cd->ur_w) {
-      if (cd->ur[cd->ur_r] != c_stop) {
-	debug(("cm206_bh: c_stop echoed 0x%x\n", cd->ur[cd->ur_r]));
-	stats(echo);
-      }
-      cd->ur_r++; cd->ur_r %= UR_SIZE;
-    }
-    cd->background++;
-    break;
-  case 4:
-    if (cd->ur_r != cd->ur_w) {
-      if (cd->ur[cd->ur_r] != 0xff) {
-	debug(("cm206_bh: c_stop reacted with 0x%x\n", cd->ur[cd->ur_r]));
-	stats(stop_0xff);
-      }
-      cd->ur_r++; cd->ur_r %= UR_SIZE;
-    }
-    cd->background=0;
-  }
+	debug(("bh: %d\n", cd->background));
+	switch (cd->background) {
+	case 1:
+		stats(bh);
+		if (!(cd->intr_ls & ls_transmitter_buffer_empty)) {
+			cd->command = c_stop;
+			outw(dc_mask_sync_error | dc_no_stop_on_error |
+			     (inw(r_data_status) & 0x7f), r_data_control);
+			cd->background = 2;
+			break;	/* we'd better not time-out here! */
+		} else
+			outw(c_stop, r_uart_transmit);
+		/* fall into case 2: */
+	case 2:
+		/* the write has been satisfied by interrupt routine */
+		cd->background = 3;
+		break;
+	case 3:
+		if (cd->ur_r != cd->ur_w) {
+			if (cd->ur[cd->ur_r] != c_stop) {
+				debug(("cm206_bh: c_stop echoed 0x%x\n",
+				       cd->ur[cd->ur_r]));
+				stats(echo);
+			}
+			cd->ur_r++;
+			cd->ur_r %= UR_SIZE;
+		}
+		cd->background++;
+		break;
+	case 4:
+		if (cd->ur_r != cd->ur_w) {
+			if (cd->ur[cd->ur_r] != 0xff) {
+				debug(("cm206_bh: c_stop reacted with 0x%x\n", cd->ur[cd->ur_r]));
+				stats(stop_0xff);
+			}
+			cd->ur_r++;
+			cd->ur_r %= UR_SIZE;
+		}
+		cd->background = 0;
+	}
 }
 
 /* This command clears the dsb_possible_media_change flag, so we must 
@@ -716,66 +749,67 @@
  */
 void get_drive_status(void)
 {
-  uch status[2];
-  type_1_command(c_drive_status, 2, status); /* this might be done faster */
-  cd->dsb=status[0];
-  cd->cc=status[1];
-  cd->media_changed |= 
-    !!(cd->dsb & (dsb_possible_media_change | 
-		  dsb_drive_not_ready | dsb_tray_not_closed));
+	uch status[2];
+	type_1_command(c_drive_status, 2, status);	/* this might be done faster */
+	cd->dsb = status[0];
+	cd->cc = status[1];
+	cd->media_changed |=
+	    !!(cd->dsb & (dsb_possible_media_change |
+			  dsb_drive_not_ready | dsb_tray_not_closed));
 }
 
 void get_disc_status(void)
 {
-  if (type_1_command(c_disc_status, 7, cd->disc_status)) {
-    debug(("get_disc_status: error\n"));
-  }
+	if (type_1_command(c_disc_status, 7, cd->disc_status)) {
+		debug(("get_disc_status: error\n"));
+	}
 }
 
 /* The new open. The real opening strategy is defined in cdrom.c. */
 
-static int cm206_open(struct cdrom_device_info * cdi, int purpose) 
+static int cm206_open(struct cdrom_device_info *cdi, int purpose)
 {
-  MOD_INC_USE_COUNT;
-  if (!cd->openfiles) {		/* reset only first time */
-    cd->background=0;
-    reset_cm260();
-    cd->adapter_last = -1;	/* invalidate adapter memory */
-    cd->sector_last = -1;
-  }
-  ++cd->openfiles;
-  stats(open);
-  return 0;
-}
-
-static void cm206_release(struct cdrom_device_info * cdi)
-{
-  if (cd->openfiles==1) {
-    if (cd->background) {
-      cd->background=0;
-      stop_read();
-    }
-    cd->sector_last = -1;	/* Make our internal buffer invalid */
-    FIRST_TRACK = 0;		/* No valid disc status */
-  }
-  --cd->openfiles;
-  MOD_DEC_USE_COUNT;
+	MOD_INC_USE_COUNT;
+	if (!cd->openfiles) {	/* reset only first time */
+		cd->background = 0;
+		reset_cm260();
+		cd->adapter_last = -1;	/* invalidate adapter memory */
+		cd->sector_last = -1;
+	}
+	++cd->openfiles;
+	stats(open);
+	return 0;
+}
+
+static void cm206_release(struct cdrom_device_info *cdi)
+{
+	if (cd->openfiles == 1) {
+		if (cd->background) {
+			cd->background = 0;
+			stop_read();
+		}
+		cd->sector_last = -1;	/* Make our internal buffer invalid */
+		FIRST_TRACK = 0;	/* No valid disc status */
+	}
+	--cd->openfiles;
+	MOD_DEC_USE_COUNT;
 }
 
 /* Empty buffer empties $sectors$ sectors of the adapter card buffer,
  * and then reads a sector in kernel memory.  */
-void empty_buffer(int sectors) 
+void empty_buffer(int sectors)
 {
-  while (sectors>=0) {
-    transport_data(r_fifo_output_buffer, cd->sector + cd->fifo_overflowed, 
-	 RAW_SECTOR_SIZE/2 - cd->fifo_overflowed);
-    --sectors;
-    ++cd->adapter_first;	/* update the current adapter sector */
-    cd->fifo_overflowed=0;	/* reset overflow bit */
-    stats(sector_transferred);
-  } 
-  cd->sector_first=cd->adapter_first-1;
-  cd->sector_last=cd->adapter_first; /* update the buffer sector */
+	while (sectors >= 0) {
+		transport_data(r_fifo_output_buffer,
+			       cd->sector + cd->fifo_overflowed,
+			       RAW_SECTOR_SIZE / 2 - cd->fifo_overflowed);
+		--sectors;
+		++cd->adapter_first;	/* update the current adapter sector */
+		cd->fifo_overflowed = 0;	/* reset overflow bit */
+		stats(sector_transferred);
+	}
+	cd->sector_first = cd->adapter_first - 1;
+	cd->sector_last = cd->adapter_first;	/* update the buffer sector */
 }
 
 /* try_adapter. This function determines if the requested sector is
@@ -783,29 +817,27 @@
    success */
 int try_adapter(int sector)
 {
-  if (cd->adapter_first <= sector && sector < cd->adapter_last) { 
-    /* sector is in adapter memory */
-    empty_buffer(sector - cd->adapter_first);
-    return 0;
-  }
-  else if (cd->background==1 && cd->adapter_first <= sector
-	   && sector < cd->adapter_first+cd->max_sectors) {
-    /* a read is going on, we can wait for it */
-    cd->wait_back=1;
-    while (sector >= cd->adapter_last) {
-      if (sleep_or_timeout(&cd->data, DATA_TIMEOUT)) {
-	debug(("Timed out during background wait: %d %d %d %d\n", sector, 
-	       cd->adapter_last, cd->adapter_first, cd->background));
-	stats(back_read_timeout);
-	cd->wait_back=0;
-	return -1;
-      }
-    }
-    cd->wait_back=0;
-    empty_buffer(sector - cd->adapter_first);
-    return 0;
-  }
-  else return -2;
+	if (cd->adapter_first <= sector && sector < cd->adapter_last) {
+		/* sector is in adapter memory */
+		empty_buffer(sector - cd->adapter_first);
+		return 0;
+	} else if (cd->background == 1 && cd->adapter_first <= sector
+		   && sector < cd->adapter_first + cd->max_sectors) {
+		/* a read is going on, we can wait for it */
+		cd->wait_back = 1;
+		while (sector >= cd->adapter_last) {
+			if (sleep_or_timeout(&cd->data, DATA_TIMEOUT)) {
+				debug(("Timed out during background wait: %d %d %d %d\n", sector, cd->adapter_last, cd->adapter_first, cd->background));
+				stats(back_read_timeout);
+				cd->wait_back = 0;
+				return -1;
+			}
+		}
+		cd->wait_back = 0;
+		empty_buffer(sector - cd->adapter_first);
+		return 0;
+	} else
+		return -2;
 }
 
 /* This is not a very smart implementation. We could optimize for 
@@ -813,45 +845,50 @@
    bring down the processor load. */
 static void do_cm206_request(request_queue_t * q)
 {
-  long int i, cd_sec_no;
-  int quarter, error; 
-  uch * source, * dest;
-  
-  while(1) {	 /* repeat until all requests have been satisfied */
-    INIT_REQUEST;
-    if (QUEUE_EMPTY || CURRENT->rq_status == RQ_INACTIVE)
-      return;
-    if (CURRENT->cmd != READ) {
-      debug(("Non-read command %d on cdrom\n", CURRENT->cmd));
-      end_request(0);
-      continue;
-    }
-    spin_unlock_irq(&io_request_lock);
-    error=0;
-    for (i=0; i<CURRENT->nr_sectors; i++) {
-      int e1, e2;
-      cd_sec_no = (CURRENT->sector+i)/BLOCKS_ISO; /* 4 times 512 bytes */
-      quarter = (CURRENT->sector+i) % BLOCKS_ISO; 
-      dest = CURRENT->buffer + i*LINUX_BLOCK_SIZE;
-      /* is already in buffer memory? */
-      if (cd->sector_first <= cd_sec_no && cd_sec_no < cd->sector_last) {
-	source = ((uch *) cd->sector) + 16 + quarter*LINUX_BLOCK_SIZE 
-	  + (cd_sec_no-cd->sector_first)*RAW_SECTOR_SIZE;
- 	memcpy(dest, source, LINUX_BLOCK_SIZE); 
-      }
-      else if (!(e1=try_adapter(cd_sec_no)) || 
-	       !(e2=read_sector(cd_sec_no))) {
-	source =  ((uch *) cd->sector)+16+quarter*LINUX_BLOCK_SIZE;
-	memcpy(dest, source, LINUX_BLOCK_SIZE); 
-      }
-      else {
-	error=1;
-	debug(("cm206_request: %d %d\n", e1, e2));
-      }
-    }
-    spin_lock_irq(&io_request_lock);
-    end_request(!error);
-  }
+	long int i, cd_sec_no;
+	int quarter, error;
+	uch *source, *dest;
+
+	while (1) {		/* repeat until all requests have been satisfied */
+		INIT_REQUEST;
+		if (QUEUE_EMPTY || CURRENT->rq_status == RQ_INACTIVE)
+			return;
+		if (CURRENT->cmd != READ) {
+			debug(("Non-read command %d on cdrom\n",
+			       CURRENT->cmd));
+			end_request(0);
+			continue;
+		}
+		spin_unlock_irq(&io_request_lock);
+		error = 0;
+		for (i = 0; i < CURRENT->nr_sectors; i++) {
+			int e1, e2;
+			cd_sec_no = (CURRENT->sector + i) / BLOCKS_ISO;	/* 4 times 512 bytes */
+			quarter = (CURRENT->sector + i) % BLOCKS_ISO;
+			dest = CURRENT->buffer + i * LINUX_BLOCK_SIZE;
+			/* is already in buffer memory? */
+			if (cd->sector_first <= cd_sec_no
+			    && cd_sec_no < cd->sector_last) {
+				source =
+				    ((uch *) cd->sector) + 16 +
+				    quarter * LINUX_BLOCK_SIZE +
+				    (cd_sec_no -
+				     cd->sector_first) * RAW_SECTOR_SIZE;
+				memcpy(dest, source, LINUX_BLOCK_SIZE);
+			} else if (!(e1 = try_adapter(cd_sec_no)) ||
+				   !(e2 = read_sector(cd_sec_no))) {
+				source =
+				    ((uch *) cd->sector) + 16 +
+				    quarter * LINUX_BLOCK_SIZE;
+				memcpy(dest, source, LINUX_BLOCK_SIZE);
+			} else {
+				error = 1;
+				debug(("cm206_request: %d %d\n", e1, e2));
+			}
+		}
+		spin_lock_irq(&io_request_lock);
+		end_request(!error);
+	}
 }
 
 /* Audio support. I've tried very hard, but the cm206 drive doesn't 
@@ -870,24 +907,27 @@
 /* seek seeks to address lba. It does wait to arrive there. */
 void seek(int lba)
 {
-  int i;
-  uch seek_command[4]={c_seek, };
-  
-  fsm(lba, &seek_command[1]);
-  for (i=0; i<4; i++) type_0_command(seek_command[i], 0);
-  cd->dsb = wait_dsb();
+	int i;
+	uch seek_command[4] = { c_seek, };
+
+	fsm(lba, &seek_command[1]);
+	for (i = 0; i < 4; i++)
+		type_0_command(seek_command[i], 0);
+	cd->dsb = wait_dsb();
 }
 
-uch bcdbin(unsigned char bcd)	/* stolen from mcd.c! */
-{
-  return (bcd >> 4)*10 + (bcd & 0xf);
-} 
+uch bcdbin(unsigned char bcd)
+{				/* stolen from mcd.c! */
+	return (bcd >> 4) * 10 + (bcd & 0xf);
+}
 
-inline uch normalize_track(uch track) 
+inline uch normalize_track(uch track)
 {
-  if (track<1) return 1;
-  if (track>LAST_TRACK) return LAST_TRACK+1;
-  return track;
+	if (track < 1)
+		return 1;
+	if (track > LAST_TRACK)
+		return LAST_TRACK + 1;
+	return track;
 }
 
 /* This function does a binary search for track start. It records all
@@ -896,150 +936,175 @@
  */
 int get_toc_lba(uch track)
 {
-  int max=74*60*75-150, min=fsm2lba(cd->toc[1].fsm);
-  int i, lba, l, old_lba=0;
-  uch * q = cd->q;
-  uch ct;			/* current track */
-  int binary=0;
-  const int skip = 3*60*75;		/* 3 minutes */
-
-  for (i=track; i>0; i--) if (cd->toc[i].track) {
-    min = fsm2lba(cd->toc[i].fsm);
-    break;
-  }
-  lba = min + skip;
-  do {
-    seek(lba); 
-    type_1_command(c_read_current_q, 10, q);
-    ct = normalize_track(q[1]);
-    if (!cd->toc[ct].track) {
-      l = q[9]-bcdbin(q[5]) + 75*(q[8]-bcdbin(q[4])-2 + 
-				  60*(q[7]-bcdbin(q[3])));
-      cd->toc[ct].track=q[1];	/* lead out still 0xaa */
-      fsm(l, cd->toc[ct].fsm);
-      cd->toc[ct].q0 = q[0];	/* contains adr and ctrl info */
-      if (ct==track) return l;
-    }
-    old_lba=lba;
-    if (binary) {
-      if (ct < track) min = lba; else max = lba;
-      lba = (min+max)/2; 
-    } else {
-      if(ct < track) lba += skip;
-      else {
-	binary=1;
-	max = lba; min = lba - skip;
-	lba = (min+max)/2;
-      }
-    }
-  } while (lba!=old_lba);
-  return lba;
+	int max = 74 * 60 * 75 - 150, min = fsm2lba(cd->toc[1].fsm);
+	int i, lba, l, old_lba = 0;
+	uch *q = cd->q;
+	uch ct;			/* current track */
+	int binary = 0;
+	const int skip = 3 * 60 * 75;	/* 3 minutes */
+
+	for (i = track; i > 0; i--)
+		if (cd->toc[i].track) {
+			min = fsm2lba(cd->toc[i].fsm);
+			break;
+		}
+	lba = min + skip;
+	do {
+		seek(lba);
+		type_1_command(c_read_current_q, 10, q);
+		ct = normalize_track(q[1]);
+		if (!cd->toc[ct].track) {
+			l = q[9] - bcdbin(q[5]) + 75 * (q[8] -
+							bcdbin(q[4]) - 2 +
+							60 * (q[7] -
+							      bcdbin(q
+								     [3])));
+			cd->toc[ct].track = q[1];	/* lead out still 0xaa */
+			fsm(l, cd->toc[ct].fsm);
+			cd->toc[ct].q0 = q[0];	/* contains adr and ctrl info */
+			if (ct == track)
+				return l;
+		}
+		old_lba = lba;
+		if (binary) {
+			if (ct < track)
+				min = lba;
+			else
+				max = lba;
+			lba = (min + max) / 2;
+		} else {
+			if (ct < track)
+				lba += skip;
+			else {
+				binary = 1;
+				max = lba;
+				min = lba - skip;
+				lba = (min + max) / 2;
+			}
+		}
+	} while (lba != old_lba);
+	return lba;
+}
+
+void update_toc_entry(uch track)
+{
+	track = normalize_track(track);
+	if (!cd->toc[track].track)
+		get_toc_lba(track);
 }
 
-void update_toc_entry(uch track) 
+/* return 0 upon success */
+int read_toc_header(struct cdrom_tochdr *hp)
 {
-  track = normalize_track(track);
-  if (!cd->toc[track].track) get_toc_lba(track);
+	if (!FIRST_TRACK)
+		get_disc_status();
+	if (hp) {
+		int i;
+		hp->cdth_trk0 = FIRST_TRACK;
+		hp->cdth_trk1 = LAST_TRACK;
+		/* fill in first track position */
+		for (i = 0; i < 3; i++)
+			cd->toc[1].fsm[i] = cd->disc_status[3 + i];
+		update_toc_entry(LAST_TRACK + 1);	/* find most entries */
+		return 0;
+	}
+	return -1;
 }
 
-/* return 0 upon success */
-int read_toc_header(struct cdrom_tochdr * hp)
+void play_from_to_msf(struct cdrom_msf *msfp)
 {
-  if (!FIRST_TRACK) get_disc_status();
-  if (hp) { 
-    int i;
-    hp->cdth_trk0 = FIRST_TRACK;
-    hp->cdth_trk1 = LAST_TRACK; 
-				/* fill in first track position */
-    for (i=0; i<3; i++) cd->toc[1].fsm[i] = cd->disc_status[3+i];
-    update_toc_entry(LAST_TRACK+1);		/* find most entries */
-    return 0;
-  }
-  return -1;
-}  
-
-void play_from_to_msf(struct cdrom_msf* msfp)
-{
-  uch play_command[] = {c_play, 
-	   msfp->cdmsf_frame0, msfp->cdmsf_sec0, msfp->cdmsf_min0,
-	   msfp->cdmsf_frame1, msfp->cdmsf_sec1, msfp->cdmsf_min1, 2, 2};
-  int i;
-  for (i=0; i<9; i++) type_0_command(play_command[i], 0);
-  for (i=0; i<3; i++) 
-    PLAY_TO.fsm[i] = play_command[i+4];
-  PLAY_TO.track = 0;		/* say no track end */
-  cd->dsb = wait_dsb();
-}  
+	uch play_command[] = { c_play,
+		msfp->cdmsf_frame0, msfp->cdmsf_sec0, msfp->cdmsf_min0,
+		msfp->cdmsf_frame1, msfp->cdmsf_sec1, msfp->cdmsf_min1, 2,
+		    2
+	};
+	int i;
+	for (i = 0; i < 9; i++)
+		type_0_command(play_command[i], 0);
+	for (i = 0; i < 3; i++)
+		PLAY_TO.fsm[i] = play_command[i + 4];
+	PLAY_TO.track = 0;	/* say no track end */
+	cd->dsb = wait_dsb();
+}
 
 void play_from_to_track(int from, int to)
 {
-  uch play_command[8] = {c_play, };
-  int i;
+	uch play_command[8] = { c_play, };
+	int i;
 
-  if (from==0) {		/* continue paused play */
-    for (i=0; i<3; i++) { 
-      play_command[i+1] = cd->audio_status[i+2];
-      play_command[i+4] = PLAY_TO.fsm[i];
-    }
-  } else {
-    update_toc_entry(from); update_toc_entry(to+1);
-    for (i=0; i<3; i++) {
-      play_command[i+1] = cd->toc[from].fsm[i];
-      PLAY_TO.fsm[i] = play_command[i+4] = cd->toc[to+1].fsm[i];
-    }
-    PLAY_TO.track = to; 
-  }
-  for (i=0; i<7; i++) type_0_command(play_command[i],0);
-  for (i=0; i<2; i++) type_0_command(0x2, 0); /* volume */
-  cd->dsb = wait_dsb();
-}
-
-int get_current_q(struct cdrom_subchnl * qp)
-{
-  int i;
-  uch * q = cd->q;
-  if (type_1_command(c_read_current_q, 10, q)) return 0;
+	if (from == 0) {	/* continue paused play */
+		for (i = 0; i < 3; i++) {
+			play_command[i + 1] = cd->audio_status[i + 2];
+			play_command[i + 4] = PLAY_TO.fsm[i];
+		}
+	} else {
+		update_toc_entry(from);
+		update_toc_entry(to + 1);
+		for (i = 0; i < 3; i++) {
+			play_command[i + 1] = cd->toc[from].fsm[i];
+			PLAY_TO.fsm[i] = play_command[i + 4] =
+			    cd->toc[to + 1].fsm[i];
+		}
+		PLAY_TO.track = to;
+	}
+	for (i = 0; i < 7; i++)
+		type_0_command(play_command[i], 0);
+	for (i = 0; i < 2; i++)
+		type_0_command(0x2, 0);	/* volume */
+	cd->dsb = wait_dsb();
+}
+
+int get_current_q(struct cdrom_subchnl *qp)
+{
+	int i;
+	uch *q = cd->q;
+	if (type_1_command(c_read_current_q, 10, q))
+		return 0;
 /*  q[0] = bcdbin(q[0]); Don't think so! */
-  for (i=2; i<6; i++) q[i]=bcdbin(q[i]); 
-  qp->cdsc_adr = q[0] & 0xf; qp->cdsc_ctrl = q[0] >> 4;	/* from mcd.c */
-  qp->cdsc_trk = q[1];  qp->cdsc_ind = q[2];
-  if (qp->cdsc_format == CDROM_MSF) {
-    qp->cdsc_reladdr.msf.minute = q[3];
-    qp->cdsc_reladdr.msf.second = q[4];
-    qp->cdsc_reladdr.msf.frame = q[5];
-    qp->cdsc_absaddr.msf.minute = q[7];
-    qp->cdsc_absaddr.msf.second = q[8];
-    qp->cdsc_absaddr.msf.frame = q[9];
-  } else {
-    qp->cdsc_reladdr.lba = f_s_m2lba(q[5], q[4], q[3]);
-    qp->cdsc_absaddr.lba = f_s_m2lba(q[9], q[8], q[7]);
-  }
-  get_drive_status();
-  if (cd->dsb & dsb_play_in_progress) 
-    qp->cdsc_audiostatus = CDROM_AUDIO_PLAY ;
-  else if (PAUSED) 
-    qp->cdsc_audiostatus = CDROM_AUDIO_PAUSED;
-  else qp->cdsc_audiostatus = CDROM_AUDIO_NO_STATUS;
-  return 0;
+	for (i = 2; i < 6; i++)
+		q[i] = bcdbin(q[i]);
+	qp->cdsc_adr = q[0] & 0xf;
+	qp->cdsc_ctrl = q[0] >> 4;	/* from mcd.c */
+	qp->cdsc_trk = q[1];
+	qp->cdsc_ind = q[2];
+	if (qp->cdsc_format == CDROM_MSF) {
+		qp->cdsc_reladdr.msf.minute = q[3];
+		qp->cdsc_reladdr.msf.second = q[4];
+		qp->cdsc_reladdr.msf.frame = q[5];
+		qp->cdsc_absaddr.msf.minute = q[7];
+		qp->cdsc_absaddr.msf.second = q[8];
+		qp->cdsc_absaddr.msf.frame = q[9];
+	} else {
+		qp->cdsc_reladdr.lba = f_s_m2lba(q[5], q[4], q[3]);
+		qp->cdsc_absaddr.lba = f_s_m2lba(q[9], q[8], q[7]);
+	}
+	get_drive_status();
+	if (cd->dsb & dsb_play_in_progress)
+		qp->cdsc_audiostatus = CDROM_AUDIO_PLAY;
+	else if (PAUSED)
+		qp->cdsc_audiostatus = CDROM_AUDIO_PAUSED;
+	else
+		qp->cdsc_audiostatus = CDROM_AUDIO_NO_STATUS;
+	return 0;
 }
 
 void invalidate_toc(void)
 {
-  memset(cd->toc, 0, sizeof(cd->toc));
-  memset(cd->disc_status, 0, sizeof(cd->disc_status));
+	memset(cd->toc, 0, sizeof(cd->toc));
+	memset(cd->disc_status, 0, sizeof(cd->disc_status));
 }
 
 /* cdrom.c guarantees that cdte_format == CDROM_MSF */
-void get_toc_entry(struct cdrom_tocentry * ep)
+void get_toc_entry(struct cdrom_tocentry *ep)
 {
-  uch track = normalize_track(ep->cdte_track);
-  update_toc_entry(track);
-  ep->cdte_addr.msf.frame = cd->toc[track].fsm[0];
-  ep->cdte_addr.msf.second = cd->toc[track].fsm[1];
-  ep->cdte_addr.msf.minute = cd->toc[track].fsm[2];
-  ep->cdte_adr = cd->toc[track].q0 & 0xf; 
-  ep->cdte_ctrl = cd->toc[track].q0 >> 4;
-  ep->cdte_datamode=0;
+	uch track = normalize_track(ep->cdte_track);
+	update_toc_entry(track);
+	ep->cdte_addr.msf.frame = cd->toc[track].fsm[0];
+	ep->cdte_addr.msf.second = cd->toc[track].fsm[1];
+	ep->cdte_addr.msf.minute = cd->toc[track].fsm[2];
+	ep->cdte_adr = cd->toc[track].q0 & 0xf;
+	ep->cdte_ctrl = cd->toc[track].q0 >> 4;
+	ep->cdte_datamode = 0;
 }
 
 /* Audio ioctl.  Ioctl commands connected to audio are in such an
@@ -1047,244 +1112,262 @@
  * upon success. Memory checking has been done by cdrom_ioctl(), the
  * calling function, as well as LBA/MSF sanitization.
 */
-int cm206_audio_ioctl(struct cdrom_device_info * cdi, unsigned int cmd, 
-		      void * arg)  
+int cm206_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
+		      void *arg)
 {
-  switch (cmd) {
-  case CDROMREADTOCHDR: 
-    return read_toc_header((struct cdrom_tochdr *) arg);
-  case CDROMREADTOCENTRY: 	
-    get_toc_entry((struct cdrom_tocentry *) arg);
-    return 0;
-  case CDROMPLAYMSF: 
-    play_from_to_msf((struct cdrom_msf *) arg);
-    return 0;
-  case CDROMPLAYTRKIND:		/* admittedly, not particularly beautiful */
-    play_from_to_track(((struct cdrom_ti *)arg)->cdti_trk0, 
-		       ((struct cdrom_ti *)arg)->cdti_trk1);
-    return 0;
-  case CDROMSTOP: 
-    PAUSED=0;
-    if (cd->dsb & dsb_play_in_progress) return type_0_command(c_stop, 1);
-    else return 0;
-  case CDROMPAUSE: 
-    get_drive_status();
-    if (cd->dsb & dsb_play_in_progress) {
-      type_0_command(c_stop, 1);
-      type_1_command(c_audio_status, 5, cd->audio_status);
-      PAUSED=1;	/* say we're paused */
-    }
-    return 0;
-  case CDROMRESUME:
-    if (PAUSED) play_from_to_track(0,0);
-    PAUSED=0;
-    return 0;
-  case CDROMSTART:
-  case CDROMVOLCTRL:
-    return 0;
-  case CDROMSUBCHNL: 
-    return get_current_q((struct cdrom_subchnl *)arg);
-  default:
-    return -EINVAL;
-  }
+	switch (cmd) {
+	case CDROMREADTOCHDR:
+		return read_toc_header((struct cdrom_tochdr *) arg);
+	case CDROMREADTOCENTRY:
+		get_toc_entry((struct cdrom_tocentry *) arg);
+		return 0;
+	case CDROMPLAYMSF:
+		play_from_to_msf((struct cdrom_msf *) arg);
+		return 0;
+	case CDROMPLAYTRKIND:	/* admittedly, not particularly beautiful */
+		play_from_to_track(((struct cdrom_ti *) arg)->cdti_trk0,
+				   ((struct cdrom_ti *) arg)->cdti_trk1);
+		return 0;
+	case CDROMSTOP:
+		PAUSED = 0;
+		if (cd->dsb & dsb_play_in_progress)
+			return type_0_command(c_stop, 1);
+		else
+			return 0;
+	case CDROMPAUSE:
+		get_drive_status();
+		if (cd->dsb & dsb_play_in_progress) {
+			type_0_command(c_stop, 1);
+			type_1_command(c_audio_status, 5,
+				       cd->audio_status);
+			PAUSED = 1;	/* say we're paused */
+		}
+		return 0;
+	case CDROMRESUME:
+		if (PAUSED)
+			play_from_to_track(0, 0);
+		PAUSED = 0;
+		return 0;
+	case CDROMSTART:
+	case CDROMVOLCTRL:
+		return 0;
+	case CDROMSUBCHNL:
+		return get_current_q((struct cdrom_subchnl *) arg);
+	default:
+		return -EINVAL;
+	}
 }
 
 /* Ioctl. These ioctls are specific to the cm206 driver. I have made
    some driver statistics accessible through ioctl calls.
  */
 
-static int cm206_ioctl(struct cdrom_device_info * cdi, unsigned int cmd, 
+static int cm206_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
 		       unsigned long arg)
 {
-  switch (cmd) {
+	switch (cmd) {
 #ifdef STATISTICS
-  case CM206CTL_GET_STAT:
-    if (arg >= NR_STATS) return -EINVAL;
-    else return cd->stats[arg];
-  case CM206CTL_GET_LAST_STAT:
-    if (arg >= NR_STATS) return -EINVAL;
-    else return cd->last_stat[arg];
-#endif    
-  default:
-    debug(("Unknown ioctl call 0x%x\n", cmd));
-    return -EINVAL;
-  }
-}     
-
-int cm206_media_changed(struct cdrom_device_info * cdi, int disc_nr) 
-{
-  if (cd != NULL) {
-    int r;
-    get_drive_status();		/* ensure cd->media_changed OK */
-    r = cd->media_changed;
-    cd->media_changed = 0;	/* clear bit */
-    return r;
-  }
-  else return -EIO;
+	case CM206CTL_GET_STAT:
+		if (arg >= NR_STATS)
+			return -EINVAL;
+		else
+			return cd->stats[arg];
+	case CM206CTL_GET_LAST_STAT:
+		if (arg >= NR_STATS)
+			return -EINVAL;
+		else
+			return cd->last_stat[arg];
+#endif
+	default:
+		debug(("Unknown ioctl call 0x%x\n", cmd));
+		return -EINVAL;
+	}
+}
+
+int cm206_media_changed(struct cdrom_device_info *cdi, int disc_nr)
+{
+	if (cd != NULL) {
+		int r;
+		get_drive_status();	/* ensure cd->media_changed OK */
+		r = cd->media_changed;
+		cd->media_changed = 0;	/* clear bit */
+		return r;
+	} else
+		return -EIO;
 }
 
 /* The new generic cdrom support. Routines should be concise, most of
    the logic should be in cdrom.c */
 
 /* returns number of times device is in use */
-int cm206_open_files(struct cdrom_device_info * cdi)	
+int cm206_open_files(struct cdrom_device_info *cdi)
 {
-  if (cd) return cd->openfiles;
-  return -1;
+	if (cd)
+		return cd->openfiles;
+	return -1;
 }
 
 /* controls tray movement */
-int cm206_tray_move(struct cdrom_device_info * cdi, int position) 
+int cm206_tray_move(struct cdrom_device_info *cdi, int position)
 {
-  if (position) {		/* 1: eject */
-    type_0_command(c_open_tray,1);
-    invalidate_toc();
-  } 
-  else type_0_command(c_close_tray, 1);	/* 0: close */
-  return 0;
+	if (position) {		/* 1: eject */
+		type_0_command(c_open_tray, 1);
+		invalidate_toc();
+	} else
+		type_0_command(c_close_tray, 1);	/* 0: close */
+	return 0;
 }
 
 /* gives current state of the drive */
-int cm206_drive_status(struct cdrom_device_info * cdi, int slot_nr)
+int cm206_drive_status(struct cdrom_device_info *cdi, int slot_nr)
 {
-  get_drive_status();
-  if (cd->dsb & dsb_tray_not_closed) return CDS_TRAY_OPEN;
-  if (!(cd->dsb & dsb_disc_present)) return CDS_NO_DISC; 
-  if (cd->dsb & dsb_drive_not_ready) return CDS_DRIVE_NOT_READY;
-  return CDS_DISC_OK;
+	get_drive_status();
+	if (cd->dsb & dsb_tray_not_closed)
+		return CDS_TRAY_OPEN;
+	if (!(cd->dsb & dsb_disc_present))
+		return CDS_NO_DISC;
+	if (cd->dsb & dsb_drive_not_ready)
+		return CDS_DRIVE_NOT_READY;
+	return CDS_DISC_OK;
 }
- 
+
 /* locks or unlocks door lock==1: lock; return 0 upon success */
-int cm206_lock_door(struct cdrom_device_info * cdi, int lock)
+int cm206_lock_door(struct cdrom_device_info *cdi, int lock)
 {
-  uch command = (lock) ? c_lock_tray : c_unlock_tray;
-  type_0_command(command, 1);	/* wait and get dsb */
-  /* the logic calculates the success, 0 means successful */
-  return lock ^ ((cd->dsb & dsb_tray_locked) != 0);
+	uch command = (lock) ? c_lock_tray : c_unlock_tray;
+	type_0_command(command, 1);	/* wait and get dsb */
+	/* the logic calculates the success, 0 means successful */
+	return lock ^ ((cd->dsb & dsb_tray_locked) != 0);
 }
-  
+
 /* Although a session start should be in LBA format, we return it in 
    MSF format because it is slightly easier, and the new generic ioctl
    will take care of the necessary conversion. */
-int cm206_get_last_session(struct cdrom_device_info * cdi, 
-			   struct cdrom_multisession * mssp) 
+int cm206_get_last_session(struct cdrom_device_info *cdi,
+			   struct cdrom_multisession *mssp)
 {
-  if (!FIRST_TRACK) get_disc_status();
-  if (mssp != NULL) {
-    if (DISC_STATUS & cds_multi_session) { /* multi-session */
-      mssp->addr.msf.frame = cd->disc_status[3];
-      mssp->addr.msf.second = cd->disc_status[4];
-      mssp->addr.msf.minute = cd->disc_status[5];
-      mssp->addr_format = CDROM_MSF;
-      mssp->xa_flag = 1;
-    } else {
-      mssp->xa_flag = 0;
-    }
-    return 1;
-  }
-  return 0;
-}
-
-int cm206_get_upc(struct cdrom_device_info * cdi, struct cdrom_mcn * mcn)
-{
-  uch upc[10];
-  char * ret = mcn->medium_catalog_number;
-  int i;
-  
-  if (type_1_command(c_read_upc, 10, upc)) return -EIO;
-  for (i=0; i<13; i++) {
-    int w=i/2+1, r=i%2;
-    if (r) ret[i] = 0x30 | (upc[w] & 0x0f);
-    else ret[i] = 0x30 | ((upc[w] >> 4) & 0x0f);
-  }
-  ret[13] = '\0';
-  return 0;
-} 
-
-int cm206_reset(struct cdrom_device_info * cdi)
-{
-  stop_read();
-  reset_cm260();
-  outw(dc_normal | dc_break | READ_AHEAD, r_data_control);
-  mdelay(1);			/* 750 musec minimum */
-  outw(dc_normal | READ_AHEAD, r_data_control);
-  cd->sector_last = -1;		/* flag no data buffered */
-  cd->adapter_last = -1;    
-  invalidate_toc();
-  return 0;
-}
-
-int cm206_select_speed(struct cdrom_device_info * cdi, int speed)
-{
-  int r;
-  switch (speed) {
-  case 0: 
-    r = type_0_command(c_auto_mode, 1);
-    break;
-  case 1:
-    r = type_0_command(c_force_1x, 1);
-    break;
-  case 2:
-    r = type_0_command(c_force_2x, 1);
-    break;
-  default:
-    return -1;
-  }
-  if (r<0) return r;
-  else return 1;
+	if (!FIRST_TRACK)
+		get_disc_status();
+	if (mssp != NULL) {
+		if (DISC_STATUS & cds_multi_session) {	/* multi-session */
+			mssp->addr.msf.frame = cd->disc_status[3];
+			mssp->addr.msf.second = cd->disc_status[4];
+			mssp->addr.msf.minute = cd->disc_status[5];
+			mssp->addr_format = CDROM_MSF;
+			mssp->xa_flag = 1;
+		} else {
+			mssp->xa_flag = 0;
+		}
+		return 1;
+	}
+	return 0;
+}
+
+int cm206_get_upc(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
+{
+	uch upc[10];
+	char *ret = mcn->medium_catalog_number;
+	int i;
+
+	if (type_1_command(c_read_upc, 10, upc))
+		return -EIO;
+	for (i = 0; i < 13; i++) {
+		int w = i / 2 + 1, r = i % 2;
+		if (r)
+			ret[i] = 0x30 | (upc[w] & 0x0f);
+		else
+			ret[i] = 0x30 | ((upc[w] >> 4) & 0x0f);
+	}
+	ret[13] = '\0';
+	return 0;
+}
+
+int cm206_reset(struct cdrom_device_info *cdi)
+{
+	stop_read();
+	reset_cm260();
+	outw(dc_normal | dc_break | READ_AHEAD, r_data_control);
+	mdelay(1);		/* 750 musec minimum */
+	outw(dc_normal | READ_AHEAD, r_data_control);
+	cd->sector_last = -1;	/* flag no data buffered */
+	cd->adapter_last = -1;
+	invalidate_toc();
+	return 0;
+}
+
+int cm206_select_speed(struct cdrom_device_info *cdi, int speed)
+{
+	int r;
+	switch (speed) {
+	case 0:
+		r = type_0_command(c_auto_mode, 1);
+		break;
+	case 1:
+		r = type_0_command(c_force_1x, 1);
+		break;
+	case 2:
+		r = type_0_command(c_force_2x, 1);
+		break;
+	default:
+		return -1;
+	}
+	if (r < 0)
+		return r;
+	else
+		return 1;
 }
 
 static struct cdrom_device_ops cm206_dops = {
-	open:			cm206_open,
-	release:		cm206_release,
-	drive_status:		cm206_drive_status,
-	media_changed:		cm206_media_changed,
-	tray_move:		cm206_tray_move,
-	lock_door:		cm206_lock_door,
-	select_speed:		cm206_select_speed,
-	get_last_session:	cm206_get_last_session,
-	get_mcn:		cm206_get_upc,
-	reset:			cm206_reset,
-	audio_ioctl:		cm206_audio_ioctl,
-	dev_ioctl:		cm206_ioctl,
-	capability:		CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
-				CDC_MULTI_SESSION | CDC_MEDIA_CHANGED |
-				CDC_MCN | CDC_PLAY_AUDIO | CDC_SELECT_SPEED |
-				CDC_IOCTLS | CDC_DRIVE_STATUS, 
-	n_minors:		1,
+	open:cm206_open,
+	release:cm206_release,
+	drive_status:cm206_drive_status,
+	media_changed:cm206_media_changed,
+	tray_move:cm206_tray_move,
+	lock_door:cm206_lock_door,
+	select_speed:cm206_select_speed,
+	get_last_session:cm206_get_last_session,
+	get_mcn:cm206_get_upc,
+	reset:cm206_reset,
+	audio_ioctl:cm206_audio_ioctl,
+	dev_ioctl:cm206_ioctl,
+	capability:CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
+	    CDC_MULTI_SESSION | CDC_MEDIA_CHANGED |
+	    CDC_MCN | CDC_PLAY_AUDIO | CDC_SELECT_SPEED |
+	    CDC_IOCTLS | CDC_DRIVE_STATUS,
+	n_minors:1,
 };
 
 
 static struct cdrom_device_info cm206_info = {
-	ops:		&cm206_dops,
-	speed:		2,
-	capacity:	1,
-	name:		"cm206",
+	ops:&cm206_dops,
+	speed:2,
+	capacity:1,
+	name:"cm206",
 };
 
 /* This routine gets called during initialization if things go wrong,
  * can be used in cleanup_module as well. */
 static void cleanup(int level)
 {
-  switch (level) {
-  case 4: 
-    if (unregister_cdrom(&cm206_info)) {
-      printk("Can't unregister cdrom cm206\n");
-      return;
-    }
-    if (devfs_unregister_blkdev(MAJOR_NR, "cm206")) {
-      printk("Can't unregister major cm206\n");
-      return;
-    }
-    blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
-  case 3: 
-    free_irq(cm206_irq, NULL);
-  case 2: 
-  case 1: 
-    kfree(cd);
-    release_region(cm206_base, 16);
-  default:;
-  }
+	switch (level) {
+	case 4:
+		if (unregister_cdrom(&cm206_info)) {
+			printk("Can't unregister cdrom cm206\n");
+			return;
+		}
+		if (devfs_unregister_blkdev(MAJOR_NR, "cm206")) {
+			printk("Can't unregister major cm206\n");
+			return;
+		}
+		blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
+	case 3:
+		free_irq(cm206_irq, NULL);
+	case 2:
+	case 1:
+		kfree(cd);
+		release_region(cm206_base, 16);
+	default:;
+	}
 }
 
 /* This function probes for the adapter card. It returns the base
@@ -1299,117 +1382,129 @@
  */
 int __init probe_base_port(int base)
 {
-  int b=0x300, e=0x370;		/* this is the range of start addresses */
-  volatile int fool, i;
+	int b = 0x300, e = 0x370;	/* this is the range of start addresses */
+	volatile int fool, i;
 
-  if (base) b=e=base;
-  for (base=b; base<=e; base += 0x10) {
-    if (check_region(base, 0x10)) continue;
-    for (i=0; i<3; i++) 
-      fool = inw(base+2); /* empty possibly uart_receive_buffer */
-    if((inw(base+6) & 0xffef) != 0x0001 || /* line_status */
-       (inw(base) & 0xad00) != 0) /* data status */
-      continue;
-    return(base);
-  }
-  return 0;
+	if (base)
+		b = e = base;
+	for (base = b; base <= e; base += 0x10) {
+		if (check_region(base, 0x10))
+			continue;
+		for (i = 0; i < 3; i++)
+			fool = inw(base + 2);	/* empty possibly uart_receive_buffer */
+		if ((inw(base + 6) & 0xffef) != 0x0001 ||	/* line_status */
+		    (inw(base) & 0xad00) != 0)	/* data status */
+			continue;
+		return (base);
+	}
+	return 0;
 }
 
 #if !defined(MODULE) || defined(AUTO_PROBE_MODULE)
 /* Probe for irq# nr. If nr==0, probe for all possible irq's. */
-int __init probe_irq(int nr){
-  int irqs, irq;
-  outw(dc_normal | READ_AHEAD, r_data_control);	/* disable irq-generation */
-  sti(); 
-  irqs = probe_irq_on();
-  reset_cm260();		/* causes interrupt */
-  udelay(100);			/* wait for it */
-  irq = probe_irq_off(irqs);
-  outw(dc_normal | READ_AHEAD, r_data_control);	/* services interrupt */
-  if (nr && irq!=nr && irq>0) return 0;	/* wrong interrupt happened */
-  else return irq;
+int __init probe_irq(int nr)
+{
+	int irqs, irq;
+	outw(dc_normal | READ_AHEAD, r_data_control);	/* disable irq-generation */
+	sti();
+	irqs = probe_irq_on();
+	reset_cm260();		/* causes interrupt */
+	udelay(100);		/* wait for it */
+	irq = probe_irq_off(irqs);
+	outw(dc_normal | READ_AHEAD, r_data_control);	/* services interrupt */
+	if (nr && irq != nr && irq > 0)
+		return 0;	/* wrong interrupt happened */
+	else
+		return irq;
 }
 #endif
 
 int __init cm206_init(void)
 {
-  uch e=0;
-  long int size=sizeof(struct cm206_struct);
+	uch e = 0;
+	long int size = sizeof(struct cm206_struct);
 
-  printk(KERN_INFO "cm206 cdrom driver " REVISION);
-  cm206_base = probe_base_port(auto_probe ? 0 : cm206_base);
-  if (!cm206_base) {
-    printk(" can't find adapter!\n");
-    return -EIO;
-  }
-  printk(" adapter at 0x%x", cm206_base);
-  request_region(cm206_base, 16, "cm206");
-  cd = (struct cm206_struct *) kmalloc(size, GFP_KERNEL);
-  if (!cd) return -EIO;
-  /* Now we have found the adaptor card, try to reset it. As we have
-   * found out earlier, this process generates an interrupt as well,
-   * so we might just exploit that fact for irq probing! */
+	printk(KERN_INFO "cm206 cdrom driver " REVISION);
+	cm206_base = probe_base_port(auto_probe ? 0 : cm206_base);
+	if (!cm206_base) {
+		printk(" can't find adapter!\n");
+		return -EIO;
+	}
+	printk(" adapter at 0x%x", cm206_base);
+	request_region(cm206_base, 16, "cm206");
+	cd = (struct cm206_struct *) kmalloc(size, GFP_KERNEL);
+	if (!cd)
+		return -EIO;
+	/* Now we have found the adaptor card, try to reset it. As we have
+	 * found out earlier, this process generates an interrupt as well,
+	 * so we might just exploit that fact for irq probing! */
 #if !defined(MODULE) || defined(AUTO_PROBE_MODULE)
-  cm206_irq = probe_irq(auto_probe ? 0 : cm206_irq);	
-  if (cm206_irq<=0) {
-    printk("can't find IRQ!\n");
-    cleanup(1);
-    return -EIO;
-  }
-  else printk(" IRQ %d found\n", cm206_irq);
+	cm206_irq = probe_irq(auto_probe ? 0 : cm206_irq);
+	if (cm206_irq <= 0) {
+		printk("can't find IRQ!\n");
+		cleanup(1);
+		return -EIO;
+	} else
+		printk(" IRQ %d found\n", cm206_irq);
 #else
-  cli();
-  reset_cm260();
-  /* Now, the problem here is that reset_cm260 can generate an
-     interrupt. It seems that this can cause a kernel oops some time
-     later. So we wait a while and `service' this interrupt. */
-  mdelay(1);
-  outw(dc_normal | READ_AHEAD, r_data_control);
-  sti();
-  printk(" using IRQ %d\n", cm206_irq);
+	cli();
+	reset_cm260();
+	/* Now, the problem here is that reset_cm260 can generate an
+	   interrupt. It seems that this can cause a kernel oops some time
+	   later. So we wait a while and `service' this interrupt. */
+	mdelay(1);
+	outw(dc_normal | READ_AHEAD, r_data_control);
+	sti();
+	printk(" using IRQ %d\n", cm206_irq);
 #endif
-  if (send_receive_polled(c_drive_configuration) != c_drive_configuration) 
-    {
-      printk(KERN_INFO " drive not there\n");
-      cleanup(1);
-      return -EIO;
-    }
-  e = send_receive_polled(c_gimme);
-  printk(KERN_INFO "Firmware revision %d", e & dcf_revision_code);
-  if (e & dcf_transfer_rate) printk(" double");
-  else printk(" single");
-  printk(" speed drive");
-  if (e & dcf_motorized_tray) printk(", motorized tray");
-  if (request_irq(cm206_irq, cm206_interrupt, 0, "cm206", NULL)) {
-    printk("\nUnable to reserve IRQ---aborted\n");
-    cleanup(2);
-    return -EIO;
-  }
-  printk(".\n");
-  if (devfs_register_blkdev(MAJOR_NR, "cm206", &cdrom_fops) != 0) {
-    printk(KERN_INFO "Cannot register for major %d!\n", MAJOR_NR);
-    cleanup(3);
-    return -EIO;
-  }
-  cm206_info.dev = MKDEV(MAJOR_NR,0);
-  if (register_cdrom(&cm206_info) != 0) {
-    printk(KERN_INFO "Cannot register for cdrom %d!\n", MAJOR_NR);
-    cleanup(3);
-    return -EIO;
-  }    
-  blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
-  blksize_size[MAJOR_NR] = cm206_blocksizes;
-  read_ahead[MAJOR_NR] = 16;	/* reads ahead what? */
-  init_bh(CM206_BH, cm206_bh);
-
-  memset(cd, 0, sizeof(*cd));	/* give'm some reasonable value */
-  cd->sector_last = -1;		/* flag no data buffered */
-  cd->adapter_last = -1;
-  cd->timer.function = cm206_timeout;
-  cd->max_sectors = (inw(r_data_status) & ds_ram_size) ? 24 : 97;
-  printk(KERN_INFO "%d kB adapter memory available, "  
-	 " %ld bytes kernel memory used.\n", cd->max_sectors*2, size);
-  return 0;
+	if (send_receive_polled(c_drive_configuration) !=
+	    c_drive_configuration) {
+		printk(KERN_INFO " drive not there\n");
+		cleanup(1);
+		return -EIO;
+	}
+	e = send_receive_polled(c_gimme);
+	printk(KERN_INFO "Firmware revision %d", e & dcf_revision_code);
+	if (e & dcf_transfer_rate)
+		printk(" double");
+	else
+		printk(" single");
+	printk(" speed drive");
+	if (e & dcf_motorized_tray)
+		printk(", motorized tray");
+	if (request_irq(cm206_irq, cm206_interrupt, 0, "cm206", NULL)) {
+		printk("\nUnable to reserve IRQ---aborted\n");
+		cleanup(2);
+		return -EIO;
+	}
+	printk(".\n");
+	if (devfs_register_blkdev(MAJOR_NR, "cm206", &cdrom_fops) != 0) {
+		printk(KERN_INFO "Cannot register for major %d!\n",
+		       MAJOR_NR);
+		cleanup(3);
+		return -EIO;
+	}
+	cm206_info.dev = MKDEV(MAJOR_NR, 0);
+	if (register_cdrom(&cm206_info) != 0) {
+		printk(KERN_INFO "Cannot register for cdrom %d!\n",
+		       MAJOR_NR);
+		cleanup(3);
+		return -EIO;
+	}
+	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
+	blksize_size[MAJOR_NR] = cm206_blocksizes;
+	read_ahead[MAJOR_NR] = 16;	/* reads ahead what? */
+	init_bh(CM206_BH, cm206_bh);
+
+	memset(cd, 0, sizeof(*cd));	/* give'm some reasonable value */
+	cd->sector_last = -1;	/* flag no data buffered */
+	cd->adapter_last = -1;
+	cd->timer.function = cm206_timeout;
+	cd->max_sectors = (inw(r_data_status) & ds_ram_size) ? 24 : 97;
+	printk(KERN_INFO "%d kB adapter memory available, "
+	       " %ld bytes kernel memory used.\n", cd->max_sectors * 2,
+	       size);
+	return 0;
 }
 
 #ifdef MODULE
@@ -1417,65 +1512,67 @@
 
 static void __init parse_options(void)
 {
-  int i;
-  for (i=0; i<2; i++) {
-    if (0x300 <= cm206[i] && i<= 0x370 && cm206[i] % 0x10 == 0) {
-      cm206_base = cm206[i];
-      auto_probe=0;
-    }
-    else if (3 <= cm206[i] && cm206[i] <= 15) {
-      cm206_irq = cm206[i];
-      auto_probe=0;
-    }
-  }
+	int i;
+	for (i = 0; i < 2; i++) {
+		if (0x300 <= cm206[i] && i <= 0x370
+		    && cm206[i] % 0x10 == 0) {
+			cm206_base = cm206[i];
+			auto_probe = 0;
+		} else if (3 <= cm206[i] && cm206[i] <= 15) {
+			cm206_irq = cm206[i];
+			auto_probe = 0;
+		}
+	}
 }
 
 int __cm206_init(void)
 {
 	parse_options();
 #if !defined(AUTO_PROBE_MODULE)
-	auto_probe=0;
+	auto_probe = 0;
 #endif
 	return cm206_init();
 }
 
 void __exit cm206_exit(void)
 {
-  cleanup(4);
-  printk(KERN_INFO "cm206 removed\n");
+	cleanup(4);
+	printk(KERN_INFO "cm206 removed\n");
 }
 
 module_init(__cm206_init);
 module_exit(cm206_exit);
-      
-#else /* !MODULE */
+
+#else				/* !MODULE */
 
 /* This setup function accepts either `auto' or numbers in the range
  * 3--11 (for irq) or 0x300--0x370 (for base port) or both. */
 
 static int __init cm206_setup(char *s)
 {
-  int i, p[4];
-  
-  (void)get_options(s, ARRAY_SIZE(p), p);
-  
-  if (!strcmp(s, "auto")) auto_probe=1;
-  for(i=1; i<=p[0]; i++) {
-    if (0x300 <= p[i] && i<= 0x370 && p[i] % 0x10 == 0) {
-      cm206_base = p[i];
-      auto_probe = 0;
-    }
-    else if (3 <= p[i] && p[i] <= 15) {
-      cm206_irq = p[i];
-      auto_probe = 0;
-    }
-  }
- return 1;
+	int i, p[4];
+
+	(void) get_options(s, ARRAY_SIZE(p), p);
+
+	if (!strcmp(s, "auto"))
+		auto_probe = 1;
+	for (i = 1; i <= p[0]; i++) {
+		if (0x300 <= p[i] && i <= 0x370 && p[i] % 0x10 == 0) {
+			cm206_base = p[i];
+			auto_probe = 0;
+		} else if (3 <= p[i] && p[i] <= 15) {
+			cm206_irq = p[i];
+			auto_probe = 0;
+		}
+	}
+	return 1;
 }
 
 __setup("cm206=", cm206_setup);
 
-#endif /* !MODULE */
+#endif				/* !MODULE */
+
+
 /*
  * Local variables:
  * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -fno-strength-reduce -m486 -DMODULE -DMODVERSIONS -include /usr/src/linux/include/linux/modversions.h  -c -o cm206.o cm206.c"
diff -u --recursive --new-file v2.4.9/linux/drivers/cdrom/gscd.c linux/drivers/cdrom/gscd.c
--- v2.4.9/linux/drivers/cdrom/gscd.c	Fri Feb  9 11:30:22 2001
+++ linux/drivers/cdrom/gscd.c	Fri Sep  7 09:28:38 2001
@@ -41,8 +41,8 @@
 
 */
 
-/* These settings are for various debug-level. Leave they untouched ... */ 
-#define  NO_GSCD_DEBUG 
+/* These settings are for various debug-level. Leave they untouched ... */
+#define  NO_GSCD_DEBUG
 #define  NO_IOCTL_DEBUG
 #define  NO_MODULE_DEBUG
 #define  NO_FUTURE_WORK
@@ -71,81 +71,82 @@
 
 #define MAJOR_NR GOLDSTAR_CDROM_MAJOR
 #include <linux/blk.h>
-#define gscd_port gscd /* for compatible parameter passing with "insmod" */
+#define gscd_port gscd		/* for compatible parameter passing with "insmod" */
 #include "gscd.h"
 
-static int gscd_blocksizes[1] = {512};
+static int gscd_blocksizes[1] = { 512 };
 
-static int gscdPresent            = 0;
+static int gscdPresent = 0;
 
-static unsigned char gscd_buf[2048];    /* buffer for block size conversion */
-static int   gscd_bn              = -1;
-static short gscd_port            = GSCD_BASE_ADDR;
+static unsigned char gscd_buf[2048];	/* buffer for block size conversion */
+static int gscd_bn = -1;
+static short gscd_port = GSCD_BASE_ADDR;
 MODULE_PARM(gscd, "h");
 
 /* Kommt spaeter vielleicht noch mal dran ...
  *    static DECLARE_WAIT_QUEUE_HEAD(gscd_waitq);
- */ 
+ */
 
-static void gscd_transfer         (void);
-static void gscd_read_cmd         (void);
-static void gscd_hsg2msf          (long hsg, struct msf *msf);
-static void gscd_bin2bcd          (unsigned char *p);
+static void gscd_transfer(void);
+static void gscd_read_cmd(void);
+static void gscd_hsg2msf(long hsg, struct msf *msf);
+static void gscd_bin2bcd(unsigned char *p);
 
 /* Schnittstellen zum Kern/FS */
 
-static void do_gscd_request       (request_queue_t *);
-static void __do_gscd_request     (unsigned long dummy);
-static int  gscd_ioctl            (struct inode *, struct file *, unsigned int, unsigned long);
-static int  gscd_open             (struct inode *, struct file *);
-static int  gscd_release          (struct inode *, struct file *);
-static int  check_gscd_med_chg    (kdev_t);
+static void do_gscd_request(request_queue_t *);
+static void __do_gscd_request(unsigned long dummy);
+static int gscd_ioctl(struct inode *, struct file *, unsigned int,
+		      unsigned long);
+static int gscd_open(struct inode *, struct file *);
+static int gscd_release(struct inode *, struct file *);
+static int check_gscd_med_chg(kdev_t);
 
 /*      GoldStar Funktionen    */
 
-static void cc_Reset             (void);
-static int  wait_drv_ready       (void);
-static int  find_drives          (void);
-static void cmd_out              (int, char *, char *, int);
-static void cmd_status           (void);
-static void cc_Ident             (char *);
-static void cc_SetSpeed          (void);
-static void init_cd_drive        (int);
-
-static int  get_status           (void);
-static void clear_Audio          (void);
-static void cc_invalidate        (void);
+static void cc_Reset(void);
+static int wait_drv_ready(void);
+static int find_drives(void);
+static void cmd_out(int, char *, char *, int);
+static void cmd_status(void);
+static void cc_Ident(char *);
+static void cc_SetSpeed(void);
+static void init_cd_drive(int);
+
+static int get_status(void);
+static void clear_Audio(void);
+static void cc_invalidate(void);
 
 /* some things for the next version */
 #ifdef FUTURE_WORK
-static void update_state          (void);
-static long gscd_msf2hsg          (struct msf *mp);
-static int  gscd_bcd2bin          (unsigned char bcd);
+static void update_state(void);
+static long gscd_msf2hsg(struct msf *mp);
+static int gscd_bcd2bin(unsigned char bcd);
 #endif
 
 /*    common GoldStar Initialization    */
 
-static int my_gscd_init (void);
+static int my_gscd_init(void);
 
 
 /*      lo-level cmd-Funktionen    */
 
-static void cmd_info_in          ( char *, int );
-static void cmd_end              ( void );
-static void cmd_read_b           ( char *, int, int );
-static void cmd_read_w           ( char *, int, int );
-static int  cmd_unit_alive       ( void );
-static void cmd_write_cmd        ( char * );
+static void cmd_info_in(char *, int);
+static void cmd_end(void);
+static void cmd_read_b(char *, int, int);
+static void cmd_read_w(char *, int, int);
+static int cmd_unit_alive(void);
+static void cmd_write_cmd(char *);
 
 
 /*      GoldStar Variablen     */
 
-static int  curr_drv_state;
-static int  drv_states[]       = {0,0,0,0,0,0,0,0};
-static int  drv_mode;
-static int  disk_state;
-static int  speed;
-static int  ndrives;
+static int curr_drv_state;
+static int drv_states[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+static int drv_mode;
+static int disk_state;
+static int speed;
+static int ndrives;
 
 static unsigned char drv_num_read;
 static unsigned char f_dsk_valid;
@@ -155,93 +156,91 @@
 
 static char f_AudioPlay;
 static char f_AudioPause;
-static int  AudioStart_m;
-static int  AudioStart_f;
-static int  AudioEnd_m;
-static int  AudioEnd_f;
- 
+static int AudioStart_m;
+static int AudioStart_f;
+static int AudioEnd_m;
+static int AudioEnd_f;
+
 static struct timer_list gscd_timer;
 
 static struct block_device_operations gscd_fops = {
-	open:			gscd_open,
-	release:		gscd_release,
-	ioctl:			gscd_ioctl,
-	check_media_change:	check_gscd_med_chg,
+	open:gscd_open,
+	release:gscd_release,
+	ioctl:gscd_ioctl,
+	check_media_change:check_gscd_med_chg,
 };
 
 /* 
  * Checking if the media has been changed
  * (not yet implemented)
  */
-static int check_gscd_med_chg (kdev_t full_dev)
+static int check_gscd_med_chg(kdev_t full_dev)
 {
-   int target;
+	int target;
 
 
-   target = MINOR(full_dev);
+	target = MINOR(full_dev);
 
-   if (target > 0) 
-   {
-      printk("GSCD: GoldStar CD-ROM request error: invalid device.\n");
-      return 0;
-   }
+	if (target > 0) {
+		printk
+		    ("GSCD: GoldStar CD-ROM request error: invalid device.\n");
+		return 0;
+	}
+#ifdef GSCD_DEBUG
+	printk("gscd: check_med_change\n");
+#endif
 
-   #ifdef GSCD_DEBUG
-   printk ("gscd: check_med_change\n");
-   #endif
- 
-  return 0;
+	return 0;
 }
 
 
 #ifndef MODULE
 /* Using new interface for kernel-parameters */
-  
-static int __init gscd_setup (char *str)
+
+static int __init gscd_setup(char *str)
 {
-  int ints[2];
-  (void)get_options(str, ARRAY_SIZE(ints), ints);
-  
-  if (ints[0] > 0) 
-  {
-     gscd_port = ints[1];
-  }
- return 1;
+	int ints[2];
+	(void) get_options(str, ARRAY_SIZE(ints), ints);
+
+	if (ints[0] > 0) {
+		gscd_port = ints[1];
+	}
+	return 1;
 }
 
 __setup("gscd=", gscd_setup);
 
 #endif
 
-static int gscd_ioctl (struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg)
+static int gscd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
+		      unsigned long arg)
 {
-unsigned char to_do[10];
-unsigned char dummy;
+	unsigned char to_do[10];
+	unsigned char dummy;
+
 
-                             
-    switch (cmd)
-    {
-       case CDROMSTART:     /* Spin up the drive */
+	switch (cmd) {
+	case CDROMSTART:	/* Spin up the drive */
 		/* Don't think we can do this.  Even if we could,
- 		 * I think the drive times out and stops after a while
+		 * I think the drive times out and stops after a while
 		 * anyway.  For now, ignore it.
 		 */
-            return 0;
+		return 0;
 
-       case CDROMRESUME:   /* keine Ahnung was das ist */
-            return 0;
+	case CDROMRESUME:	/* keine Ahnung was das ist */
+		return 0;
 
 
-       case CDROMEJECT:
-            cmd_status ();
-            to_do[0] = CMD_TRAY_CTL;
-            cmd_out (TYPE_INFO, (char *)&to_do, (char *)&dummy, 0);
+	case CDROMEJECT:
+		cmd_status();
+		to_do[0] = CMD_TRAY_CTL;
+		cmd_out(TYPE_INFO, (char *) &to_do, (char *) &dummy, 0);
 
-            return 0;
+		return 0;
 
-       default:
-            return -EINVAL;
-    }
+	default:
+		return -EINVAL;
+	}
 
 }
 
@@ -251,17 +250,16 @@
  * When Linux gets variable block sizes this will probably go away.
  */
 
-static void gscd_transfer (void)
+static void gscd_transfer(void)
 {
-long offs;
+	long offs;
 
-	while (CURRENT -> nr_sectors > 0 && gscd_bn == CURRENT -> sector / 4)
-	{
-		offs = (CURRENT -> sector & 3) * 512;
-		memcpy(CURRENT -> buffer, gscd_buf + offs, 512);
-		CURRENT -> nr_sectors--;
-		CURRENT -> sector++;
-		CURRENT -> buffer += 512;
+	while (CURRENT->nr_sectors > 0 && gscd_bn == CURRENT->sector / 4) {
+		offs = (CURRENT->sector & 3) * 512;
+		memcpy(CURRENT->buffer, gscd_buf + offs, 512);
+		CURRENT->nr_sectors--;
+		CURRENT->sector++;
+		CURRENT->buffer += 512;
 	}
 }
 
@@ -270,17 +268,17 @@
  * I/O request routine called from Linux kernel.
  */
 
-static void do_gscd_request (request_queue_t * q)
+static void do_gscd_request(request_queue_t * q)
 {
-  __do_gscd_request(0);
+	__do_gscd_request(0);
 }
 
-static void __do_gscd_request (unsigned long dummy)
+static void __do_gscd_request(unsigned long dummy)
 {
-unsigned int block,dev;
-unsigned int nsect;
+	unsigned int block, dev;
+	unsigned int nsect;
 
-repeat:
+      repeat:
 	if (QUEUE_EMPTY || CURRENT->rq_status == RQ_INACTIVE)
 		goto out;
 	INIT_REQUEST;
@@ -288,18 +286,16 @@
 	block = CURRENT->sector;
 	nsect = CURRENT->nr_sectors;
 
-	if (QUEUE_EMPTY || CURRENT -> sector == -1)
+	if (QUEUE_EMPTY || CURRENT->sector == -1)
 		goto out;
 
-	if (CURRENT -> cmd != READ)
-	{
-		printk("GSCD: bad cmd %d\n", CURRENT -> cmd);
+	if (CURRENT->cmd != READ) {
+		printk("GSCD: bad cmd %d\n", CURRENT->cmd);
 		end_request(0);
 		goto repeat;
 	}
 
-	if (MINOR(CURRENT -> rq_dev) != 0)
-	{
+	if (MINOR(CURRENT->rq_dev) != 0) {
 		printk("GSCD: this version supports only one device\n");
 		end_request(0);
 		goto repeat;
@@ -309,18 +305,16 @@
 
 	/* if we satisfied the request from the buffer, we're done. */
 
-	if (CURRENT -> nr_sectors == 0)
-	{
+	if (CURRENT->nr_sectors == 0) {
 		end_request(1);
 		goto repeat;
 	}
-
 #ifdef GSCD_DEBUG
-        printk ("GSCD: dev %d, block %d, nsect %d\n", dev, block, nsect );
+	printk("GSCD: dev %d, block %d, nsect %d\n", dev, block, nsect);
 #endif
 
-	gscd_read_cmd ();
-out:
+	gscd_read_cmd();
+      out:
 	return;
 }
 
@@ -331,47 +325,42 @@
  * read-data command.
  */
 
-static void
-gscd_read_cmd (void)
+static void gscd_read_cmd(void)
 {
-long   block;
-struct gscd_Play_msf gscdcmd;
-char   cmd[] = { CMD_READ, 0x80, 0,0,0, 0,1 }; /* cmd mode M-S-F secth sectl */
+	long block;
+	struct gscd_Play_msf gscdcmd;
+	char cmd[] = { CMD_READ, 0x80, 0, 0, 0, 0, 1 };	/* cmd mode M-S-F secth sectl */
 
 
 
-        cmd_status ();
-        if ( disk_state & (ST_NO_DISK | ST_DOOR_OPEN) )
-        {
-           printk ( "GSCD: no disk or door open\n" );
-           end_request (0);
-        }
-        else
-        {
-           if ( disk_state & ST_INVALID )
-           {
-              printk ( "GSCD: disk invalid\n" );
-              end_request (0);
-           }
-           else
-           {
-              gscd_bn = -1;		/* purge our buffer */
-              block = CURRENT -> sector / 4;
-              gscd_hsg2msf(block, &gscdcmd.start);	/* cvt to msf format */
-
-              cmd[2] = gscdcmd.start.min;
-              cmd[3] = gscdcmd.start.sec;
-              cmd[4] = gscdcmd.start.frame;
+	cmd_status();
+	if (disk_state & (ST_NO_DISK | ST_DOOR_OPEN)) {
+		printk("GSCD: no disk or door open\n");
+		end_request(0);
+	} else {
+		if (disk_state & ST_INVALID) {
+			printk("GSCD: disk invalid\n");
+			end_request(0);
+		} else {
+			gscd_bn = -1;	/* purge our buffer */
+			block = CURRENT->sector / 4;
+			gscd_hsg2msf(block, &gscdcmd.start);	/* cvt to msf format */
+
+			cmd[2] = gscdcmd.start.min;
+			cmd[3] = gscdcmd.start.sec;
+			cmd[4] = gscdcmd.start.frame;
 
 #ifdef GSCD_DEBUG
-              printk ("GSCD: read msf %d:%d:%d\n", cmd[2], cmd[3], cmd[4] ); 
-#endif 
-              cmd_out ( TYPE_DATA, (char *)&cmd, (char *)&gscd_buf[0], 1 );
-        
-              gscd_bn = CURRENT -> sector / 4;
-              gscd_transfer();
-              end_request(1);
-	   }
+			printk("GSCD: read msf %d:%d:%d\n", cmd[2], cmd[3],
+			       cmd[4]);
+#endif
+			cmd_out(TYPE_DATA, (char *) &cmd,
+				(char *) &gscd_buf[0], 1);
+
+			gscd_bn = CURRENT->sector / 4;
+			gscd_transfer();
+			end_request(1);
+		}
 	}
 	SET_TIMER(__do_gscd_request, 1);
 }
@@ -381,28 +370,27 @@
  * Open the device special file.  Check that a disk is in.
  */
 
-static int gscd_open (struct inode *ip, struct file *fp)
+static int gscd_open(struct inode *ip, struct file *fp)
 {
-int   st;
+	int st;
 
 #ifdef GSCD_DEBUG
-printk ( "GSCD: open\n" );
+	printk("GSCD: open\n");
 #endif
 
 	if (gscdPresent == 0)
-		return -ENXIO;			/* no hardware */
+		return -ENXIO;	/* no hardware */
 
 	MOD_INC_USE_COUNT;
 
-        get_status ();
-        st = disk_state & (ST_NO_DISK | ST_DOOR_OPEN);
-        if ( st )
-        {
-           printk ( "GSCD: no disk or door open\n" );
-           MOD_DEC_USE_COUNT;
-           return -ENXIO;
-        }
-                   
+	get_status();
+	st = disk_state & (ST_NO_DISK | ST_DOOR_OPEN);
+	if (st) {
+		printk("GSCD: no disk or door open\n");
+		MOD_DEC_USE_COUNT;
+		return -ENXIO;
+	}
+
 /*	if (updateToc() < 0)
 		return -EIO;
 */
@@ -415,11 +403,11 @@
  * On close, we flush all gscd blocks from the buffer cache.
  */
 
-static int gscd_release (struct inode * inode, struct file * file)
+static int gscd_release(struct inode *inode, struct file *file)
 {
 
 #ifdef GSCD_DEBUG
-printk ( "GSCD: release\n" );
+	printk("GSCD: release\n");
 #endif
 
 	gscd_bn = -1;
@@ -429,692 +417,642 @@
 }
 
 
-int get_status (void)
+int get_status(void)
 {
-int  status;
+	int status;
+
+	cmd_status();
+	status = disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01);
 
-    cmd_status ();
-    status = disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01);
-     
-    if ( status == (ST_x08 | ST_x04 | ST_INVALID | ST_x01) )
-    {
-       cc_invalidate ();
-       return 1;
-    }
-    else
-    {
-       return 0;
-    }
+	if (status == (ST_x08 | ST_x04 | ST_INVALID | ST_x01)) {
+		cc_invalidate();
+		return 1;
+	} else {
+		return 0;
+	}
 }
 
 
-void cc_invalidate (void)
-{
-   drv_num_read  = 0xFF;
-   f_dsk_valid   = 0xFF;
-   current_drive = 0xFF;
-   f_drv_ok      = 0xFF;
-
-   clear_Audio ();
-   
-}   
-
-void clear_Audio (void)
-{
-
-   f_AudioPlay = 0;
-   f_AudioPause = 0;
-   AudioStart_m = 0;
-   AudioStart_f = 0;
-   AudioEnd_m   = 0;
-   AudioEnd_f   = 0;
-   
+void cc_invalidate(void)
+{
+	drv_num_read = 0xFF;
+	f_dsk_valid = 0xFF;
+	current_drive = 0xFF;
+	f_drv_ok = 0xFF;
+
+	clear_Audio();
+
+}
+
+void clear_Audio(void)
+{
+
+	f_AudioPlay = 0;
+	f_AudioPause = 0;
+	AudioStart_m = 0;
+	AudioStart_f = 0;
+	AudioEnd_m = 0;
+	AudioEnd_f = 0;
+
 }
 
 /*
  *   waiting ?  
  */
 
-int wait_drv_ready (void)
+int wait_drv_ready(void)
 {
-int found, read;
+	int found, read;
+
+	do {
+		found = inb(GSCDPORT(0));
+		found &= 0x0f;
+		read = inb(GSCDPORT(0));
+		read &= 0x0f;
+	} while (read != found);
 
-   do
-   {  
-       found = inb ( GSCDPORT(0) ); 
-       found &= 0x0f;
-       read  = inb ( GSCDPORT(0) );
-       read  &= 0x0f;
-   } while ( read != found );
-   
 #ifdef GSCD_DEBUG
-printk ( "Wait for: %d\n", read );
-#endif   
-   
-   return read;
+	printk("Wait for: %d\n", read);
+#endif
+
+	return read;
 }
 
-void cc_Ident (char * respons)
+void cc_Ident(char *respons)
 {
-char to_do [] = {CMD_IDENT, 0, 0};
+	char to_do[] = { CMD_IDENT, 0, 0 };
 
-    cmd_out (TYPE_INFO, (char *)&to_do, (char *)respons, (int)0x1E );
+	cmd_out(TYPE_INFO, (char *) &to_do, (char *) respons, (int) 0x1E);
 
 }
 
-void cc_SetSpeed (void)
+void cc_SetSpeed(void)
 {
-char to_do [] = {CMD_SETSPEED, 0, 0};
-char dummy;
+	char to_do[] = { CMD_SETSPEED, 0, 0 };
+	char dummy;
 
-    if ( speed > 0 )
-    {
-       to_do[1] = speed & 0x0F;
-       cmd_out (TYPE_INFO, (char *)&to_do, (char *)&dummy, 0);
-    }
+	if (speed > 0) {
+		to_do[1] = speed & 0x0F;
+		cmd_out(TYPE_INFO, (char *) &to_do, (char *) &dummy, 0);
+	}
 }
 
 
-void cc_Reset (void)
+void cc_Reset(void)
 {
-char to_do [] = {CMD_RESET, 0};
-char dummy;
+	char to_do[] = { CMD_RESET, 0 };
+	char dummy;
 
-   cmd_out (TYPE_INFO, (char *)&to_do, (char *)&dummy, 0);
+	cmd_out(TYPE_INFO, (char *) &to_do, (char *) &dummy, 0);
 }
 
 
 
-void cmd_status (void)
+void cmd_status(void)
 {
-char to_do [] = {CMD_STATUS, 0};
-char dummy;
+	char to_do[] = { CMD_STATUS, 0 };
+	char dummy;
 
-   cmd_out (TYPE_INFO, (char *)&to_do, (char *)&dummy, 0);
+	cmd_out(TYPE_INFO, (char *) &to_do, (char *) &dummy, 0);
 
 #ifdef GSCD_DEBUG
-printk ("GSCD: Status: %d\n", disk_state );
+	printk("GSCD: Status: %d\n", disk_state);
 #endif
 
 }
 
-void cmd_out ( int cmd_type, char * cmd, char * respo_buf, int respo_count )
+void cmd_out(int cmd_type, char *cmd, char *respo_buf, int respo_count)
 {
-int        result;
+	int result;
+
+
+	result = wait_drv_ready();
+	if (result != drv_mode) {
+		unsigned long test_loops = 0xFFFF;
+		int i, dummy;
 
+		outb(curr_drv_state, GSCDPORT(0));
 
-       result = wait_drv_ready ();
-       if ( result != drv_mode )
-       {
-       unsigned long test_loops = 0xFFFF;
-       int           i,dummy;
-
-          outb ( curr_drv_state, GSCDPORT(0));
-          
-          /* LOCLOOP_170 */
-          do
-          {
-             result = wait_drv_ready ();
-             test_loops--;
-          } while ( (result != drv_mode) && (test_loops > 0) );
-
-          if ( result != drv_mode )
-          {
-             disk_state = ST_x08 | ST_x04 | ST_INVALID;
-             return;
-          }          
-        
-          /* ...and waiting */
-          for ( i=1,dummy=1 ; i<0xFFFF ; i++ )
-          {
-             dummy *= i;
-          }              
-       }
-
-       /* LOC_172 */    
-       /* check the unit */
-       /* and wake it up */
-       if ( cmd_unit_alive () != 0x08 )
-       {
-          /* LOC_174 */
-          /* game over for this unit */
-          disk_state = ST_x08 | ST_x04 | ST_INVALID;
-          return;
-       }
-       
-       /* LOC_176 */
-       #ifdef GSCD_DEBUG
-        printk ("LOC_176 ");
-       #endif       
-       if ( drv_mode == 0x09 )
-       {
-          /* magic... */
-          printk ("GSCD: magic ...\n");       
-          outb ( result, GSCDPORT(2));
-       }
-
-       /* write the command to the drive */
-       cmd_write_cmd (cmd);
-
-       /* LOC_178 */
-       for (;;)
-       {
-          result = wait_drv_ready ();
-          if ( result != drv_mode )
-          {
-             /* LOC_179 */
-             if ( result == 0x04 )                  /* Mode 4 */
-             {
-                /* LOC_205 */
-                #ifdef GSCD_DEBUG
-                printk ("LOC_205 ");	              
-                #endif
-                disk_state = inb ( GSCDPORT (2));
-             
-                do
-                {
-                   result = wait_drv_ready ();
-                } while ( result != drv_mode );
-                return;
-
-             }
-             else
-             {
-                if ( result == 0x06 )               /* Mode 6 */
-                {
-                   /* LOC_181 */
-                   #ifdef GSCD_DEBUG
-                    printk ("LOC_181 ");	              
-                   #endif
-
-                   if (cmd_type == TYPE_DATA)
-                   {
-                      /* read data */
-                      /* LOC_184 */
-                      if ( drv_mode == 9 )
-                      {
-                         /* read the data to the buffer (word) */
- 
-                         /* (*(cmd+1))?(CD_FRAMESIZE/2):(CD_FRAMESIZE_RAW/2) */
-                         cmd_read_w ( respo_buf, respo_count, CD_FRAMESIZE/2 );
-                         return;
-                      } 
-                      else
-                      { 
-                         /* read the data to the buffer (byte) */
-                         
-                         /* (*(cmd+1))?(CD_FRAMESIZE):(CD_FRAMESIZE_RAW)    */
-                         cmd_read_b ( respo_buf, respo_count, CD_FRAMESIZE );
-                         return;
-                      }
-                   }
-                   else
-                   { 
-                      /* read the info to the buffer */
-                      cmd_info_in ( respo_buf, respo_count ); 
-                      return;
-                   }                  
-
-                   return;
-                }
-             }
-
-          }
-          else
-          {
-             disk_state = ST_x08 | ST_x04 | ST_INVALID;         
-             return;
-          }    
-       } /* for (;;) */
+		/* LOCLOOP_170 */
+		do {
+			result = wait_drv_ready();
+			test_loops--;
+		} while ((result != drv_mode) && (test_loops > 0));
 
+		if (result != drv_mode) {
+			disk_state = ST_x08 | ST_x04 | ST_INVALID;
+			return;
+		}
+
+		/* ...and waiting */
+		for (i = 1, dummy = 1; i < 0xFFFF; i++) {
+			dummy *= i;
+		}
+	}
 
+	/* LOC_172 */
+	/* check the unit */
+	/* and wake it up */
+	if (cmd_unit_alive() != 0x08) {
+		/* LOC_174 */
+		/* game over for this unit */
+		disk_state = ST_x08 | ST_x04 | ST_INVALID;
+		return;
+	}
+
+	/* LOC_176 */
 #ifdef GSCD_DEBUG
-printk ("\n");       
-#endif    
+	printk("LOC_176 ");
+#endif
+	if (drv_mode == 0x09) {
+		/* magic... */
+		printk("GSCD: magic ...\n");
+		outb(result, GSCDPORT(2));
+	}
+
+	/* write the command to the drive */
+	cmd_write_cmd(cmd);
+
+	/* LOC_178 */
+	for (;;) {
+		result = wait_drv_ready();
+		if (result != drv_mode) {
+			/* LOC_179 */
+			if (result == 0x04) {	/* Mode 4 */
+				/* LOC_205 */
+#ifdef GSCD_DEBUG
+				printk("LOC_205 ");
+#endif
+				disk_state = inb(GSCDPORT(2));
+
+				do {
+					result = wait_drv_ready();
+				} while (result != drv_mode);
+				return;
+
+			} else {
+				if (result == 0x06) {	/* Mode 6 */
+					/* LOC_181 */
+#ifdef GSCD_DEBUG
+					printk("LOC_181 ");
+#endif
+
+					if (cmd_type == TYPE_DATA) {
+						/* read data */
+						/* LOC_184 */
+						if (drv_mode == 9) {
+							/* read the data to the buffer (word) */
+
+							/* (*(cmd+1))?(CD_FRAMESIZE/2):(CD_FRAMESIZE_RAW/2) */
+							cmd_read_w
+							    (respo_buf,
+							     respo_count,
+							     CD_FRAMESIZE /
+							     2);
+							return;
+						} else {
+							/* read the data to the buffer (byte) */
+
+							/* (*(cmd+1))?(CD_FRAMESIZE):(CD_FRAMESIZE_RAW)    */
+							cmd_read_b
+							    (respo_buf,
+							     respo_count,
+							     CD_FRAMESIZE);
+							return;
+						}
+					} else {
+						/* read the info to the buffer */
+						cmd_info_in(respo_buf,
+							    respo_count);
+						return;
+					}
+
+					return;
+				}
+			}
+
+		} else {
+			disk_state = ST_x08 | ST_x04 | ST_INVALID;
+			return;
+		}
+	}			/* for (;;) */
+
+
+#ifdef GSCD_DEBUG
+	printk("\n");
+#endif
+}
+
+
+static void cmd_write_cmd(char *pstr)
+{
+	int i, j;
+
+	/* LOC_177 */
+#ifdef GSCD_DEBUG
+	printk("LOC_177 ");
+#endif
+
+	/* calculate the number of parameter */
+	j = *pstr & 0x0F;
+
+	/* shift it out */
+	for (i = 0; i < j; i++) {
+		outb(*pstr, GSCDPORT(2));
+		pstr++;
+	}
 }
 
 
-static void cmd_write_cmd ( char *pstr )
+static int cmd_unit_alive(void)
 {
-int  i,j;
+	int result;
+	unsigned long max_test_loops;
+
+
+	/* LOC_172 */
+#ifdef GSCD_DEBUG
+	printk("LOC_172 ");
+#endif
+
+	outb(curr_drv_state, GSCDPORT(0));
+	max_test_loops = 0xFFFF;
 
-    /* LOC_177 */
-    #ifdef GSCD_DEBUG
-     printk ("LOC_177 ");       
-    #endif
-       
-    /* calculate the number of parameter */
-    j = *pstr & 0x0F;
-
-    /* shift it out */
-    for ( i=0 ; i<j ; i++ )
-    {
-       outb ( *pstr, GSCDPORT(2) );
-       pstr++;
-    }
-}
-
-
-static int cmd_unit_alive ( void )
-{
-int            result;
-unsigned long  max_test_loops;
-
-
-    /* LOC_172 */
-    #ifdef GSCD_DEBUG
-     printk ("LOC_172 ");       
-    #endif
-
-    outb ( curr_drv_state, GSCDPORT(0));       
-    max_test_loops = 0xFFFF;
-     
-    do
-    {
-       result = wait_drv_ready ();
-       max_test_loops--;
-    } while ( (result != 0x08) && (max_test_loops > 0) );
-
-    return result;
-}       
-
-
-static void cmd_info_in ( char *pb, int count )
-{
-int   result;
-char  read;
-
-
-        /* read info */
-        /* LOC_182 */
-        #ifdef GSCD_DEBUG
-         printk ("LOC_182 ");				              
-        #endif
-       
-        do
-        {
-           read = inb (GSCDPORT(2)); 
-           if ( count > 0 )
-           {
-              *pb = read;
-              pb++;
-              count--;
-           }
-                         
-           /* LOC_183 */
-           do
-           {
-              result = wait_drv_ready ();
-           } while ( result == 0x0E );
-        } while ( result == 6 );                     
-
-        cmd_end ();
-        return;
-}
-
-
-static void cmd_read_b ( char *pb, int count, int size )
-{
-int  result;
-int  i;
-                     
-                     
-       /* LOC_188 */
-       /* LOC_189 */
-       #ifdef GSCD_DEBUG
-        printk ("LOC_189 ");			              
-       #endif
-
-       do 
-       {
-          do
-          {
-             result = wait_drv_ready ();
-          } while ( result != 6 || result == 0x0E );
-                         
-          if ( result != 6 )
-          {
-             cmd_end ();
-             return;
-          }                       
-          
-          #ifdef GSCD_DEBUG
-           printk ("LOC_191 ");       
-          #endif
-
-          for ( i=0 ; i< size ; i++ )
-          {
-             *pb = inb (GSCDPORT(2));
-             pb++;
-          }
-          count--;
-       } while ( count > 0 );
-       
-       cmd_end ();
-       return;
-}
-
-
-static void cmd_end (void)
-{
-int   result;
-
-
-      /* LOC_204 */
-      #ifdef GSCD_DEBUG
-       printk ("LOC_204 ");				              
-      #endif
-      
-      do
-      {
-         result = wait_drv_ready ();
-         if ( result == drv_mode )
-         {
-            return;
-         }
-      } while ( result != 4 );
-
-      /* LOC_205 */
-      #ifdef GSCD_DEBUG
-       printk ("LOC_205 ");			              
-      #endif
-       
-      disk_state = inb ( GSCDPORT (2));
-             
-      do
-      {
-         result = wait_drv_ready ();
-      } while ( result != drv_mode );
-      return;
-
-}
-
-
-static void cmd_read_w ( char *pb, int count, int size )
-{
-int  result;
-int  i;
-
-
-    #ifdef GSCD_DEBUG
-     printk ("LOC_185 ");			              
-    #endif
- 
-    do 
-    {
-       /* LOC_185 */
-       do
-       {
-          result = wait_drv_ready ();
-       } while ( result != 6 || result == 0x0E );
-                         
-       if ( result != 6 )
-       {
-          cmd_end ();
-          return;
-       }                       
-                         
-       for ( i=0 ; i<size ; i++ )
-       {
-           /* na, hier muss ich noch mal drueber nachdenken */
-           *pb = inw(GSCDPORT(2));
-           pb++;
-        }
-        count--;
-     } while ( count > 0 );
-                    
-     cmd_end ();
-     return;
-}
-
-int __init find_drives (void)
-{
-int *pdrv;
-int drvnum;
-int subdrv;
-int i;
-
-    speed           = 0;
-    pdrv            = (int *)&drv_states;
-    curr_drv_state  = 0xFE;
-    subdrv          = 0;
-    drvnum          = 0;
-
-    for ( i=0 ; i<8 ; i++ )
-    { 
-       subdrv++;
-       cmd_status ();
-       disk_state &= ST_x08 | ST_x04 | ST_INVALID | ST_x01;
-       if ( disk_state != (ST_x08 | ST_x04 | ST_INVALID) )
-       {
-          /* LOC_240 */
-          *pdrv = curr_drv_state;
-          init_cd_drive (drvnum);
-          pdrv++;
-          drvnum++;
-       }
-       else
-       {
-          if ( subdrv < 2 )
-          {
-             continue;
-          }
-          else
-          {
-             subdrv = 0;
-          }
-       }   
+	do {
+		result = wait_drv_ready();
+		max_test_loops--;
+	} while ((result != 0x08) && (max_test_loops > 0));
+
+	return result;
+}
 
-/*       curr_drv_state<<1;         <-- das geht irgendwie nicht */ 
+
+static void cmd_info_in(char *pb, int count)
+{
+	int result;
+	char read;
+
+
+	/* read info */
+	/* LOC_182 */
+#ifdef GSCD_DEBUG
+	printk("LOC_182 ");
+#endif
+
+	do {
+		read = inb(GSCDPORT(2));
+		if (count > 0) {
+			*pb = read;
+			pb++;
+			count--;
+		}
+
+		/* LOC_183 */
+		do {
+			result = wait_drv_ready();
+		} while (result == 0x0E);
+	} while (result == 6);
+
+	cmd_end();
+	return;
+}
+
+
+static void cmd_read_b(char *pb, int count, int size)
+{
+	int result;
+	int i;
+
+
+	/* LOC_188 */
+	/* LOC_189 */
+#ifdef GSCD_DEBUG
+	printk("LOC_189 ");
+#endif
+
+	do {
+		do {
+			result = wait_drv_ready();
+		} while (result != 6 || result == 0x0E);
+
+		if (result != 6) {
+			cmd_end();
+			return;
+		}
+#ifdef GSCD_DEBUG
+		printk("LOC_191 ");
+#endif
+
+		for (i = 0; i < size; i++) {
+			*pb = inb(GSCDPORT(2));
+			pb++;
+		}
+		count--;
+	} while (count > 0);
+
+	cmd_end();
+	return;
+}
+
+
+static void cmd_end(void)
+{
+	int result;
+
+
+	/* LOC_204 */
+#ifdef GSCD_DEBUG
+	printk("LOC_204 ");
+#endif
+
+	do {
+		result = wait_drv_ready();
+		if (result == drv_mode) {
+			return;
+		}
+	} while (result != 4);
+
+	/* LOC_205 */
+#ifdef GSCD_DEBUG
+	printk("LOC_205 ");
+#endif
+
+	disk_state = inb(GSCDPORT(2));
+
+	do {
+		result = wait_drv_ready();
+	} while (result != drv_mode);
+	return;
+
+}
+
+
+static void cmd_read_w(char *pb, int count, int size)
+{
+	int result;
+	int i;
+
+
+#ifdef GSCD_DEBUG
+	printk("LOC_185 ");
+#endif
+
+	do {
+		/* LOC_185 */
+		do {
+			result = wait_drv_ready();
+		} while (result != 6 || result == 0x0E);
+
+		if (result != 6) {
+			cmd_end();
+			return;
+		}
+
+		for (i = 0; i < size; i++) {
+			/* na, hier muss ich noch mal drueber nachdenken */
+			*pb = inw(GSCDPORT(2));
+			pb++;
+		}
+		count--;
+	} while (count > 0);
+
+	cmd_end();
+	return;
+}
+
+int __init find_drives(void)
+{
+	int *pdrv;
+	int drvnum;
+	int subdrv;
+	int i;
+
+	speed = 0;
+	pdrv = (int *) &drv_states;
+	curr_drv_state = 0xFE;
+	subdrv = 0;
+	drvnum = 0;
+
+	for (i = 0; i < 8; i++) {
+		subdrv++;
+		cmd_status();
+		disk_state &= ST_x08 | ST_x04 | ST_INVALID | ST_x01;
+		if (disk_state != (ST_x08 | ST_x04 | ST_INVALID)) {
+			/* LOC_240 */
+			*pdrv = curr_drv_state;
+			init_cd_drive(drvnum);
+			pdrv++;
+			drvnum++;
+		} else {
+			if (subdrv < 2) {
+				continue;
+			} else {
+				subdrv = 0;
+			}
+		}
+
+/*       curr_drv_state<<1;         <-- das geht irgendwie nicht */
 /* muss heissen:    curr_drv_state <<= 1; (ist ja Wert-Zuweisung) */
-         curr_drv_state *= 2;
-         curr_drv_state |= 1;
+		curr_drv_state *= 2;
+		curr_drv_state |= 1;
 #ifdef GSCD_DEBUG
-         printk ("DriveState: %d\n", curr_drv_state );
+		printk("DriveState: %d\n", curr_drv_state);
 #endif
-    } 
+	}
 
-    ndrives = drvnum;
-    return drvnum;
-}    
+	ndrives = drvnum;
+	return drvnum;
+}
 
-void __init init_cd_drive ( int num )
+void __init init_cd_drive(int num)
 {
-char resp [50];
-int  i;
+	char resp[50];
+	int i;
 
-   printk ("GSCD: init unit %d\n", num );
-   cc_Ident ((char *)&resp);
+	printk("GSCD: init unit %d\n", num);
+	cc_Ident((char *) &resp);
 
-   printk ("GSCD: identification: ");
-   for ( i=0 ; i<0x1E; i++ )
-   {
-      printk ( "%c", resp[i] );
-   }
-   printk ("\n");
-   
-   cc_SetSpeed ();  
+	printk("GSCD: identification: ");
+	for (i = 0; i < 0x1E; i++) {
+		printk("%c", resp[i]);
+	}
+	printk("\n");
 
-}    
+	cc_SetSpeed();
+
+}
 
 #ifdef FUTURE_WORK
 /* return_done */
-static void update_state ( void )
+static void update_state(void)
 {
-unsigned int AX;
+	unsigned int AX;
+
+
+	if ((disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01)) == 0) {
+		if (disk_state == (ST_x08 | ST_x04 | ST_INVALID)) {
+			AX = ST_INVALID;
+		}
+
+		if ((disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01))
+		    == 0) {
+			invalidate();
+			f_drv_ok = 0;
+		}
+
+		AX |= 0x8000;
+	}
+
+	if (disk_state & ST_PLAYING) {
+		AX |= 0x200;
+	}
 
+	AX |= 0x100;
+	/* pkt_esbx = AX; */
 
-    if ( (disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01)) == 0 )
-    {
-       if ( disk_state == (ST_x08 | ST_x04 | ST_INVALID))
-       {
-          AX = ST_INVALID;
-       }
-  
-       if ( (disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01)) == 0 )
-       {
-          invalidate ();
-          f_drv_ok = 0;
-       }
-       
-       AX |= 0x8000;
-    }
-    
-    if ( disk_state & ST_PLAYING )
-    {
-       AX |= 0x200;
-    }
-    
-    AX |= 0x100;
-    /* pkt_esbx = AX; */
+	disk_state = 0;
 
-    disk_state = 0;
-    
 }
 #endif
 
 /* Init for the Module-Version */
 int init_gscd(void)
 {
-long err;
+	long err;
 
 
-     /* call the GoldStar-init */
-     err = my_gscd_init ( );
+	/* call the GoldStar-init */
+	err = my_gscd_init();
 
-     if ( err < 0 )
-     {
-         return err;
-     }
-     else
-     {
-        printk (KERN_INFO "Happy GoldStar !\n" );
-        return 0;
-     }    
+	if (err < 0) {
+		return err;
+	} else {
+		printk(KERN_INFO "Happy GoldStar !\n");
+		return 0;
+	}
 }
 
 void __exit exit_gscd(void)
 {
-   CLEAR_TIMER;
+	CLEAR_TIMER;
 
-   devfs_unregister(devfs_find_handle(NULL, "gscd", 0, 0, DEVFS_SPECIAL_BLK,
-				      0));
-   if ((devfs_unregister_blkdev(MAJOR_NR, "gscd" ) == -EINVAL))
-   {
-      printk("What's that: can't unregister GoldStar-module\n" );
-      return;
-   }
-   blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
-   release_region (gscd_port,4);
-   printk(KERN_INFO "GoldStar-module released.\n" );
+	devfs_unregister(devfs_find_handle
+			 (NULL, "gscd", 0, 0, DEVFS_SPECIAL_BLK, 0));
+	if ((devfs_unregister_blkdev(MAJOR_NR, "gscd") == -EINVAL)) {
+		printk("What's that: can't unregister GoldStar-module\n");
+		return;
+	}
+	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
+	release_region(gscd_port, 4);
+	printk(KERN_INFO "GoldStar-module released.\n");
 }
 
 #ifdef MODULE
 module_init(init_gscd);
-#endif 
+#endif
 module_exit(exit_gscd);
 
 
 /* Test for presence of drive and initialize it.  Called only at boot time. */
-int __init gscd_init (void)
+int __init gscd_init(void)
 {
-   return my_gscd_init ();
+	return my_gscd_init();
 }
 
 
 /* This is the common initialisation for the GoldStar drive. */
 /* It is called at boot time AND for module init.           */
-int __init my_gscd_init (void)
+int __init my_gscd_init(void)
 {
-int i;
-int result;
+	int i;
+	int result;
 
-        printk (KERN_INFO "GSCD: version %s\n", GSCD_VERSION);
-        printk (KERN_INFO "GSCD: Trying to detect a Goldstar R420 CD-ROM drive at 0x%X.\n", gscd_port);
-
-        if (check_region(gscd_port, 4)) 
-        {
-	  printk("GSCD: Init failed, I/O port (%X) already in use.\n", gscd_port);
-	  return -EIO;
+	printk(KERN_INFO "GSCD: version %s\n", GSCD_VERSION);
+	printk(KERN_INFO
+	       "GSCD: Trying to detect a Goldstar R420 CD-ROM drive at 0x%X.\n",
+	       gscd_port);
+
+	if (check_region(gscd_port, 4)) {
+		printk
+		    ("GSCD: Init failed, I/O port (%X) already in use.\n",
+		     gscd_port);
+		return -EIO;
 	}
-	  
+
 
 	/* check for card */
-	result = wait_drv_ready ();
-        if ( result == 0x09 )
-        {
-           printk ("GSCD: DMA kann ich noch nicht!\n" );
-           return -EIO;
-        }
- 
-        if ( result == 0x0b )
-        {
-           drv_mode = result;
-           i = find_drives ();
-           if ( i == 0 )
-           {
-              printk ( "GSCD: GoldStar CD-ROM Drive is not found.\n" );
-              return -EIO;
-           }
-        }
-
-        if ( (result != 0x0b) && (result != 0x09) )
-        {
-              printk ("GSCD: GoldStar Interface Adapter does not exist or H/W error\n" );
-              return -EIO;
-        }          		            
-
-        /* reset all drives */
-        i = 0;
-        while ( drv_states[i] != 0 )
-        {
-           curr_drv_state = drv_states[i];
-           printk (KERN_INFO "GSCD: Reset unit %d ... ",i );
-           cc_Reset ();
-           printk ( "done\n" );
-           i++;
-        }
-
-	if (devfs_register_blkdev(MAJOR_NR, "gscd", &gscd_fops) != 0)
-	{
-		printk("GSCD: Unable to get major %d for GoldStar CD-ROM\n",
-		       MAJOR_NR);
+	result = wait_drv_ready();
+	if (result == 0x09) {
+		printk("GSCD: DMA kann ich noch nicht!\n");
 		return -EIO;
 	}
-	devfs_register (NULL, "gscd", DEVFS_FL_DEFAULT, MAJOR_NR, 0,
-			S_IFBLK | S_IRUGO | S_IWUGO, &gscd_fops, NULL);
+
+	if (result == 0x0b) {
+		drv_mode = result;
+		i = find_drives();
+		if (i == 0) {
+			printk
+			    ("GSCD: GoldStar CD-ROM Drive is not found.\n");
+			return -EIO;
+		}
+	}
+
+	if ((result != 0x0b) && (result != 0x09)) {
+		printk
+		    ("GSCD: GoldStar Interface Adapter does not exist or H/W error\n");
+		return -EIO;
+	}
+
+	/* reset all drives */
+	i = 0;
+	while (drv_states[i] != 0) {
+		curr_drv_state = drv_states[i];
+		printk(KERN_INFO "GSCD: Reset unit %d ... ", i);
+		cc_Reset();
+		printk("done\n");
+		i++;
+	}
+
+	if (devfs_register_blkdev(MAJOR_NR, "gscd", &gscd_fops) != 0) {
+		printk
+		    ("GSCD: Unable to get major %d for GoldStar CD-ROM\n",
+		     MAJOR_NR);
+		return -EIO;
+	}
+	devfs_register(NULL, "gscd", DEVFS_FL_DEFAULT, MAJOR_NR, 0,
+		       S_IFBLK | S_IRUGO | S_IWUGO, &gscd_fops, NULL);
 
 	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
 	blksize_size[MAJOR_NR] = gscd_blocksizes;
 	read_ahead[MAJOR_NR] = 4;
-        
-        disk_state = 0;
-        gscdPresent = 1;
+
+	disk_state = 0;
+	gscdPresent = 1;
 
 	request_region(gscd_port, 4, "gscd");
-	register_disk(NULL, MKDEV(MAJOR_NR,0), 1, &gscd_fops, 0);
+	register_disk(NULL, MKDEV(MAJOR_NR, 0), 1, &gscd_fops, 0);
 
-        printk (KERN_INFO "GSCD: GoldStar CD-ROM Drive found.\n" );
+	printk(KERN_INFO "GSCD: GoldStar CD-ROM Drive found.\n");
 	return 0;
 }
 
-static void gscd_hsg2msf (long hsg, struct msf *msf)
+static void gscd_hsg2msf(long hsg, struct msf *msf)
 {
 	hsg += CD_MSF_OFFSET;
-	msf -> min = hsg / (CD_FRAMES*CD_SECS);
-	hsg %= CD_FRAMES*CD_SECS;
-	msf -> sec = hsg / CD_FRAMES;
-	msf -> frame = hsg % CD_FRAMES;
+	msf->min = hsg / (CD_FRAMES * CD_SECS);
+	hsg %= CD_FRAMES * CD_SECS;
+	msf->sec = hsg / CD_FRAMES;
+	msf->frame = hsg % CD_FRAMES;
 
-	gscd_bin2bcd(&msf -> min);		/* convert to BCD */
-	gscd_bin2bcd(&msf -> sec);
-	gscd_bin2bcd(&msf -> frame);
+	gscd_bin2bcd(&msf->min);	/* convert to BCD */
+	gscd_bin2bcd(&msf->sec);
+	gscd_bin2bcd(&msf->frame);
 }
- 
 
-static void gscd_bin2bcd (unsigned char *p)
+
+static void gscd_bin2bcd(unsigned char *p)
 {
-int u, t;
+	int u, t;
 
 	u = *p % 10;
 	t = *p / 10;
@@ -1123,18 +1061,19 @@
 
 
 #ifdef FUTURE_WORK
-static long gscd_msf2hsg (struct msf *mp)
+static long gscd_msf2hsg(struct msf *mp)
 {
-	return gscd_bcd2bin(mp -> frame)
-		+ gscd_bcd2bin(mp -> sec) * CD_FRAMES
-		+ gscd_bcd2bin(mp -> min) * CD_FRAMES * CD_SECS
-		- CD_MSF_OFFSET;
+	return gscd_bcd2bin(mp->frame)
+	    + gscd_bcd2bin(mp->sec) * CD_FRAMES
+	    + gscd_bcd2bin(mp->min) * CD_FRAMES * CD_SECS - CD_MSF_OFFSET;
 }
 
-static int gscd_bcd2bin (unsigned char bcd)
+static int gscd_bcd2bin(unsigned char bcd)
 {
 	return (bcd >> 4) * 10 + (bcd & 0xF);
 }
 #endif
 
-
+MODULE_AUTHOR("Oliver Raupach <raupach@nwfs1.rz.fh-hannover.de>");
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
diff -u --recursive --new-file v2.4.9/linux/drivers/cdrom/isp16.c linux/drivers/cdrom/isp16.c
--- v2.4.9/linux/drivers/cdrom/isp16.c	Mon Dec 13 14:08:40 1999
+++ linux/drivers/cdrom/isp16.c	Fri Sep  7 09:28:38 2001
@@ -44,9 +44,7 @@
 #define ISP16_VERSION_MAJOR 0
 #define ISP16_VERSION_MINOR 6
 
-#ifdef MODULE
 #include <linux/module.h>
-#endif  /* MODULE */
 
 #include <linux/fs.h>
 #include <linux/kernel.h>
@@ -59,8 +57,9 @@
 static short isp16_detect(void);
 static short isp16_c928__detect(void);
 static short isp16_c929__detect(void);
-static short isp16_cdi_config(int base, u_char drive_type, int irq, int dma);
-static short isp16_type; /* dependent on type of interface card */
+static short isp16_cdi_config(int base, u_char drive_type, int irq,
+			      int dma);
+static short isp16_type;	/* dependent on type of interface card */
 static u_char isp16_ctrl;
 static u_short isp16_enable_port;
 
@@ -69,11 +68,12 @@
 static int isp16_cdrom_dma = ISP16_CDROM_DMA;
 static char *isp16_cdrom_type = ISP16_CDROM_TYPE;
 
-#ifdef MODULE
 MODULE_PARM(isp16_cdrom_base, "i");
 MODULE_PARM(isp16_cdrom_irq, "i");
 MODULE_PARM(isp16_cdrom_dma, "i");
 MODULE_PARM(isp16_cdrom_type, "s");
+
+#ifdef MODULE
 void isp16_exit(void);
 #endif
 
@@ -82,243 +82,279 @@
 
 #ifndef MODULE
 
-static int 
+static int
 __init isp16_setup(char *str)
 {
-  int ints[4];
-  
-  (void)get_options(str, ARRAY_SIZE(ints), ints);
-  if ( ints[0] > 0 )
-    isp16_cdrom_base = ints[1];
-  if ( ints[0] > 1 )      
-    isp16_cdrom_irq = ints[2];
-  if ( ints[0] > 2 )      
-    isp16_cdrom_dma = ints[3];
-  if ( str )
-    isp16_cdrom_type = str;
+	int ints[4];
 
-  return 1;
+	(void) get_options(str, ARRAY_SIZE(ints), ints);
+	if (ints[0] > 0)
+		isp16_cdrom_base = ints[1];
+	if (ints[0] > 1)
+		isp16_cdrom_irq = ints[2];
+	if (ints[0] > 2)
+		isp16_cdrom_dma = ints[3];
+	if (str)
+		isp16_cdrom_type = str;
+
+	return 1;
 }
 
 __setup("isp16=", isp16_setup);
 
-#endif /* MODULE */
+#endif				/* MODULE */
 
 /*
  *  ISP16 initialisation.
  *
  */
-int __init 
-isp16_init(void)
+int __init isp16_init(void)
 {
-  u_char expected_drive;
-
-  printk(KERN_INFO "ISP16: configuration cdrom interface, version %d.%d.\n", ISP16_VERSION_MAJOR,
-    ISP16_VERSION_MINOR);
+	u_char expected_drive;
 
-  if ( !strcmp(isp16_cdrom_type, "noisp16") ) {
-    printk("ISP16: no cdrom interface configured.\n");
-    return(0);
-  }
-
-  if (check_region(ISP16_IO_BASE, ISP16_IO_SIZE)) {
-    printk("ISP16: i/o ports already in use.\n");
-    return(-EIO);
-  }
-
-  if ( (isp16_type=isp16_detect()) < 0 ) {
-    printk("ISP16: no cdrom interface found.\n");
-    return(-EIO);
-  }
-
-  printk(KERN_INFO "ISP16: cdrom interface (with OPTi 82C92%d chip) detected.\n",
-    (isp16_type==2) ? 9 : 8);
-
-  if ( !strcmp(isp16_cdrom_type, "Sanyo") )
-    expected_drive = (isp16_type ? ISP16_SANYO1 : ISP16_SANYO0);
-  else if ( !strcmp(isp16_cdrom_type, "Sony") )
-    expected_drive = ISP16_SONY;
-  else if ( !strcmp(isp16_cdrom_type, "Panasonic") )
-    expected_drive = (isp16_type ? ISP16_PANASONIC1 : ISP16_PANASONIC0);
-  else if ( !strcmp(isp16_cdrom_type, "Mitsumi") )
-    expected_drive = ISP16_MITSUMI;
-  else {
-    printk("ISP16: %s not supported by cdrom interface.\n", isp16_cdrom_type);
-    return(-EIO);
-  }
-
-  if ( isp16_cdi_config(isp16_cdrom_base, expected_drive,
-    isp16_cdrom_irq, isp16_cdrom_dma ) < 0) {
-    printk("ISP16: cdrom interface has not been properly configured.\n");
-    return(-EIO);
-  }
-  printk(KERN_INFO "ISP16: cdrom interface set up with io base 0x%03X, irq %d, dma %d,"
-    " type %s.\n", isp16_cdrom_base, isp16_cdrom_irq, isp16_cdrom_dma,
-    isp16_cdrom_type);
-  return(0);
+	printk(KERN_INFO
+	       "ISP16: configuration cdrom interface, version %d.%d.\n",
+	       ISP16_VERSION_MAJOR, ISP16_VERSION_MINOR);
+
+	if (!strcmp(isp16_cdrom_type, "noisp16")) {
+		printk("ISP16: no cdrom interface configured.\n");
+		return (0);
+	}
+
+	if (check_region(ISP16_IO_BASE, ISP16_IO_SIZE)) {
+		printk("ISP16: i/o ports already in use.\n");
+		return (-EIO);
+	}
+
+	if ((isp16_type = isp16_detect()) < 0) {
+		printk("ISP16: no cdrom interface found.\n");
+		return (-EIO);
+	}
+
+	printk(KERN_INFO
+	       "ISP16: cdrom interface (with OPTi 82C92%d chip) detected.\n",
+	       (isp16_type == 2) ? 9 : 8);
+
+	if (!strcmp(isp16_cdrom_type, "Sanyo"))
+		expected_drive =
+		    (isp16_type ? ISP16_SANYO1 : ISP16_SANYO0);
+	else if (!strcmp(isp16_cdrom_type, "Sony"))
+		expected_drive = ISP16_SONY;
+	else if (!strcmp(isp16_cdrom_type, "Panasonic"))
+		expected_drive =
+		    (isp16_type ? ISP16_PANASONIC1 : ISP16_PANASONIC0);
+	else if (!strcmp(isp16_cdrom_type, "Mitsumi"))
+		expected_drive = ISP16_MITSUMI;
+	else {
+		printk("ISP16: %s not supported by cdrom interface.\n",
+		       isp16_cdrom_type);
+		return (-EIO);
+	}
+
+	if (isp16_cdi_config(isp16_cdrom_base, expected_drive,
+			     isp16_cdrom_irq, isp16_cdrom_dma) < 0) {
+		printk
+		    ("ISP16: cdrom interface has not been properly configured.\n");
+		return (-EIO);
+	}
+	printk(KERN_INFO
+	       "ISP16: cdrom interface set up with io base 0x%03X, irq %d, dma %d,"
+	       " type %s.\n", isp16_cdrom_base, isp16_cdrom_irq,
+	       isp16_cdrom_dma, isp16_cdrom_type);
+	return (0);
 }
 
-static short __init 
-isp16_detect(void)
+static short __init isp16_detect(void)
 {
 
-  if ( isp16_c929__detect() >= 0 )
-    return(2);
-  else
-    return(isp16_c928__detect());
+	if (isp16_c929__detect() >= 0)
+		return (2);
+	else
+		return (isp16_c928__detect());
 }
 
-static short __init 
-isp16_c928__detect(void)
+static short __init isp16_c928__detect(void)
 {
-  u_char ctrl;
-  u_char enable_cdrom;
-  u_char io;
-  short i = -1;
-
-  isp16_ctrl = ISP16_C928__CTRL;
-  isp16_enable_port = ISP16_C928__ENABLE_PORT;
-
-  /* read' and write' are a special read and write, respectively */
-
-  /* read' ISP16_CTRL_PORT, clear last two bits and write' back the result */
-  ctrl = ISP16_IN( ISP16_CTRL_PORT ) & 0xFC;
-  ISP16_OUT( ISP16_CTRL_PORT, ctrl );
-
-  /* read' 3,4 and 5-bit from the cdrom enable port */
-  enable_cdrom = ISP16_IN( ISP16_C928__ENABLE_PORT ) & 0x38;
-
-  if ( !(enable_cdrom & 0x20) ) {  /* 5-bit not set */
-    /* read' last 2 bits of ISP16_IO_SET_PORT */
-    io = ISP16_IN( ISP16_IO_SET_PORT ) & 0x03;
-    if ( ((io&0x01)<<1) == (io&0x02) ) {  /* bits are the same */
-      if ( io == 0 ) {  /* ...the same and 0 */
-        i = 0;
-        enable_cdrom |= 0x20;
-      }
-      else {  /* ...the same and 1 */  /* my card, first time 'round */
-        i = 1;
-        enable_cdrom |= 0x28;
-      }
-      ISP16_OUT( ISP16_C928__ENABLE_PORT, enable_cdrom );
-    }
-    else {  /* bits are not the same */
-      ISP16_OUT( ISP16_CTRL_PORT, ctrl );
-      return(i); /* -> not detected: possibly incorrect conclusion */
-    }
-  }
-  else if ( enable_cdrom == 0x20 )
-    i = 0;
-  else if ( enable_cdrom == 0x28 )  /* my card, already initialised */
-    i = 1;
+	u_char ctrl;
+	u_char enable_cdrom;
+	u_char io;
+	short i = -1;
+
+	isp16_ctrl = ISP16_C928__CTRL;
+	isp16_enable_port = ISP16_C928__ENABLE_PORT;
+
+	/* read' and write' are a special read and write, respectively */
+
+	/* read' ISP16_CTRL_PORT, clear last two bits and write' back the result */
+	ctrl = ISP16_IN(ISP16_CTRL_PORT) & 0xFC;
+	ISP16_OUT(ISP16_CTRL_PORT, ctrl);
+
+	/* read' 3,4 and 5-bit from the cdrom enable port */
+	enable_cdrom = ISP16_IN(ISP16_C928__ENABLE_PORT) & 0x38;
+
+	if (!(enable_cdrom & 0x20)) {	/* 5-bit not set */
+		/* read' last 2 bits of ISP16_IO_SET_PORT */
+		io = ISP16_IN(ISP16_IO_SET_PORT) & 0x03;
+		if (((io & 0x01) << 1) == (io & 0x02)) {	/* bits are the same */
+			if (io == 0) {	/* ...the same and 0 */
+				i = 0;
+				enable_cdrom |= 0x20;
+			} else {	/* ...the same and 1 *//* my card, first time 'round */
+				i = 1;
+				enable_cdrom |= 0x28;
+			}
+			ISP16_OUT(ISP16_C928__ENABLE_PORT, enable_cdrom);
+		} else {	/* bits are not the same */
+			ISP16_OUT(ISP16_CTRL_PORT, ctrl);
+			return (i);	/* -> not detected: possibly incorrect conclusion */
+		}
+	} else if (enable_cdrom == 0x20)
+		i = 0;
+	else if (enable_cdrom == 0x28)	/* my card, already initialised */
+		i = 1;
 
-  ISP16_OUT( ISP16_CTRL_PORT, ctrl );
+	ISP16_OUT(ISP16_CTRL_PORT, ctrl);
 
-  return(i);
+	return (i);
 }
 
-static short __init 
-isp16_c929__detect(void)
+static short __init isp16_c929__detect(void)
 {
-  u_char ctrl;
-  u_char tmp;
+	u_char ctrl;
+	u_char tmp;
 
-  isp16_ctrl = ISP16_C929__CTRL;
-  isp16_enable_port = ISP16_C929__ENABLE_PORT;
+	isp16_ctrl = ISP16_C929__CTRL;
+	isp16_enable_port = ISP16_C929__ENABLE_PORT;
 
-  /* read' and write' are a special read and write, respectively */
+	/* read' and write' are a special read and write, respectively */
 
-  /* read' ISP16_CTRL_PORT and save */
-  ctrl = ISP16_IN( ISP16_CTRL_PORT );
+	/* read' ISP16_CTRL_PORT and save */
+	ctrl = ISP16_IN(ISP16_CTRL_PORT);
 
-  /* write' zero to the ctrl port and get response */
-  ISP16_OUT( ISP16_CTRL_PORT, 0 );
-  tmp = ISP16_IN( ISP16_CTRL_PORT );
+	/* write' zero to the ctrl port and get response */
+	ISP16_OUT(ISP16_CTRL_PORT, 0);
+	tmp = ISP16_IN(ISP16_CTRL_PORT);
 
-  if ( tmp != 2 )  /* isp16 with 82C929 not detected */
-    return(-1);
+	if (tmp != 2)		/* isp16 with 82C929 not detected */
+		return (-1);
 
-  /* restore ctrl port value */
-  ISP16_OUT( ISP16_CTRL_PORT, ctrl );
-  
-  return(2);
+	/* restore ctrl port value */
+	ISP16_OUT(ISP16_CTRL_PORT, ctrl);
+
+	return (2);
 }
 
-static short __init 
+static short __init
 isp16_cdi_config(int base, u_char drive_type, int irq, int dma)
 {
-  u_char base_code;
-  u_char irq_code;
-  u_char dma_code;
-  u_char i;
-
-  if ( (drive_type == ISP16_MITSUMI) && (dma != 0) )
-    printk("ISP16: Mitsumi cdrom drive has no dma support.\n");
-
-  switch (base) {
-  case 0x340: base_code = ISP16_BASE_340; break;
-  case 0x330: base_code = ISP16_BASE_330; break;
-  case 0x360: base_code = ISP16_BASE_360; break;
-  case 0x320: base_code = ISP16_BASE_320; break;
-  default:
-    printk("ISP16: base address 0x%03X not supported by cdrom interface.\n",
-      base);
-    return(-1);
-  }
-  switch (irq) {
-  case 0: irq_code = ISP16_IRQ_X; break; /* disable irq */
-  case 5: irq_code = ISP16_IRQ_5;
-          printk("ISP16: irq 5 shouldn't be used by cdrom interface,"
-            " due to possible conflicts with the sound card.\n");
-          break;
-  case 7: irq_code = ISP16_IRQ_7;
-          printk("ISP16: irq 7 shouldn't be used by cdrom interface,"
-            " due to possible conflicts with the sound card.\n");
-          break;
-  case 3: irq_code = ISP16_IRQ_3; break;
-  case 9: irq_code = ISP16_IRQ_9; break;
-  case 10: irq_code = ISP16_IRQ_10; break;
-  case 11: irq_code = ISP16_IRQ_11; break;
-  default:
-    printk("ISP16: irq %d not supported by cdrom interface.\n", irq );
-    return(-1);
-  }
-  switch (dma) {
-  case 0: dma_code = ISP16_DMA_X; break;  /* disable dma */
-  case 1: printk("ISP16: dma 1 cannot be used by cdrom interface,"
-            " due to conflict with the sound card.\n");
-          return(-1); break;
-  case 3: dma_code = ISP16_DMA_3; break;
-  case 5: dma_code = ISP16_DMA_5; break;
-  case 6: dma_code = ISP16_DMA_6; break;
-  case 7: dma_code = ISP16_DMA_7; break;
-  default:
-    printk("ISP16: dma %d not supported by cdrom interface.\n", dma);
-    return(-1);
-  }
-
-  if ( drive_type != ISP16_SONY && drive_type != ISP16_PANASONIC0 &&
-    drive_type != ISP16_PANASONIC1 && drive_type != ISP16_SANYO0 &&
-    drive_type != ISP16_SANYO1 && drive_type != ISP16_MITSUMI &&
-    drive_type != ISP16_DRIVE_X ) {
-    printk("ISP16: drive type (code 0x%02X) not supported by cdrom"
-     " interface.\n", drive_type );
-    return(-1);
-  }
-
-  /* set type of interface */
-  i = ISP16_IN(ISP16_DRIVE_SET_PORT) & ISP16_DRIVE_SET_MASK;  /* clear some bits */
-  ISP16_OUT( ISP16_DRIVE_SET_PORT, i|drive_type );
-
-  /* enable cdrom on interface with 82C929 chip */
-  if ( isp16_type > 1 )
-    ISP16_OUT( isp16_enable_port, ISP16_ENABLE_CDROM );
-
-  /* set base address, irq and dma */
-  i = ISP16_IN(ISP16_IO_SET_PORT) & ISP16_IO_SET_MASK;  /* keep some bits */
-  ISP16_OUT( ISP16_IO_SET_PORT, i|base_code|irq_code|dma_code );
+	u_char base_code;
+	u_char irq_code;
+	u_char dma_code;
+	u_char i;
+
+	if ((drive_type == ISP16_MITSUMI) && (dma != 0))
+		printk("ISP16: Mitsumi cdrom drive has no dma support.\n");
+
+	switch (base) {
+	case 0x340:
+		base_code = ISP16_BASE_340;
+		break;
+	case 0x330:
+		base_code = ISP16_BASE_330;
+		break;
+	case 0x360:
+		base_code = ISP16_BASE_360;
+		break;
+	case 0x320:
+		base_code = ISP16_BASE_320;
+		break;
+	default:
+		printk
+		    ("ISP16: base address 0x%03X not supported by cdrom interface.\n",
+		     base);
+		return (-1);
+	}
+	switch (irq) {
+	case 0:
+		irq_code = ISP16_IRQ_X;
+		break;		/* disable irq */
+	case 5:
+		irq_code = ISP16_IRQ_5;
+		printk("ISP16: irq 5 shouldn't be used by cdrom interface,"
+		       " due to possible conflicts with the sound card.\n");
+		break;
+	case 7:
+		irq_code = ISP16_IRQ_7;
+		printk("ISP16: irq 7 shouldn't be used by cdrom interface,"
+		       " due to possible conflicts with the sound card.\n");
+		break;
+	case 3:
+		irq_code = ISP16_IRQ_3;
+		break;
+	case 9:
+		irq_code = ISP16_IRQ_9;
+		break;
+	case 10:
+		irq_code = ISP16_IRQ_10;
+		break;
+	case 11:
+		irq_code = ISP16_IRQ_11;
+		break;
+	default:
+		printk("ISP16: irq %d not supported by cdrom interface.\n",
+		       irq);
+		return (-1);
+	}
+	switch (dma) {
+	case 0:
+		dma_code = ISP16_DMA_X;
+		break;		/* disable dma */
+	case 1:
+		printk("ISP16: dma 1 cannot be used by cdrom interface,"
+		       " due to conflict with the sound card.\n");
+		return (-1);
+		break;
+	case 3:
+		dma_code = ISP16_DMA_3;
+		break;
+	case 5:
+		dma_code = ISP16_DMA_5;
+		break;
+	case 6:
+		dma_code = ISP16_DMA_6;
+		break;
+	case 7:
+		dma_code = ISP16_DMA_7;
+		break;
+	default:
+		printk("ISP16: dma %d not supported by cdrom interface.\n",
+		       dma);
+		return (-1);
+	}
+
+	if (drive_type != ISP16_SONY && drive_type != ISP16_PANASONIC0 &&
+	    drive_type != ISP16_PANASONIC1 && drive_type != ISP16_SANYO0 &&
+	    drive_type != ISP16_SANYO1 && drive_type != ISP16_MITSUMI &&
+	    drive_type != ISP16_DRIVE_X) {
+		printk
+		    ("ISP16: drive type (code 0x%02X) not supported by cdrom"
+		     " interface.\n", drive_type);
+		return (-1);
+	}
+
+	/* set type of interface */
+	i = ISP16_IN(ISP16_DRIVE_SET_PORT) & ISP16_DRIVE_SET_MASK;	/* clear some bits */
+	ISP16_OUT(ISP16_DRIVE_SET_PORT, i | drive_type);
+
+	/* enable cdrom on interface with 82C929 chip */
+	if (isp16_type > 1)
+		ISP16_OUT(isp16_enable_port, ISP16_ENABLE_CDROM);
+
+	/* set base address, irq and dma */
+	i = ISP16_IN(ISP16_IO_SET_PORT) & ISP16_IO_SET_MASK;	/* keep some bits */
+	ISP16_OUT(ISP16_IO_SET_PORT, i | base_code | irq_code | dma_code);
 
-  return(0);
+	return (0);
 }
 
 void __exit isp16_exit(void)
@@ -332,4 +368,5 @@
 #endif
 module_exit(isp16_exit);
 
-
+EXPORT_NO_SYMBOLS;
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.9/linux/drivers/cdrom/mcd.c linux/drivers/cdrom/mcd.c
--- v2.4.9/linux/drivers/cdrom/mcd.c	Wed Jul 25 17:10:19 2001
+++ linux/drivers/cdrom/mcd.c	Sun Sep  9 10:43:02 2001
@@ -2,6 +2,7 @@
 	linux/kernel/blk_drv/mcd.c - Mitsumi CDROM driver
 
 	Copyright (C) 1992  Martin Harriss
+	Portions Copyright (C) 2001 Red Hat
 
 	martin@bdsi.com (no longer valid - where are you now, Martin?)
 
@@ -74,7 +75,8 @@
 			 module_init & module_exit.
 			 Torben Mathiasen <tmm@image.dk>
 		
-			 
+	September 2001 - Reformatted and cleaned up the code
+			 Alan Cox <alan@redhat.com>			 
 */
 
 #include <linux/module.h>
@@ -102,14 +104,14 @@
 #define MAJOR_NR MITSUMI_CDROM_MAJOR
 #include <linux/blk.h>
 
-#define mcd_port mcd    /* for compatible parameter passing with "insmod" */
+#define mcd_port mcd		/* for compatible parameter passing with "insmod" */
 #include "mcd.h"
 
 static int mcd_blocksizes[1];
 
 
 /* I added A flag to drop to 1x speed if too many errors 0 = 1X ; 1 = 2X */
-static int mcdDouble; 
+static int mcdDouble;
 
 /* How many sectors to hold at 1x speed counter */
 static int mcd1xhold;
@@ -117,22 +119,8 @@
 /* Is the drive connected properly and responding?? */
 static int mcdPresent;
 
-#if 0
-#define TEST1 /* <int-..> */
-#define TEST2 /* do_mcd_req */
-#define TEST3 */ /* MCD_S_state */
-#define TEST4 /* QUICK_LOOP-counter */
-#define TEST5 */ /* port(1) state */
-#endif
-
-#if 1
-#define QUICK_LOOP_DELAY udelay(45)  /* use udelay */
+#define QUICK_LOOP_DELAY udelay(45)	/* use udelay */
 #define QUICK_LOOP_COUNT 20
-#else
-#define QUICK_LOOP_DELAY
-#define QUICK_LOOP_COUNT 140 /* better wait constant time */
-#endif
-/* #define DOUBLE_QUICK_ONLY */
 
 #define CURRENT_VALID \
 (!QUEUE_EMPTY && MAJOR(CURRENT -> rq_dev) == MAJOR_NR && CURRENT -> cmd == READ \
@@ -141,32 +129,30 @@
 #define MFL_STATUSorDATA (MFL_STATUS | MFL_DATA)
 #define MCD_BUF_SIZ 16
 static volatile int mcd_transfer_is_active;
-static char mcd_buf[2048*MCD_BUF_SIZ];	/* buffer for block size conversion */
+static char mcd_buf[2048 * MCD_BUF_SIZ];	/* buffer for block size conversion */
 static volatile int mcd_buf_bn[MCD_BUF_SIZ], mcd_next_bn;
 static volatile int mcd_buf_in, mcd_buf_out = -1;
 static volatile int mcd_error;
 static int mcd_open_count;
 enum mcd_state_e {
-  MCD_S_IDLE,   /* 0 */
-  MCD_S_START,  /* 1 */
-  MCD_S_MODE, /* 2 */
-  MCD_S_READ,   /* 3 */
-  MCD_S_DATA,   /* 4 */
-  MCD_S_STOP,   /* 5 */
-  MCD_S_STOPPING /* 6 */
+	MCD_S_IDLE,		/* 0 */
+	MCD_S_START,		/* 1 */
+	MCD_S_MODE,		/* 2 */
+	MCD_S_READ,		/* 3 */
+	MCD_S_DATA,		/* 4 */
+	MCD_S_STOP,		/* 5 */
+	MCD_S_STOPPING		/* 6 */
 };
 static volatile enum mcd_state_e mcd_state = MCD_S_IDLE;
 static int mcd_mode = -1;
-static int MCMD_DATA_READ= MCMD_PLAY_READ;
+static int MCMD_DATA_READ = MCMD_PLAY_READ;
+
 #define READ_TIMEOUT 3000
-#define WORK_AROUND_MITSUMI_BUG_92
-#define WORK_AROUND_MITSUMI_BUG_93
-#ifdef WORK_AROUND_MITSUMI_BUG_93
+
 int mitsumi_bug_93_wait;
-#endif /* WORK_AROUND_MITSUMI_BUG_93 */
 
-static short mcd_port = CONFIG_MCD_BASE; /* used as "mcd" by "insmod" */
-static int   mcd_irq  = CONFIG_MCD_IRQ; /* must directly follow mcd_port */
+static short mcd_port = CONFIG_MCD_BASE;	/* used as "mcd" by "insmod" */
+static int mcd_irq = CONFIG_MCD_IRQ;	/* must directly follow mcd_port */
 MODULE_PARM(mcd, "1-2i");
 
 static int McdTimeout, McdTries;
@@ -195,75 +181,58 @@
 static int GetDiskInfo(void);
 static int GetToc(void);
 static int getValue(unsigned char *result);
-static int mcd_open(struct cdrom_device_info * cdi, int purpose);
-static void mcd_release(struct cdrom_device_info * cdi);
-static int mcd_media_changed(struct cdrom_device_info * cdi, int disc_nr);
-static int mcd_tray_move(struct cdrom_device_info * cdi, int position);
-int mcd_audio_ioctl(struct cdrom_device_info * cdi, unsigned int cmd,
-                      void * arg);
-int mcd_drive_status(struct cdrom_device_info * cdi, int slot_nr);
+static int mcd_open(struct cdrom_device_info *cdi, int purpose);
+static void mcd_release(struct cdrom_device_info *cdi);
+static int mcd_media_changed(struct cdrom_device_info *cdi, int disc_nr);
+static int mcd_tray_move(struct cdrom_device_info *cdi, int position);
+int mcd_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
+		    void *arg);
+int mcd_drive_status(struct cdrom_device_info *cdi, int slot_nr);
 
 static struct timer_list mcd_timer;
 
 static struct cdrom_device_ops mcd_dops = {
-	open:			mcd_open,
-	release:		mcd_release,
-	drive_status:		mcd_drive_status,
-	media_changed:		mcd_media_changed,
-	tray_move:		mcd_tray_move,
-	audio_ioctl:		mcd_audio_ioctl,
-	capability:		CDC_OPEN_TRAY | CDC_MEDIA_CHANGED |
-				CDC_PLAY_AUDIO | CDC_DRIVE_STATUS,
+	open:mcd_open,
+	release:mcd_release,
+	drive_status:mcd_drive_status,
+	media_changed:mcd_media_changed,
+	tray_move:mcd_tray_move,
+	audio_ioctl:mcd_audio_ioctl,
+	capability:CDC_OPEN_TRAY | CDC_MEDIA_CHANGED |
+	    CDC_PLAY_AUDIO | CDC_DRIVE_STATUS,
 };
 
 static struct cdrom_device_info mcd_info = {
-	ops:			&mcd_dops,
-	speed:			2,
-	capacity:		1,
-	name:			"mcd",
+	ops:&mcd_dops,
+	speed:2,
+	capacity:1,
+	name:"mcd",
 };
 
 #ifndef MODULE
 static int __init mcd_setup(char *str)
 {
-   int ints[9];
-   
-   (void)get_options(str, ARRAY_SIZE(ints), ints);
-   
-   if (ints[0] > 0)
-      mcd_port = ints[1];
-   if (ints[0] > 1)      
-      mcd_irq  = ints[2];
-#ifdef WORK_AROUND_MITSUMI_BUG_93
-   if (ints[0] > 2)
-      mitsumi_bug_93_wait = ints[3];
-#endif /* WORK_AROUND_MITSUMI_BUG_93 */
+	int ints[9];
+
+	(void) get_options(str, ARRAY_SIZE(ints), ints);
 
- return 1;
+	if (ints[0] > 0)
+		mcd_port = ints[1];
+	if (ints[0] > 1)
+		mcd_irq = ints[2];
+	if (ints[0] > 2)
+		mitsumi_bug_93_wait = ints[3];
+
+	return 1;
 }
 
 __setup("mcd=", mcd_setup);
 
-#endif /* MODULE */ 
+#endif				/* MODULE */
 
-static int mcd_media_changed(struct cdrom_device_info * cdi, int disc_nr)
+static int mcd_media_changed(struct cdrom_device_info *cdi, int disc_nr)
 {
-   int retval;
-
-
-#if 1	 /* the below is not reliable */
-   return 0;
-#endif  
-
-   if (cdi->dev) {
-      printk("mcd: Mitsumi CD-ROM request error: invalid device.\n");
-      return 0;
-   }
-
-   retval = mcdDiskChanged;
-   mcdDiskChanged = 0;
-
-   return retval;
+	return 0;
 }
 
 
@@ -272,18 +241,17 @@
  * because it calls 'getMcdStatus' which sleeps.
  */
 
-static int
-statusCmd(void)
+static int statusCmd(void)
 {
 	int st = -1, retry;
 
-	for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++)
-	{
-		outb(MCMD_GET_STATUS, MCDPORT(0));    /* send get-status cmd */
+	for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++) {
+		/* send get-status cmd */
+		outb(MCMD_GET_STATUS, MCDPORT(0));
 
 		st = getMcdStatus(MCD_STATUS_DELAY);
-		if (st != -1) 
-        		break;
+		if (st != -1)
+			break;
 	}
 
 	return st;
@@ -294,13 +262,11 @@
  * Send a 'Play' command and get the status.  Use only from the top half.
  */
 
-static int
-mcdPlay(struct mcd_Play_msf *arg)
+static int mcdPlay(struct mcd_Play_msf *arg)
 {
 	int retry, st = -1;
 
-	for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++)
-	{
+	for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++) {
 		sendMcdCmd(MCMD_PLAY_READ, arg);
 		st = getMcdStatus(2 * MCD_STATUS_DELAY);
 		if (st != -1)
@@ -311,45 +277,39 @@
 }
 
 
-static int 
-mcd_tray_move(struct cdrom_device_info * cdi, int position)
+static int mcd_tray_move(struct cdrom_device_info *cdi, int position)
 {
 	int i;
 	if (position) {
-	/*  Eject */
-       		/* all drives can at least stop! */
+		/*  Eject */
+		/* all drives can at least stop! */
 		if (audioStatus == CDROM_AUDIO_PLAY) {
-	  	outb(MCMD_STOP, MCDPORT(0));
-	  	i = getMcdStatus(MCD_STATUS_DELAY);
+			outb(MCMD_STOP, MCDPORT(0));
+			i = getMcdStatus(MCD_STATUS_DELAY);
 		}
 
-                audioStatus = CDROM_AUDIO_NO_STATUS;
+		audioStatus = CDROM_AUDIO_NO_STATUS;
 
-                outb(MCMD_EJECT, MCDPORT(0));
-                /*
-                 * the status (i) shows failure on all but the FX drives.
-                 * But nothing we can do about that in software!
-                 * So just read the status and forget it. - Jon.
-                 */
-                i = getMcdStatus(MCD_STATUS_DELAY);
-                return 0;
-	}
-	else 
+		outb(MCMD_EJECT, MCDPORT(0));
+		/*
+		 * the status (i) shows failure on all but the FX drives.
+		 * But nothing we can do about that in software!
+		 * So just read the status and forget it. - Jon.
+		 */
+		i = getMcdStatus(MCD_STATUS_DELAY);
+		return 0;
+	} else
 		return -EINVAL;
 }
 
-long
-msf2hsg(struct msf *mp)
+long msf2hsg(struct msf *mp)
 {
-	return bcd2bin(mp -> frame)
-		+ bcd2bin(mp -> sec) * 75
-		+ bcd2bin(mp -> min) * 4500
-		- 150;
+	return bcd2bin(mp->frame) + bcd2bin(mp->sec) * 75 + bcd2bin(mp->min) * 4500 - 150;
 }
 
 
-int mcd_audio_ioctl(struct cdrom_device_info * cdi, unsigned int cmd,
-                      void * arg)
+int mcd_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
+		    void *arg)
 {
 	int i, st;
 	struct mcd_Toc qInfo;
@@ -365,24 +325,22 @@
 	if (st < 0)
 		return -EIO;
 
-	if (!tocUpToDate)
-	{
+	if (!tocUpToDate) {
 		i = updateToc();
-		if (i < 0) 
+		if (i < 0)
 			return i;	/* error reading TOC */
 	}
 
-	switch (cmd)
-	{
-	case CDROMSTART:     /* Spin up the drive */
+	switch (cmd) {
+	case CDROMSTART:	/* Spin up the drive */
 		/* Don't think we can do this.  Even if we could,
- 		 * I think the drive times out and stops after a while
+		 * I think the drive times out and stops after a while
 		 * anyway.  For now, ignore it.
 		 */
 
 		return 0;
 
-	case CDROMSTOP:      /* Spin down the drive */
+	case CDROMSTOP:	/* Spin down the drive */
 		outb(MCMD_STOP, MCDPORT(0));
 		i = getMcdStatus(MCD_STATUS_DELAY);
 
@@ -391,15 +349,14 @@
 		audioStatus = CDROM_AUDIO_NO_STATUS;
 		return 0;
 
-	case CDROMPAUSE:     /* Pause the drive */
+	case CDROMPAUSE:	/* Pause the drive */
 		if (audioStatus != CDROM_AUDIO_PLAY)
 			return -EINVAL;
 
 		outb(MCMD_STOP, MCDPORT(0));
 		i = getMcdStatus(MCD_STATUS_DELAY);
 
-		if (GetQChannelInfo(&qInfo) < 0)
-		{
+		if (GetQChannelInfo(&qInfo) < 0) {
 			/* didn't get q channel info */
 
 			audioStatus = CDROM_AUDIO_NO_STATUS;
@@ -411,15 +368,14 @@
 		audioStatus = CDROM_AUDIO_PAUSED;
 		return 0;
 
-	case CDROMRESUME:    /* Play it again, Sam */
+	case CDROMRESUME:	/* Play it again, Sam */
 		if (audioStatus != CDROM_AUDIO_PAUSED)
 			return -EINVAL;
 
 		/* restart the drive at the saved position. */
 
 		i = mcdPlay(&mcd_Play);
-		if (i < 0)
-		{
+		if (i < 0) {
 			audioStatus = CDROM_AUDIO_ERROR;
 			return -EIO;
 		}
@@ -427,14 +383,13 @@
 		audioStatus = CDROM_AUDIO_PLAY;
 		return 0;
 
-	case CDROMPLAYTRKIND:     /* Play a track.  This currently ignores index. */
+	case CDROMPLAYTRKIND:	/* Play a track.  This currently ignores index. */
 
-		ti=(struct cdrom_ti *) arg;
+		ti = (struct cdrom_ti *) arg;
 
 		if (ti->cdti_trk0 < DiskInfo.first
-			|| ti->cdti_trk0 > DiskInfo.last
-			|| ti->cdti_trk1 < ti->cdti_trk0)
-		{
+		    || ti->cdti_trk0 > DiskInfo.last
+		    || ti->cdti_trk1 < ti->cdti_trk0) {
 			return -EINVAL;
 		}
 
@@ -445,14 +400,14 @@
 		mcd_Play.end = Toc[ti->cdti_trk1 + 1].diskTime;
 
 #ifdef MCD_DEBUG
-printk("play: %02x:%02x.%02x to %02x:%02x.%02x\n",
-	mcd_Play.start.min, mcd_Play.start.sec, mcd_Play.start.frame,
-	mcd_Play.end.min, mcd_Play.end.sec, mcd_Play.end.frame);
+		printk("play: %02x:%02x.%02x to %02x:%02x.%02x\n",
+		       mcd_Play.start.min, mcd_Play.start.sec,
+		       mcd_Play.start.frame, mcd_Play.end.min,
+		       mcd_Play.end.sec, mcd_Play.end.frame);
 #endif
 
 		i = mcdPlay(&mcd_Play);
-		if (i < 0)
-		{
+		if (i < 0) {
 			audioStatus = CDROM_AUDIO_ERROR;
 			return -EIO;
 		}
@@ -460,15 +415,15 @@
 		audioStatus = CDROM_AUDIO_PLAY;
 		return 0;
 
-	case CDROMPLAYMSF:   /* Play starting at the given MSF address. */
+	case CDROMPLAYMSF:	/* Play starting at the given MSF address. */
 
 		if (audioStatus == CDROM_AUDIO_PLAY) {
-		  outb(MCMD_STOP, MCDPORT(0));
-		  i = getMcdStatus(MCD_STATUS_DELAY);
-		  audioStatus = CDROM_AUDIO_NO_STATUS;
+			outb(MCMD_STOP, MCDPORT(0));
+			i = getMcdStatus(MCD_STATUS_DELAY);
+			audioStatus = CDROM_AUDIO_NO_STATUS;
 		}
 
-		msf=(struct cdrom_msf *) arg;
+		msf = (struct cdrom_msf *) arg;
 
 		/* convert to bcd */
 
@@ -487,14 +442,14 @@
 		mcd_Play.end.frame = msf->cdmsf_frame1;
 
 #ifdef MCD_DEBUG
-printk("play: %02x:%02x.%02x to %02x:%02x.%02x\n",
-mcd_Play.start.min, mcd_Play.start.sec, mcd_Play.start.frame,
-mcd_Play.end.min, mcd_Play.end.sec, mcd_Play.end.frame);
+		printk("play: %02x:%02x.%02x to %02x:%02x.%02x\n",
+		       mcd_Play.start.min, mcd_Play.start.sec,
+		       mcd_Play.start.frame, mcd_Play.end.min,
+		       mcd_Play.end.sec, mcd_Play.end.frame);
 #endif
 
 		i = mcdPlay(&mcd_Play);
-		if (i < 0)
-		{
+		if (i < 0) {
 			audioStatus = CDROM_AUDIO_ERROR;
 			return -EIO;
 		}
@@ -502,35 +457,37 @@
 		audioStatus = CDROM_AUDIO_PLAY;
 		return 0;
 
-	case CDROMREADTOCHDR:        /* Read the table of contents header */
-	        tocHdr=(struct cdrom_tochdr *) arg; 
+	case CDROMREADTOCHDR:	/* Read the table of contents header */
+		tocHdr = (struct cdrom_tochdr *) arg;
 		tocHdr->cdth_trk0 = DiskInfo.first;
 		tocHdr->cdth_trk1 = DiskInfo.last;
 		return 0;
 
-	case CDROMREADTOCENTRY:      /* Read an entry in the table of contents */
-		entry=(struct cdrom_tocentry *) arg;
+	case CDROMREADTOCENTRY:	/* Read an entry in the table of contents */
+		entry = (struct cdrom_tocentry *) arg;
 		if (entry->cdte_track == CDROM_LEADOUT)
 			tocPtr = &Toc[DiskInfo.last - DiskInfo.first + 1];
 
 		else if (entry->cdte_track > DiskInfo.last
-				|| entry->cdte_track < DiskInfo.first)
+			 || entry->cdte_track < DiskInfo.first)
 			return -EINVAL;
 
 		else
 			tocPtr = &Toc[entry->cdte_track];
 
-		entry->cdte_adr = tocPtr -> ctrl_addr;
-		entry->cdte_ctrl = tocPtr -> ctrl_addr >> 4;
+		entry->cdte_adr = tocPtr->ctrl_addr;
+		entry->cdte_ctrl = tocPtr->ctrl_addr >> 4;
 
 		if (entry->cdte_format == CDROM_LBA)
-			entry->cdte_addr.lba = msf2hsg(&tocPtr -> diskTime);
+			entry->cdte_addr.lba = msf2hsg(&tocPtr->diskTime);
 
-		else if (entry->cdte_format == CDROM_MSF)
-		{
-			entry->cdte_addr.msf.minute = bcd2bin(tocPtr -> diskTime.min);
-			entry->cdte_addr.msf.second = bcd2bin(tocPtr -> diskTime.sec);
-			entry->cdte_addr.msf.frame = bcd2bin(tocPtr -> diskTime.frame);
+		else if (entry->cdte_format == CDROM_MSF) {
+			entry->cdte_addr.msf.minute =
+			    bcd2bin(tocPtr->diskTime.min);
+			entry->cdte_addr.msf.second =
+			    bcd2bin(tocPtr->diskTime.sec);
+			entry->cdte_addr.msf.frame =
+			    bcd2bin(tocPtr->diskTime.frame);
 		}
 
 		else
@@ -538,9 +495,9 @@
 
 		return 0;
 
-	case CDROMSUBCHNL:   /* Get subchannel info */
+	case CDROMSUBCHNL:	/* Get subchannel info */
 
-                subchnl=(struct cdrom_subchnl *) arg;
+		subchnl = (struct cdrom_subchnl *) arg;
 		if (GetQChannelInfo(&qInfo) < 0)
 			return -EIO;
 
@@ -551,14 +508,14 @@
 		subchnl->cdsc_ind = bcd2bin(qInfo.pointIndex);
 		subchnl->cdsc_absaddr.msf.minute = bcd2bin(qInfo.diskTime.min);
 		subchnl->cdsc_absaddr.msf.second = bcd2bin(qInfo.diskTime.sec);
-		subchnl->cdsc_absaddr.msf.frame = bcd2bin(qInfo.diskTime.frame);
+		subchnl->cdsc_absaddr.msf.frame  = bcd2bin(qInfo.diskTime.frame);
 		subchnl->cdsc_reladdr.msf.minute = bcd2bin(qInfo.trackTime.min);
 		subchnl->cdsc_reladdr.msf.second = bcd2bin(qInfo.trackTime.sec);
-		subchnl->cdsc_reladdr.msf.frame = bcd2bin(qInfo.trackTime.frame);
-		return(0);
+		subchnl->cdsc_reladdr.msf.frame  = bcd2bin(qInfo.trackTime.frame);
+		return (0);
 
-	case CDROMVOLCTRL:   /* Volume control */
-		volctrl=(struct cdrom_volctrl *) arg;
+	case CDROMVOLCTRL:	/* Volume control */
+		volctrl = (struct cdrom_volctrl *) arg;
 		outb(MCMD_SET_VOLUME, MCDPORT(0));
 		outb(volctrl->channel0, MCDPORT(0));
 		outb(255, MCDPORT(0));
@@ -590,37 +547,37 @@
  * When Linux gets variable block sizes this will probably go away.
  */
 
-static void
-mcd_transfer(void)
+static void mcd_transfer(void)
 {
-  if (CURRENT_VALID) {
-    while (CURRENT -> nr_sectors) {
-      int bn = CURRENT -> sector / 4;
-      int i;
-      for (i = 0; i < MCD_BUF_SIZ && mcd_buf_bn[i] != bn; ++i)
-	;
-      if (i < MCD_BUF_SIZ) {
-	int offs = (i * 4 + (CURRENT -> sector & 3)) * 512;
-	int nr_sectors = 4 - (CURRENT -> sector & 3);
-	if (mcd_buf_out != i) {
-	  mcd_buf_out = i;
-	  if (mcd_buf_bn[i] != bn) {
-	    mcd_buf_out = -1;
-	    continue;
-	  }
-	}
-	if (nr_sectors > CURRENT -> nr_sectors)
-	  nr_sectors = CURRENT -> nr_sectors;
-	memcpy(CURRENT -> buffer, mcd_buf + offs, nr_sectors * 512);
-	CURRENT -> nr_sectors -= nr_sectors;
-	CURRENT -> sector += nr_sectors;
-	CURRENT -> buffer += nr_sectors * 512;
-      } else {
-	mcd_buf_out = -1;
-	break;
-      }
-    }
-  }
+	if (CURRENT_VALID) {
+		while (CURRENT->nr_sectors) {
+			int bn = CURRENT->sector / 4;
+			int i;
+			for (i = 0; i < MCD_BUF_SIZ && mcd_buf_bn[i] != bn;
+			     ++i);
+			if (i < MCD_BUF_SIZ) {
+				int offs =(i * 4 + (CURRENT->sector & 3)) * 512;
+				int nr_sectors = 4 - (CURRENT->sector & 3);
+				if (mcd_buf_out != i) {
+					mcd_buf_out = i;
+					if (mcd_buf_bn[i] != bn) {
+						mcd_buf_out = -1;
+						continue;
+					}
+				}
+				if (nr_sectors > CURRENT->nr_sectors)
+					nr_sectors = CURRENT->nr_sectors;
+				memcpy(CURRENT->buffer, mcd_buf + offs,
+				       nr_sectors * 512);
+				CURRENT->nr_sectors -= nr_sectors;
+				CURRENT->sector += nr_sectors;
+				CURRENT->buffer += nr_sectors * 512;
+			} else {
+				mcd_buf_out = -1;
+				break;
+			}
+		}
+	}
 }
 
 
@@ -629,500 +586,423 @@
  * Just take the interrupt and clear out the status reg.
  */
 
-static void
-mcd_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+static void mcd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	int st;
 
 	st = inb(MCDPORT(1)) & 0xFF;
-#ifdef TEST1
-		printk("<int1-%02X>", st);
-#endif
-	if (!(st & MFL_STATUS))
-	{
+	test1(printk("<int1-%02X>", st));
+	if (!(st & MFL_STATUS)) {
 		st = inb(MCDPORT(0)) & 0xFF;
-#ifdef TEST1
-		printk("<int0-%02X>", st);
-#endif
+		test1(printk("<int0-%02X>", st));
 		if ((st & 0xFF) != 0xFF)
-		  mcd_error = st ? st & 0xFF : -1;
+			mcd_error = st ? st & 0xFF : -1;
 	}
 }
 
 
-static void
-do_mcd_request(request_queue_t * q)
+static void do_mcd_request(request_queue_t * q)
 {
-#ifdef TEST2
-  printk(" do_mcd_request(%ld+%ld)\n", CURRENT -> sector, CURRENT -> nr_sectors);
-#endif
-  mcd_transfer_is_active = 1;
-  while (CURRENT_VALID) {
-    if (CURRENT->bh) {
-      if (!buffer_locked(CURRENT->bh))
-	panic(DEVICE_NAME ": block not locked");
-    }
-    mcd_transfer();
-    if (CURRENT -> nr_sectors == 0) {
-      end_request(1);
-    } else {
-      mcd_buf_out = -1;		/* Want to read a block not in buffer */
-      if (mcd_state == MCD_S_IDLE) {
-	if (!tocUpToDate) {
-	  if (updateToc() < 0) {
-	    while (CURRENT_VALID)
-	      end_request(0);
-	    break;
-	  }
-	}
-	mcd_state = MCD_S_START;
-	McdTries = 5;
-	SET_TIMER(mcd_poll, 1);
-      }
-      break;
-    }
-  }
-  mcd_transfer_is_active = 0;
-#ifdef TEST2
-  printk(" do_mcd_request ends\n");
-#endif
+	test2(printk(" do_mcd_request(%ld+%ld)\n", CURRENT->sector,
+	       CURRENT->nr_sectors));
+
+		mcd_transfer_is_active = 1;
+	while (CURRENT_VALID) {
+		if (CURRENT->bh) {
+			if (!buffer_locked(CURRENT->bh))
+				panic(DEVICE_NAME ": block not locked");
+		}
+		mcd_transfer();
+		if (CURRENT->nr_sectors == 0) {
+			end_request(1);
+		} else {
+			mcd_buf_out = -1;	/* Want to read a block not in buffer */
+			if (mcd_state == MCD_S_IDLE) {
+				if (!tocUpToDate) {
+					if (updateToc() < 0) {
+						while (CURRENT_VALID)
+							end_request(0);
+						break;
+					}
+				}
+				mcd_state = MCD_S_START;
+				McdTries = 5;
+				mcd_timer.function = mcd_poll;
+				mod_timer(&mcd_timer, jiffies + 1);
+			}
+			break;
+		}
+	}
+	mcd_transfer_is_active = 0;
+	test2(printk(" do_mcd_request ends\n"));
 }
 
 
 
-static void
-mcd_poll(unsigned long dummy)
+static void mcd_poll(unsigned long dummy)
 {
-  int st;
+	int st;
 
 
-  if (mcd_error) 
-  {
-    if (mcd_error & 0xA5) 
-    {
-      printk("mcd: I/O error 0x%02x", mcd_error);
-      if (mcd_error & 0x80)
-	printk(" (Door open)");
-      if (mcd_error & 0x20)
-	printk(" (Disk changed)");
-      if (mcd_error & 0x04)
-	{
-	printk(" (Read error)"); /* Bitch about the problem. */
-	
-	/* Time to get fancy! If at 2x speed and 1 error, drop to 1x speed! */
-	/* Interesting how it STAYS at MCD_RETRY_ATTEMPTS on first error! */
-	/* But I find that rather HANDY!!! */
-	/* Neat! it REALLY WORKS on those LOW QUALITY CD's!!! Smile! :) */
-	/* AJK [06/17/95] */
-	
-	/* Slap the CD down to single speed! */
-	if (mcdDouble == 1 && McdTries == MCD_RETRY_ATTEMPTS && MCMD_DATA_READ == MCMD_2X_READ) 
-		{
-		MCMD_DATA_READ = MCMD_PLAY_READ; /* Uhhh, Ummmm, muhuh-huh! */
-		mcd1xhold = SINGLE_HOLD_SECTORS; /* Hey Beavis! */
-		printk(" Speed now 1x");	 /* Pull my finger! */
+	if (mcd_error) {
+		if (mcd_error & 0xA5) {
+			printk(KERN_ERR "mcd: I/O error 0x%02x", mcd_error);
+			if (mcd_error & 0x80)
+				printk(" (Door open)");
+			if (mcd_error & 0x20)
+				printk(" (Disk changed)");
+			if (mcd_error & 0x04) {
+				printk(" (Read error)");	/* Bitch about the problem. */
+
+				/* Time to get fancy! If at 2x speed and 1 error, drop to 1x speed! */
+				/* Interesting how it STAYS at MCD_RETRY_ATTEMPTS on first error! */
+				/* But I find that rather HANDY!!! */
+				/* Neat! it REALLY WORKS on those LOW QUALITY CD's!!! Smile! :) */
+				/* AJK [06/17/95] */
+
+				/* Slap the CD down to single speed! */
+				if (mcdDouble == 1
+				    && McdTries == MCD_RETRY_ATTEMPTS
+				    && MCMD_DATA_READ == MCMD_2X_READ) {
+					MCMD_DATA_READ = MCMD_PLAY_READ;	/* Uhhh, Ummmm, muhuh-huh! */
+					mcd1xhold = SINGLE_HOLD_SECTORS;	/* Hey Beavis! */
+					printk(" Speed now 1x");	/* Pull my finger! */
+				}
+			}
+			printk("\n");
+			mcd_invalidate_buffers();
+#ifdef WARN_IF_READ_FAILURE
+			if (McdTries == MCD_RETRY_ATTEMPTS)
+				printk(KERN_ERR "mcd: read of block %d failed\n",
+				       mcd_next_bn);
+#endif
+			if (!McdTries--) {
+				/* Nuts! This cd is ready for recycling! */
+				/* When WAS the last time YOU cleaned it CORRECTLY?! */
+				printk(KERN_ERR "mcd: read of block %d failed, giving up\n",
+				     mcd_next_bn);
+				if (mcd_transfer_is_active) {
+					McdTries = 0;
+					goto ret;
+				}
+				if (CURRENT_VALID)
+					end_request(0);
+				McdTries = MCD_RETRY_ATTEMPTS;
+			}
 		}
+		mcd_error = 0;
+		mcd_state = MCD_S_STOP;
 	}
-      printk("\n");
-      mcd_invalidate_buffers();
-#ifdef WARN_IF_READ_FAILURE
-      if (McdTries == MCD_RETRY_ATTEMPTS)
-	printk("mcd: read of block %d failed\n", mcd_next_bn);
-#endif
-      if (!McdTries--) 
-        {
-	/* Nuts! This cd is ready for recycling! */
-	/* When WAS the last time YOU cleaned it CORRECTLY?! */
-	printk("mcd: read of block %d failed, giving up\n", mcd_next_bn);
-	if (mcd_transfer_is_active) 
-	{
-	  McdTries = 0;
-	  goto ret;
-	}
-	if (CURRENT_VALID)
-	  end_request(0);
-	McdTries = MCD_RETRY_ATTEMPTS;
-      }
-    }
-    mcd_error = 0;
-    mcd_state = MCD_S_STOP;
-  }
 	/* Switch back to Double speed if enough GOOD sectors were read! */
-	
-	/* Are we a double speed with a crappy CD?! */
-    if (mcdDouble == 1 && McdTries == MCD_RETRY_ATTEMPTS && MCMD_DATA_READ == MCMD_PLAY_READ)
-    	{
-	/* We ARE a double speed and we ARE bitching! */
-	if (mcd1xhold == 0) /* Okay, Like are we STILL at single speed? */
-		{ /* We need to switch back to double speed now... */
-		MCMD_DATA_READ = MCMD_2X_READ; /* Uhhh... BACK You GO! */
-		printk("mcd: Switching back to 2X speed!\n"); /* Tell 'em! */
-		}
-	else mcd1xhold--; /* No?! Count down the good reads some more... */
-				/* and try, try again! */
-    	}
-
-
-
- immediately:
-  switch (mcd_state) {
-
 
+	/* Are we a double speed with a crappy CD?! */
+	if (mcdDouble == 1 && McdTries == MCD_RETRY_ATTEMPTS
+	    && MCMD_DATA_READ == MCMD_PLAY_READ) {
+		/* We ARE a double speed and we ARE bitching! */
+		if (mcd1xhold == 0) {	/* Okay, Like are we STILL at single speed? *//* We need to switch back to double speed now... */
+			MCMD_DATA_READ = MCMD_2X_READ;	/* Uhhh... BACK You GO! */
+			printk(KERN_INFO "mcd: Switching back to 2X speed!\n");	/* Tell 'em! */
+		} else
+			mcd1xhold--;	/* No?! Count down the good reads some more... */
+		/* and try, try again! */
+	}
+
+immediately:
+	switch (mcd_state) {
+	case MCD_S_IDLE:
+		test3(printk("MCD_S_IDLE\n"));
+		goto out;
+
+	case MCD_S_START:
+		test3(printk("MCD_S_START\n"));
+		outb(MCMD_GET_STATUS, MCDPORT(0));
+		mcd_state = mcd_mode == 1 ? MCD_S_READ : MCD_S_MODE;
+		McdTimeout = 3000;
+		break;
+
+	case MCD_S_MODE:
+		test3(printk("MCD_S_MODE\n"));
+		if ((st = mcdStatus()) != -1) {
+			if (st & MST_DSK_CHG) {
+				mcdDiskChanged = 1;
+				tocUpToDate = 0;
+				mcd_invalidate_buffers();
+			}
 
-  case MCD_S_IDLE:
-#ifdef TEST3
-    printk("MCD_S_IDLE\n");
-#endif
-    goto out;
-
-
-
-  case MCD_S_START:
-#ifdef TEST3
-    printk("MCD_S_START\n");
-#endif
-
-    outb(MCMD_GET_STATUS, MCDPORT(0));
-    mcd_state = mcd_mode == 1 ? MCD_S_READ : MCD_S_MODE;
-    McdTimeout = 3000;
-    break;
-
-
-
-  case MCD_S_MODE:
-#ifdef TEST3
-    printk("MCD_S_MODE\n");
-#endif
-
-    if ((st = mcdStatus()) != -1) {
-
-      if (st & MST_DSK_CHG) {
-	mcdDiskChanged = 1;
-	tocUpToDate = 0;
-	mcd_invalidate_buffers();
-      }
-
-    set_mode_immediately:
-
-      if ((st & MST_DOOR_OPEN) || !(st & MST_READY)) {
-	mcdDiskChanged = 1;
-	tocUpToDate = 0;
-	if (mcd_transfer_is_active) {
-	  mcd_state = MCD_S_START;
-	  goto immediately;
-	}
-	printk((st & MST_DOOR_OPEN) ? "mcd: door open\n" : "mcd: disk removed\n");
-	mcd_state = MCD_S_IDLE;
-	while (CURRENT_VALID)
-	  end_request(0);
-	goto out;
-      }
-
-      outb(MCMD_SET_MODE, MCDPORT(0));
-      outb(1, MCDPORT(0));
-      mcd_mode = 1;
-      mcd_state = MCD_S_READ;
-      McdTimeout = 3000;
-
-    }
-    break;
-
+set_mode_immediately:
+			if ((st & MST_DOOR_OPEN) || !(st & MST_READY)) {
+				mcdDiskChanged = 1;
+				tocUpToDate = 0;
+				if (mcd_transfer_is_active) {
+					mcd_state = MCD_S_START;
+					goto immediately;
+				}
+				printk(KERN_INFO);
+				printk((st & MST_DOOR_OPEN) ?
+				       "mcd: door open\n" :
+				       "mcd: disk removed\n");
+				mcd_state = MCD_S_IDLE;
+				while (CURRENT_VALID)
+					end_request(0);
+				goto out;
+			}
+			outb(MCMD_SET_MODE, MCDPORT(0));
+			outb(1, MCDPORT(0));
+			mcd_mode = 1;
+			mcd_state = MCD_S_READ;
+			McdTimeout = 3000;
+		}
+		break;
 
+	case MCD_S_READ:
+		test3(printk("MCD_S_READ\n"));
+		if ((st = mcdStatus()) != -1) {
+			if (st & MST_DSK_CHG) {
+				mcdDiskChanged = 1;
+				tocUpToDate = 0;
+				mcd_invalidate_buffers();
+			}
 
-  case MCD_S_READ:
-#ifdef TEST3
-    printk("MCD_S_READ\n");
-#endif
+read_immediately:
+			if ((st & MST_DOOR_OPEN) || !(st & MST_READY)) {
+				mcdDiskChanged = 1;
+				tocUpToDate = 0;
+				if (mcd_transfer_is_active) {
+					mcd_state = MCD_S_START;
+					goto immediately;
+				}
+				printk(KERN_INFO);
+				printk((st & MST_DOOR_OPEN) ?
+				       "mcd: door open\n" :
+				       "mcd: disk removed\n");
+				mcd_state = MCD_S_IDLE;
+				while (CURRENT_VALID)
+					end_request(0);
+				goto out;
+			}
 
-    if ((st = mcdStatus()) != -1) {
+			if (CURRENT_VALID) {
+				struct mcd_Play_msf msf;
+				mcd_next_bn = CURRENT->sector / 4;
+				hsg2msf(mcd_next_bn, &msf.start);
+				msf.end.min = ~0;
+				msf.end.sec = ~0;
+				msf.end.frame = ~0;
+				sendMcdCmd(MCMD_DATA_READ, &msf);
+				mcd_state = MCD_S_DATA;
+				McdTimeout = READ_TIMEOUT;
+			} else {
+				mcd_state = MCD_S_STOP;
+				goto immediately;
+			}
 
-      if (st & MST_DSK_CHG) {
-	mcdDiskChanged = 1;
-	tocUpToDate = 0;
-	mcd_invalidate_buffers();
-      }
+		}
+		break;
 
-    read_immediately:
+	case MCD_S_DATA:
+		test3(printk("MCD_S_DATA\n"));
+		st = inb(MCDPORT(1)) & (MFL_STATUSorDATA);
+data_immediately:
+		test5(printk("Status %02x\n", st))
+		switch (st) {
+		case MFL_DATA:
+#ifdef WARN_IF_READ_FAILURE
+			if (McdTries == 5)
+				printk(KERN_WARNING "mcd: read of block %d failed\n",
+				       mcd_next_bn);
+#endif
+			if (!McdTries--) {
+				printk(KERN_ERR "mcd: read of block %d failed, giving up\n", mcd_next_bn);
+				if (mcd_transfer_is_active) {
+					McdTries = 0;
+					break;
+				}
+				if (CURRENT_VALID)
+					end_request(0);
+				McdTries = 5;
+			}
+			mcd_state = MCD_S_START;
+			McdTimeout = READ_TIMEOUT;
+			goto immediately;
 
-      if ((st & MST_DOOR_OPEN) || !(st & MST_READY)) {
-	mcdDiskChanged = 1;
-	tocUpToDate = 0;
-	if (mcd_transfer_is_active) {
-	  mcd_state = MCD_S_START;
-	  goto immediately;
-	}
-	printk((st & MST_DOOR_OPEN) ? "mcd: door open\n" : "mcd: disk removed\n");
-	mcd_state = MCD_S_IDLE;
-	while (CURRENT_VALID)
-	  end_request(0);
-	goto out;
-      }
-
-      if (CURRENT_VALID) {
-	struct mcd_Play_msf msf;
-	mcd_next_bn = CURRENT -> sector / 4;
-	hsg2msf(mcd_next_bn, &msf.start);
-	msf.end.min = ~0;
-	msf.end.sec = ~0;
-	msf.end.frame = ~0;
-	sendMcdCmd(MCMD_DATA_READ, &msf);
-	mcd_state = MCD_S_DATA;
-	McdTimeout = READ_TIMEOUT;
-      } else {
-	mcd_state = MCD_S_STOP;
-	goto immediately;
-      }
-
-    }
-    break;
-
-
-  case MCD_S_DATA:
-#ifdef TEST3
-    printk("MCD_S_DATA\n");
-#endif
+		case MFL_STATUSorDATA:
+			break;
 
-    st = inb(MCDPORT(1)) & (MFL_STATUSorDATA);
-  data_immediately:
-#ifdef TEST5
-    printk("Status %02x\n",st);
-#endif
-    switch (st) {
+		default:
+			McdTries = 5;
+			if (!CURRENT_VALID && mcd_buf_in == mcd_buf_out) {
+				mcd_state = MCD_S_STOP;
+				goto immediately;
+			}
+			mcd_buf_bn[mcd_buf_in] = -1;
+			insb(MCDPORT(0), mcd_buf + 2048 * mcd_buf_in,
+				  2048);
+			mcd_buf_bn[mcd_buf_in] = mcd_next_bn++;
+			if (mcd_buf_out == -1)
+				mcd_buf_out = mcd_buf_in;
+			mcd_buf_in = mcd_buf_in + 1 == MCD_BUF_SIZ ? 0 : mcd_buf_in + 1;
+			if (!mcd_transfer_is_active) {
+				while (CURRENT_VALID) {
+					mcd_transfer();
+					if (CURRENT->nr_sectors == 0)
+						end_request(1);
+					else
+						break;
+				}
+			}
 
-    case MFL_DATA:
-#ifdef WARN_IF_READ_FAILURE
-      if (McdTries == 5)
-	printk("mcd: read of block %d failed\n", mcd_next_bn);
-#endif
-      if (!McdTries--) {
-	printk("mcd: read of block %d failed, giving up\n", mcd_next_bn);
-	if (mcd_transfer_is_active) {
-	  McdTries = 0;
-	  break;
-	}
-	if (CURRENT_VALID)
-	  end_request(0);
-	McdTries = 5;
-      }
-      mcd_state = MCD_S_START;
-      McdTimeout = READ_TIMEOUT;
-      goto immediately;
-
-    case MFL_STATUSorDATA:
-      break;
-
-    default:
-      McdTries = 5;
-      if (!CURRENT_VALID && mcd_buf_in == mcd_buf_out) {
-	mcd_state = MCD_S_STOP;
-	goto immediately;
-      }
-      mcd_buf_bn[mcd_buf_in] = -1;
-      READ_DATA(MCDPORT(0), mcd_buf + 2048 * mcd_buf_in, 2048);
-      mcd_buf_bn[mcd_buf_in] = mcd_next_bn++;
-      if (mcd_buf_out == -1)
-	mcd_buf_out = mcd_buf_in;
-      mcd_buf_in = mcd_buf_in + 1 == MCD_BUF_SIZ ? 0 : mcd_buf_in + 1;
-      if (!mcd_transfer_is_active) {
-	while (CURRENT_VALID) {
-	  mcd_transfer();
-	  if (CURRENT -> nr_sectors == 0)
-	    end_request(1);
-	  else
-	    break;
-	}
-      }
-
-      if (CURRENT_VALID
-	  && (CURRENT -> sector / 4 < mcd_next_bn || 
-	      CURRENT -> sector / 4 > mcd_next_bn + 16)) {
-	mcd_state = MCD_S_STOP;
-	goto immediately;
-      }
-      McdTimeout = READ_TIMEOUT;
-#ifdef DOUBLE_QUICK_ONLY
-      if (MCMD_DATA_READ != MCMD_PLAY_READ)
-#endif
-      {
-	int count= QUICK_LOOP_COUNT;
-	while (count--) {
-          QUICK_LOOP_DELAY;
-	  if ((st = (inb(MCDPORT(1))) & (MFL_STATUSorDATA)) != (MFL_STATUSorDATA)) {
-#   ifdef TEST4
-/*	    printk("Quickloop success at %d\n",QUICK_LOOP_COUNT-count); */
-	    printk(" %d ",QUICK_LOOP_COUNT-count);
-#   endif
-	    goto data_immediately;
-	  }
-	}
-#   ifdef TEST4
-/*      printk("Quickloop ended at %d\n",QUICK_LOOP_COUNT); */
-	printk("ended ");
-#   endif
-      }
-      break;
-    }
-    break;
+			if (CURRENT_VALID
+			    && (CURRENT->sector / 4 < mcd_next_bn ||
+				CURRENT->sector / 4 > mcd_next_bn + 16)) {
+				mcd_state = MCD_S_STOP;
+				goto immediately;
+			}
+			McdTimeout = READ_TIMEOUT;
+			{
+				int count = QUICK_LOOP_COUNT;
+				while (count--) {
+					QUICK_LOOP_DELAY;
+					if ((st = (inb(MCDPORT(1))) & (MFL_STATUSorDATA)) != (MFL_STATUSorDATA)) {
+						test4(printk(" %d ", QUICK_LOOP_COUNT - count));
+						goto data_immediately;
+					}
+				}
+				test4(printk("ended "));
+			}
+			break;
+		}
+		break;
 
+	case MCD_S_STOP:
+		test3(printk("MCD_S_STOP\n"));
+		if (!mitsumi_bug_93_wait)
+			goto do_not_work_around_mitsumi_bug_93_1;
+
+		McdTimeout = mitsumi_bug_93_wait;
+		mcd_state = 9 + 3 + 1;
+		break;
 
+	case 9 + 3 + 1:
+		if (McdTimeout)
+			break;
 
-  case MCD_S_STOP:
-#ifdef TEST3
-    printk("MCD_S_STOP\n");
-#endif
+do_not_work_around_mitsumi_bug_93_1:
+		outb(MCMD_STOP, MCDPORT(0));
+		if ((inb(MCDPORT(1)) & MFL_STATUSorDATA) == MFL_STATUS) {
+			int i = 4096;
+			do {
+				inb(MCDPORT(0));
+			} while ((inb(MCDPORT(1)) & MFL_STATUSorDATA) == MFL_STATUS && --i);
+			outb(MCMD_STOP, MCDPORT(0));
+			if ((inb(MCDPORT(1)) & MFL_STATUSorDATA) == MFL_STATUS) {
+				i = 4096;
+				do {
+					inb(MCDPORT(0));
+				} while ((inb(MCDPORT(1)) & MFL_STATUSorDATA) == MFL_STATUS && --i);
+				outb(MCMD_STOP, MCDPORT(0));
+			}
+		}
 
-#ifdef WORK_AROUND_MITSUMI_BUG_93
-    if (!mitsumi_bug_93_wait)
-      goto do_not_work_around_mitsumi_bug_93_1;
-
-    McdTimeout = mitsumi_bug_93_wait;
-    mcd_state = 9+3+1;
-    break;
-
-  case 9+3+1:
-    if (McdTimeout)
-      break;
-
-  do_not_work_around_mitsumi_bug_93_1:
-#endif /* WORK_AROUND_MITSUMI_BUG_93 */
-
-    outb(MCMD_STOP, MCDPORT(0));
-
-#ifdef WORK_AROUND_MITSUMI_BUG_92
-    if ((inb(MCDPORT(1)) & MFL_STATUSorDATA) == MFL_STATUS) {
-      int i = 4096;
-      do {
-	inb(MCDPORT(0));
-      } while ((inb(MCDPORT(1)) & MFL_STATUSorDATA) == MFL_STATUS && --i);
-      outb(MCMD_STOP, MCDPORT(0));
-      if ((inb(MCDPORT(1)) & MFL_STATUSorDATA) == MFL_STATUS) {
-	i = 4096;
-	do {
-	  inb(MCDPORT(0));
-	} while ((inb(MCDPORT(1)) & MFL_STATUSorDATA) == MFL_STATUS && --i);
-	outb(MCMD_STOP, MCDPORT(0));
-      }
-    }
-#endif /* WORK_AROUND_MITSUMI_BUG_92 */
-
-    mcd_state = MCD_S_STOPPING;
-    McdTimeout = 1000;
-    break;
-
-  case MCD_S_STOPPING:
-#ifdef TEST3
-    printk("MCD_S_STOPPING\n");
-#endif
+		mcd_state = MCD_S_STOPPING;
+		McdTimeout = 1000;
+		break;
+
+	case MCD_S_STOPPING:
+		test3(printk("MCD_S_STOPPING\n"));
+		if ((st = mcdStatus()) == -1 && McdTimeout)
+			break;
 
-    if ((st = mcdStatus()) == -1 && McdTimeout)
-      break;
+		if ((st != -1) && (st & MST_DSK_CHG)) {
+			mcdDiskChanged = 1;
+			tocUpToDate = 0;
+			mcd_invalidate_buffers();
+		}
+		if (!mitsumi_bug_93_wait)
+			goto do_not_work_around_mitsumi_bug_93_2;
 
-    if ((st != -1) && (st & MST_DSK_CHG)) {
-      mcdDiskChanged = 1;
-      tocUpToDate = 0;
-      mcd_invalidate_buffers();
-    }
-
-#ifdef WORK_AROUND_MITSUMI_BUG_93
-    if (!mitsumi_bug_93_wait)
-      goto do_not_work_around_mitsumi_bug_93_2;
-
-    McdTimeout = mitsumi_bug_93_wait;
-    mcd_state = 9+3+2;
-    break;
-
-  case 9+3+2:
-    if (McdTimeout)
-      break;
-
-    st = -1;
-
-  do_not_work_around_mitsumi_bug_93_2:
-#endif /* WORK_AROUND_MITSUMI_BUG_93 */
-
-#ifdef TEST3
-    printk("CURRENT_VALID %d mcd_mode %d\n",
-	   CURRENT_VALID, mcd_mode);
-#endif
+		McdTimeout = mitsumi_bug_93_wait;
+		mcd_state = 9 + 3 + 2;
+		break;
 
-    if (CURRENT_VALID) {
-      if (st != -1) {
-	if (mcd_mode == 1)
-	  goto read_immediately;
-	else
-	  goto set_mode_immediately;
-      } else {
-	mcd_state = MCD_S_START;
-	McdTimeout = 1;
-      }
-    } else {
-      mcd_state = MCD_S_IDLE;
-      goto out;
-    }
-    break;
-
-  default:
-    printk("mcd: invalid state %d\n", mcd_state);
-    goto out;
-  }
-
- ret:
-  if (!McdTimeout--) {
-    printk("mcd: timeout in state %d\n", mcd_state);
-    mcd_state = MCD_S_STOP;
-  }
+	case 9 + 3 + 2:
+		if (McdTimeout)
+			break;
+		st = -1;
 
-  SET_TIMER(mcd_poll, 1);
+do_not_work_around_mitsumi_bug_93_2:
+		test3(printk("CURRENT_VALID %d mcd_mode %d\n", CURRENT_VALID, mcd_mode));
+		if (CURRENT_VALID) {
+			if (st != -1) {
+				if (mcd_mode == 1)
+					goto read_immediately;
+				else
+					goto set_mode_immediately;
+			} else {
+				mcd_state = MCD_S_START;
+				McdTimeout = 1;
+			}
+		} else {
+			mcd_state = MCD_S_IDLE;
+			goto out;
+		}
+		break;
+	default:
+		printk(KERN_ERR "mcd: invalid state %d\n", mcd_state);
+		goto out;
+	}
+ret:
+	if (!McdTimeout--) {
+		printk(KERN_WARNING "mcd: timeout in state %d\n", mcd_state);
+		mcd_state = MCD_S_STOP;
+	}
+	mcd_timer.function = mcd_poll;
+	mod_timer(&mcd_timer, jiffies + 1);
 out:
-  return;
+	return;
 }
 
-
-
-static void
-mcd_invalidate_buffers(void)
+static void mcd_invalidate_buffers(void)
 {
-  int i;
-  for (i = 0; i < MCD_BUF_SIZ; ++i)
-    mcd_buf_bn[i] = -1;
-  mcd_buf_out = -1;
+	int i;
+	for (i = 0; i < MCD_BUF_SIZ; ++i)
+		mcd_buf_bn[i] = -1;
+	mcd_buf_out = -1;
 }
 
-
 /*
  * Open the device special file.  Check that a disk is in.
  */
-static int mcd_open(struct cdrom_device_info * cdi, int purpose)
+static int mcd_open(struct cdrom_device_info *cdi, int purpose)
 {
-	int st, count=0;
+	int st, count = 0;
 	if (mcdPresent == 0)
-		return -ENXIO;			/* no hardware */
+		return -ENXIO;	/* no hardware */
 
-        MOD_INC_USE_COUNT;
+	MOD_INC_USE_COUNT;
 
-        if (mcd_open_count || mcd_state != MCD_S_IDLE)
+	if (mcd_open_count || mcd_state != MCD_S_IDLE)
 		goto bump_count;
 
-        mcd_invalidate_buffers();
-        do {
-                st = statusCmd();               /* check drive status */
-                if (st == -1)
-                        goto err_out;            /* drive doesn't respond */
-                if ((st & MST_READY) == 0) {    /* no disk? wait a sec... */
-                        current->state = TASK_INTERRUPTIBLE;
-                        schedule_timeout(HZ);
-                }
-        } while (((st & MST_READY) == 0) && count++ < MCD_RETRY_ATTEMPTS);
+	mcd_invalidate_buffers();
+	do {
+		st = statusCmd();	/* check drive status */
+		if (st == -1)
+			goto err_out;	/* drive doesn't respond */
+		if ((st & MST_READY) == 0) {	/* no disk? wait a sec... */
+			current->state = TASK_INTERRUPTIBLE;
+			schedule_timeout(HZ);
+		}
+	} while (((st & MST_READY) == 0) && count++ < MCD_RETRY_ATTEMPTS);
 
-        if (updateToc() < 0)
-                       goto err_out;
+	if (updateToc() < 0)
+		goto err_out;
 
 bump_count:
 	++mcd_open_count;
 	return 0;
 
 err_out:
-        MOD_DEC_USE_COUNT;
+	MOD_DEC_USE_COUNT;
 	return -EIO;
 }
 
@@ -1130,11 +1010,12 @@
 /*
  * On close, we flush all mcd blocks from the buffer cache.
  */
-static void mcd_release(struct cdrom_device_info * cdi)
-{ MOD_DEC_USE_COUNT;
-  if (!--mcd_open_count) {
-	mcd_invalidate_buffers();
-  }
+static void mcd_release(struct cdrom_device_info *cdi)
+{
+	if (!--mcd_open_count) {
+		mcd_invalidate_buffers();
+	}
+	MOD_DEC_USE_COUNT;
 }
 
 
@@ -1143,23 +1024,23 @@
  * and is used in mcd_exit as well. */
 static void cleanup(int level)
 {
-  switch (level) {
-  case 3:
-    if (unregister_cdrom(&mcd_info)) {
-      printk(KERN_WARNING "Can't unregister cdrom mcd\n");
-      return;
-    }
-    free_irq(mcd_irq, NULL);
-  case 2:
-    release_region(mcd_port,4);
-  case 1:
-    if (devfs_unregister_blkdev(MAJOR_NR, "mcd")) {
-      printk(KERN_WARNING "Can't unregister major mcd\n");
-      return;
-    }
-    blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
-  default:;
-  }
+	switch (level) {
+	case 3:
+		if (unregister_cdrom(&mcd_info)) {
+			printk(KERN_WARNING "Can't unregister cdrom mcd\n");
+			return;
+		}
+		free_irq(mcd_irq, NULL);
+	case 2:
+		release_region(mcd_port, 4);
+	case 1:
+		if (devfs_unregister_blkdev(MAJOR_NR, "mcd")) {
+			printk(KERN_WARNING "Can't unregister major mcd\n");
+			return;
+		}
+		blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
+	default:;
+	}
 }
 
 
@@ -1175,21 +1056,18 @@
 	char msg[80];
 
 	if (mcd_port <= 0 || mcd_irq <= 0) {
-	  printk("skip mcd_init\n");
-          return -EIO;
+		printk(KERN_INFO "mcd: not probing.\n");
+		return -EIO;
 	}
 
-	if (devfs_register_blkdev(MAJOR_NR, "mcd", &cdrom_fops) != 0)
-	{
-		printk("Unable to get major %d for Mitsumi CD-ROM\n",
-		       MAJOR_NR);
-                return -EIO;
-	}
-        if (check_region(mcd_port, 4)) {
-	  cleanup(1);
-	  printk("Init failed, I/O port (%X) already in use\n",
-		 mcd_port);
-          return -EIO;
+	if (devfs_register_blkdev(MAJOR_NR, "mcd", &cdrom_fops) != 0) {
+		printk(KERN_ERR "mcd: Unable to get major %d for Mitsumi CD-ROM\n", MAJOR_NR);
+		return -EIO;
+	}
+	if (check_region(mcd_port, 4)) {
+		cleanup(1);
+		printk(KERN_ERR "mcd: Initialization failed, I/O port (%X) already in use\n", mcd_port);
+		return -EIO;
 	}
 
 	blksize_size[MAJOR_NR] = mcd_blocksizes;
@@ -1198,106 +1076,103 @@
 
 	/* check for card */
 
-	outb(0, MCDPORT(1));			/* send reset */
+	outb(0, MCDPORT(1));	/* send reset */
 	for (count = 0; count < 2000000; count++)
-		(void) inb(MCDPORT(1));		/* delay a bit */
+		(void) inb(MCDPORT(1));	/* delay a bit */
 
-	outb(0x40, MCDPORT(0));	                /* send get-stat cmd */
+	outb(0x40, MCDPORT(0));	/* send get-stat cmd */
 	for (count = 0; count < 2000000; count++)
 		if (!(inb(MCDPORT(1)) & MFL_STATUS))
 			break;
 
 	if (count >= 2000000) {
-		printk("Init failed. No mcd device at 0x%x irq %d\n",
-		     mcd_port, mcd_irq);
+		printk(KERN_INFO "mcd: initialisation failed - No mcd device at 0x%x irq %d\n",
+		       mcd_port, mcd_irq);
 		cleanup(1);
-                return -EIO;
+		return -EIO;
 	}
-	count = inb(MCDPORT(0));		/* pick up the status */
-	
-	outb(MCMD_GET_VERSION,MCDPORT(0));
-	for(count=0;count<3;count++)
-		if(getValue(result+count)) {
-			printk("mitsumi get version failed at 0x%x\n",
+	count = inb(MCDPORT(0));	/* pick up the status */
+
+	outb(MCMD_GET_VERSION, MCDPORT(0));
+	for (count = 0; count < 3; count++)
+		if (getValue(result + count)) {
+			printk(KERN_ERR "mcd: mitsumi get version failed at 0x%x\n",
 			       mcd_port);
-                        cleanup(1);
-                        return -EIO;
-		}	
+			cleanup(1);
+			return -EIO;
+		}
 
 	if (result[0] == result[1] && result[1] == result[2]) {
 		cleanup(1);
-                return -EIO;
+		return -EIO;
 	}
 
-	mcdVersion=result[2];
+	mcdVersion = result[2];
 
-	if (mcdVersion >=4)
-		outb(4,MCDPORT(2)); 	/* magic happens */
+	if (mcdVersion >= 4)
+		outb(4, MCDPORT(2));	/* magic happens */
 
 	/* don't get the IRQ until we know for sure the drive is there */
 
-	if (request_irq(mcd_irq, mcd_interrupt, SA_INTERRUPT, "Mitsumi CD", NULL))
-	{
-		printk("Unable to get IRQ%d for Mitsumi CD-ROM\n", mcd_irq);
+	if (request_irq(mcd_irq, mcd_interrupt, SA_INTERRUPT, "Mitsumi CD", NULL)) {
+		printk(KERN_ERR "mcd: Unable to get IRQ%d for Mitsumi CD-ROM\n", mcd_irq);
 		cleanup(1);
-                return -EIO;
+		return -EIO;
 	}
 
-        if (result[1] == 'D') 
-	{
+	if (result[1] == 'D') {
 		MCMD_DATA_READ = MCMD_2X_READ;
 		/* Added flag to drop to 1x speed if too many errors */
 		mcdDouble = 1;
-        } else 
+	} else
 		mcd_info.speed = 1;
 	sprintf(msg, " mcd: Mitsumi %s Speed CD-ROM at port=0x%x,"
-		     " irq=%d\n", mcd_info.speed == 1 ?  "Single" : "Double", mcd_port, mcd_irq);
+		" irq=%d\n", mcd_info.speed == 1 ? "Single" : "Double",
+		mcd_port, mcd_irq);
 
 	request_region(mcd_port, 4, "mcd");
 
 	outb(MCMD_CONFIG_DRIVE, MCDPORT(0));
-	outb(0x02,MCDPORT(0));
-	outb(0x00,MCDPORT(0));
+	outb(0x02, MCDPORT(0));
+	outb(0x00, MCDPORT(0));
 	getValue(result);
 
 	outb(MCMD_CONFIG_DRIVE, MCDPORT(0));
-	outb(0x10,MCDPORT(0));
-	outb(0x04,MCDPORT(0));
+	outb(0x10, MCDPORT(0));
+	outb(0x04, MCDPORT(0));
 	getValue(result);
 
 	mcd_invalidate_buffers();
 	mcdPresent = 1;
 
-	mcd_info.dev = MKDEV(MAJOR_NR,0);
+	mcd_info.dev = MKDEV(MAJOR_NR, 0);
 
-        if (register_cdrom(&mcd_info) != 0) {
-              printk("Cannot register Mitsumi CD-ROM!\n");
-              cleanup(3);
-              return -EIO;
-        }
-        printk(msg);
+	if (register_cdrom(&mcd_info) != 0) {
+		printk(KERN_ERR "mcd: Unable to register Mitsumi CD-ROM.\n");
+		cleanup(3);
+		return -EIO;
+	}
+	printk(msg);
 
 	return 0;
 }
 
 
-static void
-hsg2msf(long hsg, struct msf *msf)
+static void hsg2msf(long hsg, struct msf *msf)
 {
 	hsg += 150;
-	msf -> min = hsg / 4500;
+	msf->min = hsg / 4500;
 	hsg %= 4500;
-	msf -> sec = hsg / 75;
-	msf -> frame = hsg % 75;
+	msf->sec = hsg / 75;
+	msf->frame = hsg % 75;
 
-	bin2bcd(&msf -> min);		/* convert to BCD */
-	bin2bcd(&msf -> sec);
-	bin2bcd(&msf -> frame);
+	bin2bcd(&msf->min);	/* convert to BCD */
+	bin2bcd(&msf->sec);
+	bin2bcd(&msf->frame);
 }
 
 
-static void
-bin2bcd(unsigned char *p)
+static void bin2bcd(unsigned char *p)
 {
 	int u, t;
 
@@ -1306,8 +1181,7 @@
 	*p = u | (t << 4);
 }
 
-static int
-bcd2bin(unsigned char bcd)
+static int bcd2bin(unsigned char bcd)
 {
 	return (bcd >> 4) * 10 + (bcd & 0xF);
 }
@@ -1318,19 +1192,16 @@
  * if it is ready.
  */
 
-static int
-mcdStatus(void)
+static int mcdStatus(void)
 {
 	int i;
 	int st;
 
 	st = inb(MCDPORT(1)) & MFL_STATUS;
-	if (!st)
-	{
+	if (!st) {
 		i = inb(MCDPORT(0)) & 0xFF;
 		return i;
-	}
-	else
+	} else
 		return -1;
 }
 
@@ -1339,16 +1210,15 @@
  * Send a play or read command to the drive
  */
 
-static void
-sendMcdCmd(int cmd, struct mcd_Play_msf *params)
+static void sendMcdCmd(int cmd, struct mcd_Play_msf *params)
 {
 	outb(cmd, MCDPORT(0));
-	outb(params -> start.min, MCDPORT(0));
-	outb(params -> start.sec, MCDPORT(0));
-	outb(params -> start.frame, MCDPORT(0));
-	outb(params -> end.min, MCDPORT(0));
-	outb(params -> end.sec, MCDPORT(0));
-	outb(params -> end.frame, MCDPORT(0));
+	outb(params->start.min, MCDPORT(0));
+	outb(params->start.sec, MCDPORT(0));
+	outb(params->start.frame, MCDPORT(0));
+	outb(params->end.min, MCDPORT(0));
+	outb(params->end.sec, MCDPORT(0));
+	outb(params->end.frame, MCDPORT(0));
 }
 
 
@@ -1357,23 +1227,20 @@
  * (see the next routine)
  */
 
-static void
-mcdStatTimer(unsigned long dummy)
+static void mcdStatTimer(unsigned long dummy)
 {
-	if (!(inb(MCDPORT(1)) & MFL_STATUS))
-	{
+	if (!(inb(MCDPORT(1)) & MFL_STATUS)) {
 		wake_up(&mcd_waitq);
 		return;
 	}
 
 	McdTimeout--;
-	if (McdTimeout <= 0)
-	{
+	if (McdTimeout <= 0) {
 		wake_up(&mcd_waitq);
 		return;
 	}
-
-	SET_TIMER(mcdStatTimer, 1);
+	mcd_timer.function = mcdStatTimer;
+	mod_timer(&mcd_timer, jiffies + 1);
 }
 
 
@@ -1383,13 +1250,13 @@
  * excessive rescheduling.
  */
 
-static int
-getMcdStatus(int timeout)
+static int getMcdStatus(int timeout)
 {
 	int st;
 
 	McdTimeout = timeout;
-	SET_TIMER(mcdStatTimer, 1);
+	mcd_timer.function = mcdStatTimer;
+	mod_timer(&mcd_timer, jiffies + 1);
 	sleep_on(&mcd_waitq);
 	if (McdTimeout <= 0)
 		return -1;
@@ -1402,8 +1269,7 @@
 		/* XXX might be an error? look at q-channel? */
 		audioStatus = CDROM_AUDIO_COMPLETED;
 
-	if (st & MST_DSK_CHG)
-	{
+	if (st & MST_DSK_CHG) {
 		mcdDiskChanged = 1;
 		tocUpToDate = 0;
 		audioStatus = CDROM_AUDIO_NO_STATUS;
@@ -1415,18 +1281,23 @@
 
 /* gives current state of the drive This function is quite unreliable, 
    and should probably be rewritten by someone, eventually... */
-int mcd_drive_status(struct cdrom_device_info * cdi, int slot_nr)
+
+int mcd_drive_status(struct cdrom_device_info *cdi, int slot_nr)
 {
-  int st;
+	int st;
 
-  st = statusCmd();               /* check drive status */
-  if (st == -1)
-      return -EIO;            /* drive doesn't respond */
-  if ((st & MST_READY)) return CDS_DISC_OK;
-  if ((st & MST_DOOR_OPEN)) return CDS_TRAY_OPEN;
-  if ((st & MST_DSK_CHG)) return CDS_NO_DISC;
-  if ((st & MST_BUSY)) return CDS_DRIVE_NOT_READY;
-  return -EIO;
+	st = statusCmd();	/* check drive status */
+	if (st == -1)
+		return -EIO;	/* drive doesn't respond */
+	if ((st & MST_READY))
+		return CDS_DISC_OK;
+	if ((st & MST_DOOR_OPEN))
+		return CDS_TRAY_OPEN;
+	if ((st & MST_DSK_CHG))
+		return CDS_NO_DISC;
+	if ((st & MST_BUSY))
+		return CDS_DRIVE_NOT_READY;
+	return -EIO;
 }
 
 
@@ -1434,18 +1305,16 @@
  * Read a value from the drive.
  */
 
-static int
-getValue(unsigned char *result)
+static int getValue(unsigned char *result)
 {
-        int count;
+	int count;
 	int s;
 
 	for (count = 0; count < 2000; count++)
 		if (!(inb(MCDPORT(1)) & MFL_STATUS))
 			break;
 
-	if (count >= 2000)
-	{
+	if (count >= 2000) {
 		printk("mcd: getValue timeout\n");
 		return -1;
 	}
@@ -1455,20 +1324,17 @@
 	return 0;
 }
 
-
 /*
  * Read the current Q-channel info.  Also used for reading the
  * table of contents.
  */
 
-int
-GetQChannelInfo(struct mcd_Toc *qp)
+int GetQChannelInfo(struct mcd_Toc *qp)
 {
 	unsigned char notUsed;
 	int retry;
 
-	for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++)
-	{
+	for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++) {
 		outb(MCMD_GET_Q_CHANNEL, MCDPORT(0));
 		if (getMcdStatus(MCD_STATUS_DELAY) != -1)
 			break;
@@ -1477,27 +1343,35 @@
 	if (retry >= MCD_RETRY_ATTEMPTS)
 		return -1;
 
-	if (getValue(&qp -> ctrl_addr) < 0) return -1;
-	if (getValue(&qp -> track) < 0) return -1;
-	if (getValue(&qp -> pointIndex) < 0) return -1;
-	if (getValue(&qp -> trackTime.min) < 0) return -1;
-	if (getValue(&qp -> trackTime.sec) < 0) return -1;
-	if (getValue(&qp -> trackTime.frame) < 0) return -1;
-	if (getValue(&notUsed) < 0) return -1;
-	if (getValue(&qp -> diskTime.min) < 0) return -1;
-	if (getValue(&qp -> diskTime.sec) < 0) return -1;
-	if (getValue(&qp -> diskTime.frame) < 0) return -1;
+	if (getValue(&qp->ctrl_addr) < 0)
+		return -1;
+	if (getValue(&qp->track) < 0)
+		return -1;
+	if (getValue(&qp->pointIndex) < 0)
+		return -1;
+	if (getValue(&qp->trackTime.min) < 0)
+		return -1;
+	if (getValue(&qp->trackTime.sec) < 0)
+		return -1;
+	if (getValue(&qp->trackTime.frame) < 0)
+		return -1;
+	if (getValue(&notUsed) < 0)
+		return -1;
+	if (getValue(&qp->diskTime.min) < 0)
+		return -1;
+	if (getValue(&qp->diskTime.sec) < 0)
+		return -1;
+	if (getValue(&qp->diskTime.frame) < 0)
+		return -1;
 
 	return 0;
 }
 
-
 /*
  * Read the table of contents (TOC) and TOC header if necessary
  */
 
-static int
-updateToc()
+static int updateToc(void)
 {
 	if (tocUpToDate)
 		return 0;
@@ -1512,18 +1386,15 @@
 	return 0;
 }
 
-
 /*
  * Read the table of contents header
  */
 
-static int
-GetDiskInfo()
+static int GetDiskInfo(void)
 {
 	int retry;
 
-	for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++)
-	{
+	for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++) {
 		outb(MCMD_GET_DISK_INFO, MCDPORT(0));
 		if (getMcdStatus(MCD_STATUS_DELAY) != -1)
 			break;
@@ -1532,41 +1403,44 @@
 	if (retry >= MCD_RETRY_ATTEMPTS)
 		return -1;
 
-	if (getValue(&DiskInfo.first) < 0) return -1;
-	if (getValue(&DiskInfo.last) < 0) return -1;
+	if (getValue(&DiskInfo.first) < 0)
+		return -1;
+	if (getValue(&DiskInfo.last) < 0)
+		return -1;
 
 	DiskInfo.first = bcd2bin(DiskInfo.first);
 	DiskInfo.last = bcd2bin(DiskInfo.last);
 
 #ifdef MCD_DEBUG
-printk("Disk Info: first %d last %d length %02x:%02x.%02x first %02x:%02x.%02x\n",
-	DiskInfo.first,
-	DiskInfo.last,
-	DiskInfo.diskLength.min,
-	DiskInfo.diskLength.sec,
-	DiskInfo.diskLength.frame,
-	DiskInfo.firstTrack.min,
-	DiskInfo.firstTrack.sec,
-	DiskInfo.firstTrack.frame);
+	printk
+	    ("Disk Info: first %d last %d length %02x:%02x.%02x first %02x:%02x.%02x\n",
+	     DiskInfo.first, DiskInfo.last, DiskInfo.diskLength.min,
+	     DiskInfo.diskLength.sec, DiskInfo.diskLength.frame,
+	     DiskInfo.firstTrack.min, DiskInfo.firstTrack.sec,
+	     DiskInfo.firstTrack.frame);
 #endif
 
-	if (getValue(&DiskInfo.diskLength.min) < 0) return -1;
-	if (getValue(&DiskInfo.diskLength.sec) < 0) return -1;
-	if (getValue(&DiskInfo.diskLength.frame) < 0) return -1;
-	if (getValue(&DiskInfo.firstTrack.min) < 0) return -1;
-	if (getValue(&DiskInfo.firstTrack.sec) < 0) return -1;
-	if (getValue(&DiskInfo.firstTrack.frame) < 0) return -1;
+	if (getValue(&DiskInfo.diskLength.min) < 0)
+		return -1;
+	if (getValue(&DiskInfo.diskLength.sec) < 0)
+		return -1;
+	if (getValue(&DiskInfo.diskLength.frame) < 0)
+		return -1;
+	if (getValue(&DiskInfo.firstTrack.min) < 0)
+		return -1;
+	if (getValue(&DiskInfo.firstTrack.sec) < 0)
+		return -1;
+	if (getValue(&DiskInfo.firstTrack.frame) < 0)
+		return -1;
 
 	return 0;
 }
 
-
 /*
  * Read the table of contents (TOC)
  */
 
-static int
-GetToc()
+static int GetToc(void)
 {
 	int i, px;
 	int limit;
@@ -1578,8 +1452,7 @@
 
 	i = DiskInfo.last + 3;
 
-	for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++)
-	{
+	for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++) {
 		outb(MCMD_STOP, MCDPORT(0));
 		if (getMcdStatus(MCD_STATUS_DELAY) != -1)
 			break;
@@ -1588,10 +1461,9 @@
 	if (retry >= MCD_RETRY_ATTEMPTS)
 		return -1;
 
-	for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++)
-	{
+	for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++) {
 		outb(MCMD_SET_MODE, MCDPORT(0));
-		outb(0x05, MCDPORT(0));			/* mode: toc */
+		outb(0x05, MCDPORT(0));	/* mode: toc */
 		mcd_mode = 0x05;
 		if (getMcdStatus(MCD_STATUS_DELAY) != -1)
 			break;
@@ -1600,15 +1472,13 @@
 	if (retry >= MCD_RETRY_ATTEMPTS)
 		return -1;
 
-	for (limit = 300; limit > 0; limit--)
-	{
+	for (limit = 300; limit > 0; limit--) {
 		if (GetQChannelInfo(&qInfo) < 0)
 			break;
 
 		px = bcd2bin(qInfo.pointIndex);
 		if (px > 0 && px < MAX_TRACKS && qInfo.track == 0)
-			if (Toc[px].pointIndex == 0)
-			{
+			if (Toc[px].pointIndex == 0) {
 				Toc[px] = qInfo;
 				i--;
 			}
@@ -1619,41 +1489,44 @@
 
 	Toc[DiskInfo.last + 1].diskTime = DiskInfo.diskLength;
 
-	for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++)
-	{
-                outb(MCMD_SET_MODE, MCDPORT(0));
-                outb(0x01, MCDPORT(0));
+	for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++) {
+		outb(MCMD_SET_MODE, MCDPORT(0));
+		outb(0x01, MCDPORT(0));
 		mcd_mode = 1;
-                if (getMcdStatus(MCD_STATUS_DELAY) != -1)
-                        break;
+		if (getMcdStatus(MCD_STATUS_DELAY) != -1)
+			break;
 	}
 
 #ifdef MCD_DEBUG
-for (i = 1; i <= DiskInfo.last; i++)
-printk("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X    %02X:%02X.%02X\n",
-i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
-Toc[i].trackTime.min, Toc[i].trackTime.sec, Toc[i].trackTime.frame,
-Toc[i].diskTime.min, Toc[i].diskTime.sec, Toc[i].diskTime.frame);
-for (i = 100; i < 103; i++)
-printk("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X    %02X:%02X.%02X\n",
-i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
-Toc[i].trackTime.min, Toc[i].trackTime.sec, Toc[i].trackTime.frame,
-Toc[i].diskTime.min, Toc[i].diskTime.sec, Toc[i].diskTime.frame);
+	for (i = 1; i <= DiskInfo.last; i++)
+		printk
+		    ("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X    %02X:%02X.%02X\n",
+		     i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
+		     Toc[i].trackTime.min, Toc[i].trackTime.sec,
+		     Toc[i].trackTime.frame, Toc[i].diskTime.min,
+		     Toc[i].diskTime.sec, Toc[i].diskTime.frame);
+	for (i = 100; i < 103; i++)
+		printk
+		    ("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X    %02X:%02X.%02X\n",
+		     i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
+		     Toc[i].trackTime.min, Toc[i].trackTime.sec,
+		     Toc[i].trackTime.frame, Toc[i].diskTime.min,
+		     Toc[i].diskTime.sec, Toc[i].diskTime.frame);
 #endif
 
 	return limit > 0 ? 0 : -1;
 }
 
-
 void __exit mcd_exit(void)
 {
-  cleanup(3);
-  del_timer_sync(&mcd_timer);
+	cleanup(3);
+	del_timer_sync(&mcd_timer);
 }
 
 #ifdef MODULE
 module_init(mcd_init);
-#endif 
+#endif
 module_exit(mcd_exit);
 
-
+MODULE_AUTHOR("Martin Harriss");
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.9/linux/drivers/cdrom/mcd.h linux/drivers/cdrom/mcd.h
--- v2.4.9/linux/drivers/cdrom/mcd.h	Wed Jul  5 11:24:41 2000
+++ linux/drivers/cdrom/mcd.h	Sun Sep  9 10:43:02 2001
@@ -70,17 +70,6 @@
 
 /* borrowed from hd.c */
 
-#define READ_DATA(port, buf, nr) \
-insb(port, buf, nr)
-
-#define SET_TIMER(func, jifs) 				\
-	do {						\
-		mcd_timer.function = func;		\
-		mod_timer(&mcd_timer, jiffies + jifs);	\
-	} while (0)
-
-#define CLEAR_TIMER		del_timer_async(&mcd_timer);
-
 #define MAX_TRACKS		104
 
 struct msf {
@@ -108,3 +97,10 @@
 	struct msf	trackTime;
 	struct msf	diskTime;
 };
+
+#define test1(x)
+#define test2(x)
+#define test3(x)
+#define test4(x)
+#define test5(x)
+
diff -u --recursive --new-file v2.4.9/linux/drivers/cdrom/mcdx.c linux/drivers/cdrom/mcdx.c
--- v2.4.9/linux/drivers/cdrom/mcdx.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/cdrom/mcdx.c	Fri Sep  7 09:28:38 2001
@@ -53,7 +53,7 @@
 
 #if RCS
 static const char *mcdx_c_version
-		= "$Id: mcdx.c,v 1.21 1997/01/26 07:12:59 davem Exp $";
+    = "$Id: mcdx.c,v 1.21 1997/01/26 07:12:59 davem Exp $";
 #endif
 
 #include <linux/version.h>
@@ -120,10 +120,10 @@
 enum datamodes { MODE0, MODE1, MODE2 };
 enum resetmodes { SOFT, HARD };
 
-const int SINGLE = 0x01;		/* single speed drive (FX001S, LU) */
-const int DOUBLE = 0x02;		/* double speed drive (FX001D, ..? */
-const int DOOR   = 0x04;		/* door locking capability */
-const int MULTI  = 0x08;		/* multi session capability */
+const int SINGLE = 0x01;	/* single speed drive (FX001S, LU) */
+const int DOUBLE = 0x02;	/* double speed drive (FX001D, ..? */
+const int DOOR = 0x04;		/* door locking capability */
+const int MULTI = 0x08;		/* multi session capability */
 
 const unsigned char READ1X = 0xc0;
 const unsigned char READ2X = 0xc1;
@@ -159,53 +159,53 @@
 
 struct s_drive_stuff {
 	/* waitqueues */
-    wait_queue_head_t busyq;
-    wait_queue_head_t lockq;
-    wait_queue_head_t sleepq;
-
- 	/* flags */
-    volatile int introk;	/* status of last irq operation */
-    volatile int busy;		/* drive performs an operation */
-    volatile int lock;		/* exclusive usage */
+	wait_queue_head_t busyq;
+	wait_queue_head_t lockq;
+	wait_queue_head_t sleepq;
+
+	/* flags */
+	volatile int introk;	/* status of last irq operation */
+	volatile int busy;	/* drive performs an operation */
+	volatile int lock;	/* exclusive usage */
 
 	/* cd infos */
 	struct s_diskinfo di;
 	struct s_multi multi;
-	struct s_subqcode* toc;	/* first entry of the toc array */
+	struct s_subqcode *toc;	/* first entry of the toc array */
 	struct s_subqcode start;
-    struct s_subqcode stop;
-	int xa;					/* 1 if xa disk */
-	int audio;				/* 1 if audio disk */
+	struct s_subqcode stop;
+	int xa;			/* 1 if xa disk */
+	int audio;		/* 1 if audio disk */
 	int audiostatus;
 
 	/* `buffer' control */
-    volatile int valid;			/* pending, ..., values are valid */
-    volatile int pending;		/* next sector to be read */
-    volatile int low_border;	/* first sector not to be skipped direct */
-    volatile int high_border; /* first sector `out of area' */
+	volatile int valid;	/* pending, ..., values are valid */
+	volatile int pending;	/* next sector to be read */
+	volatile int low_border;	/* first sector not to be skipped direct */
+	volatile int high_border;	/* first sector `out of area' */
 #ifdef AK2
-    volatile int int_err;
-#endif /* AK2 */
+	volatile int int_err;
+#endif				/* AK2 */
 
 	/* adds and odds */
-	void* wreg_data;	/* w data */
-	void* wreg_reset;	/* w hardware reset */
-	void* wreg_hcon;	/* w hardware conf */
-	void* wreg_chn;		/* w channel */
-	void* rreg_data;	/* r data */
-	void* rreg_status;	/* r status */
-
-    int irq;			/* irq used by this drive */
-    int minor;			/* minor number of this drive */
-    int present;	    /* drive present and its capabilities */
-    unsigned char readcmd;	/* read cmd depends on single/double speed */
-    unsigned char playcmd;  /* play should always be single speed */
-    unsigned int xxx;      /* set if changed, reset while open */
-    unsigned int yyy;      /* set if changed, reset by media_changed */
-    int users;				/* keeps track of open/close */
-    int lastsector;			/* last block accessible */
-    int status;				/* last operation's error / status */
-	int readerrs;			/* # of blocks read w/o error */
+	void *wreg_data;	/* w data */
+	void *wreg_reset;	/* w hardware reset */
+	void *wreg_hcon;	/* w hardware conf */
+	void *wreg_chn;		/* w channel */
+	void *rreg_data;	/* r data */
+	void *rreg_status;	/* r status */
+
+	int irq;		/* irq used by this drive */
+	int minor;		/* minor number of this drive */
+	int present;		/* drive present and its capabilities */
+	unsigned char readcmd;	/* read cmd depends on single/double speed */
+	unsigned char playcmd;	/* play should always be single speed */
+	unsigned int xxx;	/* set if changed, reset while open */
+	unsigned int yyy;	/* set if changed, reset by media_changed */
+	int users;		/* keeps track of open/close */
+	int lastsector;		/* last block accessible */
+	int status;		/* last operation's error / status */
+	int readerrs;		/* # of blocks read w/o error */
 };
 
 
@@ -225,299 +225,333 @@
 	structure mcdx_dops. */
 
 /* ???  exported by the mcdx_sigaction struct */
-static void mcdx_intr(int, void *, struct pt_regs*);
+static void mcdx_intr(int, void *, struct pt_regs *);
 
 /* exported by file_ops */
-static int mcdx_open(struct cdrom_device_info * cdi, int purpose);
-static void mcdx_close(struct cdrom_device_info * cdi);
-static int mcdx_media_changed(struct cdrom_device_info * cdi, int disc_nr);
-static int mcdx_tray_move(struct cdrom_device_info * cdi, int position);
-static int mcdx_lockdoor(struct cdrom_device_info * cdi, int lock);
-static int mcdx_audio_ioctl(struct cdrom_device_info * cdi, unsigned int cmd,
-                      void * arg);
+static int mcdx_open(struct cdrom_device_info *cdi, int purpose);
+static void mcdx_close(struct cdrom_device_info *cdi);
+static int mcdx_media_changed(struct cdrom_device_info *cdi, int disc_nr);
+static int mcdx_tray_move(struct cdrom_device_info *cdi, int position);
+static int mcdx_lockdoor(struct cdrom_device_info *cdi, int lock);
+static int mcdx_audio_ioctl(struct cdrom_device_info *cdi,
+			    unsigned int cmd, void *arg);
 
 /* misc internal support functions */
-static void log2msf(unsigned int, struct cdrom_msf0*);
-static unsigned int msf2log(const struct cdrom_msf0*);
+static void log2msf(unsigned int, struct cdrom_msf0 *);
+static unsigned int msf2log(const struct cdrom_msf0 *);
 static unsigned int uint2bcd(unsigned int);
 static unsigned int bcd2uint(unsigned char);
-static char *port(int*);
-static int irq(int*);
-static void mcdx_delay(struct s_drive_stuff*, long jifs);
-static int mcdx_transfer(struct s_drive_stuff*, char* buf, int sector, int nr_sectors);
-static int mcdx_xfer(struct s_drive_stuff*, char* buf, int sector, int nr_sectors);
-
-static int mcdx_config(struct s_drive_stuff*, int);
-static int mcdx_requestversion(struct s_drive_stuff*, struct s_version*, int);
-static int mcdx_stop(struct s_drive_stuff*, int);
-static int mcdx_hold(struct s_drive_stuff*, int);
-static int mcdx_reset(struct s_drive_stuff*, enum resetmodes, int);
-static int mcdx_setdrivemode(struct s_drive_stuff*, enum drivemodes, int);
-static int mcdx_setdatamode(struct s_drive_stuff*, enum datamodes, int);
-static int mcdx_requestsubqcode(struct s_drive_stuff*, struct s_subqcode*, int);
-static int mcdx_requestmultidiskinfo(struct s_drive_stuff*, struct s_multi*, int);
-static int mcdx_requesttocdata(struct s_drive_stuff*, struct s_diskinfo*, int);
-static int mcdx_getstatus(struct s_drive_stuff*, int);
-static int mcdx_getval(struct s_drive_stuff*, int to, int delay, char*);
-static int mcdx_talk(struct s_drive_stuff*,
-		const unsigned char* cmd, size_t,
-        void *buffer, size_t size,
-        unsigned int timeout, int);
-static int mcdx_readtoc(struct s_drive_stuff*);
-static int mcdx_playtrk(struct s_drive_stuff*, const struct cdrom_ti*);
-static int mcdx_playmsf(struct s_drive_stuff*, const struct cdrom_msf*);
-static int mcdx_setattentuator(struct s_drive_stuff*, struct cdrom_volctrl*, int);
+static char *port(int *);
+static int irq(int *);
+static void mcdx_delay(struct s_drive_stuff *, long jifs);
+static int mcdx_transfer(struct s_drive_stuff *, char *buf, int sector,
+			 int nr_sectors);
+static int mcdx_xfer(struct s_drive_stuff *, char *buf, int sector,
+		     int nr_sectors);
+
+static int mcdx_config(struct s_drive_stuff *, int);
+static int mcdx_requestversion(struct s_drive_stuff *, struct s_version *,
+			       int);
+static int mcdx_stop(struct s_drive_stuff *, int);
+static int mcdx_hold(struct s_drive_stuff *, int);
+static int mcdx_reset(struct s_drive_stuff *, enum resetmodes, int);
+static int mcdx_setdrivemode(struct s_drive_stuff *, enum drivemodes, int);
+static int mcdx_setdatamode(struct s_drive_stuff *, enum datamodes, int);
+static int mcdx_requestsubqcode(struct s_drive_stuff *,
+				struct s_subqcode *, int);
+static int mcdx_requestmultidiskinfo(struct s_drive_stuff *,
+				     struct s_multi *, int);
+static int mcdx_requesttocdata(struct s_drive_stuff *, struct s_diskinfo *,
+			       int);
+static int mcdx_getstatus(struct s_drive_stuff *, int);
+static int mcdx_getval(struct s_drive_stuff *, int to, int delay, char *);
+static int mcdx_talk(struct s_drive_stuff *,
+		     const unsigned char *cmd, size_t,
+		     void *buffer, size_t size, unsigned int timeout, int);
+static int mcdx_readtoc(struct s_drive_stuff *);
+static int mcdx_playtrk(struct s_drive_stuff *, const struct cdrom_ti *);
+static int mcdx_playmsf(struct s_drive_stuff *, const struct cdrom_msf *);
+static int mcdx_setattentuator(struct s_drive_stuff *,
+			       struct cdrom_volctrl *, int);
 
 /* static variables ************************************************/
 
 static int mcdx_blocksizes[MCDX_NDRIVES];
 static int mcdx_drive_map[][2] = MCDX_DRIVEMAP;
-static struct s_drive_stuff* mcdx_stuffp[MCDX_NDRIVES];
-static struct s_drive_stuff* mcdx_irq_map[16] =
-		{0, 0, 0, 0, 0, 0, 0, 0,
-		0, 0, 0, 0, 0, 0, 0, 0};
+static struct s_drive_stuff *mcdx_stuffp[MCDX_NDRIVES];
+static struct s_drive_stuff *mcdx_irq_map[16] = { 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0
+};
 MODULE_PARM(mcdx, "1-4i");
 
 static struct cdrom_device_ops mcdx_dops = {
-		open:			mcdx_open,
-		release:		mcdx_close,
-		media_changed:	mcdx_media_changed,
-		tray_move:		mcdx_tray_move,
-		lock_door:		mcdx_lockdoor,
-		audio_ioctl:	mcdx_audio_ioctl,
-		capability:		CDC_OPEN_TRAY | CDC_LOCK | CDC_MEDIA_CHANGED |
-						CDC_PLAY_AUDIO | CDC_DRIVE_STATUS,
+	open:mcdx_open,
+	release:mcdx_close,
+	media_changed:mcdx_media_changed,
+	tray_move:mcdx_tray_move,
+	lock_door:mcdx_lockdoor,
+	audio_ioctl:mcdx_audio_ioctl,
+	capability:CDC_OPEN_TRAY | CDC_LOCK | CDC_MEDIA_CHANGED |
+	    CDC_PLAY_AUDIO | CDC_DRIVE_STATUS,
 };
 
 static struct cdrom_device_info mcdx_info = {
-	ops:				&mcdx_dops,
-	speed:				2,
-	capacity:			1,
-	name:				"mcdx",
+	ops:&mcdx_dops,
+	speed:2,
+	capacity:1,
+	name:"mcdx",
 };
 
 
 /* KERNEL INTERFACE FUNCTIONS **************************************/
 
 
-static int mcdx_audio_ioctl(struct cdrom_device_info * cdi, unsigned int cmd,
-                      void * arg)
+static int mcdx_audio_ioctl(struct cdrom_device_info *cdi,
+			    unsigned int cmd, void *arg)
 {
 	struct s_drive_stuff *stuffp = mcdx_stuffp[MINOR(cdi->dev)];
 
-	if (!stuffp->present) return -ENXIO;
+	if (!stuffp->present)
+		return -ENXIO;
 
-	if (stuffp->xxx)
-	{
-		if(-1 == mcdx_requesttocdata(stuffp, &stuffp->di, 1))
-		{
+	if (stuffp->xxx) {
+		if (-1 == mcdx_requesttocdata(stuffp, &stuffp->di, 1)) {
 			stuffp->lastsector = -1;
-		}
-		else
-		{
+		} else {
 			stuffp->lastsector = (CD_FRAMESIZE / 512)
-					* msf2log(&stuffp->di.msf_leadout) - 1;
+			    * msf2log(&stuffp->di.msf_leadout) - 1;
 		}
 
-		if (stuffp->toc)
-		{
+		if (stuffp->toc) {
 			kfree(stuffp->toc);
 			stuffp->toc = NULL;
-			if (-1 == mcdx_readtoc(stuffp)) return -1;
+			if (-1 == mcdx_readtoc(stuffp))
+				return -1;
 		}
 
-		stuffp->xxx=0;
+		stuffp->xxx = 0;
 	}
 
 	switch (cmd) {
-		case CDROMSTART: {       
-			     xtrace(IOCTL, "ioctl() START\n");
-		        /* Spin up the drive.  Don't think we can do this.
-                 * For now, ignore it.
-                 */
+	case CDROMSTART:{
+			xtrace(IOCTL, "ioctl() START\n");
+			/* Spin up the drive.  Don't think we can do this.
+			   * For now, ignore it.
+			 */
 			return 0;
 		}
 
-		case CDROMSTOP: {
+	case CDROMSTOP:{
 			xtrace(IOCTL, "ioctl() STOP\n");
-            stuffp->audiostatus = CDROM_AUDIO_INVALID;
+			stuffp->audiostatus = CDROM_AUDIO_INVALID;
 			if (-1 == mcdx_stop(stuffp, 1))
 				return -EIO;
 			return 0;
 		}
 
-		case CDROMPLAYTRKIND: {
-			struct cdrom_ti *ti=(struct cdrom_ti *) arg;
+	case CDROMPLAYTRKIND:{
+			struct cdrom_ti *ti = (struct cdrom_ti *) arg;
 
 			xtrace(IOCTL, "ioctl() PLAYTRKIND\n");
 			if ((ti->cdti_trk0 < stuffp->di.n_first)
-					|| (ti->cdti_trk0 > stuffp->di.n_last)
-					|| (ti->cdti_trk1 < stuffp->di.n_first))
-			return -EINVAL;
+			    || (ti->cdti_trk0 > stuffp->di.n_last)
+			    || (ti->cdti_trk1 < stuffp->di.n_first))
+				return -EINVAL;
 			if (ti->cdti_trk1 > stuffp->di.n_last)
-					ti->cdti_trk1 = stuffp->di.n_last;
-            xtrace(PLAYTRK, "ioctl() track %d to %d\n", ti->cdti_trk0, ti->cdti_trk1);
-            return mcdx_playtrk(stuffp, ti);
-        }
+				ti->cdti_trk1 = stuffp->di.n_last;
+			xtrace(PLAYTRK, "ioctl() track %d to %d\n",
+			       ti->cdti_trk0, ti->cdti_trk1);
+			return mcdx_playtrk(stuffp, ti);
+		}
 
-        case CDROMPLAYMSF: {
-            struct cdrom_msf *msf=(struct cdrom_msf *) arg;
+	case CDROMPLAYMSF:{
+			struct cdrom_msf *msf = (struct cdrom_msf *) arg;
 
-            xtrace(IOCTL, "ioctl() PLAYMSF\n");
+			xtrace(IOCTL, "ioctl() PLAYMSF\n");
 
-            if ((stuffp->audiostatus == CDROM_AUDIO_PLAY)
-                && (-1 == mcdx_hold(stuffp, 1))) return -EIO;
+			if ((stuffp->audiostatus == CDROM_AUDIO_PLAY)
+			    && (-1 == mcdx_hold(stuffp, 1)))
+				return -EIO;
 
-            msf->cdmsf_min0 = uint2bcd(msf->cdmsf_min0);
-            msf->cdmsf_sec0 = uint2bcd(msf->cdmsf_sec0);
-            msf->cdmsf_frame0 = uint2bcd(msf->cdmsf_frame0);
+			msf->cdmsf_min0 = uint2bcd(msf->cdmsf_min0);
+			msf->cdmsf_sec0 = uint2bcd(msf->cdmsf_sec0);
+			msf->cdmsf_frame0 = uint2bcd(msf->cdmsf_frame0);
 
-            msf->cdmsf_min1 = uint2bcd(msf->cdmsf_min1);
-            msf->cdmsf_sec1 = uint2bcd(msf->cdmsf_sec1);
-            msf->cdmsf_frame1 = uint2bcd(msf->cdmsf_frame1);
+			msf->cdmsf_min1 = uint2bcd(msf->cdmsf_min1);
+			msf->cdmsf_sec1 = uint2bcd(msf->cdmsf_sec1);
+			msf->cdmsf_frame1 = uint2bcd(msf->cdmsf_frame1);
 
-            stuffp->stop.dt.minute = msf->cdmsf_min1;
-            stuffp->stop.dt.second = msf->cdmsf_sec1;
-            stuffp->stop.dt.frame = msf->cdmsf_frame1;
+			stuffp->stop.dt.minute = msf->cdmsf_min1;
+			stuffp->stop.dt.second = msf->cdmsf_sec1;
+			stuffp->stop.dt.frame = msf->cdmsf_frame1;
 
-            return mcdx_playmsf(stuffp, msf);
-        }
+			return mcdx_playmsf(stuffp, msf);
+		}
 
-        case CDROMRESUME: {
-            xtrace(IOCTL, "ioctl() RESUME\n");
-            return mcdx_playtrk(stuffp, NULL);
-        }
+	case CDROMRESUME:{
+			xtrace(IOCTL, "ioctl() RESUME\n");
+			return mcdx_playtrk(stuffp, NULL);
+		}
 
-		case CDROMREADTOCENTRY: {
-			struct cdrom_tocentry *entry=(struct cdrom_tocentry *) arg;
+	case CDROMREADTOCENTRY:{
+			struct cdrom_tocentry *entry =
+			    (struct cdrom_tocentry *) arg;
 			struct s_subqcode *tp = NULL;
 			xtrace(IOCTL, "ioctl() READTOCENTRY\n");
 
-            if (-1 == mcdx_readtoc(stuffp)) return -1;
+			if (-1 == mcdx_readtoc(stuffp))
+				return -1;
 			if (entry->cdte_track == CDROM_LEADOUT)
-				tp = &stuffp->toc[stuffp->di.n_last - stuffp->di.n_first + 1];
+				tp = &stuffp->toc[stuffp->di.n_last -
+						  stuffp->di.n_first + 1];
 			else if (entry->cdte_track > stuffp->di.n_last
-					|| entry->cdte_track < stuffp->di.n_first) return -EINVAL;
-			else tp = &stuffp->toc[entry->cdte_track - stuffp->di.n_first];
+				 || entry->cdte_track < stuffp->di.n_first)
+				return -EINVAL;
+			else
+				tp = &stuffp->toc[entry->cdte_track -
+						  stuffp->di.n_first];
 
-			if (NULL == tp) 
+			if (NULL == tp)
 				return -EIO;
 			entry->cdte_adr = tp->control;
 			entry->cdte_ctrl = tp->control >> 4;
-            /* Always return stuff in MSF, and let the Uniform cdrom driver
-                worry about what the user actually wants */
-			entry->cdte_addr.msf.minute = bcd2uint(tp->dt.minute);
-			entry->cdte_addr.msf.second = bcd2uint(tp->dt.second);
-			entry->cdte_addr.msf.frame = bcd2uint(tp->dt.frame);
+			/* Always return stuff in MSF, and let the Uniform cdrom driver
+			   worry about what the user actually wants */
+			entry->cdte_addr.msf.minute =
+			    bcd2uint(tp->dt.minute);
+			entry->cdte_addr.msf.second =
+			    bcd2uint(tp->dt.second);
+			entry->cdte_addr.msf.frame =
+			    bcd2uint(tp->dt.frame);
 			return 0;
 		}
 
-		case CDROMSUBCHNL: {
-			struct cdrom_subchnl *sub= (struct cdrom_subchnl *)arg;
+	case CDROMSUBCHNL:{
+			struct cdrom_subchnl *sub =
+			    (struct cdrom_subchnl *) arg;
 			struct s_subqcode q;
 
 			xtrace(IOCTL, "ioctl() SUBCHNL\n");
 
-			if (-1 == mcdx_requestsubqcode(stuffp, &q, 2)) 
+			if (-1 == mcdx_requestsubqcode(stuffp, &q, 2))
 				return -EIO;
 
-            xtrace(SUBCHNL, "audiostatus: %x\n", stuffp->audiostatus);
+			xtrace(SUBCHNL, "audiostatus: %x\n",
+			       stuffp->audiostatus);
 			sub->cdsc_audiostatus = stuffp->audiostatus;
 			sub->cdsc_adr = q.control;
 			sub->cdsc_ctrl = q.control >> 4;
 			sub->cdsc_trk = bcd2uint(q.tno);
 			sub->cdsc_ind = bcd2uint(q.index);
 
-            xtrace(SUBCHNL, "trk %d, ind %d\n",
-                    sub->cdsc_trk, sub->cdsc_ind);
-            /* Always return stuff in MSF, and let the Uniform cdrom driver
-                worry about what the user actually wants */
-			sub->cdsc_absaddr.msf.minute = bcd2uint(q.dt.minute);
-			sub->cdsc_absaddr.msf.second = bcd2uint(q.dt.second);
+			xtrace(SUBCHNL, "trk %d, ind %d\n",
+			       sub->cdsc_trk, sub->cdsc_ind);
+			/* Always return stuff in MSF, and let the Uniform cdrom driver
+			   worry about what the user actually wants */
+			sub->cdsc_absaddr.msf.minute =
+			    bcd2uint(q.dt.minute);
+			sub->cdsc_absaddr.msf.second =
+			    bcd2uint(q.dt.second);
 			sub->cdsc_absaddr.msf.frame = bcd2uint(q.dt.frame);
-			sub->cdsc_reladdr.msf.minute = bcd2uint(q.tt.minute);
-			sub->cdsc_reladdr.msf.second = bcd2uint(q.tt.second);
+			sub->cdsc_reladdr.msf.minute =
+			    bcd2uint(q.tt.minute);
+			sub->cdsc_reladdr.msf.second =
+			    bcd2uint(q.tt.second);
 			sub->cdsc_reladdr.msf.frame = bcd2uint(q.tt.frame);
 			xtrace(SUBCHNL,
-					"msf: abs %02d:%02d:%02d, rel %02d:%02d:%02d\n",
-					sub->cdsc_absaddr.msf.minute, sub->cdsc_absaddr.msf.second,
-					sub->cdsc_absaddr.msf.frame, sub->cdsc_reladdr.msf.minute,
-					sub->cdsc_reladdr.msf.second, sub->cdsc_reladdr.msf.frame);
+			       "msf: abs %02d:%02d:%02d, rel %02d:%02d:%02d\n",
+			       sub->cdsc_absaddr.msf.minute,
+			       sub->cdsc_absaddr.msf.second,
+			       sub->cdsc_absaddr.msf.frame,
+			       sub->cdsc_reladdr.msf.minute,
+			       sub->cdsc_reladdr.msf.second,
+			       sub->cdsc_reladdr.msf.frame);
 
 			return 0;
 		}
 
-		case CDROMREADTOCHDR: {
-			struct cdrom_tochdr *toc=(struct cdrom_tochdr *) arg;
+	case CDROMREADTOCHDR:{
+			struct cdrom_tochdr *toc =
+			    (struct cdrom_tochdr *) arg;
 
 			xtrace(IOCTL, "ioctl() READTOCHDR\n");
 			toc->cdth_trk0 = stuffp->di.n_first;
 			toc->cdth_trk1 = stuffp->di.n_last;
-			xtrace(TOCHDR, "ioctl() track0 = %d, track1 = %d\n",
-					stuffp->di.n_first, stuffp->di.n_last);
+			xtrace(TOCHDR,
+			       "ioctl() track0 = %d, track1 = %d\n",
+			       stuffp->di.n_first, stuffp->di.n_last);
 			return 0;
 		}
 
-		case CDROMPAUSE: {
+	case CDROMPAUSE:{
 			xtrace(IOCTL, "ioctl() PAUSE\n");
-			if (stuffp->audiostatus != CDROM_AUDIO_PLAY) return -EINVAL;
-			if (-1 == mcdx_stop(stuffp, 1)) return -EIO;
-            stuffp->audiostatus = CDROM_AUDIO_PAUSED;
-			if (-1 == mcdx_requestsubqcode(stuffp, &stuffp->start, 1))
+			if (stuffp->audiostatus != CDROM_AUDIO_PLAY)
+				return -EINVAL;
+			if (-1 == mcdx_stop(stuffp, 1))
+				return -EIO;
+			stuffp->audiostatus = CDROM_AUDIO_PAUSED;
+			if (-1 ==
+			    mcdx_requestsubqcode(stuffp, &stuffp->start,
+						 1))
 				return -EIO;
 			return 0;
 		}
 
-		case CDROMMULTISESSION: {
-			struct cdrom_multisession *ms=(struct cdrom_multisession *) arg;
+	case CDROMMULTISESSION:{
+			struct cdrom_multisession *ms =
+			    (struct cdrom_multisession *) arg;
 			xtrace(IOCTL, "ioctl() MULTISESSION\n");
 			/* Always return stuff in LBA, and let the Uniform cdrom driver
-				worry about what the user actually wants */
+			   worry about what the user actually wants */
 			ms->addr.lba = msf2log(&stuffp->multi.msf_last);
 			ms->xa_flag = !!stuffp->multi.multi;
-			xtrace(MS, "ioctl() (%d, 0x%08x [%02x:%02x.%02x])\n",
-				ms->xa_flag, ms->addr.lba, stuffp->multi.msf_last.minute,
-                    stuffp->multi.msf_last.second,stuffp->multi.msf_last.frame);
- 
+			xtrace(MS,
+			       "ioctl() (%d, 0x%08x [%02x:%02x.%02x])\n",
+			       ms->xa_flag, ms->addr.lba,
+			       stuffp->multi.msf_last.minute,
+			       stuffp->multi.msf_last.second,
+			       stuffp->multi.msf_last.frame);
+
 			return 0;
 		}
 
-		case CDROMEJECT: {
+	case CDROMEJECT:{
 			xtrace(IOCTL, "ioctl() EJECT\n");
-			if (stuffp->users > 1) return -EBUSY;
-			return(mcdx_tray_move(cdi, 1));
+			if (stuffp->users > 1)
+				return -EBUSY;
+			return (mcdx_tray_move(cdi, 1));
 		}
 
-        case CDROMCLOSETRAY: {
-            xtrace(IOCTL, "ioctl() CDROMCLOSETRAY\n");
-            return(mcdx_tray_move(cdi, 0));
-        }
+	case CDROMCLOSETRAY:{
+			xtrace(IOCTL, "ioctl() CDROMCLOSETRAY\n");
+			return (mcdx_tray_move(cdi, 0));
+		}
 
-        case CDROMVOLCTRL: {
-			struct cdrom_volctrl *volctrl=(struct cdrom_volctrl *)arg;
-            xtrace(IOCTL, "ioctl() VOLCTRL\n");
+	case CDROMVOLCTRL:{
+			struct cdrom_volctrl *volctrl =
+			    (struct cdrom_volctrl *) arg;
+			xtrace(IOCTL, "ioctl() VOLCTRL\n");
 
-#if 0		/* not tested! */
+#if 0				/* not tested! */
 			/* adjust for the weirdness of workman (md) */
 			/* can't test it (hs) */
 			volctrl.channel2 = volctrl.channel1;
 			volctrl.channel1 = volctrl.channel3 = 0x00;
 #endif
-            return mcdx_setattentuator(stuffp, volctrl, 2);
-        }
+			return mcdx_setattentuator(stuffp, volctrl, 2);
+		}
 
-		default:
-			xwarn("ioctl(): unknown request 0x%04x\n", cmd);
-	    	return -EINVAL;
+	default:
+		return -EINVAL;
 	}
 }
 
 void do_mcdx_request(request_queue_t * q)
 {
-    int dev;
-    struct s_drive_stuff *stuffp;
+	int dev;
+	struct s_drive_stuff *stuffp;
 
-  again:
+      again:
 
 	if (QUEUE_EMPTY) {
 		xtrace(REQUEST, "end_request(0): CURRENT == NULL\n");
@@ -525,237 +559,257 @@
 	}
 
 	if (CURRENT->rq_status == RQ_INACTIVE) {
-		xtrace(REQUEST, "end_request(0): rq_status == RQ_INACTIVE\n");
+		xtrace(REQUEST,
+		       "end_request(0): rq_status == RQ_INACTIVE\n");
 		return;
 	}
 
-    INIT_REQUEST;
+	INIT_REQUEST;
 
-    dev = MINOR(CURRENT->rq_dev);
-    stuffp = mcdx_stuffp[dev];
+	dev = MINOR(CURRENT->rq_dev);
+	stuffp = mcdx_stuffp[dev];
 
 	if ((dev < 0)
-		|| (dev >= MCDX_NDRIVES)
-		|| !stuffp
-		|| (!stuffp->present)) {
+	    || (dev >= MCDX_NDRIVES)
+	    || !stuffp || (!stuffp->present)) {
 		xwarn("do_request(): bad device: %s\n",
-				kdevname(CURRENT->rq_dev));
+		      kdevname(CURRENT->rq_dev));
 		xtrace(REQUEST, "end_request(0): bad device\n");
-		end_request(0); return;
-    }
+		end_request(0);
+		return;
+	}
 
 	if (stuffp->audio) {
 		xwarn("do_request() attempt to read from audio cd\n");
 		xtrace(REQUEST, "end_request(0): read from audio\n");
-		end_request(0); return;
+		end_request(0);
+		return;
 	}
 
 	xtrace(REQUEST, "do_request() (%lu + %lu)\n",
-			CURRENT->sector, CURRENT->nr_sectors);
+	       CURRENT->sector, CURRENT->nr_sectors);
 
-    switch (CURRENT->cmd) {
-      case WRITE:
-	  xwarn("do_request(): attempt to write to cd!!\n");
-	  xtrace(REQUEST, "end_request(0): write\n");
-	  end_request(0); return;
-
-      case READ:
-	  stuffp->status = 0;
-	  while (CURRENT->nr_sectors) {
-	      int i;
-
-	      i = mcdx_transfer(stuffp,
-				  CURRENT->buffer,
-				  CURRENT->sector,
-				  CURRENT->nr_sectors);
-
-		  if (i == -1) {
-			  end_request(0);
-			  goto again;
-		  }
-		  CURRENT->sector += i;
-	 	  CURRENT->nr_sectors -= i;
-		  CURRENT->buffer += (i * 512);
-	  }
-	  end_request(1);
-	  goto again;
-
-	  xtrace(REQUEST, "end_request(1)\n");
-	  end_request(1);
-	  break;
-
-      default:
-	  panic(MCDX "do_request: unknown command.\n");
-	  break;
-    }
+	switch (CURRENT->cmd) {
+	case WRITE:
+		xwarn("do_request(): attempt to write to cd!!\n");
+		xtrace(REQUEST, "end_request(0): write\n");
+		end_request(0);
+		return;
+
+	case READ:
+		stuffp->status = 0;
+		while (CURRENT->nr_sectors) {
+			int i;
+
+			i = mcdx_transfer(stuffp,
+					  CURRENT->buffer,
+					  CURRENT->sector,
+					  CURRENT->nr_sectors);
+
+			if (i == -1) {
+				end_request(0);
+				goto again;
+			}
+			CURRENT->sector += i;
+			CURRENT->nr_sectors -= i;
+			CURRENT->buffer += (i * 512);
+		}
+		end_request(1);
+		goto again;
+
+		xtrace(REQUEST, "end_request(1)\n");
+		end_request(1);
+		break;
+
+	default:
+		panic(MCDX "do_request: unknown command.\n");
+		break;
+	}
 
-    goto again;
+	goto again;
 }
 
-static int 
-mcdx_open(struct cdrom_device_info * cdi, int purpose)
+static int mcdx_open(struct cdrom_device_info *cdi, int purpose)
 {
-    struct s_drive_stuff *stuffp;
+	struct s_drive_stuff *stuffp;
 	xtrace(OPENCLOSE, "open()\n");
-    stuffp = mcdx_stuffp[MINOR(cdi->dev)];
-    if (!stuffp->present) return -ENXIO;
+	stuffp = mcdx_stuffp[MINOR(cdi->dev)];
+	if (!stuffp->present)
+		return -ENXIO;
 
 	/* Make the modules looking used ... (thanx bjorn).
 	 * But we shouldn't forget to decrement the module counter
 	 * on error return */
 	MOD_INC_USE_COUNT;
 
-    /* this is only done to test if the drive talks with us */
-    if (-1 == mcdx_getstatus(stuffp, 1)) {
+	/* this is only done to test if the drive talks with us */
+	if (-1 == mcdx_getstatus(stuffp, 1)) {
 		MOD_DEC_USE_COUNT;
 		return -EIO;
 	}
 
-    if (stuffp->xxx) {
+	if (stuffp->xxx) {
+
+		xtrace(OPENCLOSE, "open() media changed\n");
+		stuffp->audiostatus = CDROM_AUDIO_INVALID;
+		stuffp->readcmd = 0;
+		xtrace(OPENCLOSE, "open() Request multisession info\n");
+		if (-1 ==
+		    mcdx_requestmultidiskinfo(stuffp, &stuffp->multi, 6))
+			xinfo("No multidiskinfo\n");
+	} else {
+		/* multisession ? */
+		if (!stuffp->multi.multi)
+			stuffp->multi.msf_last.second = 2;
+
+		xtrace(OPENCLOSE, "open() MS: %d, last @ %02x:%02x.%02x\n",
+		       stuffp->multi.multi,
+		       stuffp->multi.msf_last.minute,
+		       stuffp->multi.msf_last.second,
+		       stuffp->multi.msf_last.frame);
+
+		{;
+		}		/* got multisession information */
+		/* request the disks table of contents (aka diskinfo) */
+		if (-1 == mcdx_requesttocdata(stuffp, &stuffp->di, 1)) {
+
+			stuffp->lastsector = -1;
 
-        xtrace(OPENCLOSE, "open() media changed\n");
-        stuffp->audiostatus = CDROM_AUDIO_INVALID;
-        stuffp->readcmd = 0;
-        xtrace(OPENCLOSE, "open() Request multisession info\n");
-        if (-1 == mcdx_requestmultidiskinfo( stuffp, &stuffp->multi, 6))
-            	xinfo("No multidiskinfo\n");
 		} else {
-            /* multisession ? */
-            if (!stuffp->multi.multi)
-                stuffp->multi.msf_last.second = 2;
-
-            xtrace(OPENCLOSE, "open() MS: %d, last @ %02x:%02x.%02x\n",
-                    stuffp->multi.multi,
-                    stuffp->multi.msf_last.minute,
-                    stuffp->multi.msf_last.second,
-                    stuffp->multi.msf_last.frame);
-
-        { ; } /* got multisession information */
-        /* request the disks table of contents (aka diskinfo) */
-        if (-1 == mcdx_requesttocdata(stuffp, &stuffp->di, 1)) {
-
-            stuffp->lastsector = -1;
-
-        } else {
-
-            stuffp->lastsector = (CD_FRAMESIZE / 512)
-                    * msf2log(&stuffp->di.msf_leadout) - 1;
-
-            xtrace(OPENCLOSE, "open() start %d (%02x:%02x.%02x) %d\n",
-                    stuffp->di.n_first,
-                    stuffp->di.msf_first.minute,
-                    stuffp->di.msf_first.second,
-                    stuffp->di.msf_first.frame,
-                    msf2log(&stuffp->di.msf_first));
-            xtrace(OPENCLOSE, "open() last %d (%02x:%02x.%02x) %d\n",
-                    stuffp->di.n_last,
-                    stuffp->di.msf_leadout.minute,
-                    stuffp->di.msf_leadout.second,
-                    stuffp->di.msf_leadout.frame,
-                    msf2log(&stuffp->di.msf_leadout));
-        }
-      
-        if (stuffp->toc) {
-            xtrace(MALLOC, "open() free old toc @ %p\n", stuffp->toc);
-            kfree(stuffp->toc);
-
-            stuffp->toc = NULL;
-        }
-
-        xtrace(OPENCLOSE, "open() init irq generation\n");
-        if (-1 == mcdx_config(stuffp, 1)) {
-            MOD_DEC_USE_COUNT;
-            return -EIO;
-        }
 
+			stuffp->lastsector = (CD_FRAMESIZE / 512)
+			    * msf2log(&stuffp->di.msf_leadout) - 1;
+
+			xtrace(OPENCLOSE,
+			       "open() start %d (%02x:%02x.%02x) %d\n",
+			       stuffp->di.n_first,
+			       stuffp->di.msf_first.minute,
+			       stuffp->di.msf_first.second,
+			       stuffp->di.msf_first.frame,
+			       msf2log(&stuffp->di.msf_first));
+			xtrace(OPENCLOSE,
+			       "open() last %d (%02x:%02x.%02x) %d\n",
+			       stuffp->di.n_last,
+			       stuffp->di.msf_leadout.minute,
+			       stuffp->di.msf_leadout.second,
+			       stuffp->di.msf_leadout.frame,
+			       msf2log(&stuffp->di.msf_leadout));
+		}
+
+		if (stuffp->toc) {
+			xtrace(MALLOC, "open() free old toc @ %p\n",
+			       stuffp->toc);
+			kfree(stuffp->toc);
+
+			stuffp->toc = NULL;
+		}
+
+		xtrace(OPENCLOSE, "open() init irq generation\n");
+		if (-1 == mcdx_config(stuffp, 1)) {
+			MOD_DEC_USE_COUNT;
+			return -EIO;
+		}
 #if FALLBACK
-        /* Set the read speed */
-        xwarn("AAA %x AAA\n", stuffp->readcmd);
-        if (stuffp->readerrs) stuffp->readcmd = READ1X;
-        else stuffp->readcmd =
-                stuffp->present | SINGLE ? READ1X : READ2X;
-        xwarn("XXX %x XXX\n", stuffp->readcmd);
+		/* Set the read speed */
+		xwarn("AAA %x AAA\n", stuffp->readcmd);
+		if (stuffp->readerrs)
+			stuffp->readcmd = READ1X;
+		else
+			stuffp->readcmd =
+			    stuffp->present | SINGLE ? READ1X : READ2X;
+		xwarn("XXX %x XXX\n", stuffp->readcmd);
 #else
-        stuffp->readcmd = stuffp->present | SINGLE ? READ1X : READ2X;
+		stuffp->readcmd =
+		    stuffp->present | SINGLE ? READ1X : READ2X;
 #endif
 
-        /* try to get the first sector, iff any ... */
-        if (stuffp->lastsector >= 0) {
-            char buf[512];
-            int ans;
-            int tries;
-
-            stuffp->xa = 0;
-            stuffp->audio = 0;
-
-            for (tries = 6; tries; tries--) {
-
-                stuffp->introk = 1;
-
-                xtrace(OPENCLOSE, "open() try as %s\n",
-                    stuffp->xa ? "XA" : "normal");
-                /* set data mode */
-                if (-1 == (ans = mcdx_setdatamode(stuffp,
-                        stuffp->xa ? MODE2 : MODE1, 1))) {
-                    /* MOD_DEC_USE_COUNT, return -EIO; */
-                    stuffp->xa = 0;
-                    break;
-                }
-
-                if ((stuffp->audio = e_audio(ans))) break;
-
-                while (0 == (ans = mcdx_transfer(stuffp, buf, 0, 1)))
-                    ;
-
-                if (ans == 1) break;
-                stuffp->xa = !stuffp->xa;
-            }
-        }
-        /* xa disks will be read in raw mode, others not */
-        if (-1 == mcdx_setdrivemode(stuffp,
-                stuffp->xa ? RAW : COOKED, 1)) {
-            MOD_DEC_USE_COUNT;
-            return -EIO;
-        }
-        if (stuffp->audio) {
-            xinfo("open() audio disk found\n");
-        } else if (stuffp->lastsector >= 0) {
-            xinfo("open() %s%s disk found\n",
-                    stuffp->xa ? "XA / " : "",
-                    stuffp->multi.multi ? "Multi Session" : "Single Session");
-        }
-    }
+		/* try to get the first sector, iff any ... */
+		if (stuffp->lastsector >= 0) {
+			char buf[512];
+			int ans;
+			int tries;
+
+			stuffp->xa = 0;
+			stuffp->audio = 0;
+
+			for (tries = 6; tries; tries--) {
+
+				stuffp->introk = 1;
+
+				xtrace(OPENCLOSE, "open() try as %s\n",
+				       stuffp->xa ? "XA" : "normal");
+				/* set data mode */
+				if (-1 == (ans = mcdx_setdatamode(stuffp,
+								  stuffp->
+								  xa ?
+								  MODE2 :
+								  MODE1,
+								  1))) {
+					/* MOD_DEC_USE_COUNT, return -EIO; */
+					stuffp->xa = 0;
+					break;
+				}
+
+				if ((stuffp->audio = e_audio(ans)))
+					break;
+
+				while (0 ==
+				       (ans =
+					mcdx_transfer(stuffp, buf, 0, 1)));
+
+				if (ans == 1)
+					break;
+				stuffp->xa = !stuffp->xa;
+			}
+		}
+		/* xa disks will be read in raw mode, others not */
+		if (-1 == mcdx_setdrivemode(stuffp,
+					    stuffp->xa ? RAW : COOKED,
+					    1)) {
+			MOD_DEC_USE_COUNT;
+			return -EIO;
+		}
+		if (stuffp->audio) {
+			xinfo("open() audio disk found\n");
+		} else if (stuffp->lastsector >= 0) {
+			xinfo("open() %s%s disk found\n",
+			      stuffp->xa ? "XA / " : "",
+			      stuffp->multi.
+			      multi ? "Multi Session" : "Single Session");
+		}
+	}
 	stuffp->xxx = 0;
-    stuffp->users++;
-    return 0;
+	stuffp->users++;
+	return 0;
 }
 
-static void mcdx_close(struct cdrom_device_info * cdi)
+static void mcdx_close(struct cdrom_device_info *cdi)
 {
-    struct s_drive_stuff *stuffp;
+	struct s_drive_stuff *stuffp;
 
-    xtrace(OPENCLOSE, "close()\n");
+	xtrace(OPENCLOSE, "close()\n");
 
-    stuffp = mcdx_stuffp[MINOR(cdi->dev)];
+	stuffp = mcdx_stuffp[MINOR(cdi->dev)];
 
-    --stuffp->users;
+	--stuffp->users;
 
-    MOD_DEC_USE_COUNT;
+	MOD_DEC_USE_COUNT;
 }
 
-static int mcdx_media_changed(struct cdrom_device_info * cdi, int disc_nr) 
+static int mcdx_media_changed(struct cdrom_device_info *cdi, int disc_nr)
 /*	Return: 1 if media changed since last call to this function
 			0 otherwise */
 {
-    struct s_drive_stuff *stuffp;
+	struct s_drive_stuff *stuffp;
 
-    xinfo("mcdx_media_changed called for device %s\n",
-	  kdevname(cdi->dev));
+	xinfo("mcdx_media_changed called for device %s\n",
+	      kdevname(cdi->dev));
 
 	stuffp = mcdx_stuffp[MINOR(cdi->dev)];
 	mcdx_getstatus(stuffp, 1);
 
-	if (stuffp->yyy == 0) return 0;
+	if (stuffp->yyy == 0)
+		return 0;
 
 	stuffp->yyy = 0;
 	return 1;
@@ -765,10 +819,12 @@
 static int __init mcdx_setup(char *str)
 {
 	int pi[4];
-	(void)get_options(str, ARRAY_SIZE(pi), pi);
-	
-	if (pi[0] > 0) mcdx_drive_map[0][0] = pi[1];
-	if (pi[0] > 1) mcdx_drive_map[0][1] = pi[2];
+	(void) get_options(str, ARRAY_SIZE(pi), pi);
+
+	if (pi[0] > 0)
+		mcdx_drive_map[0][0] = pi[1];
+	if (pi[0] > 1)
+		mcdx_drive_map[0][1] = pi[2];
 	return 1;
 }
 
@@ -787,7 +843,8 @@
  *	May be we could use a simple count loop w/ jumps to itself, but
  *	I wanna make this independent of cpu speed. [1 jiffy is 1/HZ] sec */
 {
-	if (jifs < 0) return;
+	if (jifs < 0)
+		return;
 
 	xtrace(SLEEP, "*** delay: sleepq\n");
 	interruptible_sleep_on_timeout(&stuff->sleepq, jifs);
@@ -797,24 +854,22 @@
 	}
 }
 
-static void
-mcdx_intr(int irq, void *dev_id, struct pt_regs* regs)
+static void mcdx_intr(int irq, void *dev_id, struct pt_regs *regs)
 {
-    struct s_drive_stuff *stuffp;
+	struct s_drive_stuff *stuffp;
 	unsigned char b;
 
-    stuffp = mcdx_irq_map[irq];
+	stuffp = mcdx_irq_map[irq];
 
-    if (stuffp == NULL ) {
+	if (stuffp == NULL) {
 		xwarn("mcdx: no device for intr %d\n", irq);
 		return;
-    }
-
+	}
 #ifdef AK2
-	if ( !stuffp->busy && stuffp->pending )
+	if (!stuffp->busy && stuffp->pending)
 		stuffp->int_err = 1;
 
-#endif /* AK2 */
+#endif				/* AK2 */
 	/* get the interrupt status */
 	b = inb((unsigned int) stuffp->rreg_status);
 	stuffp->introk = ~b & MCDX_RBIT_DTEN;
@@ -829,26 +884,23 @@
 	if (!stuffp->introk) {
 		xtrace(IRQ, "intr() irq %d hw status 0x%02x\n", irq, b);
 		if (~b & MCDX_RBIT_STEN) {
-			xinfo(  "intr() irq %d    status 0x%02x\n",
-					irq, inb((unsigned int) stuffp->rreg_data));
+			xinfo("intr() irq %d    status 0x%02x\n",
+			      irq, inb((unsigned int) stuffp->rreg_data));
 		} else {
-			xinfo(  "intr() irq %d ambiguous hw status\n", irq);
+			xinfo("intr() irq %d ambiguous hw status\n", irq);
 		}
 	} else {
 		xtrace(IRQ, "irq() irq %d ok, status %02x\n", irq, b);
-    }
+	}
 
-    stuffp->busy = 0;
-    wake_up_interruptible(&stuffp->busyq);
+	stuffp->busy = 0;
+	wake_up_interruptible(&stuffp->busyq);
 }
 
 
-static int
-mcdx_talk (
-		struct s_drive_stuff *stuffp,
-		const unsigned char *cmd, size_t cmdlen,
-		void *buffer, size_t size,
-		unsigned int timeout, int tries)
+static int mcdx_talk(struct s_drive_stuff *stuffp,
+	  const unsigned char *cmd, size_t cmdlen,
+	  void *buffer, size_t size, unsigned int timeout, int tries)
 /* Send a command to the drive, wait for the result.
  * returns -1 on timeout, drive status otherwise
  * If buffer is not zero, the result (length size) is stored there.
@@ -857,99 +909,108 @@
  */
 {
 	int st;
-    char c;
-    int discard;
+	char c;
+	int discard;
 
 	/* Somebody wants the data read? */
-    if ((discard = (buffer == NULL))) buffer = &c;
+	if ((discard = (buffer == NULL)))
+		buffer = &c;
 
-    while (stuffp->lock) {
+	while (stuffp->lock) {
 		xtrace(SLEEP, "*** talk: lockq\n");
 		interruptible_sleep_on(&stuffp->lockq);
 		xtrace(SLEEP, "talk: awoken\n");
 	}
 
-    stuffp->lock = 1;
+	stuffp->lock = 1;
 
 	/* An operation other then reading data destroys the
-     * data already requested and remembered in stuffp->request, ... */
-    stuffp->valid = 0;
+	   * data already requested and remembered in stuffp->request, ... */
+	stuffp->valid = 0;
 
 #if MCDX_DEBUG & TALK
 	{
 		unsigned char i;
-		xtrace(TALK, "talk() %d / %d tries, res.size %d, command 0x%02x",
-				tries, timeout, size, (unsigned char) cmd[0]);
-		for (i = 1; i < cmdlen; i++) xtrace(TALK, " 0x%02x", cmd[i]);
+		xtrace(TALK,
+		       "talk() %d / %d tries, res.size %d, command 0x%02x",
+		       tries, timeout, size, (unsigned char) cmd[0]);
+		for (i = 1; i < cmdlen; i++)
+			xtrace(TALK, " 0x%02x", cmd[i]);
 		xtrace(TALK, "\n");
 	}
 #endif
 
-    /*  give up if all tries are done (bad) or if the status
-     *  st != -1 (good) */
+	/*  give up if all tries are done (bad) or if the status
+	 *  st != -1 (good) */
 	for (st = -1; st == -1 && tries; tries--) {
 
-		char *bp = (char*) buffer;
+		char *bp = (char *) buffer;
 		size_t sz = size;
 
 		outsb((unsigned int) stuffp->wreg_data, cmd, cmdlen);
-        xtrace(TALK, "talk() command sent\n");
+		xtrace(TALK, "talk() command sent\n");
 
-        /* get the status byte */
-        if (-1 == mcdx_getval(stuffp, timeout, 0, bp)) {
-            xinfo("talk() %02x timed out (status), %d tr%s left\n",
-                    cmd[0], tries - 1, tries == 2 ? "y" : "ies");
-                continue;
-        }
-        st = *bp;
-        sz--;
-        if (!discard) bp++;
-
-        xtrace(TALK, "talk() got status 0x%02x\n", st);
-
-        /* command error? */
-        if (e_cmderr(st)) {
-            xwarn("command error cmd = %02x %s \n",
-                    cmd[0], cmdlen > 1 ? "..." : "");
-            st = -1;
-            continue;
-		}
-
-        /* audio status? */
-        if (stuffp->audiostatus == CDROM_AUDIO_INVALID)
-            stuffp->audiostatus =
-                    e_audiobusy(st) ? CDROM_AUDIO_PLAY : CDROM_AUDIO_NO_STATUS;
-        else if (stuffp->audiostatus == CDROM_AUDIO_PLAY
-                && e_audiobusy(st) == 0)
-            stuffp->audiostatus = CDROM_AUDIO_COMPLETED;
-
-        /* media change? */
-        if (e_changed(st)) {
-            xinfo("talk() media changed\n");
-            stuffp->xxx = stuffp->yyy = 1;
-        }
-
-        /* now actually get the data */
-        while (sz--) {
-            if (-1 == mcdx_getval(stuffp, timeout, 0, bp)) {
-                xinfo("talk() %02x timed out (data), %d tr%s left\n",
-                        cmd[0], tries - 1, tries == 2 ? "y" : "ies");
-                st = -1; break;
-            }
-            if (!discard) bp++;
-            xtrace(TALK, "talk() got 0x%02x\n", *(bp - 1));
-        }
-    }
+		/* get the status byte */
+		if (-1 == mcdx_getval(stuffp, timeout, 0, bp)) {
+			xinfo("talk() %02x timed out (status), %d tr%s left\n",
+			     cmd[0], tries - 1, tries == 2 ? "y" : "ies");
+			continue;
+		}
+		st = *bp;
+		sz--;
+		if (!discard)
+			bp++;
+
+		xtrace(TALK, "talk() got status 0x%02x\n", st);
+
+		/* command error? */
+		if (e_cmderr(st)) {
+			xwarn("command error cmd = %02x %s \n",
+			      cmd[0], cmdlen > 1 ? "..." : "");
+			st = -1;
+			continue;
+		}
+
+		/* audio status? */
+		if (stuffp->audiostatus == CDROM_AUDIO_INVALID)
+			stuffp->audiostatus =
+			    e_audiobusy(st) ? CDROM_AUDIO_PLAY :
+			    CDROM_AUDIO_NO_STATUS;
+		else if (stuffp->audiostatus == CDROM_AUDIO_PLAY
+			 && e_audiobusy(st) == 0)
+			stuffp->audiostatus = CDROM_AUDIO_COMPLETED;
+
+		/* media change? */
+		if (e_changed(st)) {
+			xinfo("talk() media changed\n");
+			stuffp->xxx = stuffp->yyy = 1;
+		}
+
+		/* now actually get the data */
+		while (sz--) {
+			if (-1 == mcdx_getval(stuffp, timeout, 0, bp)) {
+				xinfo("talk() %02x timed out (data), %d tr%s left\n",
+				     cmd[0], tries - 1,
+				     tries == 2 ? "y" : "ies");
+				st = -1;
+				break;
+			}
+			if (!discard)
+				bp++;
+			xtrace(TALK, "talk() got 0x%02x\n", *(bp - 1));
+		}
+	}
 
 #if !MCDX_QUIET
-    if (!tries && st == -1) xinfo("talk() giving up\n");
+	if (!tries && st == -1)
+		xinfo("talk() giving up\n");
 #endif
 
-    stuffp->lock = 0;
-    wake_up_interruptible(&stuffp->lockq);
+	stuffp->lock = 0;
+	wake_up_interruptible(&stuffp->lockq);
 
 	xtrace(TALK, "talk() done with 0x%02x\n", st);
-    return st;
+	return st;
 }
 
 /* MODULE STUFF ***********************************************************/
@@ -962,51 +1023,56 @@
 	int drives = 0;
 
 	mcdx_init();
-	for (i = 0; i < MCDX_NDRIVES; i++)  {
+	for (i = 0; i < MCDX_NDRIVES; i++) {
 		if (mcdx_stuffp[i]) {
-		xtrace(INIT, "init_module() drive %d stuff @ %p\n",
-				i, mcdx_stuffp[i]);
+			xtrace(INIT, "init_module() drive %d stuff @ %p\n",
+			       i, mcdx_stuffp[i]);
 			drives++;
 		}
 	}
 
-    if (!drives)
+	if (!drives)
 		return -EIO;
 
-    return 0;
+	return 0;
 }
 
 void __exit mcdx_exit(void)
 {
-    int i;
+	int i;
 
 	xinfo("cleanup_module called\n");
 
-    for (i = 0; i < MCDX_NDRIVES; i++) {
+	for (i = 0; i < MCDX_NDRIVES; i++) {
 		struct s_drive_stuff *stuffp;
-        	if (unregister_cdrom(&mcdx_info)) {
+		if (unregister_cdrom(&mcdx_info)) {
 			printk(KERN_WARNING "Can't unregister cdrom mcdx\n");
 			return;
 		}
 		stuffp = mcdx_stuffp[i];
-		if (!stuffp) continue;
-		release_region((unsigned long) stuffp->wreg_data, MCDX_IO_SIZE);
+		if (!stuffp)
+			continue;
+		release_region((unsigned long) stuffp->wreg_data,
+			       MCDX_IO_SIZE);
 		free_irq(stuffp->irq, NULL);
 		if (stuffp->toc) {
-			xtrace(MALLOC, "cleanup_module() free toc @ %p\n", stuffp->toc);
+			xtrace(MALLOC, "cleanup_module() free toc @ %p\n",
+			       stuffp->toc);
 			kfree(stuffp->toc);
 		}
-		xtrace(MALLOC, "cleanup_module() free stuffp @ %p\n", stuffp);
+		xtrace(MALLOC, "cleanup_module() free stuffp @ %p\n",
+		       stuffp);
 		mcdx_stuffp[i] = NULL;
 		kfree(stuffp);
-    }
+	}
 
-    if (devfs_unregister_blkdev(MAJOR_NR, "mcdx") != 0) {
-        xwarn("cleanup() unregister_blkdev() failed\n");
-    }
+	if (devfs_unregister_blkdev(MAJOR_NR, "mcdx") != 0) {
+		xwarn("cleanup() unregister_blkdev() failed\n");
+	}
 	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
 #if !MCDX_QUIET
-	else xinfo("cleanup() succeeded\n");
+	else
+	xinfo("cleanup() succeeded\n");
 #endif
 }
 
@@ -1021,7 +1087,7 @@
 int __init mcdx_init_drive(int drive)
 {
 	struct s_version version;
-	struct s_drive_stuff* stuffp;
+	struct s_drive_stuff *stuffp;
 	int size = sizeof(*stuffp);
 	char msg[80];
 
@@ -1047,11 +1113,12 @@
 
 	/* setup our irq and i/o addresses */
 	stuffp->irq = irq(mcdx_drive_map[drive]);
-	stuffp->wreg_data = stuffp->rreg_data = port(mcdx_drive_map[drive]);
+	stuffp->wreg_data = stuffp->rreg_data =
+	    port(mcdx_drive_map[drive]);
 	stuffp->wreg_reset = stuffp->rreg_status = stuffp->wreg_data + 1;
 	stuffp->wreg_hcon = stuffp->wreg_reset + 1;
 	stuffp->wreg_chn = stuffp->wreg_hcon + 1;
-	
+
 	init_waitqueue_head(&stuffp->busyq);
 	init_waitqueue_head(&stuffp->lockq);
 	init_waitqueue_head(&stuffp->sleepq);
@@ -1066,7 +1133,7 @@
 		xtrace(MALLOC, "init() free stuffp @ %p\n", stuffp);
 		kfree(stuffp);
 		xtrace(INIT, "init() continue at next drive\n");
-		return 0; /* next drive */
+		return 0;	/* next drive */
 	}
 
 	xtrace(INIT, "init() i/o port is available at 0x%3p\n",
@@ -1078,8 +1145,7 @@
 	if (-1 == mcdx_requestversion(stuffp, &version, 4)) {
 		/* failed, next drive */
 		xwarn("%s=0x%3p,%d: Init failed. Can't get version.\n",
-		      MCDX,
-		      stuffp->wreg_data, stuffp->irq);
+		      MCDX, stuffp->wreg_data, stuffp->irq);
 		xtrace(MALLOC, "init() free stuffp @ %p\n", stuffp);
 		kfree(stuffp);
 		xtrace(INIT, "init() continue at next drive\n");
@@ -1088,35 +1154,35 @@
 
 	switch (version.code) {
 	case 'D':
-                stuffp->readcmd = READ2X;
-                stuffp->present = DOUBLE | DOOR | MULTI;
-                break;
+		stuffp->readcmd = READ2X;
+		stuffp->present = DOUBLE | DOOR | MULTI;
+		break;
 	case 'F':
-                stuffp->readcmd = READ1X;
-                stuffp->present = SINGLE | DOOR | MULTI;
-                break;
+		stuffp->readcmd = READ1X;
+		stuffp->present = SINGLE | DOOR | MULTI;
+		break;
 	case 'M':
-                stuffp->readcmd = READ1X;
-                stuffp->present = SINGLE;
-                break;
+		stuffp->readcmd = READ1X;
+		stuffp->present = SINGLE;
+		break;
 	default:
-                stuffp->present = 0; break;
+		stuffp->present = 0;
+		break;
 	}
 
-        stuffp->playcmd = READ1X;
+	stuffp->playcmd = READ1X;
 
 	if (!stuffp->present) {
 		xwarn("%s=0x%3p,%d: Init failed. No Mitsumi CD-ROM?.\n",
 		      MCDX, stuffp->wreg_data, stuffp->irq);
 		kfree(stuffp);
-		return 0; /* next drive */
+		return 0;	/* next drive */
 	}
 
 	xtrace(INIT, "init() register blkdev\n");
 	if (devfs_register_blkdev(MAJOR_NR, "mcdx", &cdrom_fops) != 0) {
 		xwarn("%s=0x%3p,%d: Init failed. Can't get major %d.\n",
-		      MCDX,
-		      stuffp->wreg_data, stuffp->irq, MAJOR_NR);
+		      MCDX, stuffp->wreg_data, stuffp->irq, MAJOR_NR);
 		kfree(stuffp);
 		return 1;
 	}
@@ -1129,21 +1195,19 @@
 	mcdx_irq_map[stuffp->irq] = stuffp;
 	if (request_irq(stuffp->irq, mcdx_intr, SA_INTERRUPT, "mcdx", NULL)) {
 		xwarn("%s=0x%3p,%d: Init failed. Can't get irq (%d).\n",
-		      MCDX,
-		      stuffp->wreg_data, stuffp->irq, stuffp->irq);
+		      MCDX, stuffp->wreg_data, stuffp->irq, stuffp->irq);
 		stuffp->irq = 0;
 		blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
 		kfree(stuffp);
 		return 0;
 	}
 	request_region((unsigned int) stuffp->wreg_data,
-		       MCDX_IO_SIZE,
-		       "mcdx");
+		       MCDX_IO_SIZE, "mcdx");
 
 	xtrace(INIT, "init() get garbage\n");
 	{
 		int i;
-		mcdx_delay(stuffp, HZ/2);
+		mcdx_delay(stuffp, HZ / 2);
 		for (i = 100; i; i--)
 			(void) inb((unsigned int) stuffp->rreg_status);
 	}
@@ -1160,24 +1224,23 @@
 	stuffp->minor = drive;
 
 	sprintf(msg, " mcdx: Mitsumi CD-ROM installed at 0x%3p, irq %d."
-		" (Firmware version %c %x)\n", 
-		stuffp->wreg_data, stuffp->irq, version.code,
-		version.ver);
+		" (Firmware version %c %x)\n",
+		stuffp->wreg_data, stuffp->irq, version.code, version.ver);
 	mcdx_stuffp[drive] = stuffp;
 	xtrace(INIT, "init() mcdx_stuffp[%d] = %p\n", drive, stuffp);
-	mcdx_info.dev = MKDEV(MAJOR_NR,0);
-        if (register_cdrom(&mcdx_info) != 0) {
+	mcdx_info.dev = MKDEV(MAJOR_NR, 0);
+	if (register_cdrom(&mcdx_info) != 0) {
 		printk("Cannot register Mitsumi CD-ROM!\n");
 		release_region((unsigned long) stuffp->wreg_data,
 			       MCDX_IO_SIZE);
 		free_irq(stuffp->irq, NULL);
 		kfree(stuffp);
 		if (devfs_unregister_blkdev(MAJOR_NR, "mcdx") != 0)
-        		xwarn("cleanup() unregister_blkdev() failed\n");
+			xwarn("cleanup() unregister_blkdev() failed\n");
 		blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
 		return 2;
-        }
-        printk(msg);
+	}
+	printk(msg);
 	return 0;
 }
 
@@ -1198,7 +1261,7 @@
 
 	/* do the initialisation */
 	for (drive = 0; drive < MCDX_NDRIVES; drive++) {
-		switch(mcdx_init_drive(drive)) {
+		switch (mcdx_init_drive(drive)) {
 		case 2:
 			return -EIO;
 		case 1:
@@ -1208,9 +1271,8 @@
 	return 0;
 }
 
-static int
-mcdx_transfer(struct s_drive_stuff *stuffp,
-		char *p, int sector, int nr_sectors)
+static int mcdx_transfer(struct s_drive_stuff *stuffp,
+	      char *p, int sector, int nr_sectors)
 /*	This seems to do the actually transfer.  But it does more.  It
 	keeps track of errors occurred and will (if possible) fall back
 	to single speed on error.
@@ -1222,8 +1284,10 @@
 	ans = mcdx_xfer(stuffp, p, sector, nr_sectors);
 	return ans;
 #if FALLBACK
-	if (-1 == ans) stuffp->readerrs++;
-	else return ans;
+	if (-1 == ans)
+		stuffp->readerrs++;
+	else
+		return ans;
 
 	if (stuffp->readerrs && stuffp->readcmd == READ1X) {
 		xwarn("XXX Already reading 1x -- no chance\n");
@@ -1240,99 +1304,109 @@
 
 
 static int mcdx_xfer(struct s_drive_stuff *stuffp,
-		char *p, int sector, int nr_sectors)
+		     char *p, int sector, int nr_sectors)
 /*	This does actually the transfer from the drive.
 	Return:	-1 on timeout or other error
 			else status byte (as in stuff->st) */
 {
-    int border;
-    int done = 0;
+	int border;
+	int done = 0;
 	long timeout;
 
 	if (stuffp->audio) {
-			xwarn("Attempt to read from audio CD.\n");
-			return -1;
+		xwarn("Attempt to read from audio CD.\n");
+		return -1;
 	}
 
 	if (!stuffp->readcmd) {
-			xinfo("Can't transfer from missing disk.\n");
-			return -1;
+		xinfo("Can't transfer from missing disk.\n");
+		return -1;
 	}
 
-    while (stuffp->lock) {
+	while (stuffp->lock) {
 		interruptible_sleep_on(&stuffp->lockq);
 	}
 
-    if (stuffp->valid
-			&& (sector >= stuffp->pending)
-			&& (sector < stuffp->low_border)) {
+	if (stuffp->valid && (sector >= stuffp->pending)
+	    && (sector < stuffp->low_border)) {
 
 		/* All (or at least a part of the sectors requested) seems
-         * to be already requested, so we don't need to bother the
-		 * drive with new requests ...
-		 * Wait for the drive become idle, but first
-		 * check for possible occurred errors --- the drive
-		 * seems to report them asynchronously */
-
-
-	border = stuffp->high_border < (border = sector + nr_sectors)
-			? stuffp->high_border : border;
-
-	stuffp->lock = current->pid;
-
-	do {
-
-	    while (stuffp->busy) {
-
-			timeout = interruptible_sleep_on_timeout(&stuffp->busyq, 5*HZ);
+		   * to be already requested, so we don't need to bother the
+		   * drive with new requests ...
+		   * Wait for the drive become idle, but first
+		   * check for possible occurred errors --- the drive
+		   * seems to report them asynchronously */
+
+
+		border = stuffp->high_border < (border =
+						sector + nr_sectors)
+		    ? stuffp->high_border : border;
+
+		stuffp->lock = current->pid;
+
+		do {
+
+			while (stuffp->busy) {
+
+				timeout =
+				    interruptible_sleep_on_timeout
+				    (&stuffp->busyq, 5 * HZ);
+
+				if (!stuffp->introk) {
+					xtrace(XFER,
+					       "error via interrupt\n");
+				} else if (!timeout) {
+					xtrace(XFER, "timeout\n");
+				} else if (signal_pending(current)) {
+					xtrace(XFER, "signal\n");
+				} else
+					continue;
+
+				stuffp->lock = 0;
+				stuffp->busy = 0;
+				stuffp->valid = 0;
+
+				wake_up_interruptible(&stuffp->lockq);
+				xtrace(XFER, "transfer() done (-1)\n");
+				return -1;
+			}
 
-			if (!stuffp->introk) { xtrace(XFER, "error via interrupt\n"); }
-			else if (!timeout) { xtrace(XFER, "timeout\n"); }
-			else if (signal_pending(current)) {
-				xtrace(XFER, "signal\n");
-			} else continue;
+			/* check if we need to set the busy flag (as we
+			 * expect an interrupt */
+			stuffp->busy = (3 == (stuffp->pending & 3));
+
+			/* Test if it's the first sector of a block,
+			 * there we have to skip some bytes as we read raw data */
+			if (stuffp->xa && (0 == (stuffp->pending & 3))) {
+				const int HEAD =
+				    CD_FRAMESIZE_RAW - CD_XA_TAIL -
+				    CD_FRAMESIZE;
+				insb((unsigned int) stuffp->rreg_data, p,
+				     HEAD);
+			}
 
-			stuffp->lock = 0;
-			stuffp->busy = 0;
-			stuffp->valid = 0;
+			/* now actually read the data */
+			insb((unsigned int) stuffp->rreg_data, p, 512);
 
-			wake_up_interruptible(&stuffp->lockq);
-			xtrace(XFER, "transfer() done (-1)\n");
-			return -1;
-	    }
+			/* test if it's the last sector of a block,
+			 * if so, we have to handle XA special */
+			if ((3 == (stuffp->pending & 3)) && stuffp->xa) {
+				char dummy[CD_XA_TAIL];
+				insb((unsigned int) stuffp->rreg_data,
+				     &dummy[0], CD_XA_TAIL);
+			}
 
- 		/* check if we need to set the busy flag (as we
-		 * expect an interrupt */
-		stuffp->busy = (3 == (stuffp->pending & 3));
-
-		/* Test if it's the first sector of a block,
-		 * there we have to skip some bytes as we read raw data */
-		if (stuffp->xa && (0 == (stuffp->pending & 3))) {
-			const int HEAD = CD_FRAMESIZE_RAW - CD_XA_TAIL - CD_FRAMESIZE;
-			insb((unsigned int) stuffp->rreg_data, p, HEAD);
-		}
-
-		/* now actually read the data */
-	    insb((unsigned int) stuffp->rreg_data, p, 512);
-
-		/* test if it's the last sector of a block,
-		 * if so, we have to handle XA special */
-		if ((3 == (stuffp->pending & 3)) && stuffp->xa) {
-			char dummy[CD_XA_TAIL];
-			insb((unsigned int) stuffp->rreg_data, &dummy[0], CD_XA_TAIL);
-		}
-
-	    if (stuffp->pending == sector) {
-			p += 512;
-			done++;
-			sector++;
-	    }
-	} while (++(stuffp->pending) < border);
+			if (stuffp->pending == sector) {
+				p += 512;
+				done++;
+				sector++;
+			}
+		} while (++(stuffp->pending) < border);
 
-	stuffp->lock = 0;
-	wake_up_interruptible(&stuffp->lockq);
+		stuffp->lock = 0;
+		wake_up_interruptible(&stuffp->lockq);
 
-    } else {
+	} else {
 
 		/* The requested sector(s) is/are out of the
 		 * already requested range, so we have to bother the drive
@@ -1352,8 +1426,9 @@
 
 		/* do some sanity checks */
 		if (stuffp->pending > stuffp->lastsector) {
-			xwarn("transfer() sector %d from nirvana requested.\n",
-				stuffp->pending);
+			xwarn
+			    ("transfer() sector %d from nirvana requested.\n",
+			     stuffp->pending);
 			stuffp->status = MCDX_ST_EOM;
 			stuffp->valid = 0;
 			xtrace(XFER, "transfer() done (-1)\n");
@@ -1361,17 +1436,17 @@
 		}
 
 		if ((stuffp->low_border = stuffp->pending + DIRECT_SIZE)
-				> stuffp->lastsector + 1) {
+		    > stuffp->lastsector + 1) {
 			xtrace(XFER, "cut low_border\n");
 			stuffp->low_border = stuffp->lastsector + 1;
 		}
 		if ((stuffp->high_border = stuffp->pending + REQUEST_SIZE)
-				> stuffp->lastsector + 1) {
-			xtrace(XFER,  "cut high_border\n");
+		    > stuffp->lastsector + 1) {
+			xtrace(XFER, "cut high_border\n");
 			stuffp->high_border = stuffp->lastsector + 1;
 		}
 
-		{	/* Convert the sector to be requested to MSF format */
+		{		/* Convert the sector to be requested to MSF format */
 			struct cdrom_msf0 pending;
 			log2msf(stuffp->pending / 4, &pending);
 			cmd[1] = pending.minute;
@@ -1379,59 +1454,71 @@
 			cmd[3] = pending.frame;
 		}
 
-		cmd[6] = (unsigned char) ((stuffp->high_border - stuffp->pending) / 4);
+		cmd[6] =
+		    (unsigned
+		     char) ((stuffp->high_border - stuffp->pending) / 4);
 		xtrace(XFER, "[%2d]\n", cmd[6]);
 
 		stuffp->busy = 1;
 		/* Now really issue the request command */
 		outsb((unsigned int) stuffp->wreg_data, cmd, sizeof cmd);
 
-    }
+	}
 #ifdef AK2
-	if ( stuffp->int_err ) {
+	if (stuffp->int_err) {
 		stuffp->valid = 0;
 		stuffp->int_err = 0;
 		return -1;
 	}
-#endif /* AK2 */
+#endif				/* AK2 */
 
-    stuffp->low_border = (stuffp->low_border += done) < stuffp->high_border
-	    ? stuffp->low_border : stuffp->high_border;
+	stuffp->low_border = (stuffp->low_border +=
+			      done) <
+	    stuffp->high_border ? stuffp->low_border : stuffp->high_border;
 
-    return done;
+	return done;
 }
 
 
 /*	Access to elements of the mcdx_drive_map members */
 
-static char* port(int *ip) { return (char*) ip[0]; }
-static int irq(int *ip) { return ip[1]; }
+static char *port(int *ip)
+{
+	return (char *) ip[0];
+}
+static int irq(int *ip)
+{
+	return ip[1];
+}
 
 /*	Misc number converters */
 
 static unsigned int bcd2uint(unsigned char c)
-{ return (c >> 4) * 10 + (c & 0x0f); }
+{
+	return (c >> 4) * 10 + (c & 0x0f);
+}
 
 static unsigned int uint2bcd(unsigned int ival)
-{ return ((ival / 10) << 4) | (ival % 10); }
+{
+	return ((ival / 10) << 4) | (ival % 10);
+}
 
-static void log2msf(unsigned int l, struct cdrom_msf0* pmsf)
+static void log2msf(unsigned int l, struct cdrom_msf0 *pmsf)
 {
-    l += CD_MSF_OFFSET;
-    pmsf->minute = uint2bcd(l / 4500), l %= 4500;
-    pmsf->second = uint2bcd(l / 75);
-    pmsf->frame = uint2bcd(l % 75);
+	l += CD_MSF_OFFSET;
+	pmsf->minute = uint2bcd(l / 4500), l %= 4500;
+	pmsf->second = uint2bcd(l / 75);
+	pmsf->frame = uint2bcd(l % 75);
 }
 
-static unsigned int msf2log(const struct cdrom_msf0* pmsf)
+static unsigned int msf2log(const struct cdrom_msf0 *pmsf)
 {
-    return bcd2uint(pmsf->frame)
-    + bcd2uint(pmsf->second) * 75
-    + bcd2uint(pmsf->minute) * 4500
-    - CD_MSF_OFFSET;
+	return bcd2uint(pmsf->frame)
+	    + bcd2uint(pmsf->second) * 75
+	    + bcd2uint(pmsf->minute) * 4500 - CD_MSF_OFFSET;
 }
 
-int mcdx_readtoc(struct s_drive_stuff* stuffp)
+int mcdx_readtoc(struct s_drive_stuff *stuffp)
 /*  Read the toc entries from the CD,
  *  Return: -1 on failure, else 0 */
 {
@@ -1442,17 +1529,21 @@
 	}
 
 	xtrace(READTOC, "ioctl() readtoc for %d tracks\n",
-			stuffp->di.n_last - stuffp->di.n_first + 1);
+	       stuffp->di.n_last - stuffp->di.n_first + 1);
 
-    if (-1 == mcdx_hold(stuffp, 1)) return -1;
+	if (-1 == mcdx_hold(stuffp, 1))
+		return -1;
 
 	xtrace(READTOC, "ioctl() tocmode\n");
-	if (-1 == mcdx_setdrivemode(stuffp, TOC, 1)) return -EIO;
+	if (-1 == mcdx_setdrivemode(stuffp, TOC, 1))
+		return -EIO;
 
 	/* all seems to be ok so far ... malloc */
 	{
 		int size;
-		size = sizeof(struct s_subqcode) * (stuffp->di.n_last - stuffp->di.n_first + 2);
+		size =
+		    sizeof(struct s_subqcode) * (stuffp->di.n_last -
+						 stuffp->di.n_first + 2);
 
 		xtrace(MALLOC, "ioctl() malloc %d bytes\n", size);
 		stuffp->toc = kmalloc(size, GFP_KERNEL);
@@ -1469,11 +1560,11 @@
 		int retries;
 
 		for (trk = 0;
-				trk < (stuffp->di.n_last - stuffp->di.n_first + 1);
-				trk++)
+		     trk < (stuffp->di.n_last - stuffp->di.n_first + 1);
+		     trk++)
 			stuffp->toc[trk].index = 0;
 
-		for (retries = 300; retries; retries--) { /* why 300? */
+		for (retries = 300; retries; retries--) {	/* why 300? */
 			struct s_subqcode q;
 			unsigned int idx;
 
@@ -1485,19 +1576,24 @@
 			idx = bcd2uint(q.index);
 
 			if ((idx > 0)
-					&& (idx <= stuffp->di.n_last)
-					&& (q.tno == 0)
-					&& (stuffp->toc[idx - stuffp->di.n_first].index == 0)) {
+			    && (idx <= stuffp->di.n_last)
+			    && (q.tno == 0)
+			    && (stuffp->toc[idx - stuffp->di.n_first].
+				index == 0)) {
 				stuffp->toc[idx - stuffp->di.n_first] = q;
-				xtrace(READTOC, "ioctl() toc idx %d (trk %d)\n", idx, trk);
+				xtrace(READTOC,
+				       "ioctl() toc idx %d (trk %d)\n",
+				       idx, trk);
 				trk--;
 			}
-			if (trk == 0) break;
+			if (trk == 0)
+				break;
 		}
-		memset(&stuffp->toc[stuffp->di.n_last - stuffp->di.n_first + 1],
-				0, sizeof(stuffp->toc[0]));
-		stuffp->toc[stuffp->di.n_last - stuffp->di.n_first + 1].dt
-				= stuffp->di.msf_leadout;
+		memset(&stuffp->
+		       toc[stuffp->di.n_last - stuffp->di.n_first + 1], 0,
+		       sizeof(stuffp->toc[0]));
+		stuffp->toc[stuffp->di.n_last - stuffp->di.n_first +
+			    1].dt = stuffp->di.msf_leadout;
 	}
 
 	/* unset toc mode */
@@ -1506,16 +1602,23 @@
 		return -EIO;
 
 #if MCDX_DEBUG && READTOC
-	{ int trk;
-	for (trk = 0;
-			trk < (stuffp->di.n_last - stuffp->di.n_first + 2);
-			trk++)
-		xtrace(READTOC, "ioctl() %d readtoc %02x %02x %02x"
-				"  %02x:%02x.%02x  %02x:%02x.%02x\n",
-				trk + stuffp->di.n_first,
-				stuffp->toc[trk].control, stuffp->toc[trk].tno, stuffp->toc[trk].index,
-				stuffp->toc[trk].tt.minute, stuffp->toc[trk].tt.second, stuffp->toc[trk].tt.frame,
-				stuffp->toc[trk].dt.minute, stuffp->toc[trk].dt.second, stuffp->toc[trk].dt.frame);
+	{
+		int trk;
+		for (trk = 0;
+		     trk < (stuffp->di.n_last - stuffp->di.n_first + 2);
+		     trk++)
+			xtrace(READTOC, "ioctl() %d readtoc %02x %02x %02x"
+			       "  %02x:%02x.%02x  %02x:%02x.%02x\n",
+			       trk + stuffp->di.n_first,
+			       stuffp->toc[trk].control,
+			       stuffp->toc[trk].tno,
+			       stuffp->toc[trk].index,
+			       stuffp->toc[trk].tt.minute,
+			       stuffp->toc[trk].tt.second,
+			       stuffp->toc[trk].tt.frame,
+			       stuffp->toc[trk].dt.minute,
+			       stuffp->toc[trk].dt.second,
+			       stuffp->toc[trk].dt.frame);
 	}
 #endif
 
@@ -1523,109 +1626,110 @@
 }
 
 static int
-mcdx_playmsf(struct s_drive_stuff* stuffp, const struct cdrom_msf* msf)
+mcdx_playmsf(struct s_drive_stuff *stuffp, const struct cdrom_msf *msf)
 {
-    unsigned char cmd[7] = {
-        0, 0, 0, 0, 0, 0, 0
-    };
+	unsigned char cmd[7] = {
+		0, 0, 0, 0, 0, 0, 0
+	};
 
 	if (!stuffp->readcmd) {
 		xinfo("Can't play from missing disk.\n");
 		return -1;
 	}
 
-    cmd[0] = stuffp->playcmd;
+	cmd[0] = stuffp->playcmd;
+
+	cmd[1] = msf->cdmsf_min0;
+	cmd[2] = msf->cdmsf_sec0;
+	cmd[3] = msf->cdmsf_frame0;
+	cmd[4] = msf->cdmsf_min1;
+	cmd[5] = msf->cdmsf_sec1;
+	cmd[6] = msf->cdmsf_frame1;
+
+	xtrace(PLAYMSF, "ioctl(): play %x "
+	       "%02x:%02x:%02x -- %02x:%02x:%02x\n",
+	       cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5], cmd[6]);
 
-    cmd[1] = msf->cdmsf_min0;
-    cmd[2] = msf->cdmsf_sec0;
-    cmd[3] = msf->cdmsf_frame0;
-    cmd[4] = msf->cdmsf_min1;
-    cmd[5] = msf->cdmsf_sec1;
-    cmd[6] = msf->cdmsf_frame1;
-
-    xtrace(PLAYMSF, "ioctl(): play %x "
-            "%02x:%02x:%02x -- %02x:%02x:%02x\n",
-            cmd[0], cmd[1], cmd[2], cmd[3],
-            cmd[4], cmd[5], cmd[6]);
-
-    outsb((unsigned int) stuffp->wreg_data, cmd, sizeof cmd);
-
-    if (-1 == mcdx_getval(stuffp, 3 * HZ, 0, NULL)) {
-        xwarn("playmsf() timeout\n");
-        return -1;
-    }
+	outsb((unsigned int) stuffp->wreg_data, cmd, sizeof cmd);
 
-    stuffp->audiostatus = CDROM_AUDIO_PLAY;
-    return 0;
+	if (-1 == mcdx_getval(stuffp, 3 * HZ, 0, NULL)) {
+		xwarn("playmsf() timeout\n");
+		return -1;
+	}
+
+	stuffp->audiostatus = CDROM_AUDIO_PLAY;
+	return 0;
 }
 
 static int
-mcdx_playtrk(struct s_drive_stuff* stuffp, const struct cdrom_ti* ti)
+mcdx_playtrk(struct s_drive_stuff *stuffp, const struct cdrom_ti *ti)
 {
-    struct s_subqcode* p;
-    struct cdrom_msf msf;
-
-    if (-1 == mcdx_readtoc(stuffp)) return -1;
-
-    if (ti) p = &stuffp->toc[ti->cdti_trk0 - stuffp->di.n_first];
-    else p = &stuffp->start;
+	struct s_subqcode *p;
+	struct cdrom_msf msf;
 
-    msf.cdmsf_min0 = p->dt.minute;
-    msf.cdmsf_sec0 = p->dt.second;
-    msf.cdmsf_frame0 = p->dt.frame;
-
-    if (ti) {
-        p = &stuffp->toc[ti->cdti_trk1 - stuffp->di.n_first + 1];
-        stuffp->stop = *p;
-    } else p = &stuffp->stop;
+	if (-1 == mcdx_readtoc(stuffp))
+		return -1;
 
-    msf.cdmsf_min1 = p->dt.minute;
-    msf.cdmsf_sec1 = p->dt.second;
-    msf.cdmsf_frame1 = p->dt.frame;
+	if (ti)
+		p = &stuffp->toc[ti->cdti_trk0 - stuffp->di.n_first];
+	else
+		p = &stuffp->start;
+
+	msf.cdmsf_min0 = p->dt.minute;
+	msf.cdmsf_sec0 = p->dt.second;
+	msf.cdmsf_frame0 = p->dt.frame;
+
+	if (ti) {
+		p = &stuffp->toc[ti->cdti_trk1 - stuffp->di.n_first + 1];
+		stuffp->stop = *p;
+	} else
+		p = &stuffp->stop;
+
+	msf.cdmsf_min1 = p->dt.minute;
+	msf.cdmsf_sec1 = p->dt.second;
+	msf.cdmsf_frame1 = p->dt.frame;
 
-    return mcdx_playmsf(stuffp, &msf);
+	return mcdx_playmsf(stuffp, &msf);
 }
 
 
 /* Drive functions ************************************************/
 
-static int
-mcdx_tray_move(struct cdrom_device_info * cdi, int position)
+static int mcdx_tray_move(struct cdrom_device_info *cdi, int position)
 {
-    struct s_drive_stuff *stuffp = mcdx_stuffp[MINOR(cdi->dev)];
+	struct s_drive_stuff *stuffp = mcdx_stuffp[MINOR(cdi->dev)];
 
-    if (!stuffp->present) 
+	if (!stuffp->present)
 		return -ENXIO;
 	if (!(stuffp->present & DOOR))
-		return -ENOSYS; 
+		return -ENOSYS;
 
- 	if (position)                /* 1: eject */
-        	return mcdx_talk(stuffp, "\xf6", 1, NULL, 1, 5 * HZ, 3);
-	else /* 0: close */
-			return mcdx_talk(stuffp, "\xf8", 1, NULL, 1, 5 * HZ, 3);
-    return 1;
+	if (position)		/* 1: eject */
+		return mcdx_talk(stuffp, "\xf6", 1, NULL, 1, 5 * HZ, 3);
+	else			/* 0: close */
+		return mcdx_talk(stuffp, "\xf8", 1, NULL, 1, 5 * HZ, 3);
+	return 1;
 }
 
-static int
-mcdx_stop(struct s_drive_stuff *stuffp, int tries)
-{ return mcdx_talk(stuffp, "\xf0", 1, NULL, 1, 2 * HZ, tries); }
+static int mcdx_stop(struct s_drive_stuff *stuffp, int tries)
+{
+	return mcdx_talk(stuffp, "\xf0", 1, NULL, 1, 2 * HZ, tries);
+}
 
-static int
-mcdx_hold(struct s_drive_stuff *stuffp, int tries)
-{ return mcdx_talk(stuffp, "\x70", 1, NULL, 1, 2 * HZ, tries); }
+static int mcdx_hold(struct s_drive_stuff *stuffp, int tries)
+{
+	return mcdx_talk(stuffp, "\x70", 1, NULL, 1, 2 * HZ, tries);
+}
 
-static int
-mcdx_requestsubqcode(struct s_drive_stuff *stuffp,
-        struct s_subqcode *sub,
-        int tries)
+static int mcdx_requestsubqcode(struct s_drive_stuff *stuffp,
+		     struct s_subqcode *sub, int tries)
 {
 	char buf[11];
 	int ans;
 
-	if (-1 == (ans = mcdx_talk(
-            stuffp, "\x20", 1, buf, sizeof(buf),
-            2 * HZ, tries)))
-        return -1;
+	if (-1 == (ans = mcdx_talk(stuffp, "\x20", 1, buf, sizeof(buf),
+				   2 * HZ, tries)))
+		return -1;
 	sub->control = buf[1];
 	sub->tno = buf[2];
 	sub->index = buf[3];
@@ -1639,31 +1743,34 @@
 	return ans;
 }
 
-static int
-mcdx_requestmultidiskinfo(struct s_drive_stuff *stuffp, struct s_multi *multi, int tries)
+static int mcdx_requestmultidiskinfo(struct s_drive_stuff *stuffp,
+			  struct s_multi *multi, int tries)
 {
 	char buf[5];
 	int ans;
 
-    if (stuffp->present & MULTI) {
-		ans = mcdx_talk(stuffp, "\x11", 1, buf, sizeof(buf), 2 * HZ, tries);
+	if (stuffp->present & MULTI) {
+		ans =
+		    mcdx_talk(stuffp, "\x11", 1, buf, sizeof(buf), 2 * HZ,
+			      tries);
 		multi->multi = buf[1];
-        multi->msf_last.minute = buf[2];
-        multi->msf_last.second = buf[3];
-        multi->msf_last.frame = buf[4];
-        return ans;
-    } else {
-        multi->multi = 0;
-        return 0;
-    }
+		multi->msf_last.minute = buf[2];
+		multi->msf_last.second = buf[3];
+		multi->msf_last.frame = buf[4];
+		return ans;
+	} else {
+		multi->multi = 0;
+		return 0;
+	}
 }
 
-static int
-mcdx_requesttocdata(struct s_drive_stuff *stuffp, struct s_diskinfo *info, int tries)
+static int mcdx_requesttocdata(struct s_drive_stuff *stuffp, struct s_diskinfo *info,
+		    int tries)
 {
 	char buf[9];
 	int ans;
-	ans = mcdx_talk(stuffp, "\x10", 1, buf, sizeof(buf), 2 * HZ, tries);
+	ans =
+	    mcdx_talk(stuffp, "\x10", 1, buf, sizeof(buf), 2 * HZ, tries);
 	if (ans == -1) {
 		info->n_first = 0;
 		info->n_last = 0;
@@ -1680,8 +1787,8 @@
 	return ans;
 }
 
-static int
-mcdx_setdrivemode(struct s_drive_stuff *stuffp, enum drivemodes mode, int tries)
+static int mcdx_setdrivemode(struct s_drive_stuff *stuffp, enum drivemodes mode,
+		  int tries)
 {
 	char cmd[2];
 	int ans;
@@ -1692,32 +1799,47 @@
 		return -1;
 
 	switch (mode) {
-	  case TOC: cmd[1] |= 0x04; break;
-	  case DATA: cmd[1] &= ~0x04; break;
-	  case RAW: cmd[1] |= 0x40; break;
-	  case COOKED: cmd[1] &= ~0x40; break;
-	  default: break;
+	case TOC:
+		cmd[1] |= 0x04;
+		break;
+	case DATA:
+		cmd[1] &= ~0x04;
+		break;
+	case RAW:
+		cmd[1] |= 0x40;
+		break;
+	case COOKED:
+		cmd[1] &= ~0x40;
+		break;
+	default:
+		break;
 	}
 	cmd[0] = 0x50;
 	return mcdx_talk(stuffp, cmd, 2, NULL, 1, 5 * HZ, tries);
 }
 
-static int
-mcdx_setdatamode(struct s_drive_stuff *stuffp, enum datamodes mode, int tries)
+static int mcdx_setdatamode(struct s_drive_stuff *stuffp, enum datamodes mode,
+		 int tries)
 {
 	unsigned char cmd[2] = { 0xa0 };
 	xtrace(HW, "setdatamode() %d\n", mode);
 	switch (mode) {
-	  case MODE0: cmd[1] = 0x00; break;
-	  case MODE1: cmd[1] = 0x01; break;
-	  case MODE2: cmd[1] = 0x02; break;
-	  default: return -EINVAL;
+	case MODE0:
+		cmd[1] = 0x00;
+		break;
+	case MODE1:
+		cmd[1] = 0x01;
+		break;
+	case MODE2:
+		cmd[1] = 0x02;
+		break;
+	default:
+		return -EINVAL;
 	}
 	return mcdx_talk(stuffp, cmd, 2, NULL, 1, 5 * HZ, tries);
 }
 
-static int
-mcdx_config(struct s_drive_stuff *stuffp, int tries)
+static int mcdx_config(struct s_drive_stuff *stuffp, int tries)
 {
 	char cmd[4];
 
@@ -1737,14 +1859,14 @@
 	return mcdx_talk(stuffp, cmd, 3, NULL, 1, 1 * HZ, tries);
 }
 
-static int
-mcdx_requestversion(struct s_drive_stuff *stuffp, struct s_version *ver, int tries)
+static int mcdx_requestversion(struct s_drive_stuff *stuffp, struct s_version *ver,
+		    int tries)
 {
 	char buf[3];
 	int ans;
 
 	if (-1 == (ans = mcdx_talk(stuffp, "\xdc",
-			1, buf, sizeof(buf), 2 * HZ, tries)))
+				   1, buf, sizeof(buf), 2 * HZ, tries)))
 		return ans;
 
 	ver->code = buf[1];
@@ -1753,65 +1875,66 @@
 	return ans;
 }
 
-static int
-mcdx_reset(struct s_drive_stuff *stuffp, enum resetmodes mode, int tries)
+static int mcdx_reset(struct s_drive_stuff *stuffp, enum resetmodes mode, int tries)
 {
 	if (mode == HARD) {
-		outb(0, (unsigned int) stuffp->wreg_chn);		/* no dma, no irq -> hardware */
-		outb(0, (unsigned int) stuffp->wreg_reset);		/* hw reset */
+		outb(0, (unsigned int) stuffp->wreg_chn);	/* no dma, no irq -> hardware */
+		outb(0, (unsigned int) stuffp->wreg_reset);	/* hw reset */
 		return 0;
-	} else return mcdx_talk(stuffp, "\x60", 1, NULL, 1, 5 * HZ, tries);
+	} else
+		return mcdx_talk(stuffp, "\x60", 1, NULL, 1, 5 * HZ, tries);
 }
 
-static int mcdx_lockdoor(struct cdrom_device_info * cdi, int lock)
+static int mcdx_lockdoor(struct cdrom_device_info *cdi, int lock)
 {
-    struct s_drive_stuff *stuffp = mcdx_stuffp[MINOR(cdi->dev)];
+	struct s_drive_stuff *stuffp = mcdx_stuffp[MINOR(cdi->dev)];
 	char cmd[2] = { 0xfe };
 
-    if (!(stuffp->present & DOOR))
+	if (!(stuffp->present & DOOR))
 		return -ENOSYS;
-    if (stuffp->present & DOOR) {
-        cmd[1] = lock ? 0x01 : 0x00;
-        return mcdx_talk(stuffp, cmd, sizeof(cmd), NULL, 1, 5 * HZ, 3);
-    } else return 0;
+	if (stuffp->present & DOOR) {
+		cmd[1] = lock ? 0x01 : 0x00;
+		return mcdx_talk(stuffp, cmd, sizeof(cmd), NULL, 1, 5 * HZ, 3);
+	} else
+		return 0;
 }
 
-static int
-mcdx_getstatus(struct s_drive_stuff *stuffp, int tries)
-{ return mcdx_talk(stuffp, "\x40", 1, NULL, 1, 5 * HZ, tries); }
+static int mcdx_getstatus(struct s_drive_stuff *stuffp, int tries)
+{
+	return mcdx_talk(stuffp, "\x40", 1, NULL, 1, 5 * HZ, tries);
+}
 
 static int
-mcdx_getval(struct s_drive_stuff *stuffp, int to, int delay, char* buf)
+mcdx_getval(struct s_drive_stuff *stuffp, int to, int delay, char *buf)
 {
-    unsigned long timeout = to + jiffies;
-    char c;
+	unsigned long timeout = to + jiffies;
+	char c;
 
-    if (!buf) buf = &c;
+	if (!buf)
+		buf = &c;
 
-    while (inb((unsigned int) stuffp->rreg_status) & MCDX_RBIT_STEN) {
-        if (time_after(jiffies, timeout)) return -1;
-        mcdx_delay(stuffp, delay);
-    }
+	while (inb((unsigned int) stuffp->rreg_status) & MCDX_RBIT_STEN) {
+		if (time_after(jiffies, timeout))
+			return -1;
+		mcdx_delay(stuffp, delay);
+	}
 
-    *buf = (unsigned char) inb((unsigned int) stuffp->rreg_data) & 0xff;
+	*buf = (unsigned char) inb((unsigned int) stuffp->rreg_data) & 0xff;
 
-    return 0;
+	return 0;
 }
 
-static int
-mcdx_setattentuator(
-        struct s_drive_stuff* stuffp,
-        struct cdrom_volctrl* vol,
-        int tries)
-{
-    char cmd[5];
-    cmd[0] = 0xae;
-    cmd[1] = vol->channel0;
-    cmd[2] = 0;
-    cmd[3] = vol->channel1;
-    cmd[4] = 0;
+static int mcdx_setattentuator(struct s_drive_stuff *stuffp,
+		    struct cdrom_volctrl *vol, int tries)
+{
+	char cmd[5];
+	cmd[0] = 0xae;
+	cmd[1] = vol->channel0;
+	cmd[2] = 0;
+	cmd[3] = vol->channel1;
+	cmd[4] = 0;
 
-    return mcdx_talk(stuffp, cmd, sizeof(cmd), NULL, 5, 200, tries);
+	return mcdx_talk(stuffp, cmd, sizeof(cmd), NULL, 5, 200, tries);
 }
 
-/* ex:set ts=4 sw=4 ai si: */
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.9/linux/drivers/cdrom/optcd.c linux/drivers/cdrom/optcd.c
--- v2.4.9/linux/drivers/cdrom/optcd.c	Sun Feb  4 10:05:29 2001
+++ linux/drivers/cdrom/optcd.c	Sun Sep  9 10:43:02 2001
@@ -2097,3 +2097,4 @@
 module_exit(optcd_exit);
 
 
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.9/linux/drivers/cdrom/sbpcd.c linux/drivers/cdrom/sbpcd.c
--- v2.4.9/linux/drivers/cdrom/sbpcd.c	Wed Jul 25 17:10:19 2001
+++ linux/drivers/cdrom/sbpcd.c	Sun Sep  9 10:43:02 2001
@@ -4272,6 +4272,12 @@
 		D_S[d].aud_buf=NULL;
 		D_S[d].sbp_audsiz=arg;
 		
+		if (D_S[d].sbp_audsiz>16)
+		{
+			D_S[d].sbp_audsiz = 0;
+			RETURN_UP(D_S[d].sbp_audsiz);
+		}
+	
 		if (D_S[d].sbp_audsiz>0)
 		{
 			D_S[d].aud_buf=(u_char *) vmalloc(D_S[d].sbp_audsiz*CD_FRAMESIZE_RAW);
@@ -6016,6 +6022,9 @@
 {
    return sbpcd_chk_disk_change(cdi->dev);
 }
+
+MODULE_LICENSE("GPL");
+
 /*==========================================================================*/
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
@@ -6033,3 +6042,4 @@
  * c-continued-brace-offset: 0
  * End:
  */
+
diff -u --recursive --new-file v2.4.9/linux/drivers/cdrom/sjcd.c linux/drivers/cdrom/sjcd.c
--- v2.4.9/linux/drivers/cdrom/sjcd.c	Thu Oct 26 23:35:48 2000
+++ linux/drivers/cdrom/sjcd.c	Fri Sep  7 09:28:38 2001
@@ -82,13 +82,13 @@
 
 static int sjcd_present = 0;
 
-#define SJCD_BUF_SIZ 32 /* cdr-h94a has internal 64K buffer */
+#define SJCD_BUF_SIZ 32		/* cdr-h94a has internal 64K buffer */
 
 /*
  * buffer for block size conversion
  */
-static char sjcd_buf[ 2048 * SJCD_BUF_SIZ ];
-static volatile int sjcd_buf_bn[ SJCD_BUF_SIZ ], sjcd_next_bn;
+static char sjcd_buf[2048 * SJCD_BUF_SIZ];
+static volatile int sjcd_buf_bn[SJCD_BUF_SIZ], sjcd_next_bn;
 static volatile int sjcd_buf_in, sjcd_buf_out = -1;
 
 /*
@@ -113,9 +113,7 @@
 
 static int sjcd_base = SJCD_BASE_ADDR;
 
-#ifdef MODULE
 MODULE_PARM(sjcd_base, "i");
-#endif
 
 static DECLARE_WAIT_QUEUE_HEAD(sjcd_waitq);
 
@@ -125,13 +123,13 @@
 static volatile unsigned short sjcd_transfer_is_active = 0;
 
 enum sjcd_transfer_state {
-  SJCD_S_IDLE     = 0,
-  SJCD_S_START    = 1,
-  SJCD_S_MODE     = 2,
-  SJCD_S_READ     = 3,
-  SJCD_S_DATA     = 4,
-  SJCD_S_STOP     = 5,
-  SJCD_S_STOPPING = 6
+	SJCD_S_IDLE = 0,
+	SJCD_S_START = 1,
+	SJCD_S_MODE = 2,
+	SJCD_S_READ = 3,
+	SJCD_S_DATA = 4,
+	SJCD_S_STOP = 5,
+	SJCD_S_STOPPING = 6
 };
 static enum sjcd_transfer_state sjcd_transfer_state = SJCD_S_IDLE;
 static long sjcd_transfer_timeout = 0;
@@ -166,14 +164,14 @@
  * base address.
  */
 #ifndef MODULE
-static int __init sjcd_setup( char *str)
+static int __init sjcd_setup(char *str)
 {
-   int ints[2];
-   (void)get_options(str, ARRAY_SIZE(ints), ints);
-   if (ints[0] > 0)
-      sjcd_base = ints[1];
+	int ints[2];
+	(void) get_options(str, ARRAY_SIZE(ints), ints);
+	if (ints[0] > 0)
+		sjcd_base = ints[1];
 
-   return 1;
+	return 1;
 }
 
 __setup("sjcd=", sjcd_setup);
@@ -183,168 +181,191 @@
 /*
  * Special converters.
  */
-static unsigned char bin2bcd( int bin ){
-  int u, v;
+static unsigned char bin2bcd(int bin)
+{
+	int u, v;
 
-  u = bin % 10; v = bin / 10;
-  return( u | ( v << 4 ) );
+	u = bin % 10;
+	v = bin / 10;
+	return (u | (v << 4));
 }
 
-static int bcd2bin( unsigned char bcd ){
-    return( ( bcd >> 4 ) * 10 + ( bcd & 0x0F ) );
+static int bcd2bin(unsigned char bcd)
+{
+	return ((bcd >> 4) * 10 + (bcd & 0x0F));
 }
 
-static long msf2hsg( struct msf *mp ){
-  return( bcd2bin( mp->frame ) + bcd2bin( mp->sec ) * 75
-	 + bcd2bin( mp->min ) * 4500 - 150 );
+static long msf2hsg(struct msf *mp)
+{
+	return (bcd2bin(mp->frame) + bcd2bin(mp->sec) * 75
+		+ bcd2bin(mp->min) * 4500 - 150);
 }
 
-static void hsg2msf( long hsg, struct msf *msf ){
-  hsg += 150; msf->min = hsg / 4500;
-  hsg %= 4500; msf->sec = hsg / 75; msf->frame = hsg % 75;
-  msf->min = bin2bcd( msf->min );       /* convert to BCD */
-  msf->sec = bin2bcd( msf->sec );
-  msf->frame = bin2bcd( msf->frame );
+static void hsg2msf(long hsg, struct msf *msf)
+{
+	hsg += 150;
+	msf->min = hsg / 4500;
+	hsg %= 4500;
+	msf->sec = hsg / 75;
+	msf->frame = hsg % 75;
+	msf->min = bin2bcd(msf->min);	/* convert to BCD */
+	msf->sec = bin2bcd(msf->sec);
+	msf->frame = bin2bcd(msf->frame);
 }
 
 /*
  * Send a command to cdrom. Invalidate status.
  */
-static void sjcd_send_cmd( unsigned char cmd ){
+static void sjcd_send_cmd(unsigned char cmd)
+{
 #if defined( SJCD_TRACE )
-  printk( "SJCD: send_cmd( 0x%x )\n", cmd );
+	printk("SJCD: send_cmd( 0x%x )\n", cmd);
 #endif
-  outb( cmd, SJCDPORT( 0 ) );
-  sjcd_command_is_in_progress = 1;
-  sjcd_status_valid = 0;
-  sjcd_command_failed = 0;
+	outb(cmd, SJCDPORT(0));
+	sjcd_command_is_in_progress = 1;
+	sjcd_status_valid = 0;
+	sjcd_command_failed = 0;
 }
 
 /*
  * Send a command with one arg to cdrom. Invalidate status.
  */
-static void sjcd_send_1_cmd( unsigned char cmd, unsigned char a ){
+static void sjcd_send_1_cmd(unsigned char cmd, unsigned char a)
+{
 #if defined( SJCD_TRACE )
-  printk( "SJCD: send_1_cmd( 0x%x, 0x%x )\n", cmd, a );
+	printk("SJCD: send_1_cmd( 0x%x, 0x%x )\n", cmd, a);
 #endif
-  outb( cmd, SJCDPORT( 0 ) );
-  outb( a, SJCDPORT( 0 ) );
-  sjcd_command_is_in_progress = 1;
-  sjcd_status_valid = 0;
-  sjcd_command_failed = 0;
+	outb(cmd, SJCDPORT(0));
+	outb(a, SJCDPORT(0));
+	sjcd_command_is_in_progress = 1;
+	sjcd_status_valid = 0;
+	sjcd_command_failed = 0;
 }
 
 /*
  * Send a command with four args to cdrom. Invalidate status.
  */
-static void sjcd_send_4_cmd( unsigned char cmd, unsigned char a,
-	    unsigned char b, unsigned char c, unsigned char d ){
+static void sjcd_send_4_cmd(unsigned char cmd, unsigned char a,
+			    unsigned char b, unsigned char c,
+			    unsigned char d)
+{
 #if defined( SJCD_TRACE )
-  printk( "SJCD: send_4_cmd( 0x%x )\n", cmd );
+	printk("SJCD: send_4_cmd( 0x%x )\n", cmd);
 #endif
-  outb( cmd, SJCDPORT( 0 ) );
-  outb( a, SJCDPORT( 0 ) );
-  outb( b, SJCDPORT( 0 ) );
-  outb( c, SJCDPORT( 0 ) );
-  outb( d, SJCDPORT( 0 ) );
-  sjcd_command_is_in_progress = 1;
-  sjcd_status_valid = 0;
-  sjcd_command_failed = 0;
+	outb(cmd, SJCDPORT(0));
+	outb(a, SJCDPORT(0));
+	outb(b, SJCDPORT(0));
+	outb(c, SJCDPORT(0));
+	outb(d, SJCDPORT(0));
+	sjcd_command_is_in_progress = 1;
+	sjcd_status_valid = 0;
+	sjcd_command_failed = 0;
 }
 
 /*
  * Send a play or read command to cdrom. Invalidate Status.
  */
-static void sjcd_send_6_cmd( unsigned char cmd, struct sjcd_play_msf *pms ){
+static void sjcd_send_6_cmd(unsigned char cmd, struct sjcd_play_msf *pms)
+{
 #if defined( SJCD_TRACE )
-  printk( "SJCD: send_long_cmd( 0x%x )\n", cmd );
+	printk("SJCD: send_long_cmd( 0x%x )\n", cmd);
 #endif
-  outb( cmd, SJCDPORT( 0 ) );
-  outb( pms->start.min,   SJCDPORT( 0 ) );
-  outb( pms->start.sec,   SJCDPORT( 0 ) );
-  outb( pms->start.frame, SJCDPORT( 0 ) );
-  outb( pms->end.min,     SJCDPORT( 0 ) );
-  outb( pms->end.sec,     SJCDPORT( 0 ) );
-  outb( pms->end.frame,   SJCDPORT( 0 ) );
-  sjcd_command_is_in_progress = 1;
-  sjcd_status_valid = 0;
-  sjcd_command_failed = 0;
+	outb(cmd, SJCDPORT(0));
+	outb(pms->start.min, SJCDPORT(0));
+	outb(pms->start.sec, SJCDPORT(0));
+	outb(pms->start.frame, SJCDPORT(0));
+	outb(pms->end.min, SJCDPORT(0));
+	outb(pms->end.sec, SJCDPORT(0));
+	outb(pms->end.frame, SJCDPORT(0));
+	sjcd_command_is_in_progress = 1;
+	sjcd_status_valid = 0;
+	sjcd_command_failed = 0;
 }
 
 /*
  * Get a value from the data port. Should not block, so we use a little
  * wait for a while. Returns 0 if OK.
  */
-static int sjcd_load_response( void *buf, int len ){
-  unsigned char *resp = ( unsigned char * )buf;
+static int sjcd_load_response(void *buf, int len)
+{
+	unsigned char *resp = (unsigned char *) buf;
 
-  for( ; len; --len ){ 
-    int i;
-    for( i = 200; i-- && !SJCD_STATUS_AVAILABLE( inb( SJCDPORT( 1 ) ) ); );
-    if( i > 0 ) *resp++ = ( unsigned char )inb( SJCDPORT( 0 ) );
-    else break;
-  }
-  return( len );
+	for (; len; --len) {
+		int i;
+		for (i = 200;
+		     i-- && !SJCD_STATUS_AVAILABLE(inb(SJCDPORT(1))););
+		if (i > 0)
+			*resp++ = (unsigned char) inb(SJCDPORT(0));
+		else
+			break;
+	}
+	return (len);
 }
 
 /*
  * Load and parse command completion status (drive info byte and maybe error).
  * Sorry, no error classification yet.
  */
-static void sjcd_load_status( void ){
-  sjcd_media_is_changed = 0;
-  sjcd_completion_error = 0;
-  sjcd_completion_status = inb( SJCDPORT( 0 ) );
-  if( sjcd_completion_status & SST_DOOR_OPENED ){
-    sjcd_door_closed = sjcd_media_is_available = 0;
-  } else {
-    sjcd_door_closed = 1;
-    if( sjcd_completion_status & SST_MEDIA_CHANGED )
-      sjcd_media_is_available = sjcd_media_is_changed = 1;
-    else if( sjcd_completion_status & 0x0F ){
-      /*
-       * OK, we seem to catch an error ...
-       */
-      while( !SJCD_STATUS_AVAILABLE( inb( SJCDPORT( 1 ) ) ) );
-      sjcd_completion_error = inb( SJCDPORT( 0 ) );
-      if( ( sjcd_completion_status & 0x08 ) &&
-	 ( sjcd_completion_error & 0x40 ) )
-	sjcd_media_is_available = 0;
-      else sjcd_command_failed = 1;
-    } else sjcd_media_is_available = 1;
-  }
-  /*
-   * Ok, status loaded successfully.
-   */
-  sjcd_status_valid = 1, sjcd_error_reported = 0;
-  sjcd_command_is_in_progress = 0;
-
-  /*
-   * If the disk is changed, the TOC is not valid.
-   */
-  if( sjcd_media_is_changed ) sjcd_toc_uptodate = 0;
+static void sjcd_load_status(void)
+{
+	sjcd_media_is_changed = 0;
+	sjcd_completion_error = 0;
+	sjcd_completion_status = inb(SJCDPORT(0));
+	if (sjcd_completion_status & SST_DOOR_OPENED) {
+		sjcd_door_closed = sjcd_media_is_available = 0;
+	} else {
+		sjcd_door_closed = 1;
+		if (sjcd_completion_status & SST_MEDIA_CHANGED)
+			sjcd_media_is_available = sjcd_media_is_changed =
+			    1;
+		else if (sjcd_completion_status & 0x0F) {
+			/*
+			 * OK, we seem to catch an error ...
+			 */
+			while (!SJCD_STATUS_AVAILABLE(inb(SJCDPORT(1))));
+			sjcd_completion_error = inb(SJCDPORT(0));
+			if ((sjcd_completion_status & 0x08) &&
+			    (sjcd_completion_error & 0x40))
+				sjcd_media_is_available = 0;
+			else
+				sjcd_command_failed = 1;
+		} else
+			sjcd_media_is_available = 1;
+	}
+	/*
+	 * Ok, status loaded successfully.
+	 */
+	sjcd_status_valid = 1, sjcd_error_reported = 0;
+	sjcd_command_is_in_progress = 0;
+
+	/*
+	 * If the disk is changed, the TOC is not valid.
+	 */
+	if (sjcd_media_is_changed)
+		sjcd_toc_uptodate = 0;
 #if defined( SJCD_TRACE )
-  printk( "SJCD: status %02x.%02x loaded.\n",
-	 ( int )sjcd_completion_status, ( int )sjcd_completion_error );
+	printk("SJCD: status %02x.%02x loaded.\n",
+	       (int) sjcd_completion_status, (int) sjcd_completion_error);
 #endif
 }
 
 /*
  * Read status from cdrom. Check to see if the status is available.
  */
-static int sjcd_check_status( void ){
-  /*
-   * Try to load the response from cdrom into buffer.
-   */
-  if( SJCD_STATUS_AVAILABLE( inb( SJCDPORT( 1 ) ) ) ){
-    sjcd_load_status();
-    return( 1 );
-  } else {
-    /*
-     * No status is available.
-     */
-    return( 0 );
-  }
+static int sjcd_check_status(void)
+{
+	/*
+	 * Try to load the response from cdrom into buffer.
+	 */
+	if (SJCD_STATUS_AVAILABLE(inb(SJCDPORT(1)))) {
+		sjcd_load_status();
+		return (1);
+	} else {
+		/*
+		 * No status is available.
+		 */
+		return (0);
+	}
 }
 
 /*
@@ -359,575 +380,692 @@
  */
 #define SJCD_WAIT_FOR_STATUS_TIMEOUT 1000
 
-static void sjcd_status_timer( void ){
-  if( sjcd_check_status() ){
-    /*
-     * The command completed and status is loaded, stop waiting.
-     */
-    wake_up( &sjcd_waitq );
-  } else if( --sjcd_status_timeout <= 0 ){
-    /*
-     * We are timed out. 
-     */
-    wake_up( &sjcd_waitq );
-  } else {
-    /*
-     * We have still some time to wait. Try again.
-     */
-    SJCD_SET_TIMER( sjcd_status_timer, 1 );
-  }
+static void sjcd_status_timer(void)
+{
+	if (sjcd_check_status()) {
+		/*
+		 * The command completed and status is loaded, stop waiting.
+		 */
+		wake_up(&sjcd_waitq);
+	} else if (--sjcd_status_timeout <= 0) {
+		/*
+		 * We are timed out. 
+		 */
+		wake_up(&sjcd_waitq);
+	} else {
+		/*
+		 * We have still some time to wait. Try again.
+		 */
+		SJCD_SET_TIMER(sjcd_status_timer, 1);
+	}
 }
 
 /*
  * Wait for status for 10 sec approx. Returns non-positive when timed out.
  * Should not be used while reading data CDs.
  */
-static int sjcd_wait_for_status( void ){
-  sjcd_status_timeout = SJCD_WAIT_FOR_STATUS_TIMEOUT;
-  SJCD_SET_TIMER( sjcd_status_timer, 1 ); 
-  sleep_on( &sjcd_waitq );    
+static int sjcd_wait_for_status(void)
+{
+	sjcd_status_timeout = SJCD_WAIT_FOR_STATUS_TIMEOUT;
+	SJCD_SET_TIMER(sjcd_status_timer, 1);
+	sleep_on(&sjcd_waitq);
 #if defined( SJCD_DIAGNOSTIC ) || defined ( SJCD_TRACE )
-  if( sjcd_status_timeout <= 0 )
-    printk( "SJCD: Error Wait For Status.\n" );
+	if (sjcd_status_timeout <= 0)
+		printk("SJCD: Error Wait For Status.\n");
 #endif
-  return( sjcd_status_timeout );
+	return (sjcd_status_timeout);
 }
 
-static int sjcd_receive_status( void ){
-  int i;
+static int sjcd_receive_status(void)
+{
+	int i;
 #if defined( SJCD_TRACE )
-  printk( "SJCD: receive_status\n" );
+	printk("SJCD: receive_status\n");
 #endif
-  /*
-   * Wait a bit for status available.
-   */
-  for( i = 200; i-- && ( sjcd_check_status() == 0 ); );
-  if( i < 0 ){
+	/*
+	 * Wait a bit for status available.
+	 */
+	for (i = 200; i-- && (sjcd_check_status() == 0););
+	if (i < 0) {
 #if defined( SJCD_TRACE )
-    printk( "SJCD: long wait for status\n" );
+		printk("SJCD: long wait for status\n");
 #endif
-    if( sjcd_wait_for_status() <= 0 )
-      printk( "SJCD: Timeout when read status.\n" );
-    else i = 0;
-  }
-  return( i );
+		if (sjcd_wait_for_status() <= 0)
+			printk("SJCD: Timeout when read status.\n");
+		else
+			i = 0;
+	}
+	return (i);
 }
 
 /*
  * Load the status. Issue get status command and wait for status available.
  */
-static void sjcd_get_status( void ){
+static void sjcd_get_status(void)
+{
 #if defined( SJCD_TRACE )
-  printk( "SJCD: get_status\n" );
+	printk("SJCD: get_status\n");
 #endif
-  sjcd_send_cmd( SCMD_GET_STATUS );
-  sjcd_receive_status();
+	sjcd_send_cmd(SCMD_GET_STATUS);
+	sjcd_receive_status();
 }
 
 /*
  * Check the drive if the disk is changed. Should be revised.
  */
-static int sjcd_disk_change( kdev_t full_dev ){
+static int sjcd_disk_change(kdev_t full_dev)
+{
 #if 0
-  printk( "SJCD: sjcd_disk_change( 0x%x )\n", full_dev );
+	printk("SJCD: sjcd_disk_change( 0x%x )\n", full_dev);
 #endif
-  if( MINOR( full_dev ) > 0 ){
-    printk( "SJCD: request error: invalid device minor.\n" );
-    return 0;
-  }
-  if( !sjcd_command_is_in_progress )
-    sjcd_get_status();
-  return( sjcd_status_valid ? sjcd_media_is_changed : 0 );
+	if (MINOR(full_dev) > 0) {
+		printk("SJCD: request error: invalid device minor.\n");
+		return 0;
+	}
+	if (!sjcd_command_is_in_progress)
+		sjcd_get_status();
+	return (sjcd_status_valid ? sjcd_media_is_changed : 0);
 }
 
 /*
  * Read the table of contents (TOC) and TOC header if necessary.
  * We assume that the drive contains no more than 99 toc entries.
  */
-static struct sjcd_hw_disk_info sjcd_table_of_contents[ SJCD_MAX_TRACKS ];
+static struct sjcd_hw_disk_info sjcd_table_of_contents[SJCD_MAX_TRACKS];
 static unsigned char sjcd_first_track_no, sjcd_last_track_no;
 #define sjcd_disk_length  sjcd_table_of_contents[0].un.track_msf
 
-static int sjcd_update_toc( void ){
-  struct sjcd_hw_disk_info info;
-  int i;
-#if defined( SJCD_TRACE )
-  printk( "SJCD: update toc:\n" );
-#endif
-  /*
-   * check to see if we need to do anything
-   */
-  if( sjcd_toc_uptodate ) return( 0 );
-
-  /*
-   * Get the TOC start information.
-   */
-  sjcd_send_1_cmd( SCMD_GET_DISK_INFO, SCMD_GET_1_TRACK );
-  sjcd_receive_status();
-
-  if( !sjcd_status_valid ){
-    printk( "SJCD: cannot load status.\n" );
-    return( -1 );
-  }
-
-  if( !sjcd_media_is_available ){
-    printk( "SJCD: no disk in drive\n" );
-    return( -1 );
-  }
-
-  if( !sjcd_command_failed ){
-    if( sjcd_load_response( &info, sizeof( info ) ) != 0 ){
-      printk( "SJCD: cannot load response about TOC start.\n" );
-      return( -1 );
-    }
-    sjcd_first_track_no = bcd2bin( info.un.track_no );
-  } else {
-    printk( "SJCD: get first failed\n" );
-    return( -1 );
-  }
-#if defined( SJCD_TRACE )
-  printk( "SJCD: TOC start 0x%02x ", sjcd_first_track_no );
-#endif
-  /*
-   * Get the TOC finish information.
-   */
-  sjcd_send_1_cmd( SCMD_GET_DISK_INFO, SCMD_GET_L_TRACK );
-  sjcd_receive_status();
-
-  if( !sjcd_status_valid ){
-    printk( "SJCD: cannot load status.\n" );
-    return( -1 );
-  }
-
-  if( !sjcd_media_is_available ){
-    printk( "SJCD: no disk in drive\n" );
-    return( -1 );
-  }
-
-  if( !sjcd_command_failed ){
-    if( sjcd_load_response( &info, sizeof( info ) ) != 0 ){
-      printk( "SJCD: cannot load response about TOC finish.\n" );
-      return( -1 );
-    }
-    sjcd_last_track_no = bcd2bin( info.un.track_no );
-  } else {
-    printk( "SJCD: get last failed\n" );
-    return( -1 );
-  }
-#if defined( SJCD_TRACE )
-  printk( "SJCD: TOC finish 0x%02x ", sjcd_last_track_no );
-#endif
-  for( i = sjcd_first_track_no; i <= sjcd_last_track_no; i++ ){
-    /*
-     * Get the first track information.
-     */
-    sjcd_send_1_cmd( SCMD_GET_DISK_INFO, bin2bcd( i ) );
-    sjcd_receive_status();
-
-    if( !sjcd_status_valid ){
-      printk( "SJCD: cannot load status.\n" );
-      return( -1 );
-    }
-
-    if( !sjcd_media_is_available ){
-      printk( "SJCD: no disk in drive\n" );
-      return( -1 );
-    }
-
-    if( !sjcd_command_failed ){
-      if( sjcd_load_response( &sjcd_table_of_contents[ i ],
-			     sizeof( struct sjcd_hw_disk_info ) ) != 0 ){
-	printk( "SJCD: cannot load info for %d track\n", i );
-	return( -1 );
-      }
-    } else {
-      printk( "SJCD: get info %d failed\n", i );
-      return( -1 );
-    }
-  }
-
-  /*
-   * Get the disk length info.
-   */
-  sjcd_send_1_cmd( SCMD_GET_DISK_INFO, SCMD_GET_D_SIZE );
-  sjcd_receive_status();
-
-  if( !sjcd_status_valid ){
-    printk( "SJCD: cannot load status.\n" );
-    return( -1 );
-  }
-
-  if( !sjcd_media_is_available ){
-    printk( "SJCD: no disk in drive\n" );
-    return( -1 );
-  }
-
-  if( !sjcd_command_failed ){
-    if( sjcd_load_response( &info, sizeof( info ) ) != 0 ){
-      printk( "SJCD: cannot load response about disk size.\n" );
-      return( -1 );
-    }
-    sjcd_disk_length.min = info.un.track_msf.min;
-    sjcd_disk_length.sec = info.un.track_msf.sec;
-    sjcd_disk_length.frame = info.un.track_msf.frame;
-  } else {
-    printk( "SJCD: get size failed\n" );
-    return( 1 );
-  }
+static int sjcd_update_toc(void)
+{
+	struct sjcd_hw_disk_info info;
+	int i;
 #if defined( SJCD_TRACE )
-  printk( "SJCD: (%02x:%02x.%02x)\n", sjcd_disk_length.min,
-	 sjcd_disk_length.sec, sjcd_disk_length.frame );
+	printk("SJCD: update toc:\n");
 #endif
-  return( 0 );
+	/*
+	 * check to see if we need to do anything
+	 */
+	if (sjcd_toc_uptodate)
+		return (0);
+
+	/*
+	 * Get the TOC start information.
+	 */
+	sjcd_send_1_cmd(SCMD_GET_DISK_INFO, SCMD_GET_1_TRACK);
+	sjcd_receive_status();
+
+	if (!sjcd_status_valid) {
+		printk("SJCD: cannot load status.\n");
+		return (-1);
+	}
+
+	if (!sjcd_media_is_available) {
+		printk("SJCD: no disk in drive\n");
+		return (-1);
+	}
+
+	if (!sjcd_command_failed) {
+		if (sjcd_load_response(&info, sizeof(info)) != 0) {
+			printk
+			    ("SJCD: cannot load response about TOC start.\n");
+			return (-1);
+		}
+		sjcd_first_track_no = bcd2bin(info.un.track_no);
+	} else {
+		printk("SJCD: get first failed\n");
+		return (-1);
+	}
+#if defined( SJCD_TRACE )
+	printk("SJCD: TOC start 0x%02x ", sjcd_first_track_no);
+#endif
+	/*
+	 * Get the TOC finish information.
+	 */
+	sjcd_send_1_cmd(SCMD_GET_DISK_INFO, SCMD_GET_L_TRACK);
+	sjcd_receive_status();
+
+	if (!sjcd_status_valid) {
+		printk("SJCD: cannot load status.\n");
+		return (-1);
+	}
+
+	if (!sjcd_media_is_available) {
+		printk("SJCD: no disk in drive\n");
+		return (-1);
+	}
+
+	if (!sjcd_command_failed) {
+		if (sjcd_load_response(&info, sizeof(info)) != 0) {
+			printk
+			    ("SJCD: cannot load response about TOC finish.\n");
+			return (-1);
+		}
+		sjcd_last_track_no = bcd2bin(info.un.track_no);
+	} else {
+		printk("SJCD: get last failed\n");
+		return (-1);
+	}
+#if defined( SJCD_TRACE )
+	printk("SJCD: TOC finish 0x%02x ", sjcd_last_track_no);
+#endif
+	for (i = sjcd_first_track_no; i <= sjcd_last_track_no; i++) {
+		/*
+		 * Get the first track information.
+		 */
+		sjcd_send_1_cmd(SCMD_GET_DISK_INFO, bin2bcd(i));
+		sjcd_receive_status();
+
+		if (!sjcd_status_valid) {
+			printk("SJCD: cannot load status.\n");
+			return (-1);
+		}
+
+		if (!sjcd_media_is_available) {
+			printk("SJCD: no disk in drive\n");
+			return (-1);
+		}
+
+		if (!sjcd_command_failed) {
+			if (sjcd_load_response(&sjcd_table_of_contents[i],
+					       sizeof(struct
+						      sjcd_hw_disk_info))
+			    != 0) {
+				printk
+				    ("SJCD: cannot load info for %d track\n",
+				     i);
+				return (-1);
+			}
+		} else {
+			printk("SJCD: get info %d failed\n", i);
+			return (-1);
+		}
+	}
+
+	/*
+	 * Get the disk length info.
+	 */
+	sjcd_send_1_cmd(SCMD_GET_DISK_INFO, SCMD_GET_D_SIZE);
+	sjcd_receive_status();
+
+	if (!sjcd_status_valid) {
+		printk("SJCD: cannot load status.\n");
+		return (-1);
+	}
+
+	if (!sjcd_media_is_available) {
+		printk("SJCD: no disk in drive\n");
+		return (-1);
+	}
+
+	if (!sjcd_command_failed) {
+		if (sjcd_load_response(&info, sizeof(info)) != 0) {
+			printk
+			    ("SJCD: cannot load response about disk size.\n");
+			return (-1);
+		}
+		sjcd_disk_length.min = info.un.track_msf.min;
+		sjcd_disk_length.sec = info.un.track_msf.sec;
+		sjcd_disk_length.frame = info.un.track_msf.frame;
+	} else {
+		printk("SJCD: get size failed\n");
+		return (1);
+	}
+#if defined( SJCD_TRACE )
+	printk("SJCD: (%02x:%02x.%02x)\n", sjcd_disk_length.min,
+	       sjcd_disk_length.sec, sjcd_disk_length.frame);
+#endif
+	return (0);
 }
 
 /*
  * Load subchannel information.
  */
-static int sjcd_get_q_info( struct sjcd_hw_qinfo *qp ){
-  int s;
+static int sjcd_get_q_info(struct sjcd_hw_qinfo *qp)
+{
+	int s;
 #if defined( SJCD_TRACE )
-  printk( "SJCD: load sub q\n" );
+	printk("SJCD: load sub q\n");
 #endif
-  sjcd_send_cmd( SCMD_GET_QINFO );
-  s = sjcd_receive_status();
-  if( s < 0 || sjcd_command_failed || !sjcd_status_valid ){
-    sjcd_send_cmd( 0xF2 );
-    s = sjcd_receive_status();
-    if( s < 0 || sjcd_command_failed || !sjcd_status_valid ) return( -1 );
-    sjcd_send_cmd( SCMD_GET_QINFO );
-    s = sjcd_receive_status();
-    if( s < 0 || sjcd_command_failed || !sjcd_status_valid ) return( -1 );
-  }
-  if( sjcd_media_is_available )
-    if( sjcd_load_response( qp, sizeof( *qp ) ) == 0 ) return( 0 );
-  return( -1 );
+	sjcd_send_cmd(SCMD_GET_QINFO);
+	s = sjcd_receive_status();
+	if (s < 0 || sjcd_command_failed || !sjcd_status_valid) {
+		sjcd_send_cmd(0xF2);
+		s = sjcd_receive_status();
+		if (s < 0 || sjcd_command_failed || !sjcd_status_valid)
+			return (-1);
+		sjcd_send_cmd(SCMD_GET_QINFO);
+		s = sjcd_receive_status();
+		if (s < 0 || sjcd_command_failed || !sjcd_status_valid)
+			return (-1);
+	}
+	if (sjcd_media_is_available)
+		if (sjcd_load_response(qp, sizeof(*qp)) == 0)
+			return (0);
+	return (-1);
 }
 
 /*
  * Start playing from the specified position.
  */
-static int sjcd_play( struct sjcd_play_msf *mp ){
-  struct sjcd_play_msf msf;
+static int sjcd_play(struct sjcd_play_msf *mp)
+{
+	struct sjcd_play_msf msf;
 
-  /*
-   * Turn the device to play mode.
-   */
-  sjcd_send_1_cmd( SCMD_SET_MODE, SCMD_MODE_PLAY );
-  if( sjcd_receive_status() < 0 ) return( -1 );
-
-  /*
-   * Seek to the starting point.
-   */
-  msf.start = mp->start;
-  msf.end.min = msf.end.sec = msf.end.frame = 0x00;
-  sjcd_send_6_cmd( SCMD_SEEK, &msf );
-  if( sjcd_receive_status() < 0 ) return( -1 );
-
-  /*
-   * Start playing.
-   */
-  sjcd_send_6_cmd( SCMD_PLAY, mp );
-  return( sjcd_receive_status() );
+	/*
+	 * Turn the device to play mode.
+	 */
+	sjcd_send_1_cmd(SCMD_SET_MODE, SCMD_MODE_PLAY);
+	if (sjcd_receive_status() < 0)
+		return (-1);
+
+	/*
+	 * Seek to the starting point.
+	 */
+	msf.start = mp->start;
+	msf.end.min = msf.end.sec = msf.end.frame = 0x00;
+	sjcd_send_6_cmd(SCMD_SEEK, &msf);
+	if (sjcd_receive_status() < 0)
+		return (-1);
+
+	/*
+	 * Start playing.
+	 */
+	sjcd_send_6_cmd(SCMD_PLAY, mp);
+	return (sjcd_receive_status());
 }
 
 /*
  * Tray control functions.
  */
-static int sjcd_tray_close( void ){
+static int sjcd_tray_close(void)
+{
 #if defined( SJCD_TRACE )
-  printk( "SJCD: tray_close\n" );
+	printk("SJCD: tray_close\n");
 #endif
-  sjcd_send_cmd( SCMD_CLOSE_TRAY );
-  return( sjcd_receive_status() );
+	sjcd_send_cmd(SCMD_CLOSE_TRAY);
+	return (sjcd_receive_status());
 }
 
-static int sjcd_tray_lock( void ){
+static int sjcd_tray_lock(void)
+{
 #if defined( SJCD_TRACE )
-  printk( "SJCD: tray_lock\n" );
+	printk("SJCD: tray_lock\n");
 #endif
-  sjcd_send_cmd( SCMD_LOCK_TRAY );
-  return( sjcd_receive_status() );
+	sjcd_send_cmd(SCMD_LOCK_TRAY);
+	return (sjcd_receive_status());
 }
 
-static int sjcd_tray_unlock( void ){
+static int sjcd_tray_unlock(void)
+{
 #if defined( SJCD_TRACE )
-  printk( "SJCD: tray_unlock\n" );
+	printk("SJCD: tray_unlock\n");
 #endif
-  sjcd_send_cmd( SCMD_UNLOCK_TRAY );
-  return( sjcd_receive_status() );
+	sjcd_send_cmd(SCMD_UNLOCK_TRAY);
+	return (sjcd_receive_status());
 }
 
-static int sjcd_tray_open( void ){
+static int sjcd_tray_open(void)
+{
 #if defined( SJCD_TRACE )
-  printk( "SJCD: tray_open\n" );
+	printk("SJCD: tray_open\n");
 #endif
-  sjcd_send_cmd( SCMD_EJECT_TRAY );
-  return( sjcd_receive_status() );
+	sjcd_send_cmd(SCMD_EJECT_TRAY);
+	return (sjcd_receive_status());
 }
 
 /*
  * Do some user commands.
  */
-static int sjcd_ioctl( struct inode *ip, struct file *fp,
-		       unsigned int cmd, unsigned long arg ){
-#if defined( SJCD_TRACE )
-  printk( "SJCD:ioctl\n" );
-#endif
-
-  if( ip == NULL ) return( -EINVAL );
-
-  sjcd_get_status();
-  if( !sjcd_status_valid ) return( -EIO );
-  if( sjcd_update_toc() < 0 ) return( -EIO );
-
-  switch( cmd ){
-  case CDROMSTART:{
-#if defined( SJCD_TRACE )
-    printk( "SJCD: ioctl: start\n" );
-#endif
-    return( 0 );
-  }
-
-  case CDROMSTOP:{
+static int sjcd_ioctl(struct inode *ip, struct file *fp,
+		      unsigned int cmd, unsigned long arg)
+{
 #if defined( SJCD_TRACE )
-    printk( "SJCD: ioctl: stop\n" );
+	printk("SJCD:ioctl\n");
 #endif
-    sjcd_send_cmd( SCMD_PAUSE );
-    ( void )sjcd_receive_status();
-    sjcd_audio_status = CDROM_AUDIO_NO_STATUS;
-    return( 0 );
-  }
 
-  case CDROMPAUSE:{
-    struct sjcd_hw_qinfo q_info;
-#if defined( SJCD_TRACE )
-    printk( "SJCD: ioctl: pause\n" );
-#endif
-    if( sjcd_audio_status == CDROM_AUDIO_PLAY ){
-      sjcd_send_cmd( SCMD_PAUSE );
-      ( void )sjcd_receive_status();
-      if( sjcd_get_q_info( &q_info ) < 0 ){
-	sjcd_audio_status = CDROM_AUDIO_NO_STATUS;
-      } else {
-	sjcd_audio_status = CDROM_AUDIO_PAUSED;
-	sjcd_playing.start = q_info.abs;
-      }
-      return( 0 );
-    } else return( -EINVAL );
-  }
-
-  case CDROMRESUME:{
-#if defined( SJCD_TRACE )
-    printk( "SJCD: ioctl: resume\n" );
-#endif
-    if( sjcd_audio_status == CDROM_AUDIO_PAUSED ){
-      /*
-       * continue play starting at saved location
-       */
-      if( sjcd_play( &sjcd_playing ) < 0 ){
-	sjcd_audio_status = CDROM_AUDIO_ERROR;
-	return( -EIO );
-      } else {
-	sjcd_audio_status = CDROM_AUDIO_PLAY;
-	return( 0 );
-      }
-    } else return( -EINVAL );
-  }
-
-  case CDROMPLAYTRKIND:{
-    struct cdrom_ti ti; int s;
-#if defined( SJCD_TRACE )
-    printk( "SJCD: ioctl: playtrkind\n" );
-#endif
-    if( ( s = verify_area( VERIFY_READ, (void *)arg, sizeof( ti ) ) ) == 0 ){
-      copy_from_user( &ti, (void *)arg, sizeof( ti ) );
-
-      if( ti.cdti_trk0 < sjcd_first_track_no ) return( -EINVAL );
-      if( ti.cdti_trk1 > sjcd_last_track_no )
-	ti.cdti_trk1 = sjcd_last_track_no;
-      if( ti.cdti_trk0 > ti.cdti_trk1 ) return( -EINVAL );
-
-      sjcd_playing.start = sjcd_table_of_contents[ ti.cdti_trk0 ].un.track_msf;
-      sjcd_playing.end = ( ti.cdti_trk1 < sjcd_last_track_no ) ?
-	sjcd_table_of_contents[ ti.cdti_trk1 + 1 ].un.track_msf :
-	  sjcd_table_of_contents[ 0 ].un.track_msf;
-      
-      if( sjcd_play( &sjcd_playing ) < 0 ){
-	sjcd_audio_status = CDROM_AUDIO_ERROR;
-	return( -EIO );
-      } else sjcd_audio_status = CDROM_AUDIO_PLAY;
-    }
-    return( s );
-  }
-
-  case CDROMPLAYMSF:{
-    struct cdrom_msf sjcd_msf; int s;
-#if defined( SJCD_TRACE )
-    printk( "SJCD: ioctl: playmsf\n" );
-#endif
-    if( ( s = verify_area( VERIFY_READ, (void *)arg, sizeof( sjcd_msf ) ) ) == 0 ){
-      if( sjcd_audio_status == CDROM_AUDIO_PLAY ){
-	sjcd_send_cmd( SCMD_PAUSE );
-	( void )sjcd_receive_status();
-	sjcd_audio_status = CDROM_AUDIO_NO_STATUS;
-      }
-
-      copy_from_user( &sjcd_msf, (void *)arg, sizeof( sjcd_msf ) );
-
-      sjcd_playing.start.min = bin2bcd( sjcd_msf.cdmsf_min0 );
-      sjcd_playing.start.sec = bin2bcd( sjcd_msf.cdmsf_sec0 );
-      sjcd_playing.start.frame = bin2bcd( sjcd_msf.cdmsf_frame0 );
-      sjcd_playing.end.min = bin2bcd( sjcd_msf.cdmsf_min1 );
-      sjcd_playing.end.sec = bin2bcd( sjcd_msf.cdmsf_sec1 );
-      sjcd_playing.end.frame = bin2bcd( sjcd_msf.cdmsf_frame1 );
-
-      if( sjcd_play( &sjcd_playing ) < 0 ){
-	sjcd_audio_status = CDROM_AUDIO_ERROR;
-	return( -EIO );
-      } else sjcd_audio_status = CDROM_AUDIO_PLAY;
-    }
-    return( s );
-  }
+	if (ip == NULL)
+		return (-EINVAL);
 
-  case CDROMREADTOCHDR:{
-    struct cdrom_tochdr toc_header; int s;
+	sjcd_get_status();
+	if (!sjcd_status_valid)
+		return (-EIO);
+	if (sjcd_update_toc() < 0)
+		return (-EIO);
+
+	switch (cmd) {
+	case CDROMSTART:{
+#if defined( SJCD_TRACE )
+			printk("SJCD: ioctl: start\n");
+#endif
+			return (0);
+		}
+
+	case CDROMSTOP:{
+#if defined( SJCD_TRACE )
+			printk("SJCD: ioctl: stop\n");
+#endif
+			sjcd_send_cmd(SCMD_PAUSE);
+			(void) sjcd_receive_status();
+			sjcd_audio_status = CDROM_AUDIO_NO_STATUS;
+			return (0);
+		}
+
+	case CDROMPAUSE:{
+			struct sjcd_hw_qinfo q_info;
+#if defined( SJCD_TRACE )
+			printk("SJCD: ioctl: pause\n");
+#endif
+			if (sjcd_audio_status == CDROM_AUDIO_PLAY) {
+				sjcd_send_cmd(SCMD_PAUSE);
+				(void) sjcd_receive_status();
+				if (sjcd_get_q_info(&q_info) < 0) {
+					sjcd_audio_status =
+					    CDROM_AUDIO_NO_STATUS;
+				} else {
+					sjcd_audio_status =
+					    CDROM_AUDIO_PAUSED;
+					sjcd_playing.start = q_info.abs;
+				}
+				return (0);
+			} else
+				return (-EINVAL);
+		}
+
+	case CDROMRESUME:{
+#if defined( SJCD_TRACE )
+			printk("SJCD: ioctl: resume\n");
+#endif
+			if (sjcd_audio_status == CDROM_AUDIO_PAUSED) {
+				/*
+				 * continue play starting at saved location
+				 */
+				if (sjcd_play(&sjcd_playing) < 0) {
+					sjcd_audio_status =
+					    CDROM_AUDIO_ERROR;
+					return (-EIO);
+				} else {
+					sjcd_audio_status =
+					    CDROM_AUDIO_PLAY;
+					return (0);
+				}
+			} else
+				return (-EINVAL);
+		}
+
+	case CDROMPLAYTRKIND:{
+			struct cdrom_ti ti;
+			int s;
+#if defined( SJCD_TRACE )
+			printk("SJCD: ioctl: playtrkind\n");
+#endif
+			if ((s =
+			     verify_area(VERIFY_READ, (void *) arg,
+					 sizeof(ti))) == 0) {
+				copy_from_user(&ti, (void *) arg,
+					       sizeof(ti));
+
+				if (ti.cdti_trk0 < sjcd_first_track_no)
+					return (-EINVAL);
+				if (ti.cdti_trk1 > sjcd_last_track_no)
+					ti.cdti_trk1 = sjcd_last_track_no;
+				if (ti.cdti_trk0 > ti.cdti_trk1)
+					return (-EINVAL);
+
+				sjcd_playing.start =
+				    sjcd_table_of_contents[ti.cdti_trk0].
+				    un.track_msf;
+				sjcd_playing.end =
+				    (ti.cdti_trk1 <
+				     sjcd_last_track_no) ?
+				    sjcd_table_of_contents[ti.cdti_trk1 +
+							   1].un.
+				    track_msf : sjcd_table_of_contents[0].
+				    un.track_msf;
+
+				if (sjcd_play(&sjcd_playing) < 0) {
+					sjcd_audio_status =
+					    CDROM_AUDIO_ERROR;
+					return (-EIO);
+				} else
+					sjcd_audio_status =
+					    CDROM_AUDIO_PLAY;
+			}
+			return (s);
+		}
+
+	case CDROMPLAYMSF:{
+			struct cdrom_msf sjcd_msf;
+			int s;
+#if defined( SJCD_TRACE )
+			printk("SJCD: ioctl: playmsf\n");
+#endif
+			if ((s =
+			     verify_area(VERIFY_READ, (void *) arg,
+					 sizeof(sjcd_msf))) == 0) {
+				if (sjcd_audio_status == CDROM_AUDIO_PLAY) {
+					sjcd_send_cmd(SCMD_PAUSE);
+					(void) sjcd_receive_status();
+					sjcd_audio_status =
+					    CDROM_AUDIO_NO_STATUS;
+				}
+
+				copy_from_user(&sjcd_msf, (void *) arg,
+					       sizeof(sjcd_msf));
+
+				sjcd_playing.start.min =
+				    bin2bcd(sjcd_msf.cdmsf_min0);
+				sjcd_playing.start.sec =
+				    bin2bcd(sjcd_msf.cdmsf_sec0);
+				sjcd_playing.start.frame =
+				    bin2bcd(sjcd_msf.cdmsf_frame0);
+				sjcd_playing.end.min =
+				    bin2bcd(sjcd_msf.cdmsf_min1);
+				sjcd_playing.end.sec =
+				    bin2bcd(sjcd_msf.cdmsf_sec1);
+				sjcd_playing.end.frame =
+				    bin2bcd(sjcd_msf.cdmsf_frame1);
+
+				if (sjcd_play(&sjcd_playing) < 0) {
+					sjcd_audio_status =
+					    CDROM_AUDIO_ERROR;
+					return (-EIO);
+				} else
+					sjcd_audio_status =
+					    CDROM_AUDIO_PLAY;
+			}
+			return (s);
+		}
+
+	case CDROMREADTOCHDR:{
+			struct cdrom_tochdr toc_header;
+			int s;
 #if defined (SJCD_TRACE )
-    printk( "SJCD: ioctl: readtocheader\n" );
+			printk("SJCD: ioctl: readtocheader\n");
 #endif
-    if( ( s = verify_area( VERIFY_WRITE, (void *)arg, sizeof( toc_header ) ) ) == 0 ){
-      toc_header.cdth_trk0 = sjcd_first_track_no;
-      toc_header.cdth_trk1 = sjcd_last_track_no;
-      copy_to_user( (void *)arg, &toc_header, sizeof( toc_header ) );
-    }
-    return( s );
-  }
-
-  case CDROMREADTOCENTRY:{
-    struct cdrom_tocentry toc_entry; int s;
-#if defined( SJCD_TRACE )
-    printk( "SJCD: ioctl: readtocentry\n" );
-#endif
-    if( ( s = verify_area( VERIFY_WRITE, (void *)arg, sizeof( toc_entry ) ) ) == 0 ){
-      struct sjcd_hw_disk_info *tp;
-
-      copy_from_user( &toc_entry, (void *)arg, sizeof( toc_entry ) );
-
-      if( toc_entry.cdte_track == CDROM_LEADOUT )
-	tp = &sjcd_table_of_contents[ 0 ];
-      else if( toc_entry.cdte_track < sjcd_first_track_no ) return( -EINVAL );
-      else if( toc_entry.cdte_track > sjcd_last_track_no ) return( -EINVAL );
-      else tp = &sjcd_table_of_contents[ toc_entry.cdte_track ];
-
-      toc_entry.cdte_adr = tp->track_control & 0x0F;
-      toc_entry.cdte_ctrl = tp->track_control >> 4;
-
-      switch( toc_entry.cdte_format ){
-      case CDROM_LBA:
-	toc_entry.cdte_addr.lba = msf2hsg( &( tp->un.track_msf ) );
-	break;
-      case CDROM_MSF:
-	toc_entry.cdte_addr.msf.minute = bcd2bin( tp->un.track_msf.min );
-	toc_entry.cdte_addr.msf.second = bcd2bin( tp->un.track_msf.sec );
-	toc_entry.cdte_addr.msf.frame = bcd2bin( tp->un.track_msf.frame );
-	break;
-      default: return( -EINVAL );
-      }
-      copy_to_user( (void *)arg, &toc_entry, sizeof( toc_entry ) );
-    }
-    return( s );
-  }
-
-  case CDROMSUBCHNL:{
-    struct cdrom_subchnl subchnl; int s;
-#if defined( SJCD_TRACE )
-    printk( "SJCD: ioctl: subchnl\n" );
-#endif
-    if( ( s = verify_area( VERIFY_WRITE, (void *)arg, sizeof( subchnl ) ) ) == 0 ){
-      struct sjcd_hw_qinfo q_info;
-
-      copy_from_user( &subchnl, (void *)arg, sizeof( subchnl ) );
-      if( sjcd_get_q_info( &q_info ) < 0 ) return( -EIO );
-
-      subchnl.cdsc_audiostatus = sjcd_audio_status;
-      subchnl.cdsc_adr = q_info.track_control & 0x0F;
-      subchnl.cdsc_ctrl = q_info.track_control >> 4;
-      subchnl.cdsc_trk = bcd2bin( q_info.track_no );
-      subchnl.cdsc_ind = bcd2bin( q_info.x );
-
-      switch( subchnl.cdsc_format ){
-      case CDROM_LBA:
-	subchnl.cdsc_absaddr.lba = msf2hsg( &( q_info.abs ) );
-	subchnl.cdsc_reladdr.lba = msf2hsg( &( q_info.rel ) );
-	break;
-      case CDROM_MSF:
-	subchnl.cdsc_absaddr.msf.minute = bcd2bin( q_info.abs.min );
-	subchnl.cdsc_absaddr.msf.second = bcd2bin( q_info.abs.sec );
-	subchnl.cdsc_absaddr.msf.frame = bcd2bin( q_info.abs.frame );
-	subchnl.cdsc_reladdr.msf.minute = bcd2bin( q_info.rel.min );
-	subchnl.cdsc_reladdr.msf.second = bcd2bin( q_info.rel.sec );
-	subchnl.cdsc_reladdr.msf.frame = bcd2bin( q_info.rel.frame );
-	break;
-      default: return( -EINVAL );
-      }
-      copy_to_user( (void *)arg, &subchnl, sizeof( subchnl ) );
-    }
-    return( s );
-  }
-
-  case CDROMVOLCTRL:{
-    struct cdrom_volctrl vol_ctrl; int s;
-#if defined( SJCD_TRACE )
-    printk( "SJCD: ioctl: volctrl\n" );
-#endif
-    if( ( s = verify_area( VERIFY_READ, (void *)arg, sizeof( vol_ctrl ) ) ) == 0 ){
-      unsigned char dummy[ 4 ];
-
-      copy_from_user( &vol_ctrl, (void *)arg, sizeof( vol_ctrl ) );
-      sjcd_send_4_cmd( SCMD_SET_VOLUME, vol_ctrl.channel0, 0xFF,
-		      vol_ctrl.channel1, 0xFF );
-      if( sjcd_receive_status() < 0 ) return( -EIO );
-      ( void )sjcd_load_response( dummy, 4 );
-    }
-    return( s );
-  }
-
-  case CDROMEJECT:{
-#if defined( SJCD_TRACE )
-    printk( "SJCD: ioctl: eject\n" );
-#endif
-    if( !sjcd_command_is_in_progress ){
-      sjcd_tray_unlock();
-      sjcd_send_cmd( SCMD_EJECT_TRAY );
-      ( void )sjcd_receive_status();
-    }
-    return( 0 );
-  }
+			if ((s =
+			     verify_area(VERIFY_WRITE, (void *) arg,
+					 sizeof(toc_header))) == 0) {
+				toc_header.cdth_trk0 = sjcd_first_track_no;
+				toc_header.cdth_trk1 = sjcd_last_track_no;
+				copy_to_user((void *) arg, &toc_header,
+					     sizeof(toc_header));
+			}
+			return (s);
+		}
+
+	case CDROMREADTOCENTRY:{
+			struct cdrom_tocentry toc_entry;
+			int s;
+#if defined( SJCD_TRACE )
+			printk("SJCD: ioctl: readtocentry\n");
+#endif
+			if ((s =
+			     verify_area(VERIFY_WRITE, (void *) arg,
+					 sizeof(toc_entry))) == 0) {
+				struct sjcd_hw_disk_info *tp;
+
+				copy_from_user(&toc_entry, (void *) arg,
+					       sizeof(toc_entry));
+
+				if (toc_entry.cdte_track == CDROM_LEADOUT)
+					tp = &sjcd_table_of_contents[0];
+				else if (toc_entry.cdte_track <
+					 sjcd_first_track_no)
+					return (-EINVAL);
+				else if (toc_entry.cdte_track >
+					 sjcd_last_track_no)
+					return (-EINVAL);
+				else
+					tp = &sjcd_table_of_contents
+					    [toc_entry.cdte_track];
+
+				toc_entry.cdte_adr =
+				    tp->track_control & 0x0F;
+				toc_entry.cdte_ctrl =
+				    tp->track_control >> 4;
+
+				switch (toc_entry.cdte_format) {
+				case CDROM_LBA:
+					toc_entry.cdte_addr.lba =
+					    msf2hsg(&(tp->un.track_msf));
+					break;
+				case CDROM_MSF:
+					toc_entry.cdte_addr.msf.minute =
+					    bcd2bin(tp->un.track_msf.min);
+					toc_entry.cdte_addr.msf.second =
+					    bcd2bin(tp->un.track_msf.sec);
+					toc_entry.cdte_addr.msf.frame =
+					    bcd2bin(tp->un.track_msf.
+						    frame);
+					break;
+				default:
+					return (-EINVAL);
+				}
+				copy_to_user((void *) arg, &toc_entry,
+					     sizeof(toc_entry));
+			}
+			return (s);
+		}
+
+	case CDROMSUBCHNL:{
+			struct cdrom_subchnl subchnl;
+			int s;
+#if defined( SJCD_TRACE )
+			printk("SJCD: ioctl: subchnl\n");
+#endif
+			if ((s =
+			     verify_area(VERIFY_WRITE, (void *) arg,
+					 sizeof(subchnl))) == 0) {
+				struct sjcd_hw_qinfo q_info;
+
+				copy_from_user(&subchnl, (void *) arg,
+					       sizeof(subchnl));
+				if (sjcd_get_q_info(&q_info) < 0)
+					return (-EIO);
+
+				subchnl.cdsc_audiostatus =
+				    sjcd_audio_status;
+				subchnl.cdsc_adr =
+				    q_info.track_control & 0x0F;
+				subchnl.cdsc_ctrl =
+				    q_info.track_control >> 4;
+				subchnl.cdsc_trk =
+				    bcd2bin(q_info.track_no);
+				subchnl.cdsc_ind = bcd2bin(q_info.x);
+
+				switch (subchnl.cdsc_format) {
+				case CDROM_LBA:
+					subchnl.cdsc_absaddr.lba =
+					    msf2hsg(&(q_info.abs));
+					subchnl.cdsc_reladdr.lba =
+					    msf2hsg(&(q_info.rel));
+					break;
+				case CDROM_MSF:
+					subchnl.cdsc_absaddr.msf.minute =
+					    bcd2bin(q_info.abs.min);
+					subchnl.cdsc_absaddr.msf.second =
+					    bcd2bin(q_info.abs.sec);
+					subchnl.cdsc_absaddr.msf.frame =
+					    bcd2bin(q_info.abs.frame);
+					subchnl.cdsc_reladdr.msf.minute =
+					    bcd2bin(q_info.rel.min);
+					subchnl.cdsc_reladdr.msf.second =
+					    bcd2bin(q_info.rel.sec);
+					subchnl.cdsc_reladdr.msf.frame =
+					    bcd2bin(q_info.rel.frame);
+					break;
+				default:
+					return (-EINVAL);
+				}
+				copy_to_user((void *) arg, &subchnl,
+					     sizeof(subchnl));
+			}
+			return (s);
+		}
+
+	case CDROMVOLCTRL:{
+			struct cdrom_volctrl vol_ctrl;
+			int s;
+#if defined( SJCD_TRACE )
+			printk("SJCD: ioctl: volctrl\n");
+#endif
+			if ((s =
+			     verify_area(VERIFY_READ, (void *) arg,
+					 sizeof(vol_ctrl))) == 0) {
+				unsigned char dummy[4];
+
+				copy_from_user(&vol_ctrl, (void *) arg,
+					       sizeof(vol_ctrl));
+				sjcd_send_4_cmd(SCMD_SET_VOLUME,
+						vol_ctrl.channel0, 0xFF,
+						vol_ctrl.channel1, 0xFF);
+				if (sjcd_receive_status() < 0)
+					return (-EIO);
+				(void) sjcd_load_response(dummy, 4);
+			}
+			return (s);
+		}
+
+	case CDROMEJECT:{
+#if defined( SJCD_TRACE )
+			printk("SJCD: ioctl: eject\n");
+#endif
+			if (!sjcd_command_is_in_progress) {
+				sjcd_tray_unlock();
+				sjcd_send_cmd(SCMD_EJECT_TRAY);
+				(void) sjcd_receive_status();
+			}
+			return (0);
+		}
 
 #if defined( SJCD_GATHER_STAT )
-  case 0xABCD:{
-    int s;
+	case 0xABCD:{
+			int s;
 #if defined( SJCD_TRACE )
-    printk( "SJCD: ioctl: statistic\n" );
+			printk("SJCD: ioctl: statistic\n");
 #endif
-    if( ( s = verify_area( VERIFY_WRITE, (void *)arg, sizeof( statistic ) ) ) == 0 )
-      copy_to_user( (void *)arg, &statistic, sizeof( statistic ) );
-    return( s );
-  }
+			if ((s =
+			     verify_area(VERIFY_WRITE, (void *) arg,
+					 sizeof(statistic))) == 0)
+				copy_to_user((void *) arg, &statistic,
+					     sizeof(statistic));
+			return (s);
+		}
 #endif
 
-  default:
-    return( -EINVAL );
-  }
+	default:
+		return (-EINVAL);
+	}
 }
 
 /*
  * Invalidate internal buffers of the driver.
  */
-static void sjcd_invalidate_buffers( void ){
-  int i;
-  for( i = 0; i < SJCD_BUF_SIZ; sjcd_buf_bn[ i++ ] = -1 );
-  sjcd_buf_out = -1;
+static void sjcd_invalidate_buffers(void)
+{
+	int i;
+	for (i = 0; i < SJCD_BUF_SIZ; sjcd_buf_bn[i++] = -1);
+	sjcd_buf_out = -1;
 }
 
 /*
@@ -939,508 +1077,595 @@
     ( !QUEUE_EMPTY && MAJOR( CURRENT->rq_dev ) == MAJOR_NR && \
       CURRENT->cmd == READ && CURRENT->sector != -1 )
 
-static void sjcd_transfer( void ){
+static void sjcd_transfer(void)
+{
 #if defined( SJCD_TRACE )
-  printk( "SJCD: transfer:\n" );
+	printk("SJCD: transfer:\n");
 #endif
-  if( CURRENT_IS_VALID ){
-    while( CURRENT->nr_sectors ){
-      int i, bn = CURRENT->sector / 4;
-      for( i = 0; i < SJCD_BUF_SIZ && sjcd_buf_bn[ i ] != bn; i++ );
-      if( i < SJCD_BUF_SIZ ){
-	int offs = ( i * 4 + ( CURRENT->sector & 3 ) ) * 512;
-	int nr_sectors = 4 - ( CURRENT->sector & 3 );
-	if( sjcd_buf_out != i ){
-	  sjcd_buf_out = i;
-	  if( sjcd_buf_bn[ i ] != bn ){
-	    sjcd_buf_out = -1;
-	    continue;
-	  }
-	}
-	if( nr_sectors > CURRENT->nr_sectors )
-	  nr_sectors = CURRENT->nr_sectors;
-#if defined( SJCD_TRACE )
-	printk( "SJCD: copy out\n" );
-#endif
-	memcpy( CURRENT->buffer, sjcd_buf + offs, nr_sectors * 512 );
-	CURRENT->nr_sectors -= nr_sectors;
-	CURRENT->sector += nr_sectors;
-	CURRENT->buffer += nr_sectors * 512;
-      } else {
-	sjcd_buf_out = -1;
-	break;
-      }
-    }
-  }
+	if (CURRENT_IS_VALID) {
+		while (CURRENT->nr_sectors) {
+			int i, bn = CURRENT->sector / 4;
+			for (i = 0;
+			     i < SJCD_BUF_SIZ && sjcd_buf_bn[i] != bn;
+			     i++);
+			if (i < SJCD_BUF_SIZ) {
+				int offs =
+				    (i * 4 + (CURRENT->sector & 3)) * 512;
+				int nr_sectors = 4 - (CURRENT->sector & 3);
+				if (sjcd_buf_out != i) {
+					sjcd_buf_out = i;
+					if (sjcd_buf_bn[i] != bn) {
+						sjcd_buf_out = -1;
+						continue;
+					}
+				}
+				if (nr_sectors > CURRENT->nr_sectors)
+					nr_sectors = CURRENT->nr_sectors;
+#if defined( SJCD_TRACE )
+				printk("SJCD: copy out\n");
+#endif
+				memcpy(CURRENT->buffer, sjcd_buf + offs,
+				       nr_sectors * 512);
+				CURRENT->nr_sectors -= nr_sectors;
+				CURRENT->sector += nr_sectors;
+				CURRENT->buffer += nr_sectors * 512;
+			} else {
+				sjcd_buf_out = -1;
+				break;
+			}
+		}
+	}
 #if defined( SJCD_TRACE )
-  printk( "SJCD: transfer: done\n" );
+	printk("SJCD: transfer: done\n");
 #endif
 }
 
-static void sjcd_poll( void ){
+static void sjcd_poll(void)
+{
 #if defined( SJCD_GATHER_STAT )
-  /*
-   * Update total number of ticks.
-   */
-  statistic.ticks++;
-  statistic.tticks[ sjcd_transfer_state ]++;
+	/*
+	 * Update total number of ticks.
+	 */
+	statistic.ticks++;
+	statistic.tticks[sjcd_transfer_state]++;
 #endif
 
- ReSwitch: switch( sjcd_transfer_state ){
-      
-  case SJCD_S_IDLE:{
+      ReSwitch:switch (sjcd_transfer_state) {
+
+	case SJCD_S_IDLE:{
 #if defined( SJCD_GATHER_STAT )
-    statistic.idle_ticks++;
+			statistic.idle_ticks++;
 #endif
 #if defined( SJCD_TRACE )
-    printk( "SJCD_S_IDLE\n" );
+			printk("SJCD_S_IDLE\n");
 #endif
-    return;
-  }
+			return;
+		}
 
-  case SJCD_S_START:{
+	case SJCD_S_START:{
 #if defined( SJCD_GATHER_STAT )
-    statistic.start_ticks++;
+			statistic.start_ticks++;
 #endif
-    sjcd_send_cmd( SCMD_GET_STATUS );
-    sjcd_transfer_state =
-      sjcd_mode == SCMD_MODE_COOKED ? SJCD_S_READ : SJCD_S_MODE;
-    sjcd_transfer_timeout = 500;
-#if defined( SJCD_TRACE )
-    printk( "SJCD_S_START: goto SJCD_S_%s mode\n",
-	   sjcd_transfer_state == SJCD_S_READ ? "READ" : "MODE" );
-#endif
-    break;
-  }
-    
-  case SJCD_S_MODE:{
-    if( sjcd_check_status() ){
-      /*
-       * Previous command is completed.
-       */
-      if( !sjcd_status_valid || sjcd_command_failed ){
-#if defined( SJCD_TRACE )
-	printk( "SJCD_S_MODE: pre-cmd failed: goto to SJCD_S_STOP mode\n" );
-#endif
-	sjcd_transfer_state = SJCD_S_STOP;
-	goto ReSwitch;
-      }
-
-      sjcd_mode = 0; /* unknown mode; should not be valid when failed */
-      sjcd_send_1_cmd( SCMD_SET_MODE, SCMD_MODE_COOKED );
-      sjcd_transfer_state = SJCD_S_READ; sjcd_transfer_timeout = 1000;
+			sjcd_send_cmd(SCMD_GET_STATUS);
+			sjcd_transfer_state =
+			    sjcd_mode ==
+			    SCMD_MODE_COOKED ? SJCD_S_READ : SJCD_S_MODE;
+			sjcd_transfer_timeout = 500;
+#if defined( SJCD_TRACE )
+			printk("SJCD_S_START: goto SJCD_S_%s mode\n",
+			       sjcd_transfer_state ==
+			       SJCD_S_READ ? "READ" : "MODE");
+#endif
+			break;
+		}
+
+	case SJCD_S_MODE:{
+			if (sjcd_check_status()) {
+				/*
+				 * Previous command is completed.
+				 */
+				if (!sjcd_status_valid
+				    || sjcd_command_failed) {
+#if defined( SJCD_TRACE )
+					printk
+					    ("SJCD_S_MODE: pre-cmd failed: goto to SJCD_S_STOP mode\n");
+#endif
+					sjcd_transfer_state = SJCD_S_STOP;
+					goto ReSwitch;
+				}
+
+				sjcd_mode = 0;	/* unknown mode; should not be valid when failed */
+				sjcd_send_1_cmd(SCMD_SET_MODE,
+						SCMD_MODE_COOKED);
+				sjcd_transfer_state = SJCD_S_READ;
+				sjcd_transfer_timeout = 1000;
 #if defined( SJCD_TRACE )
-      printk( "SJCD_S_MODE: goto SJCD_S_READ mode\n" );
+				printk
+				    ("SJCD_S_MODE: goto SJCD_S_READ mode\n");
 #endif
-    }
+			}
 #if defined( SJCD_GATHER_STAT )
-    else statistic.mode_ticks++;
+			else
+				statistic.mode_ticks++;
 #endif
-    break;
-  }
+			break;
+		}
 
-  case SJCD_S_READ:{
-    if( sjcd_status_valid ? 1 : sjcd_check_status() ){
-      /*
-       * Previous command is completed.
-       */
-      if( !sjcd_status_valid || sjcd_command_failed ){
-#if defined( SJCD_TRACE )
-	printk( "SJCD_S_READ: pre-cmd failed: goto to SJCD_S_STOP mode\n" );
-#endif
-	sjcd_transfer_state = SJCD_S_STOP;
-	goto ReSwitch;
-      }
-      if( !sjcd_media_is_available ){
-#if defined( SJCD_TRACE )
-	printk( "SJCD_S_READ: no disk: goto to SJCD_S_STOP mode\n" );
-#endif
-	sjcd_transfer_state = SJCD_S_STOP;
-	goto ReSwitch;
-      }
-      if( sjcd_mode != SCMD_MODE_COOKED ){
-	/*
-	 * We seem to come from set mode. So discard one byte of result.
-	 */
-	if( sjcd_load_response( &sjcd_mode, 1 ) != 0 ){
-#if defined( SJCD_TRACE )
-	  printk( "SJCD_S_READ: load failed: goto to SJCD_S_STOP mode\n" );
-#endif
-	  sjcd_transfer_state = SJCD_S_STOP;
-	  goto ReSwitch;
-	}
-	if( sjcd_mode != SCMD_MODE_COOKED ){
-#if defined( SJCD_TRACE )
-	  printk( "SJCD_S_READ: mode failed: goto to SJCD_S_STOP mode\n" );
+	case SJCD_S_READ:{
+			if (sjcd_status_valid ? 1 : sjcd_check_status()) {
+				/*
+				 * Previous command is completed.
+				 */
+				if (!sjcd_status_valid
+				    || sjcd_command_failed) {
+#if defined( SJCD_TRACE )
+					printk
+					    ("SJCD_S_READ: pre-cmd failed: goto to SJCD_S_STOP mode\n");
+#endif
+					sjcd_transfer_state = SJCD_S_STOP;
+					goto ReSwitch;
+				}
+				if (!sjcd_media_is_available) {
+#if defined( SJCD_TRACE )
+					printk
+					    ("SJCD_S_READ: no disk: goto to SJCD_S_STOP mode\n");
+#endif
+					sjcd_transfer_state = SJCD_S_STOP;
+					goto ReSwitch;
+				}
+				if (sjcd_mode != SCMD_MODE_COOKED) {
+					/*
+					 * We seem to come from set mode. So discard one byte of result.
+					 */
+					if (sjcd_load_response
+					    (&sjcd_mode, 1) != 0) {
+#if defined( SJCD_TRACE )
+						printk
+						    ("SJCD_S_READ: load failed: goto to SJCD_S_STOP mode\n");
+#endif
+						sjcd_transfer_state =
+						    SJCD_S_STOP;
+						goto ReSwitch;
+					}
+					if (sjcd_mode != SCMD_MODE_COOKED) {
+#if defined( SJCD_TRACE )
+						printk
+						    ("SJCD_S_READ: mode failed: goto to SJCD_S_STOP mode\n");
+#endif
+						sjcd_transfer_state =
+						    SJCD_S_STOP;
+						goto ReSwitch;
+					}
+				}
+
+				if (CURRENT_IS_VALID) {
+					struct sjcd_play_msf msf;
+
+					sjcd_next_bn = CURRENT->sector / 4;
+					hsg2msf(sjcd_next_bn, &msf.start);
+					msf.end.min = 0;
+					msf.end.sec = 0;
+					msf.end.frame = sjcd_read_count =
+					    SJCD_BUF_SIZ;
+#if defined( SJCD_TRACE )
+					printk
+					    ("SJCD: ---reading msf-address %x:%x:%x  %x:%x:%x\n",
+					     msf.start.min, msf.start.sec,
+					     msf.start.frame, msf.end.min,
+					     msf.end.sec, msf.end.frame);
+					printk
+					    ("sjcd_next_bn:%x buf_in:%x buf_out:%x buf_bn:%x\n",
+					     sjcd_next_bn, sjcd_buf_in,
+					     sjcd_buf_out,
+					     sjcd_buf_bn[sjcd_buf_in]);
+#endif
+					sjcd_send_6_cmd(SCMD_DATA_READ,
+							&msf);
+					sjcd_transfer_state = SJCD_S_DATA;
+					sjcd_transfer_timeout = 500;
+#if defined( SJCD_TRACE )
+					printk
+					    ("SJCD_S_READ: go to SJCD_S_DATA mode\n");
+#endif
+				} else {
+#if defined( SJCD_TRACE )
+					printk
+					    ("SJCD_S_READ: nothing to read: go to SJCD_S_STOP mode\n");
+#endif
+					sjcd_transfer_state = SJCD_S_STOP;
+					goto ReSwitch;
+				}
+			}
+#if defined( SJCD_GATHER_STAT )
+			else
+				statistic.read_ticks++;
 #endif
-	  sjcd_transfer_state = SJCD_S_STOP;
-	  goto ReSwitch;
-	}
-      }
+			break;
+		}
 
-      if( CURRENT_IS_VALID ){
-	struct sjcd_play_msf msf;
+	case SJCD_S_DATA:{
+			unsigned char stat;
 
-	sjcd_next_bn = CURRENT->sector / 4;
-	hsg2msf( sjcd_next_bn, &msf.start );
-	msf.end.min = 0; msf.end.sec = 0;            
-	msf.end.frame = sjcd_read_count = SJCD_BUF_SIZ;
-#if defined( SJCD_TRACE )
-	printk( "SJCD: ---reading msf-address %x:%x:%x  %x:%x:%x\n",
-	       msf.start.min, msf.start.sec, msf.start.frame,
-	       msf.end.min,   msf.end.sec,   msf.end.frame );
-	printk( "sjcd_next_bn:%x buf_in:%x buf_out:%x buf_bn:%x\n", \
-	     sjcd_next_bn, sjcd_buf_in, sjcd_buf_out,
-	     sjcd_buf_bn[ sjcd_buf_in ] );
-#endif	
-	sjcd_send_6_cmd( SCMD_DATA_READ, &msf );
-	sjcd_transfer_state = SJCD_S_DATA;
-	sjcd_transfer_timeout = 500;
-#if defined( SJCD_TRACE )
-	printk( "SJCD_S_READ: go to SJCD_S_DATA mode\n" );
-#endif
-      } else {
-#if defined( SJCD_TRACE )
-	printk( "SJCD_S_READ: nothing to read: go to SJCD_S_STOP mode\n" );
-#endif
-	sjcd_transfer_state = SJCD_S_STOP;
-	goto ReSwitch;
-      }
-    }
+		      sjcd_s_data:stat =
+			    inb(SJCDPORT
+				(1));
+#if defined( SJCD_TRACE )
+			printk("SJCD_S_DATA: status = 0x%02x\n", stat);
+#endif
+			if (SJCD_STATUS_AVAILABLE(stat)) {
+				/*
+				 * No data is waiting for us in the drive buffer. Status of operation
+				 * completion is available. Read and parse it.
+				 */
+				sjcd_load_status();
+
+				if (!sjcd_status_valid
+				    || sjcd_command_failed) {
+#if defined( SJCD_TRACE )
+					printk
+					    ("SJCD: read block %d failed, maybe audio disk? Giving up\n",
+					     sjcd_next_bn);
+#endif
+					if (CURRENT_IS_VALID)
+						end_request(0);
+#if defined( SJCD_TRACE )
+					printk
+					    ("SJCD_S_DATA: pre-cmd failed: go to SJCD_S_STOP mode\n");
+#endif
+					sjcd_transfer_state = SJCD_S_STOP;
+					goto ReSwitch;
+				}
+
+				if (!sjcd_media_is_available) {
+					printk
+					    ("SJCD_S_DATA: no disk: go to SJCD_S_STOP mode\n");
+					sjcd_transfer_state = SJCD_S_STOP;
+					goto ReSwitch;
+				}
+
+				sjcd_transfer_state = SJCD_S_READ;
+				goto ReSwitch;
+			} else if (SJCD_DATA_AVAILABLE(stat)) {
+				/*
+				 * One frame is read into device buffer. We must copy it to our memory.
+				 * Otherwise cdrom hangs up. Check to see if we have something to copy
+				 * to.
+				 */
+				if (!CURRENT_IS_VALID
+				    && sjcd_buf_in == sjcd_buf_out) {
+#if defined( SJCD_TRACE )
+					printk
+					    ("SJCD_S_DATA: nothing to read: go to SJCD_S_STOP mode\n");
+					printk
+					    (" ... all the date would be discarded\n");
+#endif
+					sjcd_transfer_state = SJCD_S_STOP;
+					goto ReSwitch;
+				}
+
+				/*
+				 * Everything seems to be OK. Just read the frame and recalculate
+				 * indices.
+				 */
+				sjcd_buf_bn[sjcd_buf_in] = -1;	/* ??? */
+				insb(SJCDPORT(2),
+				     sjcd_buf + 2048 * sjcd_buf_in, 2048);
+#if defined( SJCD_TRACE )
+				printk
+				    ("SJCD_S_DATA: next_bn=%d, buf_in=%d, buf_out=%d, buf_bn=%d\n",
+				     sjcd_next_bn, sjcd_buf_in,
+				     sjcd_buf_out,
+				     sjcd_buf_bn[sjcd_buf_in]);
+#endif
+				sjcd_buf_bn[sjcd_buf_in] = sjcd_next_bn++;
+				if (sjcd_buf_out == -1)
+					sjcd_buf_out = sjcd_buf_in;
+				if (++sjcd_buf_in == SJCD_BUF_SIZ)
+					sjcd_buf_in = 0;
+
+				/*
+				 * Only one frame is ready at time. So we should turn over to wait for
+				 * another frame. If we need that, of course.
+				 */
+				if (--sjcd_read_count == 0) {
+					/*
+					 * OK, request seems to be precessed. Continue transferring...
+					 */
+					if (!sjcd_transfer_is_active) {
+						while (CURRENT_IS_VALID) {
+							/*
+							 * Continue transferring.
+							 */
+							sjcd_transfer();
+							if (CURRENT->
+							    nr_sectors ==
+							    0)
+								end_request
+								    (1);
+							else
+								break;
+						}
+					}
+					if (CURRENT_IS_VALID &&
+					    (CURRENT->sector / 4 <
+					     sjcd_next_bn
+					     || CURRENT->sector / 4 >
+					     sjcd_next_bn +
+					     SJCD_BUF_SIZ)) {
+#if defined( SJCD_TRACE )
+						printk
+						    ("SJCD_S_DATA: can't read: go to SJCD_S_STOP mode\n");
+#endif
+						sjcd_transfer_state =
+						    SJCD_S_STOP;
+						goto ReSwitch;
+					}
+				}
+				/*
+				 * Now we should turn around rather than wait for while.
+				 */
+				goto sjcd_s_data;
+			}
 #if defined( SJCD_GATHER_STAT )
-    else statistic.read_ticks++;
+			else
+				statistic.data_ticks++;
 #endif
-    break;
-  }
+			break;
+		}
 
-  case SJCD_S_DATA:{
-    unsigned char stat;
-
-  sjcd_s_data: stat = inb( SJCDPORT( 1 ) );
-#if defined( SJCD_TRACE )
-    printk( "SJCD_S_DATA: status = 0x%02x\n", stat );
+	case SJCD_S_STOP:{
+			sjcd_read_count = 0;
+			sjcd_send_cmd(SCMD_STOP);
+			sjcd_transfer_state = SJCD_S_STOPPING;
+			sjcd_transfer_timeout = 500;
+#if defined( SJCD_GATHER_STAT )
+			statistic.stop_ticks++;
 #endif
-    if( SJCD_STATUS_AVAILABLE( stat ) ){
-      /*
-       * No data is waiting for us in the drive buffer. Status of operation
-       * completion is available. Read and parse it.
-       */
-      sjcd_load_status();
+			break;
+		}
 
-      if( !sjcd_status_valid || sjcd_command_failed ){
-#if defined( SJCD_TRACE )
-	printk( "SJCD: read block %d failed, maybe audio disk? Giving up\n",
-	       sjcd_next_bn );
-#endif
-	if( CURRENT_IS_VALID ) end_request( 0 );
-#if defined( SJCD_TRACE )
-	printk( "SJCD_S_DATA: pre-cmd failed: go to SJCD_S_STOP mode\n" );
+	case SJCD_S_STOPPING:{
+			unsigned char stat;
+
+			stat = inb(SJCDPORT(1));
+#if defined( SJCD_TRACE )
+			printk("SJCD_S_STOP: status = 0x%02x\n", stat);
+#endif
+			if (SJCD_DATA_AVAILABLE(stat)) {
+				int i;
+#if defined( SJCD_TRACE )
+				printk("SJCD_S_STOP: discard data\n");
+#endif
+				/*
+				 * Discard all the data from the pipe. Foolish method.
+				 */
+				for (i = 2048; i--;
+				     (void) inb(SJCDPORT(2)));
+				sjcd_transfer_timeout = 500;
+			} else if (SJCD_STATUS_AVAILABLE(stat)) {
+				sjcd_load_status();
+				if (sjcd_status_valid
+				    && sjcd_media_is_changed) {
+					sjcd_toc_uptodate = 0;
+					sjcd_invalidate_buffers();
+				}
+				if (CURRENT_IS_VALID) {
+					if (sjcd_status_valid)
+						sjcd_transfer_state =
+						    SJCD_S_READ;
+					else
+						sjcd_transfer_state =
+						    SJCD_S_START;
+				} else
+					sjcd_transfer_state = SJCD_S_IDLE;
+				goto ReSwitch;
+			}
+#if defined( SJCD_GATHER_STAT )
+			else
+				statistic.stopping_ticks++;
 #endif
-	sjcd_transfer_state = SJCD_S_STOP;
-	goto ReSwitch;
-      }
+			break;
+		}
 
-      if( !sjcd_media_is_available ){
-	printk( "SJCD_S_DATA: no disk: go to SJCD_S_STOP mode\n" );
-	sjcd_transfer_state = SJCD_S_STOP;
-	goto ReSwitch;
-      }
+	default:
+		printk("SJCD: poll: invalid state %d\n",
+		       sjcd_transfer_state);
+		return;
+	}
 
-      sjcd_transfer_state = SJCD_S_READ;
-      goto ReSwitch;
-    } else if( SJCD_DATA_AVAILABLE( stat ) ){
-      /*
-       * One frame is read into device buffer. We must copy it to our memory.
-       * Otherwise cdrom hangs up. Check to see if we have something to copy
-       * to.
-       */
-      if( !CURRENT_IS_VALID && sjcd_buf_in == sjcd_buf_out ){
-#if defined( SJCD_TRACE )
-	printk( "SJCD_S_DATA: nothing to read: go to SJCD_S_STOP mode\n" );
-	printk( " ... all the date would be discarded\n" );
-#endif
-	sjcd_transfer_state = SJCD_S_STOP;
-	goto ReSwitch;
-      }
+	if (--sjcd_transfer_timeout == 0) {
+		printk("SJCD: timeout in state %d\n", sjcd_transfer_state);
+		while (CURRENT_IS_VALID)
+			end_request(0);
+		sjcd_send_cmd(SCMD_STOP);
+		sjcd_transfer_state = SJCD_S_IDLE;
+		goto ReSwitch;
+	}
 
-      /*
-       * Everything seems to be OK. Just read the frame and recalculate
-       * indices.
-       */
-      sjcd_buf_bn[ sjcd_buf_in ] = -1; /* ??? */
-      insb( SJCDPORT( 2 ), sjcd_buf + 2048 * sjcd_buf_in, 2048 );
-#if defined( SJCD_TRACE )
-      printk( "SJCD_S_DATA: next_bn=%d, buf_in=%d, buf_out=%d, buf_bn=%d\n",
-	     sjcd_next_bn, sjcd_buf_in, sjcd_buf_out,
-	     sjcd_buf_bn[ sjcd_buf_in ] );
-#endif
-      sjcd_buf_bn[ sjcd_buf_in ] = sjcd_next_bn++;
-      if( sjcd_buf_out == -1 ) sjcd_buf_out = sjcd_buf_in;
-      if( ++sjcd_buf_in == SJCD_BUF_SIZ ) sjcd_buf_in = 0;
-
-      /*
-       * Only one frame is ready at time. So we should turn over to wait for
-       * another frame. If we need that, of course.
-       */
-      if( --sjcd_read_count == 0 ){
 	/*
-	 * OK, request seems to be precessed. Continue transferring...
+	 * Get back in some time. 1 should be replaced with count variable to
+	 * avoid unnecessary testings.
 	 */
-	if( !sjcd_transfer_is_active ){
-	  while( CURRENT_IS_VALID ){
-	    /*
-	     * Continue transferring.
-	     */
-	    sjcd_transfer();
-	    if( CURRENT->nr_sectors == 0 ) end_request( 1 );
-	    else break;
-	  }
-	}
-	if( CURRENT_IS_VALID &&
-	   ( CURRENT->sector / 4 < sjcd_next_bn ||
-	    CURRENT->sector / 4 > sjcd_next_bn + SJCD_BUF_SIZ ) ){
-#if defined( SJCD_TRACE )
-	  printk( "SJCD_S_DATA: can't read: go to SJCD_S_STOP mode\n" );
-#endif
-	  sjcd_transfer_state = SJCD_S_STOP;
-	  goto ReSwitch;
-	}
-      }
-      /*
-       * Now we should turn around rather than wait for while.
-       */
-      goto sjcd_s_data;
-    }
-#if defined( SJCD_GATHER_STAT )
-    else statistic.data_ticks++;
-#endif
-    break;
-  }
-
-  case SJCD_S_STOP:{
-    sjcd_read_count = 0;
-    sjcd_send_cmd( SCMD_STOP );
-    sjcd_transfer_state = SJCD_S_STOPPING;
-    sjcd_transfer_timeout = 500;
-#if defined( SJCD_GATHER_STAT )
-    statistic.stop_ticks++;
-#endif
-    break;
-  }
+	SJCD_SET_TIMER(sjcd_poll, 1);
+}
 
-  case SJCD_S_STOPPING:{
-    unsigned char stat;
-    
-    stat = inb( SJCDPORT( 1 ) );
-#if defined( SJCD_TRACE )
-    printk( "SJCD_S_STOP: status = 0x%02x\n", stat );
-#endif      
-    if( SJCD_DATA_AVAILABLE( stat ) ){
-      int i;
-#if defined( SJCD_TRACE )
-      printk( "SJCD_S_STOP: discard data\n" );
-#endif
-      /*
-       * Discard all the data from the pipe. Foolish method.
-       */
-      for( i = 2048; i--; ( void )inb( SJCDPORT( 2 ) ) );
-      sjcd_transfer_timeout = 500;
-    } else if( SJCD_STATUS_AVAILABLE( stat ) ){
-      sjcd_load_status();
-      if( sjcd_status_valid && sjcd_media_is_changed ) {
-	sjcd_toc_uptodate = 0;
-	sjcd_invalidate_buffers();
-      }
-      if( CURRENT_IS_VALID ){
-	if( sjcd_status_valid ) sjcd_transfer_state = SJCD_S_READ;
-	else sjcd_transfer_state = SJCD_S_START;
-      } else sjcd_transfer_state = SJCD_S_IDLE;
-      goto ReSwitch;
-    }
-#if defined( SJCD_GATHER_STAT )
-    else statistic.stopping_ticks++;
+static void do_sjcd_request(request_queue_t * q)
+{
+#if defined( SJCD_TRACE )
+	printk("SJCD: do_sjcd_request(%ld+%ld)\n",
+	       CURRENT->sector, CURRENT->nr_sectors);
 #endif
-    break;
-  }
-
-  default:
-    printk( "SJCD: poll: invalid state %d\n", sjcd_transfer_state );
-    return;
-  }
-  
-  if( --sjcd_transfer_timeout == 0 ){
-    printk( "SJCD: timeout in state %d\n", sjcd_transfer_state );
-    while( CURRENT_IS_VALID ) end_request( 0 );
-    sjcd_send_cmd( SCMD_STOP );
-    sjcd_transfer_state = SJCD_S_IDLE;
-    goto ReSwitch;
-    }
-
-  /*
-   * Get back in some time. 1 should be replaced with count variable to
-   * avoid unnecessary testings.
-   */
-  SJCD_SET_TIMER( sjcd_poll, 1 );
-}
-
-static void do_sjcd_request( request_queue_t * q ){
-#if defined( SJCD_TRACE )
-  printk( "SJCD: do_sjcd_request(%ld+%ld)\n",
-	 CURRENT->sector, CURRENT->nr_sectors );
-#endif
-  sjcd_transfer_is_active = 1;
-  while( CURRENT_IS_VALID ){
-    /*
-     * Who of us are paranoiac?
-     */
-    if( CURRENT->bh && !buffer_locked(CURRENT->bh) )
-      panic( DEVICE_NAME ": block not locked" );
-
-    sjcd_transfer();
-    if( CURRENT->nr_sectors == 0 ) end_request( 1 );
-    else {
-      sjcd_buf_out = -1;         /* Want to read a block not in buffer */
-      if( sjcd_transfer_state == SJCD_S_IDLE ){
-	if( !sjcd_toc_uptodate ){
-	  if( sjcd_update_toc() < 0 ){
-	    printk( "SJCD: transfer: discard\n" );
-	    while( CURRENT_IS_VALID ) end_request( 0 );
-	    break;
-	  }
-	}
-	sjcd_transfer_state = SJCD_S_START;
-	SJCD_SET_TIMER( sjcd_poll, HZ/100 );
-      }
-      break;
-    }
-  }
-  sjcd_transfer_is_active = 0;
-#if defined( SJCD_TRACE )
-  printk( "sjcd_next_bn:%x sjcd_buf_in:%x sjcd_buf_out:%x sjcd_buf_bn:%x\n",
-	 sjcd_next_bn, sjcd_buf_in, sjcd_buf_out, sjcd_buf_bn[ sjcd_buf_in ] );
-  printk( "do_sjcd_request ends\n" );
+	sjcd_transfer_is_active = 1;
+	while (CURRENT_IS_VALID) {
+		/*
+		 * Who of us are paranoiac?
+		 */
+		if (CURRENT->bh && !buffer_locked(CURRENT->bh))
+			panic(DEVICE_NAME ": block not locked");
+
+		sjcd_transfer();
+		if (CURRENT->nr_sectors == 0)
+			end_request(1);
+		else {
+			sjcd_buf_out = -1;	/* Want to read a block not in buffer */
+			if (sjcd_transfer_state == SJCD_S_IDLE) {
+				if (!sjcd_toc_uptodate) {
+					if (sjcd_update_toc() < 0) {
+						printk
+						    ("SJCD: transfer: discard\n");
+						while (CURRENT_IS_VALID)
+							end_request(0);
+						break;
+					}
+				}
+				sjcd_transfer_state = SJCD_S_START;
+				SJCD_SET_TIMER(sjcd_poll, HZ / 100);
+			}
+			break;
+		}
+	}
+	sjcd_transfer_is_active = 0;
+#if defined( SJCD_TRACE )
+	printk
+	    ("sjcd_next_bn:%x sjcd_buf_in:%x sjcd_buf_out:%x sjcd_buf_bn:%x\n",
+	     sjcd_next_bn, sjcd_buf_in, sjcd_buf_out,
+	     sjcd_buf_bn[sjcd_buf_in]);
+	printk("do_sjcd_request ends\n");
 #endif
 }
 
 /*
  * Open the device special file. Check disk is in.
  */
-int sjcd_open( struct inode *ip, struct file *fp ){
-  /*
-   * Check the presence of device.
-   */
-  if( !sjcd_present ) return( -ENXIO );
-  
-  /*
-   * Only read operations are allowed. Really? (:-)
-   */
-  if( fp->f_mode & 2 ) return( -EROFS );
-  
-  MOD_INC_USE_COUNT;
+int sjcd_open(struct inode *ip, struct file *fp)
+{
+	/*
+	 * Check the presence of device.
+	 */
+	if (!sjcd_present)
+		return (-ENXIO);
 
-  if( sjcd_open_count == 0 ){
-    int s, sjcd_open_tries;
+	/*
+	 * Only read operations are allowed. Really? (:-)
+	 */
+	if (fp->f_mode & 2)
+		return (-EROFS);
+
+	MOD_INC_USE_COUNT;
+
+	if (sjcd_open_count == 0) {
+		int s, sjcd_open_tries;
 /* We don't know that, do we? */
 /*
     sjcd_audio_status = CDROM_AUDIO_NO_STATUS;
 */
-    sjcd_mode = 0;
-    sjcd_door_was_open = 0;
-    sjcd_transfer_state = SJCD_S_IDLE;
-    sjcd_invalidate_buffers();
-    sjcd_status_valid = 0;
-
-    /*
-     * Strict status checking.
-     */
-    for( sjcd_open_tries = 4; --sjcd_open_tries; ){
-      if( !sjcd_status_valid ) sjcd_get_status();
-      if( !sjcd_status_valid ){
+		sjcd_mode = 0;
+		sjcd_door_was_open = 0;
+		sjcd_transfer_state = SJCD_S_IDLE;
+		sjcd_invalidate_buffers();
+		sjcd_status_valid = 0;
+
+		/*
+		 * Strict status checking.
+		 */
+		for (sjcd_open_tries = 4; --sjcd_open_tries;) {
+			if (!sjcd_status_valid)
+				sjcd_get_status();
+			if (!sjcd_status_valid) {
 #if defined( SJCD_DIAGNOSTIC )
-	printk( "SJCD: open: timed out when check status.\n" );
+				printk
+				    ("SJCD: open: timed out when check status.\n");
 #endif
-	goto err_out;
-      } else if( !sjcd_media_is_available ){
+				goto err_out;
+			} else if (!sjcd_media_is_available) {
 #if defined( SJCD_DIAGNOSTIC )
-	printk("SJCD: open: no disk in drive\n");
+				printk("SJCD: open: no disk in drive\n");
 #endif
-	if( !sjcd_door_closed ){
-	  sjcd_door_was_open = 1;
+				if (!sjcd_door_closed) {
+					sjcd_door_was_open = 1;
 #if defined( SJCD_TRACE )
-	  printk("SJCD: open: close the tray\n");
+					printk
+					    ("SJCD: open: close the tray\n");
 #endif
-	  s = sjcd_tray_close();
-	  if( s < 0 || !sjcd_status_valid || sjcd_command_failed ){
+					s = sjcd_tray_close();
+					if (s < 0 || !sjcd_status_valid
+					    || sjcd_command_failed) {
 #if defined( SJCD_DIAGNOSTIC )
-	    printk("SJCD: open: tray close attempt failed\n");
+						printk
+						    ("SJCD: open: tray close attempt failed\n");
 #endif
-	    goto err_out;
-	  }
-	  continue;
-	} else goto err_out;
-      }
-      break;
-    }
-    s = sjcd_tray_lock();
-    if( s < 0 || !sjcd_status_valid || sjcd_command_failed ){
+						goto err_out;
+					}
+					continue;
+				} else
+					goto err_out;
+			}
+			break;
+		}
+		s = sjcd_tray_lock();
+		if (s < 0 || !sjcd_status_valid || sjcd_command_failed) {
 #if defined( SJCD_DIAGNOSTIC )
-      printk("SJCD: open: tray lock attempt failed\n");
+			printk("SJCD: open: tray lock attempt failed\n");
 #endif
-      goto err_out;
-    }
+			goto err_out;
+		}
 #if defined( SJCD_TRACE )
-    printk( "SJCD: open: done\n" );
+		printk("SJCD: open: done\n");
 #endif
-  }
+	}
 
-  ++sjcd_open_count;
-  return( 0 );
+	++sjcd_open_count;
+	return (0);
 
-err_out:
-  MOD_DEC_USE_COUNT;
-  return( -EIO );
+      err_out:
+	MOD_DEC_USE_COUNT;
+	return (-EIO);
 }
 
 /*
  * On close, we flush all sjcd blocks from the buffer cache.
  */
-static int sjcd_release( struct inode *inode, struct file *file ){
-  int s;
+static int sjcd_release(struct inode *inode, struct file *file)
+{
+	int s;
 
 #if defined( SJCD_TRACE )
-  printk( "SJCD: release\n" );
+	printk("SJCD: release\n");
 #endif
 #ifdef MODULE
-  MOD_DEC_USE_COUNT;
+	MOD_DEC_USE_COUNT;
 #endif
-  if( --sjcd_open_count == 0 ){
-    sjcd_invalidate_buffers();
-    s = sjcd_tray_unlock();
-    if( s < 0 || !sjcd_status_valid || sjcd_command_failed ){
+	if (--sjcd_open_count == 0) {
+		sjcd_invalidate_buffers();
+		s = sjcd_tray_unlock();
+		if (s < 0 || !sjcd_status_valid || sjcd_command_failed) {
 #if defined( SJCD_DIAGNOSTIC )
-      printk("SJCD: release: tray unlock attempt failed.\n");
+			printk
+			    ("SJCD: release: tray unlock attempt failed.\n");
 #endif
-    }
-    if( sjcd_door_was_open ){
-      s = sjcd_tray_open();
-      if( s < 0 || !sjcd_status_valid || sjcd_command_failed ){
+		}
+		if (sjcd_door_was_open) {
+			s = sjcd_tray_open();
+			if (s < 0 || !sjcd_status_valid
+			    || sjcd_command_failed) {
 #if defined( SJCD_DIAGNOSTIC )
-	printk("SJCD: release: tray unload attempt failed.\n");
+				printk
+				    ("SJCD: release: tray unload attempt failed.\n");
 #endif
-      }
-    }
-  }
-  return 0;
+			}
+		}
+	}
+	return 0;
 }
 
 /*
  * A list of file operations allowed for this cdrom.
  */
 static struct block_device_operations sjcd_fops = {
-	open:			sjcd_open,
-	release:		sjcd_release,
-	ioctl:			sjcd_ioctl,
-	check_media_change:	sjcd_disk_change,
+	open:sjcd_open,
+	release:sjcd_release,
+	ioctl:sjcd_ioctl,
+	check_media_change:sjcd_disk_change,
 };
 
 static int blksize = 2048;
@@ -1453,146 +1678,156 @@
  * The version is two BCD-coded bytes.
  */
 static struct {
-  unsigned char major, minor;
+	unsigned char major, minor;
 } sjcd_version;
 
 /*
  * Test for presence of drive and initialize it. Called at boot time.
  * Probe cdrom, find out version and status.
  */
-int __init sjcd_init( void ){
-  int i;
+int __init sjcd_init(void)
+{
+	int i;
 
-  printk(KERN_INFO "SJCD: Sanyo CDR-H94A cdrom driver version %d.%d.\n", SJCD_VERSION_MAJOR,
-    SJCD_VERSION_MINOR);
+	printk(KERN_INFO
+	       "SJCD: Sanyo CDR-H94A cdrom driver version %d.%d.\n",
+	       SJCD_VERSION_MAJOR, SJCD_VERSION_MINOR);
 
 #if defined( SJCD_TRACE )
-  printk("SJCD: sjcd=0x%x: ", sjcd_base);
-#endif  
+	printk("SJCD: sjcd=0x%x: ", sjcd_base);
+#endif
 
 	hardsect_size[MAJOR_NR] = &secsize;
 	blksize_size[MAJOR_NR] = &blksize;
 
-  if( devfs_register_blkdev( MAJOR_NR, "sjcd", &sjcd_fops ) != 0 ){
-    printk( "SJCD: Unable to get major %d for Sanyo CD-ROM\n", MAJOR_NR );
-    return( -EIO );
-  }
-  
-  blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
-  read_ahead[ MAJOR_NR ] = 4;
-  register_disk(NULL, MKDEV(MAJOR_NR,0), 1, &sjcd_fops, 0);
-  
-  if( check_region( sjcd_base, 4 ) ){
-    printk( "SJCD: Init failed, I/O port (%X) is already in use\n",
-      sjcd_base );
-    sjcd_cleanup();
-    return( -EIO );
-  }
-  
-  /*
-   * Check for card. Since we are booting now, we can't use standard
-   * wait algorithm.
-   */
-  printk(KERN_INFO "SJCD: Resetting: " );
-  sjcd_send_cmd( SCMD_RESET );
-  for( i = 1000; i > 0 && !sjcd_status_valid; --i ){
-    unsigned long timer;
-
-    /*
-     * Wait 10ms approx.
-     */
-    for( timer = jiffies; time_before_eq(jiffies, timer); );
-    if ( (i % 100) == 0 ) printk( "." );
-    ( void )sjcd_check_status();
-  }
-  if( i == 0 || sjcd_command_failed ){
-    printk( " reset failed, no drive found.\n" );
-    sjcd_cleanup();
-    return( -EIO );
-  } else printk( "\n" );
-
-  /*
-   * Get and print out cdrom version.
-   */
-  printk(KERN_INFO "SJCD: Getting version: " );
-  sjcd_send_cmd( SCMD_GET_VERSION );
-  for( i = 1000; i > 0 && !sjcd_status_valid; --i ){
-    unsigned long timer;
-
-    /*
-     * Wait 10ms approx.
-     */
-    for( timer = jiffies; time_before_eq(jiffies, timer); );
-    if ( (i % 100) == 0 ) printk( "." );
-    ( void )sjcd_check_status();
-  }
-  if( i == 0 || sjcd_command_failed ){
-    printk( " get version failed, no drive found.\n" );
-    sjcd_cleanup();
-    return( -EIO );
-  }
-
-  if( sjcd_load_response( &sjcd_version, sizeof( sjcd_version ) ) == 0 ){
-    printk( " %1x.%02x\n", ( int )sjcd_version.major,
-	     ( int )sjcd_version.minor );
-  } else {
-    printk( " read version failed, no drive found.\n" );
-    sjcd_cleanup();
-    return( -EIO );
-  }
-
-  /*
-   * Check and print out the tray state. (if it is needed?).
-   */
-  if( !sjcd_status_valid ){
-    printk(KERN_INFO "SJCD: Getting status: " );
-    sjcd_send_cmd( SCMD_GET_STATUS );
-    for( i = 1000; i > 0 && !sjcd_status_valid; --i ){
-      unsigned long timer;
-
-      /*
-       * Wait 10ms approx.
-       */
-      for( timer = jiffies; time_before_eq(jiffies, timer); );
-      if ( (i % 100) == 0 ) printk( "." );
-      ( void )sjcd_check_status();
-    }
-    if( i == 0 || sjcd_command_failed ){
-      printk( " get status failed, no drive found.\n" );
-      sjcd_cleanup();
-      return( -EIO );
-    } else printk( "\n" );
-  }
-
-  printk(KERN_INFO "SJCD: Status: port=0x%x.\n", sjcd_base);
-  devfs_register (NULL, "sjcd", DEVFS_FL_DEFAULT, MAJOR_NR, 0,
-		  S_IFBLK | S_IRUGO | S_IWUGO, &sjcd_fops, NULL);
-
-  sjcd_present++;
-  return( 0 );
-}
-
-static int
-sjcd_cleanup(void)
-{
-  if( (devfs_unregister_blkdev(MAJOR_NR, "sjcd") == -EINVAL) )
-    printk( "SJCD: cannot unregister device.\n" );
-  else {
-    release_region( sjcd_base, 4 );
-    blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
-  }
+	if (devfs_register_blkdev(MAJOR_NR, "sjcd", &sjcd_fops) != 0) {
+		printk("SJCD: Unable to get major %d for Sanyo CD-ROM\n",
+		       MAJOR_NR);
+		return (-EIO);
+	}
+
+	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
+	read_ahead[MAJOR_NR] = 4;
+	register_disk(NULL, MKDEV(MAJOR_NR, 0), 1, &sjcd_fops, 0);
+
+	if (check_region(sjcd_base, 4)) {
+		printk
+		    ("SJCD: Init failed, I/O port (%X) is already in use\n",
+		     sjcd_base);
+		sjcd_cleanup();
+		return (-EIO);
+	}
+
+	/*
+	 * Check for card. Since we are booting now, we can't use standard
+	 * wait algorithm.
+	 */
+	printk(KERN_INFO "SJCD: Resetting: ");
+	sjcd_send_cmd(SCMD_RESET);
+	for (i = 1000; i > 0 && !sjcd_status_valid; --i) {
+		unsigned long timer;
+
+		/*
+		 * Wait 10ms approx.
+		 */
+		for (timer = jiffies; time_before_eq(jiffies, timer););
+		if ((i % 100) == 0)
+			printk(".");
+		(void) sjcd_check_status();
+	}
+	if (i == 0 || sjcd_command_failed) {
+		printk(" reset failed, no drive found.\n");
+		sjcd_cleanup();
+		return (-EIO);
+	} else
+		printk("\n");
+
+	/*
+	 * Get and print out cdrom version.
+	 */
+	printk(KERN_INFO "SJCD: Getting version: ");
+	sjcd_send_cmd(SCMD_GET_VERSION);
+	for (i = 1000; i > 0 && !sjcd_status_valid; --i) {
+		unsigned long timer;
+
+		/*
+		 * Wait 10ms approx.
+		 */
+		for (timer = jiffies; time_before_eq(jiffies, timer););
+		if ((i % 100) == 0)
+			printk(".");
+		(void) sjcd_check_status();
+	}
+	if (i == 0 || sjcd_command_failed) {
+		printk(" get version failed, no drive found.\n");
+		sjcd_cleanup();
+		return (-EIO);
+	}
+
+	if (sjcd_load_response(&sjcd_version, sizeof(sjcd_version)) == 0) {
+		printk(" %1x.%02x\n", (int) sjcd_version.major,
+		       (int) sjcd_version.minor);
+	} else {
+		printk(" read version failed, no drive found.\n");
+		sjcd_cleanup();
+		return (-EIO);
+	}
+
+	/*
+	 * Check and print out the tray state. (if it is needed?).
+	 */
+	if (!sjcd_status_valid) {
+		printk(KERN_INFO "SJCD: Getting status: ");
+		sjcd_send_cmd(SCMD_GET_STATUS);
+		for (i = 1000; i > 0 && !sjcd_status_valid; --i) {
+			unsigned long timer;
+
+			/*
+			 * Wait 10ms approx.
+			 */
+			for (timer = jiffies;
+			     time_before_eq(jiffies, timer););
+			if ((i % 100) == 0)
+				printk(".");
+			(void) sjcd_check_status();
+		}
+		if (i == 0 || sjcd_command_failed) {
+			printk(" get status failed, no drive found.\n");
+			sjcd_cleanup();
+			return (-EIO);
+		} else
+			printk("\n");
+	}
+
+	printk(KERN_INFO "SJCD: Status: port=0x%x.\n", sjcd_base);
+	devfs_register(NULL, "sjcd", DEVFS_FL_DEFAULT, MAJOR_NR, 0,
+		       S_IFBLK | S_IRUGO | S_IWUGO, &sjcd_fops, NULL);
+
+	sjcd_present++;
+	return (0);
+}
+
+static int sjcd_cleanup(void)
+{
+	if ((devfs_unregister_blkdev(MAJOR_NR, "sjcd") == -EINVAL))
+		printk("SJCD: cannot unregister device.\n");
+	else {
+		release_region(sjcd_base, 4);
+		blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
+	}
 
-  return(0);
+	return (0);
 }
 
 
 void __exit sjcd_exit(void)
 {
-  devfs_unregister(devfs_find_handle(NULL, "sjcd", 0, 0, DEVFS_SPECIAL_BLK,0));
-  if ( sjcd_cleanup() )
-    printk( "SJCD: module: cannot be removed.\n" );
-  else
-    printk(KERN_INFO "SJCD: module: removed.\n");
+	devfs_unregister(devfs_find_handle
+			 (NULL, "sjcd", 0, 0, DEVFS_SPECIAL_BLK, 0));
+	if (sjcd_cleanup())
+		printk("SJCD: module: cannot be removed.\n");
+	else
+		printk(KERN_INFO "SJCD: module: removed.\n");
 }
 
 #ifdef MODULE
@@ -1601,3 +1836,4 @@
 module_exit(sjcd_exit);
 
 
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.9/linux/drivers/cdrom/sonycd535.c linux/drivers/cdrom/sonycd535.c
--- v2.4.9/linux/drivers/cdrom/sonycd535.c	Fri Feb  9 11:30:22 2001
+++ linux/drivers/cdrom/sonycd535.c	Sun Sep  9 10:43:02 2001
@@ -1709,3 +1709,4 @@
 module_exit(sony535_exit);
 
 
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.9/linux/drivers/char/Config.in linux/drivers/char/Config.in
--- v2.4.9/linux/drivers/char/Config.in	Mon Aug 27 12:41:40 2001
+++ linux/drivers/char/Config.in	Sun Sep  9 10:43:02 2001
@@ -59,6 +59,24 @@
      tristate '    Stallion EasyIO or EC8/32 support' CONFIG_STALLION
      tristate '    Stallion EC8/64, ONboard, Brumby support' CONFIG_ISTALLION
    fi
+   if [ "$CONFIG_MIPS" = "y" ]; then
+     bool '  TMPTX3912/PR31700 serial port support' CONFIG_SERIAL_TX3912
+     dep_bool '     Console on TMPTX3912/PR31700 serial port' CONFIG_SERIAL_TX3912_CONSOLE $CONFIG_SERIAL_TX3912
+     bool '  Enable Au1000 UART Support' CONFIG_AU1000_UART
+     if [ "$CONFIG_AU1000_UART" = "y" ]; then
+         bool '        Enable Au1000 serial console' CONFIG_AU1000_SERIAL_CONSOLE
+     fi
+   fi
+fi
+if [ "$CONFIG_IT8712" = "y" ]; then
+   bool 'Enable Qtronix 990P Keyboard Support' CONFIG_QTRONIX_KEYBOARD
+   if [ "$CONFIG_QTRONIX_KEYBOARD" = "y" ]; then
+     define_bool CONFIG_IT8172_CIR y
+   else
+     bool '    Enable PS2 Keyboard Support' CONFIG_PC_KEYB
+   fi
+   bool 'Enable Smart Card Reader 0 Support ' CONFIG_IT8172_SCR0
+   bool 'Enable Smart Card Reader 1 Support ' CONFIG_IT8172_SCR1
 fi
 if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_ZORRO" = "y" ]; then
    tristate 'Commodore A2232 serial support (EXPERIMENTAL)' CONFIG_A2232
diff -u --recursive --new-file v2.4.9/linux/drivers/char/Makefile linux/drivers/char/Makefile
--- v2.4.9/linux/drivers/char/Makefile	Wed Jul 25 17:10:19 2001
+++ linux/drivers/char/Makefile	Sun Sep  9 10:43:02 2001
@@ -41,18 +41,10 @@
   SERIAL   =
 endif
 
-ifeq ($(ARCH),s390x)
-  KEYMAP   =
-  KEYBD    =
-  CONSOLE  =
-  SERIAL   =
-endif
-
-ifeq ($(ARCH),s390)
-  KEYMAP   =
-  KEYBD    =
-  CONSOLE  =
-  SERIAL   =
+ifeq ($(ARCH),mips)
+  ifneq ($(CONFIG_PC_KEYB),y)
+    KEYBD    =
+  endif
 endif
 
 ifeq ($(ARCH),s390x)
@@ -109,8 +101,9 @@
 endif
 
 ifeq ($(CONFIG_DECSTATION),y)
+  KEYMAP   =
   KEYBD    =
-  SERIAL   =
+  SERIAL   = decserial.o
 endif
 
 ifeq ($(CONFIG_BAGET_MIPS),y)
@@ -118,10 +111,18 @@
   SERIAL   =
 endif
 
+ifeq ($(CONFIG_NINO),y)
+  SERIAL   =
+endif
+
 ifneq ($(CONFIG_SUN_SERIAL),)
   SERIAL   =
 endif
 
+ifeq ($(CONFIG_QTRONIX_KEYBOARD),y)
+  KEYBD    = qtronix.o
+  KEYMAP   = qtronixmap.o
+endif
 
 obj-$(CONFIG_VT) += vt.o vc_screen.o consolemap.o consolemap_deftbl.o $(CONSOLE) selection.o
 obj-$(CONFIG_SERIAL) += $(SERIAL)
@@ -161,6 +162,7 @@
 obj-$(CONFIG_MVME147_SCC) += generic_serial.o vme_scc.o
 obj-$(CONFIG_MVME162_SCC) += generic_serial.o vme_scc.o
 obj-$(CONFIG_BVME6000_SCC) += generic_serial.o vme_scc.o
+obj-$(CONFIG_SERIAL_TX3912) += generic_serial.o serial_tx3912.o
 
 subdir-$(CONFIG_RIO) += rio
 subdir-$(CONFIG_INPUT) += joystick
@@ -241,5 +243,10 @@
 
 consolemap_deftbl.o: consolemap_deftbl.c $(TOPDIR)/include/linux/types.h
 
+.DELETE_ON_ERROR:
+
 defkeymap.c: defkeymap.map
-	loadkeys --mktable defkeymap.map > defkeymap.c
+	set -e ; loadkeys --mktable $< | sed -e 's/^static *//' > $@
+
+qtronixmap.c: qtronixmap.map
+	set -e ; loadkeys --mktable $< | sed -e 's/^static *//' > $@
diff -u --recursive --new-file v2.4.9/linux/drivers/char/agp/agp.h linux/drivers/char/agp/agp.h
--- v2.4.9/linux/drivers/char/agp/agp.h	Mon Aug 27 12:41:40 2001
+++ linux/drivers/char/agp/agp.h	Mon Aug 27 07:40:33 2001
@@ -101,6 +101,7 @@
 	int num_aperture_sizes;
 	int num_of_masks;
 	int capndx;
+	int cant_use_aperture;
 
 	/* Links to driver specific functions */
 
diff -u --recursive --new-file v2.4.9/linux/drivers/char/agp/agpgart_be.c linux/drivers/char/agp/agpgart_be.c
--- v2.4.9/linux/drivers/char/agp/agpgart_be.c	Mon Aug 27 12:41:40 2001
+++ linux/drivers/char/agp/agpgart_be.c	Mon Aug 27 07:40:33 2001
@@ -305,6 +305,9 @@
 
 void agp_copy_info(agp_kern_info * info)
 {
+	unsigned long page_mask = 0;
+	int i;
+
 	memset(info, 0, sizeof(agp_kern_info));
 	if (agp_bridge.type == NOT_SUPPORTED) {
 		info->chipset = agp_bridge.type;
@@ -319,6 +322,12 @@
 	info->aper_size = agp_return_size();
 	info->max_memory = agp_bridge.max_memory_agp;
 	info->current_memory = atomic_read(&agp_bridge.current_memory_agp);
+	info->cant_use_aperture = agp_bridge.cant_use_aperture;
+
+	for(i = 0; i < agp_bridge.num_of_masks; i++)
+		page_mask |= agp_bridge.mask_memory(page_mask, i);
+
+	info->page_mask = ~page_mask;
 }
 
 /* End - Routine to copy over information structure */
@@ -1083,6 +1092,7 @@
 	agp_bridge.free_by_type = intel_i810_free_by_type;
 	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
 	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge.cant_use_aperture = 0;
 
 	return 0;
 }
@@ -1275,6 +1285,7 @@
 	agp_bridge.free_by_type = agp_generic_free_by_type;
 	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
 	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge.cant_use_aperture = 0;
 
 	return 0;
 	
@@ -1305,6 +1316,7 @@
 	agp_bridge.free_by_type = agp_generic_free_by_type;
 	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
 	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge.cant_use_aperture = 0;
 
 	return 0;
 	
@@ -1335,6 +1347,7 @@
 	agp_bridge.free_by_type = agp_generic_free_by_type;
 	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
 	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge.cant_use_aperture = 0;
 
 	return 0;
 	
@@ -1452,6 +1465,7 @@
 	agp_bridge.free_by_type = agp_generic_free_by_type;
 	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
 	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge.cant_use_aperture = 0;
 
 	return 0;
 	
@@ -1563,6 +1577,7 @@
 	agp_bridge.free_by_type = agp_generic_free_by_type;
 	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
 	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge.cant_use_aperture = 0;
 
 	return 0;
 }
@@ -1938,6 +1953,7 @@
 	agp_bridge.free_by_type = agp_generic_free_by_type;
 	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
 	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge.cant_use_aperture = 0;
 
 	return 0;
 	
@@ -2181,6 +2197,7 @@
 	agp_bridge.free_by_type = agp_generic_free_by_type;
 	agp_bridge.agp_alloc_page = ali_alloc_page;
 	agp_bridge.agp_destroy_page = ali_destroy_page;
+	agp_bridge.cant_use_aperture = 0;
 
 	return 0;
 	
@@ -2766,6 +2783,7 @@
 	agp_bridge.free_by_type = agp_generic_free_by_type;
 	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
 	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge.cant_use_aperture = 0;
 
 	pci_read_config_dword(agp_bridge.dev,
 			      SVWRKS_APSIZE,
diff -u --recursive --new-file v2.4.9/linux/drivers/char/busmouse.c linux/drivers/char/busmouse.c
--- v2.4.9/linux/drivers/char/busmouse.c	Fri Feb  9 11:30:22 2001
+++ linux/drivers/char/busmouse.c	Fri Sep  7 09:28:38 2001
@@ -29,7 +29,7 @@
 
 /* Uncomment this if your mouse drivers expect the kernel to
  * return with EAGAIN if the mouse does not have any events
- * available, even if the mouse is opened in nonblocking mode.
+ * available, even if the mouse is opened in blocking mode.
  * Please report use of this "feature" to the author using the
  * above address.
  */
@@ -444,3 +444,5 @@
 EXPORT_SYMBOL(busmouse_add_buttons);
 EXPORT_SYMBOL(register_busmouse);
 EXPORT_SYMBOL(unregister_busmouse);
+
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.9/linux/drivers/char/decserial.c linux/drivers/char/decserial.c
--- v2.4.9/linux/drivers/char/decserial.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/decserial.c	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,98 @@
+/*
+ * sercons.c
+ *      choose the right serial device at boot time
+ *
+ * triemer 6-SEP-1998
+ *      sercons.c is designed to allow the three different kinds 
+ *      of serial devices under the decstation world to co-exist
+ *      in the same kernel.  The idea here is to abstract 
+ *      the pieces of the drivers that are common to this file
+ *      so that they do not clash at compile time and runtime.
+ *
+ * HK 16-SEP-1998 v0.002
+ *      removed the PROM console as this is not a real serial
+ *      device. Added support for PROM console in drivers/char/tty_io.c
+ *      instead. Although it may work to enable more than one 
+ *      console device I strongly recommend to use only one.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <asm/dec/machtype.h>
+
+#ifdef CONFIG_ZS
+extern int zs_init(void);
+#endif
+
+#ifdef CONFIG_DZ
+extern int dz_init(void);
+#endif
+
+#ifdef CONFIG_SERIAL_CONSOLE
+
+#ifdef CONFIG_ZS
+extern void zs_serial_console_init(void);
+#endif
+
+#ifdef CONFIG_DZ
+extern void dz_serial_console_init(void);
+#endif
+
+#endif
+
+/* rs_init - starts up the serial interface -
+   handle normal case of starting up the serial interface */
+
+#ifdef CONFIG_SERIAL
+
+int __init rs_init(void)
+{
+
+#if defined(CONFIG_ZS) && defined(CONFIG_DZ)
+    if (IOASIC)
+	return zs_init();
+    else
+	return dz_init();
+#else
+
+#ifdef CONFIG_ZS
+    return zs_init();
+#endif
+
+#ifdef CONFIG_DZ
+    return dz_init();
+#endif
+
+#endif
+}
+
+__initcall(rs_init);
+
+#endif
+
+#ifdef CONFIG_SERIAL_CONSOLE
+
+/* serial_console_init handles the special case of starting
+ *   up the console on the serial port
+ */
+void __init serial_console_init(void)
+{
+#if defined(CONFIG_ZS) && defined(CONFIG_DZ)
+    if (IOASIC)
+	zs_serial_console_init();
+    else
+	dz_serial_console_init();
+#else
+
+#ifdef CONFIG_ZS
+    zs_serial_console_init();
+#endif
+
+#ifdef CONFIG_DZ
+    dz_serial_console_init();
+#endif
+
+#endif
+}
+
+#endif
diff -u --recursive --new-file v2.4.9/linux/drivers/char/drm/ati_pcigart.h linux/drivers/char/drm/ati_pcigart.h
--- v2.4.9/linux/drivers/char/drm/ati_pcigart.h	Mon Aug 27 12:41:40 2001
+++ linux/drivers/char/drm/ati_pcigart.h	Sun Sep  9 19:06:10 2001
@@ -72,8 +72,6 @@
 	int i;
 	DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-	if ( !address ) return;
-
 	page = virt_to_page( address );
 
 	for ( i = 0 ; i <= ATI_PCIGART_TABLE_PAGES ; i++, page++ ) {
@@ -84,23 +82,40 @@
 	free_pages( address, ATI_PCIGART_TABLE_ORDER );
 }
 
-unsigned long DRM(ati_pcigart_init)( drm_device_t *dev )
+int DRM(ati_pcigart_init)( drm_device_t *dev,
+			   unsigned long *addr,
+			   dma_addr_t *bus_addr)
 {
 	drm_sg_mem_t *entry = dev->sg;
-	unsigned long address;
+	unsigned long address = 0;
 	unsigned long pages;
-	u32 *pci_gart, page_base;
-	int i, j;
+	u32 *pci_gart, page_base, bus_address = 0;
+	int i, j, ret = 0;
 
 	if ( !entry ) {
 		DRM_ERROR( "no scatter/gather memory!\n" );
-		return 0;
+		goto done;
 	}
 
 	address = DRM(ati_alloc_pcigart_table)();
 	if ( !address ) {
 		DRM_ERROR( "cannot allocate PCI GART page!\n" );
-		return 0;
+		goto done;
+	}
+
+	if ( !dev->pdev ) {
+		DRM_ERROR( "PCI device unknown!\n" );
+		goto done;
+	}
+
+	bus_address = pci_map_single(dev->pdev, (void *)address,
+				  ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
+				  PCI_DMA_TODEVICE);
+	if (bus_address == 0) {
+		DRM_ERROR( "unable to map PCIGART pages!\n" );
+		DRM(ati_free_pcigart_table)( address );
+		address = 0;
+		goto done;
 	}
 
 	pci_gart = (u32 *)address;
@@ -111,28 +126,72 @@
 	memset( pci_gart, 0, ATI_MAX_PCIGART_PAGES * sizeof(u32) );
 
 	for ( i = 0 ; i < pages ; i++ ) {
-		page_base = page_to_bus( entry->pagelist[i] );
+		/* we need to support large memory configurations */
+		entry->busaddr[i] = pci_map_single(dev->pdev,
+					   page_address( entry->pagelist[i] ),
+					   PAGE_SIZE,
+					   PCI_DMA_TODEVICE);
+		if (entry->busaddr[i] == 0) {
+			DRM_ERROR( "unable to map PCIGART pages!\n" );
+			DRM(ati_pcigart_cleanup)( dev, address, bus_address );
+			address = 0;
+			bus_address = 0;
+			goto done;
+		}
+		page_base = (u32) entry->busaddr[i];
+
 		for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
 			*pci_gart++ = cpu_to_le32( page_base );
 			page_base += ATI_PCIGART_PAGE_SIZE;
 		}
 	}
 
+	ret = 1;
+
 #if __i386__
 	asm volatile ( "wbinvd" ::: "memory" );
 #else
 	mb();
 #endif
 
-	return address;
+done:
+	*addr = address;
+	*bus_addr = bus_address;
+	return ret;
 }
 
-int DRM(ati_pcigart_cleanup)( unsigned long address )
+int DRM(ati_pcigart_cleanup)( drm_device_t *dev,
+			      unsigned long addr,
+			      dma_addr_t bus_addr)
 {
+	drm_sg_mem_t *entry = dev->sg;
+	unsigned long pages;
+	int i;
 
-	if ( address ) {
-		DRM(ati_free_pcigart_table)( address );
+	/* we need to support large memory configurations */
+	if ( !entry ) {
+		DRM_ERROR( "no scatter/gather memory!\n" );
+		return 0;
+	}
+
+	if ( bus_addr ) {
+		pci_unmap_single(dev->pdev, bus_addr,
+				 ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
+				 PCI_DMA_TODEVICE);
+
+		pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES )
+		        ? entry->pages : ATI_MAX_PCIGART_PAGES;
+
+		for ( i = 0 ; i < pages ; i++ ) {
+			if ( !entry->busaddr[i] ) break;
+			pci_unmap_single(dev->pdev, entry->busaddr[i],
+					 PAGE_SIZE, PCI_DMA_TODEVICE);
+		}
+	}
+
+	if ( addr ) {
+		DRM(ati_free_pcigart_table)( addr );
 	}
 
-	return 0;
+	return 1;
 }
diff -u --recursive --new-file v2.4.9/linux/drivers/char/drm/drmP.h linux/drivers/char/drm/drmP.h
--- v2.4.9/linux/drivers/char/drm/drmP.h	Sun Aug 12 13:27:59 2001
+++ linux/drivers/char/drm/drmP.h	Sun Sep  9 19:06:10 2001
@@ -76,6 +76,17 @@
 #include <asm/pgalloc.h>
 #include "drm.h"
 
+/* page_to_bus for earlier kernels, not optimal in all cases */
+#ifndef page_to_bus
+#define page_to_bus(page)	((unsigned int)(virt_to_bus(page_address(page))))
+#endif
+
+/* We just use virt_to_bus for pci_map_single on older kernels */
+#if LINUX_VERSION_CODE < 0x020400
+#define pci_map_single(hwdev, ptr, size, direction)	virt_to_bus(ptr)
+#define pci_unmap_single(hwdev, dma_addr, size, direction)
+#endif
+
 /* DRM template customization defaults
  */
 #ifndef __HAVE_AGP
@@ -616,6 +627,8 @@
 	int                acquired;
 	unsigned long      base;
    	int 		   agp_mtrr;
+	int		   cant_use_aperture;
+	unsigned long	   page_mask;
 } drm_agp_head_t;
 #endif
 
@@ -624,6 +637,7 @@
 	void            *virtual;
 	int             pages;
 	struct page     **pagelist;
+	dma_addr_t	*busaddr;
 } drm_sg_mem_t;
 
 typedef struct drm_sigdata {
@@ -714,6 +728,7 @@
 #if __REALLY_HAVE_AGP
 	drm_agp_head_t    *agp;
 #endif
+	struct pci_dev *pdev;
 #ifdef __alpha__
 #if LINUX_VERSION_CODE < 0x020403
 	struct pci_controler *hose;
@@ -1018,8 +1033,12 @@
 #endif
 
                                /* ATI PCIGART support (ati_pcigart.h) */
-extern unsigned long  DRM(ati_pcigart_init)(drm_device_t *dev);
-extern int            DRM(ati_pcigart_cleanup)(unsigned long address);
+extern int            DRM(ati_pcigart_init)(drm_device_t *dev,
+					    unsigned long *addr,
+					    dma_addr_t *bus_addr);
+extern int            DRM(ati_pcigart_cleanup)(drm_device_t *dev,
+					       unsigned long addr,
+					       dma_addr_t bus_addr);
 
 #endif /* __KERNEL__ */
 #endif
diff -u --recursive --new-file v2.4.9/linux/drivers/char/drm/drm_agpsupport.h linux/drivers/char/drm/drm_agpsupport.h
--- v2.4.9/linux/drivers/char/drm/drm_agpsupport.h	Sun Aug 12 13:27:59 2001
+++ linux/drivers/char/drm/drm_agpsupport.h	Sun Sep  9 19:06:10 2001
@@ -316,6 +316,14 @@
 
 		default:		head->chipset = "Unknown";       break;
 		}
+#if LINUX_VERSION_CODE <= 0x020408
+		head->cant_use_aperture = 0;
+		head->page_mask = ~(0xfff);
+#else
+		head->cant_use_aperture = head->agp_info.cant_use_aperture;
+		head->page_mask = head->agp_info.page_mask;
+#endif
+
 		DRM_INFO("AGP %d.%d on %s @ 0x%08lx %ZuMB\n",
 			 head->agp_info.version.major,
 			 head->agp_info.version.minor,
diff -u --recursive --new-file v2.4.9/linux/drivers/char/drm/drm_ioctl.h linux/drivers/char/drm/drm_ioctl.h
--- v2.4.9/linux/drivers/char/drm/drm_ioctl.h	Sun Aug 12 13:27:59 2001
+++ linux/drivers/char/drm/drm_ioctl.h	Sun Sep  9 19:06:10 2001
@@ -98,7 +98,6 @@
 	}
 	sprintf(dev->devname, "%s@%s", dev->name, dev->unique);
 
-#ifdef __alpha__
 	do {
 		struct pci_dev *pci_dev;
                 int b, d, f;
@@ -114,10 +113,13 @@
                 if (*p) break;
  
                 pci_dev = pci_find_slot(b, PCI_DEVFN(d,f));
-                if (pci_dev)
-                        dev->hose = pci_dev->sysdata;
-        } while(0);
+                if (pci_dev) {
+			dev->pdev = pci_dev;
+#ifdef __alpha__
+			dev->hose = pci_dev->sysdata;
 #endif
+		}
+        } while(0);
 
 	return 0;
 }
diff -u --recursive --new-file v2.4.9/linux/drivers/char/drm/drm_scatter.h linux/drivers/char/drm/drm_scatter.h
--- v2.4.9/linux/drivers/char/drm/drm_scatter.h	Mon Aug 27 12:41:40 2001
+++ linux/drivers/char/drm/drm_scatter.h	Sun Sep  9 19:06:10 2001
@@ -47,12 +47,15 @@
 
 	vfree( entry->virtual );
 
+	DRM(free)( entry->busaddr,
+		   entry->pages * sizeof(*entry->busaddr),
+		   DRM_MEM_PAGES );
 	DRM(free)( entry->pagelist,
-		  entry->pages * sizeof(*entry->pagelist),
-		  DRM_MEM_PAGES );
+		   entry->pages * sizeof(*entry->pagelist),
+		   DRM_MEM_PAGES );
 	DRM(free)( entry,
-		  sizeof(*entry),
-		  DRM_MEM_SGLISTS );
+		   sizeof(*entry),
+		   DRM_MEM_SGLISTS );
 }
 
 int DRM(sg_alloc)( struct inode *inode, struct file *filp,
@@ -93,16 +96,31 @@
 		DRM(free)( entry, sizeof(*entry), DRM_MEM_SGLISTS );
 		return -ENOMEM;
 	}
-	memset(entry->pagelist, 0, pages * sizeof(*entry->pagelist));
+
+	entry->busaddr = DRM(alloc)( pages * sizeof(*entry->busaddr),
+				     DRM_MEM_PAGES );
+	if ( !entry->busaddr ) {
+		DRM(free)( entry->pagelist,
+			   entry->pages * sizeof(*entry->pagelist),
+			   DRM_MEM_PAGES );
+		DRM(free)( entry,
+			   sizeof(*entry),
+			   DRM_MEM_SGLISTS );
+		return -ENOMEM;
+	}
+	memset( (void *)entry->busaddr, 0, pages * sizeof(*entry->busaddr) );
 
 	entry->virtual = vmalloc_32( pages << PAGE_SHIFT );
 	if ( !entry->virtual ) {
+		DRM(free)( entry->busaddr,
+			   entry->pages * sizeof(*entry->busaddr),
+			   DRM_MEM_PAGES );
 		DRM(free)( entry->pagelist,
-			  entry->pages * sizeof(*entry->pagelist),
-			  DRM_MEM_PAGES );
+			   entry->pages * sizeof(*entry->pagelist),
+			   DRM_MEM_PAGES );
 		DRM(free)( entry,
-			  sizeof(*entry),
-			  DRM_MEM_SGLISTS );
+			   sizeof(*entry),
+			   DRM_MEM_SGLISTS );
 		return -ENOMEM;
 	}
 
diff -u --recursive --new-file v2.4.9/linux/drivers/char/drm/drm_vm.h linux/drivers/char/drm/drm_vm.h
--- v2.4.9/linux/drivers/char/drm/drm_vm.h	Mon Aug 27 12:41:40 2001
+++ linux/drivers/char/drm/drm_vm.h	Sun Sep  9 19:06:10 2001
@@ -67,6 +67,70 @@
 			    int write_access)
 #endif
 {
+#if __REALLY_HAVE_AGP
+	drm_file_t *priv  = vma->vm_file->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_map_t *map    = NULL;
+	drm_map_list_t  *r_list;
+	struct list_head *list;
+
+	/*
+         * Find the right map
+         */
+
+	if(!dev->agp->cant_use_aperture) goto vm_nopage_error;
+
+	list_for_each(list, &dev->maplist->head) {
+		r_list = (drm_map_list_t *)list;
+		map = r_list->map;
+		if (!map) continue;
+		if (map->offset == VM_OFFSET(vma)) break;
+	}
+
+	if (map && map->type == _DRM_AGP) {
+		unsigned long offset = address - vma->vm_start;
+		unsigned long baddr = VM_OFFSET(vma) + offset;
+		struct drm_agp_mem *agpmem;
+		struct page *page;
+
+#if __alpha__
+		/*
+                 * Adjust to a bus-relative address
+                 */
+		baddr -= dev->hose->mem_space->start;
+#endif
+
+		/*
+                 * It's AGP memory - find the real physical page to map
+                 */
+		for(agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next) {
+			if (agpmem->bound <= baddr &&
+			    agpmem->bound + agpmem->pages * PAGE_SIZE > baddr) 
+				break;
+		}
+
+		if (!agpmem) goto vm_nopage_error;
+
+		/*
+                 * Get the page, inc the use count, and return it
+                 */
+		offset = (baddr - agpmem->bound) >> PAGE_SHIFT;
+		agpmem->memory->memory[offset] &= dev->agp->page_mask;
+		page = virt_to_page(__va(agpmem->memory->memory[offset]));
+		get_page(page);
+
+		DRM_DEBUG("baddr = 0x%lx page = 0x%p, offset = 0x%lx\n",
+			  baddr, __va(agpmem->memory->memory[offset]), offset);
+
+#if LINUX_VERSION_CODE < 0x020317
+		return page_address(page);
+#else
+		return page;
+#endif
+        }
+vm_nopage_error:
+#endif /* __REALLY_HAVE_AGP */
+
 	return NOPAGE_SIGBUS;		/* Disallow mremap */
 }
 
@@ -220,24 +284,27 @@
 	drm_file_t	 *priv	 = vma->vm_file->private_data;
 	drm_device_t	 *dev	 = priv->dev;
 	drm_device_dma_t *dma	 = dev->dma;
-	unsigned long	 physical;
 	unsigned long	 offset;
-	unsigned long	 page;
+	unsigned long	 page_nr;
+	struct page	 *page;
 
 	if (!dma)		   return NOPAGE_SIGBUS; /* Error */
 	if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
 	if (!dma->pagelist)	   return NOPAGE_OOM ; /* Nothing allocated */
 
 	offset	 = address - vma->vm_start; /* vm_[pg]off[set] should be 0 */
-	page	 = offset >> PAGE_SHIFT;
-	physical = dma->pagelist[page] + (offset & (~PAGE_MASK));
-	atomic_inc(&virt_to_page(physical)->count); /* Dec. by kernel */
+	page_nr  = offset >> PAGE_SHIFT;
+	page = virt_to_page((dma->pagelist[page_nr] + 
+			     (offset & (~PAGE_MASK))));
 
-	DRM_DEBUG("0x%08lx (page %lu) => 0x%08lx\n", address, page, physical);
+	get_page(page);
+
+	DRM_DEBUG("0x%08lx (page %lu) => 0x%08x\n", address, page_nr, 
+		  page_to_bus(page));
 #if LINUX_VERSION_CODE < 0x020317
-	return physical;
+	return page_address(page);
 #else
-	return virt_to_page(physical);
+	return page;
 #endif
 }
 
@@ -274,10 +341,10 @@
 	map_offset = map->offset - dev->sg->handle;
 	page_offset = (offset >> PAGE_SHIFT) + (map_offset >> PAGE_SHIFT);
 	page = entry->pagelist[page_offset];
-	atomic_inc(&page->count);                       /* Dec. by kernel */
+	get_page(page);
 
 #if LINUX_VERSION_CODE < 0x020317
-	return (unsigned long)virt_to_phys(page->virtual);
+	return page_address(page);
 #else
 	return page;
 #endif
@@ -435,9 +502,20 @@
 	}
 
 	switch (map->type) {
+        case _DRM_AGP:
+#if defined(__alpha__)
+                /*
+                 * On Alpha we can't talk to bus dma address from the
+                 * CPU, so for memory of type DRM_AGP, we'll deal with
+                 * sorting out the real physical pages and mappings
+                 * in nopage()
+                 */
+                vma->vm_ops = &DRM(vm_ops);
+                break;
+#endif
+                /* fall through to _DRM_FRAME_BUFFER... */        
 	case _DRM_FRAME_BUFFER:
 	case _DRM_REGISTERS:
-	case _DRM_AGP:
 		if (VM_OFFSET(vma) >= __pa(high_memory)) {
 #if defined(__i386__)
 			if (boot_cpu_data.x86 > 3 && map->type != _DRM_AGP) {
diff -u --recursive --new-file v2.4.9/linux/drivers/char/drm/mga_drv.h linux/drivers/char/drm/mga_drv.h
--- v2.4.9/linux/drivers/char/drm/mga_drv.h	Sun Aug 12 13:27:59 2001
+++ linux/drivers/char/drm/mga_drv.h	Mon Aug 27 07:40:33 2001
@@ -145,14 +145,28 @@
 #define mga_flush_write_combine()	mb()
 
 
-#define MGA_BASE( reg )		((u32)(dev_priv->mmio->handle))
+#define MGA_BASE( reg )		((unsigned long)(dev_priv->mmio->handle))
 #define MGA_ADDR( reg )		(MGA_BASE(reg) + reg)
 
 #define MGA_DEREF( reg )	*(volatile u32 *)MGA_ADDR( reg )
+#define MGA_DEREF8( reg )	*(volatile u8 *)MGA_ADDR( reg )
+
+#ifdef __alpha__
+#define MGA_READ( reg )		(_MGA_READ((u32 *)MGA_ADDR(reg)))
+#define MGA_WRITE( reg, val )	do { wmb(); MGA_DEREF( reg ) = val; } while (0)
+#define MGA_WRITE8( reg, val )  do { wmb(); MGA_DEREF8( reg ) = val; } while (0)
+
+static inline u32 _MGA_READ(u32 *addr)
+{
+	mb();
+	return *(volatile u32 *)addr;
+}
+
+#else
 #define MGA_READ( reg )		MGA_DEREF( reg )
 #define MGA_WRITE( reg, val )	do { MGA_DEREF( reg ) = val; } while (0)
-#define MGA_DEREF8( reg )	*(volatile u8 *)MGA_ADDR( reg )
 #define MGA_WRITE8( reg, val )  do { MGA_DEREF8( reg ) = val; } while (0)
+#endif
 
 #define DWGREG0 	0x1c00
 #define DWGREG0_END 	0x1dff
diff -u --recursive --new-file v2.4.9/linux/drivers/char/drm/r128_cce.c linux/drivers/char/drm/r128_cce.c
--- v2.4.9/linux/drivers/char/drm/r128_cce.c	Mon Aug 27 12:41:40 2001
+++ linux/drivers/char/drm/r128_cce.c	Mon Aug 27 07:40:33 2001
@@ -351,11 +351,10 @@
 		page_ofs = tmp_ofs >> PAGE_SHIFT;
 
 		R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR,
-			    page_to_bus(entry->pagelist[page_ofs]));
-
-		DRM_DEBUG( "ring rptr: offset=0x%08lx handle=0x%08lx\n",
-			   page_to_bus(entry->pagelist[page_ofs]),
-			   entry->handle + tmp_ofs );
+     			    entry->busaddr[page_ofs]);
+		DRM_DEBUG( "ring rptr: offset=0x%08x handle=0x%08lx\n",
+			   entry->busaddr[page_ofs],
+     			   entry->handle + tmp_ofs );
 	}
 
 	/* Set watermark control */
@@ -599,15 +598,14 @@
 		    dev_priv->sarea_priv->last_dispatch );
 
 	if ( dev_priv->is_pci ) {
-		dev_priv->phys_pci_gart = DRM(ati_pcigart_init)( dev );
-		if ( !dev_priv->phys_pci_gart ) {
+		if (!DRM(ati_pcigart_init)( dev, &dev_priv->phys_pci_gart,
+     					    &dev_priv->bus_pci_gart) ) {
 			DRM_ERROR( "failed to init PCI GART!\n" );
 			dev->dev_private = (void *)dev_priv;
 			r128_do_cleanup_cce( dev );
 			return -ENOMEM;
 		}
-		R128_WRITE( R128_PCI_GART_PAGE,
-			    virt_to_bus( (void *)dev_priv->phys_pci_gart ) );
+		R128_WRITE( R128_PCI_GART_PAGE, dev_priv->bus_pci_gart );
 	}
 
 	r128_cce_init_ring_buffer( dev, dev_priv );
@@ -629,6 +627,11 @@
 			DRM_IOREMAPFREE( dev_priv->cce_ring );
 			DRM_IOREMAPFREE( dev_priv->ring_rptr );
 			DRM_IOREMAPFREE( dev_priv->buffers );
+		} else {
+			if (!DRM(ati_pcigart_cleanup)( dev,
+						dev_priv->phys_pci_gart,
+						dev_priv->bus_pci_gart ))
+				DRM_ERROR( "failed to cleanup PCI GART!\n" );
 		}
 
 		DRM(free)( dev->dev_private, sizeof(drm_r128_private_t),
diff -u --recursive --new-file v2.4.9/linux/drivers/char/drm/r128_drv.h linux/drivers/char/drm/r128_drv.h
--- v2.4.9/linux/drivers/char/drm/r128_drv.h	Sun Aug 12 13:27:59 2001
+++ linux/drivers/char/drm/r128_drv.h	Mon Aug 27 07:40:33 2001
@@ -72,6 +72,7 @@
 	int usec_timeout;
 	int is_pci;
 	unsigned long phys_pci_gart;
+	dma_addr_t bus_pci_gart;
 	unsigned long cce_buffers_offset;
 
 	atomic_t idle_count;
diff -u --recursive --new-file v2.4.9/linux/drivers/char/drm/radeon_cp.c linux/drivers/char/drm/radeon_cp.c
--- v2.4.9/linux/drivers/char/drm/radeon_cp.c	Mon Aug 27 12:41:40 2001
+++ linux/drivers/char/drm/radeon_cp.c	Mon Aug 27 07:40:33 2001
@@ -624,10 +624,9 @@
 		page_ofs = tmp_ofs >> PAGE_SHIFT;
 
 		RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR,
-			      page_to_bus(entry->pagelist[page_ofs]));
-
+			     entry->busaddr[page_ofs]);
 		DRM_DEBUG( "ring rptr: offset=0x%08x handle=0x%08lx\n",
-			   page_to_bus(entry->pagelist[page_ofs]),
+			   entry->busaddr[page_ofs],
 			   entry->handle + tmp_ofs );
 	}
 
@@ -929,8 +928,8 @@
 		      dev_priv->sarea_priv->last_clear );
 
 	if ( dev_priv->is_pci ) {
-		dev_priv->phys_pci_gart = DRM(ati_pcigart_init)( dev );
-		if ( !dev_priv->phys_pci_gart ) {
+		if (!DRM(ati_pcigart_init)( dev, &dev_priv->phys_pci_gart,
+					    &dev_priv->bus_pci_gart)) {
 			DRM_ERROR( "failed to init PCI GART!\n" );
 			dev->dev_private = (void *)dev_priv;
 			radeon_do_cleanup_cp(dev);
@@ -944,8 +943,7 @@
 
 		/* set PCI GART page-table base address
 		 */
-		RADEON_WRITE( RADEON_AIC_PT_BASE,
-			      virt_to_bus( (void *)dev_priv->phys_pci_gart ) );
+		RADEON_WRITE( RADEON_AIC_PT_BASE, dev_priv->bus_pci_gart );
 
 		/* set address range for PCI address translate
 		 */
@@ -990,6 +988,11 @@
 			DRM_IOREMAPFREE( dev_priv->cp_ring );
 			DRM_IOREMAPFREE( dev_priv->ring_rptr );
 			DRM_IOREMAPFREE( dev_priv->buffers );
+		} else {
+			if (!DRM(ati_pcigart_cleanup)( dev,
+						dev_priv->phys_pci_gart,
+						dev_priv->bus_pci_gart ))
+				DRM_ERROR( "failed to cleanup PCI GART!\n" );
 		}
 
 		DRM(free)( dev->dev_private, sizeof(drm_radeon_private_t),
diff -u --recursive --new-file v2.4.9/linux/drivers/char/drm/radeon_drv.h linux/drivers/char/drm/radeon_drv.h
--- v2.4.9/linux/drivers/char/drm/radeon_drv.h	Sun Aug 12 13:27:59 2001
+++ linux/drivers/char/drm/radeon_drv.h	Mon Aug 27 07:40:33 2001
@@ -84,6 +84,7 @@
 	int usec_timeout;
 	int is_pci;
 	unsigned long phys_pci_gart;
+	dma_addr_t bus_pci_gart;
 
 	atomic_t idle_count;
 
diff -u --recursive --new-file v2.4.9/linux/drivers/char/drm/tdfx_drv.c linux/drivers/char/drm/tdfx_drv.c
--- v2.4.9/linux/drivers/char/drm/tdfx_drv.c	Sun Aug 12 13:27:59 2001
+++ linux/drivers/char/drm/tdfx_drv.c	Mon Aug 27 07:40:33 2001
@@ -44,13 +44,30 @@
 #define DRIVER_MINOR		0
 #define DRIVER_PATCHLEVEL	0
 
+#ifndef PCI_VENDOR_ID_3DFX
+#define PCI_VENDOR_ID_3DFX 0x121A
+#endif
 #ifndef PCI_DEVICE_ID_3DFX_VOODOO5
 #define PCI_DEVICE_ID_3DFX_VOODOO5 0x0009
 #endif
+#ifndef PCI_DEVICE_ID_3DFX_VOODOO4
+#define PCI_DEVICE_ID_3DFX_VOODOO4 0x0007
+#endif
+#ifndef PCI_DEVICE_ID_3DFX_VOODOO3_3000 /* Voodoo3 3000 */
+#define PCI_DEVICE_ID_3DFX_VOODOO3_3000 0x0005
+#endif
+#ifndef PCI_DEVICE_ID_3DFX_VOODOO3_2000 /* Voodoo3 3000 */
+#define PCI_DEVICE_ID_3DFX_VOODOO3_2000 0x0004
+#endif
+#ifndef PCI_DEVICE_ID_3DFX_BANSHEE
+#define PCI_DEVICE_ID_3DFX_BANSHEE 0x0003
+#endif
 
 static drm_pci_list_t DRM(idlist)[] = {
 	{ PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_BANSHEE },
-	{ PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO3 },
+	{ PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO3_2000 },
+	{ PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO3_3000 },
+	{ PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO4 },
 	{ PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO5 },
 	{ 0, 0 }
 };
diff -u --recursive --new-file v2.4.9/linux/drivers/char/dsp56k.c linux/drivers/char/dsp56k.c
--- v2.4.9/linux/drivers/char/dsp56k.c	Mon Aug 27 12:41:40 2001
+++ linux/drivers/char/dsp56k.c	Fri Sep  7 09:28:38 2001
@@ -502,7 +502,7 @@
 
 static devfs_handle_t devfs_handle;
 
-static const char banner[] __initdata = KERN_INFO "DSP56k driver installed\n";
+static char banner[] __initdata = KERN_INFO "DSP56k driver installed\n";
 
 static int __init dsp56k_init_driver(void)
 {
@@ -531,3 +531,5 @@
 	devfs_unregister(devfs_handle);
 }
 module_exit(dsp56k_cleanup_driver);
+
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.9/linux/drivers/char/dz.c linux/drivers/char/dz.c
--- v2.4.9/linux/drivers/char/dz.c	Mon Aug 27 12:41:40 2001
+++ linux/drivers/char/dz.c	Sun Sep  9 10:43:02 2001
@@ -21,15 +21,10 @@
  * [07-SEP-99] Bugfixes 
  */
 
-#define DEBUG_DZ 1
+/* #define DEBUG_DZ 1 */
 
-#ifdef MODULE
-#include <linux/module.h>
 #include <linux/version.h>
-#else
-#define MOD_INC_USE_COUNT
-#define MOD_DEC_USE_COUNT
-#endif
+#include <linux/module.h>
 
 #include <linux/config.h>
 #include <linux/kernel.h>
@@ -41,9 +36,10 @@
 #include <linux/param.h>
 #include <linux/tqueue.h>
 #include <linux/interrupt.h>
+#include <linux/serial.h>
+#include <linux/serialP.h>
 #include <asm-mips/wbflush.h>
-/* for definition of SERIAL */
-#include <asm/dec/interrupts.h>
+#include <asm/dec/interrupts.h>			/* for definition of SERIAL */
 
 /* for definition of struct console */
 #ifdef CONFIG_SERIAL_CONSOLE
@@ -91,13 +87,13 @@
  */
 static void debug_console( const char *s,int count)
 {
-    unsigned i;
+	unsigned i;
 
-    for (i = 0; i < count; i++) {
-       if (*s == 10)
-           prom_printf("%c", 13);
-       prom_printf("%c", *s++);
-    }
+	for (i = 0; i < count; i++) {
+		if (*s == 10)
+			prom_printf("%c", 13);
+		prom_printf("%c", *s++);
+	}
 }
 #endif
 
@@ -112,16 +108,16 @@
 
 static inline unsigned short dz_in (struct dz_serial *info, unsigned offset)
 {
-  volatile unsigned short *addr = (volatile unsigned short *)(info->port + offset);
-  return *addr;
+	volatile u16 *addr = (volatile u16 *)(info->port + offset);
+
+	return *addr;
 }
 
-static inline void dz_out (struct dz_serial *info, unsigned offset, unsigned short value)
+static inline void dz_out (struct dz_serial *info, unsigned offset,
+                           unsigned short value)
 {
-
-    volatile unsigned short *addr = (volatile unsigned short *)(info->port + offset);
-  *addr = value;
-
+	volatile u16 *addr = (volatile u16 *)(info->port + offset);
+	*addr = value;
 }
 
 /*
@@ -136,33 +132,32 @@
 
 static void dz_stop (struct tty_struct *tty)
 {
-  struct dz_serial *info; 
-  unsigned short mask, tmp;
+	struct dz_serial *info; 
+	unsigned short mask, tmp;
 
-  if (tty==0) 
-    return; 
+	if (!tty) 
+		return; 
  
-  info = (struct dz_serial *)tty->driver_data; 
-         
-  mask = 1 << info->line;
-  tmp = dz_in (info, DZ_TCR);       /* read the TX flag */
-
-    tmp &= ~mask;                   /* clear the TX flag */
-    dz_out (info, DZ_TCR, tmp);
-}  
+	info = (struct dz_serial *)tty->driver_data; 
+
+	mask = 1 << info->line;
+	tmp = dz_in (info, DZ_TCR);       /* read the TX flag */
+
+	tmp &= ~mask;                   /* clear the TX flag */
+	dz_out (info, DZ_TCR, tmp);
+}
 
 static void dz_start (struct tty_struct *tty)
 {
-  struct dz_serial *info = (struct dz_serial *)tty->driver_data;
-  unsigned short mask, tmp;
-
-  mask = 1 << info->line;
-  tmp = dz_in (info, DZ_TCR);      /* read the TX flag */
+	struct dz_serial *info = (struct dz_serial *)tty->driver_data;
+	unsigned short mask, tmp;
 
-    tmp |= mask;                   /* set the TX flag */
-    dz_out (info, DZ_TCR, tmp);
+	mask = 1 << info->line;
+	tmp = dz_in (info, DZ_TCR);      /* read the TX flag */
 
-}  
+	tmp |= mask;                   /* set the TX flag */
+	dz_out (info, DZ_TCR, tmp);
+}
 
 /*
  * ------------------------------------------------------------
@@ -194,9 +189,9 @@
  */
 static inline void dz_sched_event (struct dz_serial *info, int event)
 {
-  info->event |= 1 << event;
-  queue_task (&info->tqueue, &tq_serial);
-  mark_bh (SERIAL_BH);
+	info->event |= 1 << event;
+	queue_task(&info->tqueue, &tq_serial);
+	mark_bh(SERIAL_BH);
 }
 
 /*
@@ -208,98 +203,101 @@
  */
 static inline void receive_chars (struct dz_serial *info_in)
 {
+	struct dz_serial *info;
+	struct tty_struct *tty = 0;
+	struct async_icount *icount;
+	int ignore = 0;
+	unsigned short status, tmp;
+	unsigned char ch;
 
-  struct dz_serial *info;
-  struct tty_struct *tty = 0;
-  struct async_icount *icount;
-  int ignore = 0;
-  unsigned short status, tmp;
-  unsigned char ch;
-
-  /* this code is going to be a problem...
-     the call to tty_flip_buffer is going to need
-     to be rethought...
-   */
-  do
-    {
-      status = dz_in (info_in, DZ_RBUF);
-      info = lines[LINE(status)];
-
-      /* punt so we don't get duplicate characters */
-      if (!(status & DZ_DVAL))
-        goto ignore_char;
-
+	/*
+	 * This code is going to be a problem...  the call to tty_flip_buffer
+	 * is going to need to be rethought...
+	 */
+	do {
+		status = dz_in (info_in, DZ_RBUF);
+		info = lines[LINE(status)];
+
+		/* punt so we don't get duplicate characters */
+		if (!(status & DZ_DVAL))
+			goto ignore_char;
 
-    ch = UCHAR(status);                /* grab the char */
+		ch = UCHAR(status);			/* grab the char */
 
 #if 0
-    if (info->is_console) {
-      if (ch == 0) return;            /* it's a break ... */
+		if (info->is_console) {
+			if (ch == 0)
+				return;			/* it's a break ... */
 
-      wake_up (&keypress_wait);       /* It is a 'keyboard interrupt' ;-) */
-    }
+			wake_up (&keypress_wait);       /* It is a 'keyboard interrupt' ;-) */
+		}
 #endif
 
-    tty = info->tty;                  /* now tty points to the proper dev */
-    icount = &info->icount;
-
-    if (!tty) break;
-    if (tty->flip.count >= TTY_FLIPBUF_SIZE) break;
+		tty = info->tty;	/* now tty points to the proper dev */
+		icount = &info->icount;
 
-    *tty->flip.char_buf_ptr = ch;
-    *tty->flip.flag_buf_ptr = 0;
-    icount->rx++;
-
-    /* keep track of the statistics */
-    if (status & (DZ_OERR | DZ_FERR | DZ_PERR)) {
-      if (status & DZ_PERR)                /* parity error */
-        icount->parity++;
-      else if (status & DZ_FERR)           /* frame error */
-        icount->frame++;
-      if (status & DZ_OERR)                /* overrun error */
-        icount->overrun++;
-
-      /*  check to see if we should ignore the character
-	 and mask off conditions that should be ignored
-      */
-
-      if (status & info->ignore_status_mask) {
-        if (++ignore > 100 ) break;
-        goto ignore_char;
-      }
+		if (!tty)
+			break;
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE) break;
+
+		*tty->flip.char_buf_ptr = ch;
+		*tty->flip.flag_buf_ptr = 0;
+		icount->rx++;
+
+		/* keep track of the statistics */
+		if (status & (DZ_OERR | DZ_FERR | DZ_PERR)) {
+			if (status & DZ_PERR)		/* parity error */
+				icount->parity++;
+			else if (status & DZ_FERR)	/* frame error */
+				icount->frame++;
+			if (status & DZ_OERR)		/* overrun error */
+				icount->overrun++;
+
+			/*
+			 * Check to see if we should ignore the character and
+			 * mask off conditions that should be ignored
+			 */
+
+			if (status & info->ignore_status_mask) {
+				if (++ignore > 100)
+					break;
+				goto ignore_char;
+			}
 
-      /* mask off the error conditions we want to ignore */
-      tmp = status & info->read_status_mask;
+			/* mask off the error conditions we want to ignore */
+			tmp = status & info->read_status_mask;
 
-      if (tmp & DZ_PERR)
-	{
-        *tty->flip.flag_buf_ptr = TTY_PARITY;
-	  debug_console("PERR\n",5);
-	}
-      else if (tmp & DZ_FERR)
-	{
-        *tty->flip.flag_buf_ptr = TTY_FRAME;
-	  debug_console("FERR\n",5);
-	}
-      if (tmp & DZ_OERR) 
-	{ 
-	  debug_console("OERR\n",5);
-	if (tty->flip.count < TTY_FLIPBUF_SIZE) {
-          tty->flip.count++;
-          tty->flip.flag_buf_ptr++;
-          tty->flip.char_buf_ptr++;
-          *tty->flip.flag_buf_ptr = TTY_OVERRUN;
-        }
-      }
-    }
-    tty->flip.flag_buf_ptr++;
-    tty->flip.char_buf_ptr++;
-    tty->flip.count++;
-  ignore_char:
-  } while (status & DZ_DVAL);
+			if (tmp & DZ_PERR) {
+				*tty->flip.flag_buf_ptr = TTY_PARITY;
+#ifdef DEBUG_DZ
+				debug_console("PERR\n",5);
+#endif /* DEBUG_DZ */
+			} else if (tmp & DZ_FERR) {
+				*tty->flip.flag_buf_ptr = TTY_FRAME;
+#ifdef DEBUG_DZ
+				debug_console("FERR\n",5);
+#endif /* DEBUG_DZ */
+			} if (tmp & DZ_OERR) { 
+#ifdef DEBUG_DZ
+				debug_console("OERR\n",5);
+#endif /* DEBUG_DZ */
+				if (tty->flip.count < TTY_FLIPBUF_SIZE) {
+					tty->flip.count++;
+					tty->flip.flag_buf_ptr++;
+					tty->flip.char_buf_ptr++;
+					*tty->flip.flag_buf_ptr = TTY_OVERRUN;
+				}
+			}
+		}
+	tty->flip.flag_buf_ptr++;
+	tty->flip.char_buf_ptr++;
+	tty->flip.count++;
+ignore_char:
+	;
+	} while (status & DZ_DVAL);
 
-  if (tty)
-    tty_flip_buffer_push(tty);
+	if (tty)
+		tty_flip_buffer_push(tty);
 }
 
 /*
@@ -311,35 +309,37 @@
  */
 static inline void transmit_chars (struct dz_serial *info)
 {
-  unsigned char tmp;
+	unsigned char tmp;
 
+	if (info->x_char) {           /* XON/XOFF chars */
+		dz_out(info, DZ_TDR, info->x_char);
+		info->icount.tx++;
+		info->x_char = 0;
+		return;
+	}
 
+	/* if nothing to do or stopped or hardware stopped */
+	if ((info->xmit_cnt <= 0) || info->tty->stopped ||
+	    info->tty->hw_stopped) {
+		dz_stop(info->tty);
+		return;
+	}
 
-  if (info->x_char) {           /* XON/XOFF chars */
-    dz_out (info, DZ_TDR, info->x_char);
-    info->icount.tx++;
-    info->x_char = 0;
-    return;
-  }
-
-  /* if nothing to do or stopped or hardware stopped */
-  if ((info->xmit_cnt <= 0) || info->tty->stopped || info->tty->hw_stopped) {
-    dz_stop (info->tty);
-    return;
-  }
-
-  /* if something to do ... (rember the dz has no output fifo so we go one char at a time :-< */
-  tmp = (unsigned short)info->xmit_buf[info->xmit_tail++];
-  dz_out (info, DZ_TDR, tmp);
-  info->xmit_tail = info->xmit_tail & (DZ_XMIT_SIZE - 1);
-  info->icount.tx++;
-
-  if (--info->xmit_cnt < WAKEUP_CHARS)
-    dz_sched_event (info, DZ_EVENT_WRITE_WAKEUP);
-
-
-  /* Are we done */
-  if (info->xmit_cnt <= 0) dz_stop (info->tty);
+	/*
+	 * If something to do ... (rember the dz has no output fifo so we go
+	 * one char at a time :-<
+	 */
+	tmp = (unsigned short) info->xmit_buf[info->xmit_tail++];
+	dz_out(info, DZ_TDR, tmp);
+	info->xmit_tail = info->xmit_tail & (DZ_XMIT_SIZE - 1);
+	info->icount.tx++;
+
+	if (--info->xmit_cnt < WAKEUP_CHARS)
+	dz_sched_event(info, DZ_EVENT_WRITE_WAKEUP);
+
+	/* Are we done */
+	if (info->xmit_cnt <= 0)
+		dz_stop(info->tty);
 }
 
 /*
@@ -351,15 +351,17 @@
  */
 static inline void check_modem_status (struct dz_serial *info)
 {
-  unsigned short status;
+	unsigned short status;
 
-  /* if not ne modem line just return */
-  if (info->line != DZ_MODEM) return;
+	/* if not ne modem line just return */
+	if (info->line != DZ_MODEM)
+		return;
 
-  status = dz_in (info, DZ_MSR);
+	status = dz_in(info, DZ_MSR);
   
-  /* it's easy, since DSR2 is the only bit in the register */
-  if (status) info->icount.dsr++;
+	/* it's easy, since DSR2 is the only bit in the register */
+	if (status)
+		info->icount.dsr++;
 }
 
 /*
@@ -372,17 +374,18 @@
  */
 static void dz_interrupt (int irq, void *dev, struct pt_regs *regs)
 {
-  struct dz_serial *info;
-  unsigned short status;
+	struct dz_serial *info;
+	unsigned short status;
 
-  status = dz_in ((struct dz_serial *)dev, DZ_CSR); /* get the reason why we just got an irq */
-  info = lines[LINE(status)];     /* re-arrange info the proper port */
+	 /* get the reason why we just got an irq */
+	status = dz_in((struct dz_serial *)dev, DZ_CSR);
+	info = lines[LINE(status)];     /* re-arrange info the proper port */
 
-  if (status & DZ_RDONE) 
-      receive_chars (info);          /* the receive function */
+	if (status & DZ_RDONE) 
+		receive_chars(info);	/* the receive function */
 
-  if (status & DZ_TRDY) 
-    transmit_chars (info);
+	if (status & DZ_TRDY) 
+		transmit_chars (info);
 }
 
 /*
@@ -402,21 +405,23 @@
  */
 static void do_serial_bh (void)
 {
-        run_task_queue (&tq_serial);
+	run_task_queue (&tq_serial);
 }
 
 static void do_softint (void *private_data)
 {
-  struct dz_serial *info = (struct dz_serial *)private_data;
-  struct tty_struct *tty = info->tty;
+	struct dz_serial *info = (struct dz_serial *) private_data;
+	struct tty_struct *tty = info->tty;
 
-  if (!tty) return;
+	if (!tty)
+		return;
 
-  if (test_and_clear_bit (DZ_EVENT_WRITE_WAKEUP, &info->event)) {
-    if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
-      (tty->ldisc.write_wakeup) (tty);
-    wake_up_interruptible (&tty->write_wait);
-  }
+	if (test_and_clear_bit(DZ_EVENT_WRITE_WAKEUP, &info->event)) {
+		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+		    tty->ldisc.write_wakeup)
+			(tty->ldisc.write_wakeup) (tty);
+		wake_up_interruptible (&tty->write_wait);
+	}
 }
 
 /*
@@ -431,12 +436,13 @@
  */
 static void do_serial_hangup (void *private_data)
 {
-  struct dz_serial *info = (struct dz_serial *)private_data;
-  struct tty_struct *tty = info->tty;;
+	struct dz_serial *info = (struct dz_serial *) private_data;
+	struct tty_struct *tty = info->tty;;
         
-  if (!tty) return;
+	if (!tty)
+		return;
 
-  tty_hangup (tty);
+	tty_hangup(tty);
 }
 
 /*
@@ -448,57 +454,52 @@
  */
 static int startup (struct dz_serial *info)
 {
-  unsigned long page, flags;
-  unsigned short tmp;
+	unsigned long page, flags;
+	unsigned short tmp;
 
-  if (info->is_initialized) return 0;
+	if (info->is_initialized)
+		return 0;
   
-  save_flags (flags);
-  cli ();
+	save_and_cli(flags);
 
-  if (!info->port) {
-    if (info->tty) set_bit (TTY_IO_ERROR, &info->tty->flags);
-    restore_flags (flags);
-    return -ENODEV;
-  }
-
-  if (!info->xmit_buf) {
-    page = get_free_page (GFP_KERNEL);
-    if (!page) {
-      restore_flags (flags);
-      return -ENOMEM;
-    }
-    info->xmit_buf = (unsigned char *)page;
-  }
-
-  if (info->tty) clear_bit (TTY_IO_ERROR, &info->tty->flags);
-
-  /* enable the interrupt and the scanning */
-  tmp = dz_in (info, DZ_CSR);
-  tmp |= (DZ_RIE | DZ_TIE | DZ_MSE);
-  dz_out (info, DZ_CSR, tmp);
-
-  info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
-
-  /* set up the speed */
-  change_speed (info);
-
-  /* clear the line transmitter buffer 
-     I can't figure out why I need to do this - but
-     its necessary - in order for the console portion
-     and the interrupt portion to live happily side by side.
-  */
-
-  /* clear the line transmitter buffer 
-     I can't figure out why I need to do this - but
-     its necessary - in order for the console portion
-     and the interrupt portion to live happily side by side.
-  */
+	if (!info->port) {
+		if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags);
+		restore_flags(flags);
+		return -ENODEV;
+	}
+
+	if (!info->xmit_buf) {
+		page = get_free_page(GFP_KERNEL);
+		if (!page) {
+			restore_flags (flags);
+		return -ENOMEM;
+		}
+		info->xmit_buf = (unsigned char *)page;
+	}
 
-  info->is_initialized = 1;
+	if (info->tty)
+		clear_bit(TTY_IO_ERROR, &info->tty->flags);
 
-  restore_flags (flags);
-  return 0;
+	/* enable the interrupt and the scanning */
+	tmp = dz_in(info, DZ_CSR);
+	tmp |= (DZ_RIE | DZ_TIE | DZ_MSE);
+	dz_out(info, DZ_CSR, tmp);
+
+	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
+
+	change_speed(info);			/* set up the speed */
+
+	/*
+	 * Clear the line transmitter buffer I can't figure out why I need to
+	 * do this - but its necessary - in order for the console portion and
+	 * the interrupt portion to live happily side by side.
+	 */
+
+	info->is_initialized = 1;
+
+	restore_flags(flags);
+
+	return 0;
 }
 
 /* 
@@ -511,38 +512,38 @@
  */
 static void shutdown (struct dz_serial *info)
 {
-  unsigned long flags;
-  unsigned short tmp;
+	unsigned long flags;
+	unsigned short tmp;
 
-  if (!info->is_initialized) return;
+	if (!info->is_initialized)
+		return;
 
-  save_flags (flags);
-  cli ();
+	save_and_cli(flags);
 
-  dz_stop (info->tty);
+	dz_stop (info->tty);
 
+	info->cflags &= ~DZ_CREAD;	/* turn off receive enable flag */
+	dz_out(info, DZ_LPR, info->cflags);
 
+	if (info->xmit_buf) {               /* free Tx buffer */
+		free_page((unsigned long)info->xmit_buf);
+		info->xmit_buf = 0;
+	}
 
-  info->cflags &= ~DZ_CREAD;          /* turn off receive enable flag */
-  dz_out (info, DZ_LPR, info->cflags);
-
-  if (info->xmit_buf) {               /* free Tx buffer */
-    free_page ((unsigned long)info->xmit_buf);
-    info->xmit_buf = 0;
-  }
+	if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
+		tmp = dz_in(info, DZ_TCR);
+		if (tmp & DZ_MODEM_DTR) {
+			tmp &= ~DZ_MODEM_DTR;
+			dz_out(info, DZ_TCR, tmp);
+		}
+	}
 
-  if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
-    tmp = dz_in (info, DZ_TCR);
-    if (tmp & DZ_MODEM_DTR) {
-      tmp &= ~DZ_MODEM_DTR;
-      dz_out (info, DZ_TCR, tmp);
-    }
-  }
+	if (info->tty)
+		set_bit (TTY_IO_ERROR, &info->tty->flags);
 
-  if (info->tty) set_bit (TTY_IO_ERROR, &info->tty->flags);
+	info->is_initialized = 0;
 
-  info->is_initialized = 0;
-  restore_flags (flags);
+	restore_flags (flags);
 }
 
 /* 
@@ -554,65 +555,104 @@
  */
 static void change_speed (struct dz_serial *info)
 {
-  unsigned long flags;
-  unsigned cflag;
-  int baud;
+	unsigned long flags;
+	unsigned cflag;
+	int baud;
 
-  if (!info->tty || !info->tty->termios) return;
+	if (!info->tty || !info->tty->termios)
+		return;
   
-  save_flags (flags);
-  cli ();
+	save_and_cli(flags);
   
-  info->cflags = info->line;
+	info->cflags = info->line;
 
-  cflag = info->tty->termios->c_cflag;
+	cflag = info->tty->termios->c_cflag;
 
-  switch (cflag & CSIZE) {
-  case CS5: info->cflags |= DZ_CS5; break;
-  case CS6: info->cflags |= DZ_CS6; break;
-  case CS7: info->cflags |= DZ_CS7; break;
-  case CS8: 
-  default:  info->cflags |= DZ_CS8;
-  }
-
-  if (cflag & CSTOPB) info->cflags |= DZ_CSTOPB;
-  if (cflag & PARENB) info->cflags |= DZ_PARENB;
-  if (cflag & PARODD) info->cflags |= DZ_PARODD;
+	switch (cflag & CSIZE) {
+		case CS5:
+			info->cflags |= DZ_CS5;
+			break;
+		case CS6:
+			info->cflags |= DZ_CS6;
+			break;
+		case CS7:
+			info->cflags |= DZ_CS7;
+			break;
+		case CS8: 
+		default:
+			info->cflags |= DZ_CS8;
+	}
+
+	if (cflag & CSTOPB)
+		info->cflags |= DZ_CSTOPB;
+	if (cflag & PARENB)
+		info->cflags |= DZ_PARENB;
+	if (cflag & PARODD)
+		info->cflags |= DZ_PARODD;
   
-  baud = tty_get_baud_rate (info->tty);
-  switch (baud) {
-  case 50  :  info->cflags |= DZ_B50;   break;
-  case 75  :  info->cflags |= DZ_B75;   break;
-  case 110 :  info->cflags |= DZ_B110;  break;
-  case 134 :  info->cflags |= DZ_B134;  break; 
-  case 150 :  info->cflags |= DZ_B150;  break;
-  case 300 :  info->cflags |= DZ_B300;  break; 
-  case 600 :  info->cflags |= DZ_B600;  break;
-  case 1200:  info->cflags |= DZ_B1200; break; 
-  case 1800:  info->cflags |= DZ_B1800; break;
-  case 2000:  info->cflags |= DZ_B2000; break;
-  case 2400:  info->cflags |= DZ_B2400; break;
-  case 3600:  info->cflags |= DZ_B3600; break; 
-  case 4800:  info->cflags |= DZ_B4800; break;
-  case 7200:  info->cflags |= DZ_B7200; break; 
-  case 9600: 
-  default  :  info->cflags |= DZ_B9600; 
-  }
-
-  info->cflags |= DZ_RXENAB;
-  dz_out (info, DZ_LPR, info->cflags);
-
-  /* setup accept flag */
-  info->read_status_mask = DZ_OERR;
-  if (I_INPCK(info->tty))
-   info->read_status_mask |= (DZ_FERR | DZ_PERR); 
+	baud = tty_get_baud_rate(info->tty);
+	switch (baud) {
+	case 50:
+		info->cflags |= DZ_B50;
+		break;
+	case 75:
+		info->cflags |= DZ_B75;
+		break;
+	case 110:
+		info->cflags |= DZ_B110;
+		break;
+	case 134:
+		info->cflags |= DZ_B134;
+		break; 
+	case 150:
+		info->cflags |= DZ_B150;
+		break;
+	case 300:
+		info->cflags |= DZ_B300;
+		break; 
+	case 600:
+		info->cflags |= DZ_B600;
+		break;
+	case 1200:
+		info->cflags |= DZ_B1200;
+		break; 
+	case 1800:
+		info->cflags |= DZ_B1800;
+		break;
+	case 2000:
+		info->cflags |= DZ_B2000;
+		break;
+	case 2400:
+		info->cflags |= DZ_B2400;
+		break;
+	case 3600:
+		info->cflags |= DZ_B3600;
+		break; 
+	case 4800:
+		info->cflags |= DZ_B4800;
+		break;
+	case 7200:
+		info->cflags |= DZ_B7200;
+		break; 
+	case 9600: 
+	default:
+		info->cflags |= DZ_B9600; 
+	}
+
+	info->cflags |= DZ_RXENAB;
+	dz_out(info, DZ_LPR, info->cflags);
+
+	/* setup accept flag */
+	info->read_status_mask = DZ_OERR;
+	if (I_INPCK(info->tty))
+		info->read_status_mask |= (DZ_FERR | DZ_PERR); 
   
-  /* characters to ignore */
-  info->ignore_status_mask = 0;
-  if (I_IGNPAR(info->tty))
-    info->ignore_status_mask |= (DZ_FERR | DZ_PERR);
+	/* characters to ignore */
+	info->ignore_status_mask = 0;
+	if (I_IGNPAR(info->tty))
+		info->ignore_status_mask |= (DZ_FERR | DZ_PERR);
 
-  restore_flags (flags);
+	restore_flags(flags);
 }
 
 /* 
@@ -624,18 +664,16 @@
  */
 static void dz_flush_chars (struct tty_struct *tty)
 {
-  struct dz_serial *info = (struct dz_serial *)tty->driver_data;
-  unsigned long flags;
-
- if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || !info->xmit_buf)
-    return;
+	struct dz_serial *info = (struct dz_serial *)tty->driver_data;
+	unsigned long flags;
 
- save_flags (flags);
- cli ();  
-
- dz_start (info->tty);
-
- restore_flags (flags);
+	if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
+	    !info->xmit_buf)
+		return;
+
+	save_and_cli(flags);
+	dz_start (info->tty);
+	restore_flags(flags);
 }
 
 
@@ -646,83 +684,81 @@
  * main output routine.
  * ------------------------------------------------------------------- 
  */
-static int dz_write (struct tty_struct *tty, int from_user, const unsigned char *buf, int count)
+static int dz_write (struct tty_struct *tty, int from_user,
+                     const unsigned char *buf, int count)
 {
-  struct dz_serial *info = (struct dz_serial *)tty->driver_data;
-  unsigned long flags;
-  int c, ret = 0;
-
-  if (!tty ) return ret;
-  if (!info->xmit_buf) return ret;
-  if (!tmp_buf) tmp_buf = tmp_buffer;
-
-
-
-  if (from_user) {
-
-    down (&tmp_buf_sem);
-    while (1) {
-      c = MIN(count, MIN(DZ_XMIT_SIZE - info->xmit_cnt - 1, DZ_XMIT_SIZE - info->xmit_head));
-      if (c <= 0) break;
-
-      c -= copy_from_user (tmp_buf, buf, c);
-      if (!c) {
-        if (!ret) ret = -EFAULT;
-        break;
-      }
-
-      save_flags (flags);
-      cli ();
-
-      c = MIN(c, MIN(DZ_XMIT_SIZE - info->xmit_cnt - 1, DZ_XMIT_SIZE - info->xmit_head));
-      memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c);
-      info->xmit_head = ((info->xmit_head + c) & (DZ_XMIT_SIZE-1));
-      info->xmit_cnt += c;
-
-      restore_flags(flags);
-
-      buf += c;
-      count -= c;
-      ret += c;
-    }
-    
-    up (&tmp_buf_sem);
-  } else {
-
+	struct dz_serial *info = (struct dz_serial *)tty->driver_data;
+	unsigned long flags;
+	int c, ret = 0;
+
+	if (!tty )
+		return ret;
+	if (!info->xmit_buf)
+		return ret;
+	if (!tmp_buf)
+		tmp_buf = tmp_buffer;
+
+	if (from_user) {
+		down (&tmp_buf_sem);
+		while (1) {
+			c = MIN(count, MIN(DZ_XMIT_SIZE - info->xmit_cnt - 1,
+			                   DZ_XMIT_SIZE - info->xmit_head));
+			if (c <= 0)
+				break;
+
+			c -= copy_from_user (tmp_buf, buf, c);
+			if (!c) {
+				if (!ret)
+					ret = -EFAULT;
+				break;
+			}
+
+			save_and_cli(flags);
+
+			c = MIN(c, MIN(DZ_XMIT_SIZE - info->xmit_cnt - 1,
+			               DZ_XMIT_SIZE - info->xmit_head));
+			memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c);
+			info->xmit_head = ((info->xmit_head + c) &
+					   (DZ_XMIT_SIZE - 1));
+			info->xmit_cnt += c;
+			restore_flags(flags);
+
+			buf += c;
+			count -= c;
+			ret += c;
+		}
+		up(&tmp_buf_sem);
+	} else {
+		while (1) {
+			save_and_cli(flags);
+
+			c = MIN(count, MIN(DZ_XMIT_SIZE - info->xmit_cnt - 1,
+			                   DZ_XMIT_SIZE - info->xmit_head));
+			if (c <= 0) {
+				restore_flags (flags);
+				break;
+			}
+			memcpy(info->xmit_buf + info->xmit_head, buf, c);
+			info->xmit_head = ((info->xmit_head + c) &
+			                   (DZ_XMIT_SIZE-1));
+			info->xmit_cnt += c;
+			restore_flags(flags);
+
+			buf += c;
+			count -= c;
+			ret += c;
+		}
+	}
 
-    while (1) {
-      save_flags (flags);
-      cli ();     
-
-      c = MIN(count, MIN(DZ_XMIT_SIZE - info->xmit_cnt - 1, DZ_XMIT_SIZE - info->xmit_head));
-      if (c <= 0) {
-        restore_flags (flags);
-        break;
-      }
-      memcpy (info->xmit_buf + info->xmit_head, buf, c);
-      info->xmit_head = ((info->xmit_head + c) & (DZ_XMIT_SIZE-1));
-      info->xmit_cnt += c;
-
-      restore_flags (flags);
-
-      buf += c;
-      count -= c;
-      ret += c;
-    }
-  }
-
-
-  if (info->xmit_cnt)
-    {
-      if (!tty->stopped) 
-	{
-	  if (!tty->hw_stopped)
-	    {
-	      dz_start (info->tty);
-	    }
+	if (info->xmit_cnt) {
+		if (!tty->stopped) {
+			if (!tty->hw_stopped) {
+				dz_start (info->tty);
+			}
+		}
 	}
-    }
-  return ret;
+
+	return ret;
 }
 
 /* 
@@ -734,12 +770,14 @@
  */
 static int dz_write_room (struct tty_struct *tty)
 {
-  struct dz_serial *info = (struct dz_serial *)tty->driver_data;
-  int ret;
-                                
-  ret = DZ_XMIT_SIZE - info->xmit_cnt - 1;
-  if (ret < 0) ret = 0;
-  return ret;
+	struct dz_serial *info = (struct dz_serial *)tty->driver_data;
+	int ret;
+
+	ret = DZ_XMIT_SIZE - info->xmit_cnt - 1;
+	if (ret < 0)
+		ret = 0;
+
+	return ret;
 }
 
 /* 
@@ -751,9 +789,9 @@
  */
 static int dz_chars_in_buffer (struct tty_struct *tty)
 {
-  struct dz_serial *info = (struct dz_serial *)tty->driver_data;
+	struct dz_serial *info = (struct dz_serial *)tty->driver_data;
   
-  return info->xmit_cnt;
+	return info->xmit_cnt;
 }
 
 /* 
@@ -765,16 +803,17 @@
  */
 static void dz_flush_buffer (struct tty_struct *tty)
 {
-  struct dz_serial *info = (struct dz_serial *)tty->driver_data;
+	struct dz_serial *info = (struct dz_serial *)tty->driver_data;
                                 
-  cli ();
-  info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
-  sti ();
-
-  wake_up_interruptible (&tty->write_wait);
-
-  if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
-    (tty->ldisc.write_wakeup)(tty);
+	cli();
+	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
+	sti();
+
+	wake_up_interruptible (&tty->write_wait);
+
+	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+	     tty->ldisc.write_wakeup)
+		tty->ldisc.write_wakeup(tty);
 }
 
 /*
@@ -787,31 +826,32 @@
  */
 static void dz_throttle (struct tty_struct *tty)
 {
-  struct dz_serial *info = (struct dz_serial *)tty->driver_data;  
+	struct dz_serial *info = (struct dz_serial *)tty->driver_data;  
 
-  if (I_IXOFF(tty))
-    info->x_char = STOP_CHAR(tty);
+	if (I_IXOFF(tty))
+		info->x_char = STOP_CHAR(tty);
 }
 
 static void dz_unthrottle (struct tty_struct *tty)
 {
-  struct dz_serial *info = (struct dz_serial *)tty->driver_data;  
+	struct dz_serial *info = (struct dz_serial *)tty->driver_data;  
 
-  if (I_IXOFF(tty)) {
-    if (info->x_char)
-      info->x_char = 0;
-    else
-      info->x_char = START_CHAR(tty);
-  }
+	if (I_IXOFF(tty)) {
+		if (info->x_char)
+			info->x_char = 0;
+		else
+			info->x_char = START_CHAR(tty);
+	}
 }
 
 static void dz_send_xchar (struct tty_struct *tty, char ch)
 {
-  struct dz_serial *info = (struct dz_serial *)tty->driver_data;
+	struct dz_serial *info = (struct dz_serial *)tty->driver_data;
 
-  info->x_char = ch;
+	info->x_char = ch;
 
-  if (ch) dz_start (info->tty);
+	if (ch)
+		dz_start(info->tty);
 }
 
 /*
@@ -819,59 +859,62 @@
  * rs_ioctl () and friends
  * ------------------------------------------------------------
  */
-static int get_serial_info (struct dz_serial *info, struct serial_struct *retinfo)
+static int get_serial_info(struct dz_serial *info,
+                           struct serial_struct *retinfo)
 {
-  struct serial_struct tmp;
+	struct serial_struct tmp;
   
-  if (!retinfo)
-    return -EFAULT;
+	if (!retinfo)
+		return -EFAULT;
 
-  memset (&tmp, 0, sizeof(tmp));
+	memset (&tmp, 0, sizeof(tmp));
 
-  tmp.type = info->type;
-  tmp.line = info->line;
-  tmp.port = info->port;
-  tmp.irq = SERIAL;
-  tmp.flags = info->flags;
-  tmp.baud_base = info->baud_base;
-  tmp.close_delay = info->close_delay;
-  tmp.closing_wait = info->closing_wait;
-  
-  return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0;
+	tmp.type = info->type;
+	tmp.line = info->line;
+	tmp.port = info->port;
+	tmp.irq = SERIAL;
+	tmp.flags = info->flags;
+	tmp.baud_base = info->baud_base;
+	tmp.close_delay = info->close_delay;
+	tmp.closing_wait = info->closing_wait;
+
+	return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0;
 }
 
-static int set_serial_info (struct dz_serial *info, struct serial_struct *new_info)
+static int set_serial_info (struct dz_serial *info,
+                            struct serial_struct *new_info)
 {
-  struct serial_struct new_serial;
-  struct dz_serial old_info;
-  int retval = 0;
+	struct serial_struct new_serial;
+	struct dz_serial old_info;
+	int retval = 0;
 
-  if (!new_info)
-    return -EFAULT;
+	if (!new_info)
+		return -EFAULT;
 
-  if(copy_from_user (&new_serial, new_info, sizeof(new_serial)))
-    return -EFAULT;
-    
-  old_info = *info;
+	if (copy_from_user(&new_serial, new_info, sizeof(new_serial)))
+		return -EFAULT;
 
-  if (!capable(CAP_SYS_ADMIN))
-    return -EPERM;
+	old_info = *info;
 
-  if (info->count > 1)
-    return -EBUSY;
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
 
-  /*
-   * OK, past this point, all the error checking has been done.
-   * At this point, we start making changes.....
-   */
-  
-  info->baud_base = new_serial.baud_base;
-  info->type = new_serial.type;
-  info->close_delay = new_serial.close_delay;
-  info->closing_wait = new_serial.closing_wait;
+	if (info->count > 1)
+		return -EBUSY;
+
+	/*
+	 * OK, past this point, all the error checking has been done.
+	 * At this point, we start making changes.....
+	 */
 
-  retval = startup (info);
-  return retval;
+	info->baud_base = new_serial.baud_base;
+	info->type = new_serial.type;
+	info->close_delay = new_serial.close_delay;
+	info->closing_wait = new_serial.closing_wait;
+
+	retval = startup(info);
+
+	return retval;
 }
 
 /*
@@ -886,9 +929,9 @@
  */
 static int get_lsr_info (struct dz_serial *info, unsigned int *value)
 {
-  unsigned short status = dz_in (info, DZ_LPR);
+	unsigned short status = dz_in (info, DZ_LPR);
 
-  return put_user (status, value);
+	return put_user (status, value);
 }
 
 /*
@@ -896,106 +939,112 @@
  */
 static void send_break (struct dz_serial *info, int duration)
 {
-  unsigned long flags;
-  unsigned short tmp, mask;
-
-  if (!info->port)
-    return;
-
-  mask = 1 << info->line;
-  tmp = dz_in (info, DZ_TCR);
-  tmp |= mask;
+	unsigned long flags;
+	unsigned short tmp, mask;
 
-  current->state = TASK_INTERRUPTIBLE;
+	if (!info->port)
+		return;
 
-  save_flags (flags);
-  cli();
-  
-  dz_out (info, DZ_TCR, tmp);
-  
-  schedule_timeout(duration);
-  
-  tmp &= ~mask;
-  dz_out (info, DZ_TCR, tmp);
-  
-  restore_flags (flags);
-}
-
-static int dz_ioctl (struct tty_struct *tty, struct file *file,
-		     unsigned int cmd, unsigned long arg)
-{
-  struct dz_serial * info = (struct dz_serial *)tty->driver_data;
-  int retval;
+	mask = 1 << info->line;
+	tmp = dz_in (info, DZ_TCR);
+	tmp |= mask;
+
+	current->state = TASK_INTERRUPTIBLE;
+
+	save_and_cli(flags);
+	dz_out(info, DZ_TCR, tmp);
+	schedule_timeout(duration);
+	tmp &= ~mask;
+	dz_out(info, DZ_TCR, tmp);
+	restore_flags(flags);
+}
+
+static int dz_ioctl(struct tty_struct *tty, struct file *file,
+                    unsigned int cmd, unsigned long arg)
+{
+	int error;
+	struct dz_serial * info = (struct dz_serial *)tty->driver_data;
+	int retval;
+
+	if (cmd != TIOCGSERIAL && cmd != TIOCSSERIAL &&
+	    cmd != TIOCSERCONFIG && cmd != TIOCSERGWILD  &&
+	    cmd != TIOCSERSWILD && cmd != TIOCSERGSTRUCT) {
+		if (tty->flags & (1 << TTY_IO_ERROR))
+			return -EIO;
+	}
 
-  if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
-      (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD)  &&
-      (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT)) {
-    if (tty->flags & (1 << TTY_IO_ERROR))
-      return -EIO;
-  }
-
-  switch (cmd) {
-  case TCSBRK:    /* SVID version: non-zero arg --> no break */
-    retval = tty_check_change (tty);
-    if (retval)
-      return retval;
-    tty_wait_until_sent (tty, 0);
-    if (!arg)
-      send_break (info, HZ/4); /* 1/4 second */
-    return 0;
-
-  case TCSBRKP:   /* support for POSIX tcsendbreak() */
-    retval = tty_check_change (tty);
-    if (retval)
-      return retval;
-    tty_wait_until_sent (tty, 0);
-    send_break (info, arg ? arg*(HZ/10) : HZ/4);
-    return 0;
-
-  case TIOCGSOFTCAR:
-    return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long *)arg);
-
-  case TIOCSSOFTCAR:
-    if (get_user (arg, (unsigned long *)arg))
-      return -EFAULT;
-    tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) | (arg ? CLOCAL : 0));
-    return 0;
-
-  case TIOCGSERIAL:
-    return get_serial_info (info, (struct serial_struct *)arg);
-
-  case TIOCSSERIAL:
-    return set_serial_info (info, (struct serial_struct *) arg);
-
-  case TIOCSERGETLSR: /* Get line status register */
-    return get_lsr_info (info, (unsigned int *)arg);
-
-  case TIOCSERGSTRUCT:
-    return copy_to_user((struct dz_serial *)arg, info,
-		        sizeof(struct dz_serial)) ? -EFAULT : 0;
-    
-  default:
-    return -ENOIOCTLCMD;
-  }
+	switch (cmd) {
+	case TCSBRK:		/* SVID version: non-zero arg --> no break */
+		retval = tty_check_change(tty);
+		if (retval)
+			return retval;
+		tty_wait_until_sent(tty, 0);
+		if (!arg)
+			send_break(info, HZ/4); /* 1/4 second */
+		return 0;
+
+	case TCSBRKP:		/* support for POSIX tcsendbreak() */
+		retval = tty_check_change(tty);
+		if (retval)
+			return retval;
+		tty_wait_until_sent(tty, 0);
+		send_break(info, arg ? arg*(HZ/10) : HZ/4);
+		return 0;
+
+	case TIOCGSOFTCAR:
+		error = verify_area (VERIFY_WRITE, (void *)arg, sizeof(long));
+		if (error)
+			return error;
+		put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long *)arg);
+		return 0;
+
+	case TIOCSSOFTCAR:
+		if (get_user (arg, (unsigned long *)arg))
+			return -EFAULT;
+
+		tty->termios->c_cflag = (tty->termios->c_cflag & ~CLOCAL) |
+		                        (arg ? CLOCAL : 0);
+		return 0;
+
+	case TIOCGSERIAL:
+		error = verify_area(VERIFY_WRITE, (void *)arg,
+		                    sizeof(struct serial_struct));
+		if (error)
+			return error;
+		return get_serial_info(info, (struct serial_struct *)arg);
+
+	case TIOCSSERIAL:
+		return set_serial_info(info, (struct serial_struct *) arg);
+
+	case TIOCSERGETLSR:		/* Get line status register */
+		return get_lsr_info (info, (unsigned int *)arg);
+
+	case TIOCSERGSTRUCT:
+		return copy_to_user((struct dz_serial *)arg, info,
+		                    sizeof(struct dz_serial)) ? -EFAULT : 0;
+ 
+	default:
+		return -ENOIOCTLCMD;
+	}
 
-  return 0;
+	return 0;
 }
 
 static void dz_set_termios (struct tty_struct *tty,
 			    struct termios *old_termios)
 {
-  struct dz_serial *info = (struct dz_serial *)tty->driver_data;
+	struct dz_serial *info = (struct dz_serial *)tty->driver_data;
 
-  if (tty->termios->c_cflag == old_termios->c_cflag)
-    return;
+	if (tty->termios->c_cflag == old_termios->c_cflag)
+		return;
 
-  change_speed (info);
+	change_speed (info);
 
-  if ((old_termios->c_cflag & CRTSCTS) &&
-      !(tty->termios->c_cflag & CRTSCTS)) {
-    tty->hw_stopped = 0;
-    dz_start (tty);
-  }
+	if ((old_termios->c_cflag & CRTSCTS) &&
+	    !(tty->termios->c_cflag & CRTSCTS)) {
+		tty->hw_stopped = 0;
+		dz_start(tty);
+	}
 }
 
 /*
@@ -1007,97 +1056,95 @@
  * the transmit enable and receive enable flags.
  * ------------------------------------------------------------
  */
-static void dz_close (struct tty_struct *tty, struct file *filp)
+static void dz_close(struct tty_struct *tty, struct file *filp)
 {
-  struct dz_serial * info = (struct dz_serial *)tty->driver_data;
-  unsigned long flags;
+	struct dz_serial * info = (struct dz_serial *)tty->driver_data;
+	unsigned long flags;
 
-  if (!info) return;
-        
-  save_flags (flags); 
-  cli();
-        
-  if (tty_hung_up_p (filp)) {
-    restore_flags (flags);
-    return;
-  }
-
-  if ((tty->count == 1) && (info->count != 1)) {
-    /*
-     * Uh, oh.  tty->count is 1, which means that the tty
-     * structure will be freed.  Info->count should always
-     * be one in these conditions.  If it's greater than
-     * one, we've got real problems, since it means the
-     * serial port won't be shutdown.
-     */
-    printk("dz_close: bad serial port count; tty->count is 1, "
-                       "info->count is %d\n", info->count);
-                info->count = 1;
-  }
-
-  if (--info->count < 0) {
-    printk("ds_close: bad serial port count for ttys%d: %d\n",
-	   info->line, info->count);
-    info->count = 0;
-  }
-
-  if (info->count) {
-    restore_flags (flags);
-    return;
-  }
-  info->flags |= DZ_CLOSING;
-  /*
-   * Save the termios structure, since this port may have
-   * separate termios for callout and dialin.
-   */
-  if (info->flags & DZ_NORMAL_ACTIVE)
-    info->normal_termios = *tty->termios;
-  if (info->flags & DZ_CALLOUT_ACTIVE)
-    info->callout_termios = *tty->termios;
-  /*
-   * Now we wait for the transmit buffer to clear; and we notify 
-   * the line discipline to only process XON/XOFF characters.
-   */
-  tty->closing = 1;
-
-  if (info->closing_wait != DZ_CLOSING_WAIT_NONE)
-    tty_wait_until_sent (tty, info->closing_wait);
-
-  /*
-   * At this point we stop accepting input.  To do this, we
-   * disable the receive line status interrupts.
-   */
-
-  shutdown (info);
-
-  if (tty->driver.flush_buffer)
-    tty->driver.flush_buffer (tty);
-  if (tty->ldisc.flush_buffer)
-    tty->ldisc.flush_buffer (tty);
-  tty->closing = 0;
-  info->event = 0;
-  info->tty = 0;
-
-  if (tty->ldisc.num != ldiscs[N_TTY].num) {
-    if (tty->ldisc.close)
-      (tty->ldisc.close)(tty);
-    tty->ldisc = ldiscs[N_TTY];
-    tty->termios->c_line = N_TTY;
-    if (tty->ldisc.open)
-      (tty->ldisc.open)(tty);
-  }
-  if (info->blocked_open) {
-    if (info->close_delay) {
-      current->state = TASK_INTERRUPTIBLE;
-      schedule_timeout(info->close_delay);
-    }
-    wake_up_interruptible (&info->open_wait);
-  }
+	if (!info)
+		return;
+ 
+	save_and_cli(flags); 
+
+	if (tty_hung_up_p(filp)) {
+		restore_flags(flags);
+		return;
+	}
 
-  info->flags &= ~(DZ_NORMAL_ACTIVE | DZ_CALLOUT_ACTIVE | DZ_CLOSING);
-  wake_up_interruptible (&info->close_wait);
+	if ((tty->count == 1) && (info->count != 1)) {
+		/*
+		 * Uh, oh.  tty->count is 1, which means that the tty structure
+		 * will be freed.  Info->count should always be one in these
+		 * conditions.  If it's greater than one, we've got real
+		 * problems, since it means the serial port won't be shutdown.
+		 */
+		printk("dz_close: bad serial port count; tty->count is 1, "
+		       "info->count is %d\n", info->count);
+		info->count = 1;
+	}
 
-  restore_flags (flags);
+	if (--info->count < 0) {
+		printk("ds_close: bad serial port count for ttyS%02d: %d\n",
+		       info->line, info->count);
+		info->count = 0;
+	}
+
+	if (info->count) {
+		restore_flags(flags);
+		return;
+	}
+	info->flags |= DZ_CLOSING;
+	/*
+	 * Save the termios structure, since this port may have
+	 * separate termios for callout and dialin.
+	 */
+	if (info->flags & DZ_NORMAL_ACTIVE)
+		info->normal_termios = *tty->termios;
+	if (info->flags & DZ_CALLOUT_ACTIVE)
+		info->callout_termios = *tty->termios;
+	/*
+	 * Now we wait for the transmit buffer to clear; and we notify the line
+	 * discipline to only process XON/XOFF characters.
+	 */
+	tty->closing = 1;
+
+	if (info->closing_wait != DZ_CLOSING_WAIT_NONE)
+		tty_wait_until_sent(tty, info->closing_wait);
+
+	/*
+	 * At this point we stop accepting input.  To do this, we disable the
+	 * receive line status interrupts.
+	 */
+	shutdown(info);
+
+	if (tty->driver.flush_buffer)
+		tty->driver.flush_buffer (tty);
+	if (tty->ldisc.flush_buffer)
+		tty->ldisc.flush_buffer (tty);
+	tty->closing = 0;
+	info->event = 0;
+	info->tty = 0;
+
+	if (tty->ldisc.num != ldiscs[N_TTY].num) {
+		if (tty->ldisc.close)
+			tty->ldisc.close(tty);
+		tty->ldisc = ldiscs[N_TTY];
+		tty->termios->c_line = N_TTY;
+		if (tty->ldisc.open)
+			tty->ldisc.open(tty);
+	}
+	if (info->blocked_open) {
+		if (info->close_delay) {
+			current->state = TASK_INTERRUPTIBLE;
+			schedule_timeout(info->close_delay);
+		}
+		wake_up_interruptible(&info->open_wait);
+	}
+
+	info->flags &= ~(DZ_NORMAL_ACTIVE | DZ_CALLOUT_ACTIVE | DZ_CLOSING);
+	wake_up_interruptible(&info->close_wait);
+
+	restore_flags(flags);
 }
 
 /*
@@ -1105,15 +1152,15 @@
  */
 static void dz_hangup (struct tty_struct *tty)
 {
-  struct dz_serial *info = (struct dz_serial *)tty->driver_data;
+	struct dz_serial *info = (struct dz_serial *) tty->driver_data;
   
-  dz_flush_buffer (tty);
-  shutdown (info);
-  info->event = 0;
-  info->count = 0;
-  info->flags &= ~(DZ_NORMAL_ACTIVE | DZ_CALLOUT_ACTIVE);
-  info->tty = 0;
-  wake_up_interruptible (&info->open_wait);
+	dz_flush_buffer(tty);
+	shutdown(info);
+	info->event = 0;
+	info->count = 0;
+	info->flags &= ~(DZ_NORMAL_ACTIVE | DZ_CALLOUT_ACTIVE);
+	info->tty = 0;
+	wake_up_interruptible(&info->open_wait);
 }
 
 /*
@@ -1121,101 +1168,103 @@
  * rs_open() and friends
  * ------------------------------------------------------------
  */
-static int block_til_ready (struct tty_struct *tty, struct file *filp, struct dz_serial *info)
+static int block_til_ready(struct tty_struct *tty, struct file *filp,
+                           struct dz_serial *info)
 {
-  DECLARE_WAITQUEUE(wait, current); 
-  int retval;
-  int do_clocal = 0;
-
-  /*
-   * If the device is in the middle of being closed, then block
-   * until it's done, and then try again.
-   */
-  if (info->flags & DZ_CLOSING) {
-    interruptible_sleep_on (&info->close_wait);
-    return -EAGAIN;
-  }
-
-  /*
-   * If this is a callout device, then just make sure the normal
-   * device isn't being used.
-   */
-  if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
-    if (info->flags & DZ_NORMAL_ACTIVE)
-      return -EBUSY;
+	DECLARE_WAITQUEUE(wait, current); 
+	int retval;
+	int do_clocal = 0;
+
+	/*
+	 * If the device is in the middle of being closed, then block
+	 * until it's done, and then try again.
+	 */
+	if (info->flags & DZ_CLOSING) {
+		interruptible_sleep_on(&info->close_wait);
+		return -EAGAIN;
+	}
+
+	/*
+	 * If this is a callout device, then just make sure the normal
+	 * device isn't being used.
+	 */
+	if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
+		if (info->flags & DZ_NORMAL_ACTIVE)
+			return -EBUSY;
     
-    if ((info->flags & DZ_CALLOUT_ACTIVE) &&
-	(info->flags & DZ_SESSION_LOCKOUT) &&
-	(info->session != current->session))
-      return -EBUSY;
+		if ((info->flags & DZ_CALLOUT_ACTIVE) &&
+		    (info->flags & DZ_SESSION_LOCKOUT) &&
+		    (info->session != current->session))
+			return -EBUSY;
     
-    if ((info->flags & DZ_CALLOUT_ACTIVE) &&
-	(info->flags & DZ_PGRP_LOCKOUT) &&
-	(info->pgrp != current->pgrp))
-      return -EBUSY;
-    info->flags |= DZ_CALLOUT_ACTIVE;
-    return 0;
-  }
-
-  /*
-   * If non-blocking mode is set, or the port is not enabled,
-   * then make the check up front and then exit.
-   */
-  if ((filp->f_flags & O_NONBLOCK) ||
-      (tty->flags & (1 << TTY_IO_ERROR))) {
-    if (info->flags & DZ_CALLOUT_ACTIVE)
-      return -EBUSY;
-    info->flags |= DZ_NORMAL_ACTIVE;
-    return 0;
-  }
-
-  if (info->flags & DZ_CALLOUT_ACTIVE) {
-    if (info->normal_termios.c_cflag & CLOCAL)
-      do_clocal = 1;
-  } else {
-    if (tty->termios->c_cflag & CLOCAL)
-      do_clocal = 1;
-  }
-
-  /*
-   * Block waiting for the carrier detect and the line to become
-   * free (i.e., not in use by the callout).  While we are in
-   * this loop, info->count is dropped by one, so that
-   * dz_close() knows when to free things.  We restore it upon
-   * exit, either normal or abnormal.
-   */
-  retval = 0;
-  add_wait_queue (&info->open_wait, &wait);
-
-  info->count--;
-  info->blocked_open++;
-  while (1) {
-    set_current_state(TASK_INTERRUPTIBLE);
-    if (tty_hung_up_p (filp) || !(info->is_initialized)) {
-      retval = -EAGAIN;
-      break;
-    }
-    if (!(info->flags & DZ_CALLOUT_ACTIVE) &&
-	!(info->flags & DZ_CLOSING) && do_clocal)
-      break;
-    if (signal_pending (current)) {
-      retval = -ERESTARTSYS;
-      break;
-    }
-    schedule();
-  }
+		if ((info->flags & DZ_CALLOUT_ACTIVE) &&
+		    (info->flags & DZ_PGRP_LOCKOUT) &&
+		    (info->pgrp != current->pgrp))
+			return -EBUSY;
+
+		info->flags |= DZ_CALLOUT_ACTIVE;
+		return 0;
+	}
+
+	/*
+	 * If non-blocking mode is set, or the port is not enabled, then make
+	 * the check up front and then exit.
+	 */
+	if ((filp->f_flags & O_NONBLOCK) ||
+	    (tty->flags & (1 << TTY_IO_ERROR))) {
+		if (info->flags & DZ_CALLOUT_ACTIVE)
+			return -EBUSY;
+		info->flags |= DZ_NORMAL_ACTIVE;
+
+		return 0;
+	}
+
+	if (info->flags & DZ_CALLOUT_ACTIVE) {
+		if (info->normal_termios.c_cflag & CLOCAL)
+			do_clocal = 1;
+	} else {
+		if (tty->termios->c_cflag & CLOCAL)
+		do_clocal = 1;
+	}
+
+	/*
+	 * Block waiting for the carrier detect and the line to become free
+	 * (i.e., not in use by the callout).  While we are in this loop,
+	 * info->count is dropped by one, so that dz_close() knows when to free
+	 * things.  We restore it upon exit, either normal or abnormal.
+	 */
+	retval = 0;
+	add_wait_queue(&info->open_wait, &wait);
+
+	info->count--;
+	info->blocked_open++;
+	while (1) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		if (tty_hung_up_p (filp) || !(info->is_initialized)) {
+			retval = -EAGAIN;
+			break;
+		}
+		if (!(info->flags & DZ_CALLOUT_ACTIVE) &&
+		    !(info->flags & DZ_CLOSING) && do_clocal)
+			break;
+		if (signal_pending(current)) {
+			retval = -ERESTARTSYS;
+			break;
+		}
+		schedule();
+	}
 		
-  current->state = TASK_RUNNING;
-  remove_wait_queue (&info->open_wait, &wait);
-  if (!tty_hung_up_p(filp))
-    info->count++;
-  info->blocked_open--;
-
-  if (retval)
-    return retval;
-  info->flags |= DZ_NORMAL_ACTIVE;
-  return 0;
-}       
+	current->state = TASK_RUNNING;
+	remove_wait_queue (&info->open_wait, &wait);
+	if (!tty_hung_up_p(filp))
+		info->count++;
+	info->blocked_open--;
+
+	if (retval)
+		return retval;
+	info->flags |= DZ_NORMAL_ACTIVE;
+	return 0;
+}
 
 /*
  * This routine is called whenever a serial port is opened.  It
@@ -1224,201 +1273,220 @@
  */
 static int dz_open (struct tty_struct *tty, struct file *filp)
 {
-  struct dz_serial *info;
-  int retval, line;
-
-  line = MINOR(tty->device) - tty->driver.minor_start;
-
-  /* The dz lines for the mouse/keyboard must be
-   * opened using their respective drivers.
-   */
-  if ((line < 0) || (line >= DZ_NB_PORT))
-    return -ENODEV;
+	struct dz_serial *info;
+	int retval, line;
 
-  if ((line == DZ_KEYBOARD) || (line == DZ_MOUSE))
-    return -ENODEV;
+	line = MINOR(tty->device) - tty->driver.minor_start;
 
-  info = lines[line];
-  info->count++;
-
-  tty->driver_data = info;
-  info->tty = tty;
-
-  /*
-   * Start up serial port
-   */
-  retval = startup (info);
-  if (retval)
-    return retval;
+	/*
+	 * The dz lines for the mouse/keyboard must be opened using their
+	 * respective drivers.
+	 */
+	if ((line < 0) || (line >= DZ_NB_PORT))
+		return -ENODEV;
 
+	if ((line == DZ_KEYBOARD) || (line == DZ_MOUSE))
+		return -ENODEV;
 
+	info = lines[line];
+	info->count++;
 
-  retval = block_til_ready (tty, filp, info);
-  if (retval)
-    return retval;
+	tty->driver_data = info;
+	info->tty = tty;
 
-  if ((info->count == 1) && (info->flags & DZ_SPLIT_TERMIOS)) {
-    if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
-      *tty->termios = info->normal_termios;
-    else 
-      *tty->termios = info->callout_termios;
-    change_speed (info);
+	/*
+	 * Start up serial port
+	 */
+	retval = startup (info);
+	if (retval)
+		return retval;
+
+	retval = block_til_ready (tty, filp, info);
+	if (retval)
+		return retval;
+
+	if ((info->count == 1) && (info->flags & DZ_SPLIT_TERMIOS)) {
+		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
+			*tty->termios = info->normal_termios;
+		else 
+			*tty->termios = info->callout_termios;
+		change_speed(info);
+	}
 
-  }
+	info->session = current->session;
+	info->pgrp = current->pgrp;
 
-  info->session = current->session;
-  info->pgrp = current->pgrp;
-  return 0;
+	return 0;
 }
 
 static void show_serial_version (void)
 {
-  printk("%s%s\n", dz_name, dz_version);
+	printk("%s%s\n", dz_name, dz_version);
 }
 
 
 int __init dz_init(void)
 {
-  int i;
-  unsigned long flags;
-  struct dz_serial *info;
-
-  /* Setup base handler, and timer table. */
-  init_bh (SERIAL_BH, do_serial_bh);
-
-  show_serial_version ();
-
-  memset(&serial_driver, 0, sizeof(struct tty_driver));
-  serial_driver.magic = TTY_DRIVER_MAGIC;
-  serial_driver.name = "ttyS";
-  serial_driver.major = TTY_MAJOR;
-  serial_driver.minor_start = 64;
-  serial_driver.num = DZ_NB_PORT;
-  serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
-  serial_driver.subtype = SERIAL_TYPE_NORMAL;
-  serial_driver.init_termios = tty_std_termios;
-
-  serial_driver.init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-  serial_driver.flags = TTY_DRIVER_REAL_RAW;
-  serial_driver.refcount = &serial_refcount;
-  serial_driver.table = serial_table;
-  serial_driver.termios = serial_termios;
-  serial_driver.termios_locked = serial_termios_locked;
-
-  serial_driver.open = dz_open;
-  serial_driver.close = dz_close;
-  serial_driver.write = dz_write;
-  serial_driver.flush_chars = dz_flush_chars;
-  serial_driver.write_room = dz_write_room;
-  serial_driver.chars_in_buffer = dz_chars_in_buffer;
-  serial_driver.flush_buffer = dz_flush_buffer;
-  serial_driver.ioctl = dz_ioctl;
-  serial_driver.throttle = dz_throttle;
-  serial_driver.unthrottle = dz_unthrottle;
-  serial_driver.send_xchar = dz_send_xchar;
-  serial_driver.set_termios = dz_set_termios;
-  serial_driver.stop = dz_stop;
-  serial_driver.start = dz_start;
-  serial_driver.hangup = dz_hangup;
-
-  /*
-   * The callout device is just like normal device except for
-   * major number and the subtype code.
-   */
-  callout_driver = serial_driver;
-  callout_driver.name = "cua";
-  callout_driver.major = TTYAUX_MAJOR;
-  callout_driver.subtype = SERIAL_TYPE_CALLOUT;
-
-  if (tty_register_driver (&serial_driver))
-    panic("Couldn't register serial driver\n");
-  if (tty_register_driver (&callout_driver))
-    panic("Couldn't register callout driver\n");
-  save_flags(flags); cli();
- 
-  for (i=0; i < DZ_NB_PORT;  i++)  
-    {
-      info = &multi[i]; 
-      lines[i] = info;
-    info->magic = SERIAL_MAGIC;
-
-      if ((mips_machtype == MACH_DS23100) || (mips_machtype == MACH_DS5100)) 
-      info->port = (unsigned long) KN01_DZ11_BASE;
-      else 
-      info->port = (unsigned long) KN02_DZ11_BASE;
-
-    info->line = i;
-    info->tty = 0;
-    info->close_delay = 50;
-    info->closing_wait = 3000;
-    info->x_char = 0;
-    info->event = 0;
-    info->count = 0;
-    info->blocked_open = 0;
-    info->tqueue.routine = do_softint;
-    info->tqueue.data = info;
-    info->tqueue_hangup.routine = do_serial_hangup;
-    info->tqueue_hangup.data = info;
-    info->callout_termios = callout_driver.init_termios;
-    info->normal_termios = serial_driver.init_termios;
-    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. */
-    if (! info->port)
-      return 0;
+	int i, flags;
+	struct dz_serial *info;
 
-    printk("ttyS%02d at 0x%04x (irq = %d)\n", info->line, info->port, SERIAL);
-  }
+	/* Setup base handler, and timer table. */
+	init_bh(SERIAL_BH, do_serial_bh);
 
-  /* reset the chip */
+	show_serial_version();
+
+	memset(&serial_driver, 0, sizeof(struct tty_driver));
+	serial_driver.magic = TTY_DRIVER_MAGIC;
+#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))
+	serial_driver.name = "ttyS";
+#else
+	serial_driver.name = "tts/%d";
+#endif
+	serial_driver.major = TTY_MAJOR;
+	serial_driver.minor_start = 64;
+	serial_driver.num = DZ_NB_PORT;
+	serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
+	serial_driver.subtype = SERIAL_TYPE_NORMAL;
+	serial_driver.init_termios = tty_std_termios;
+
+	serial_driver.init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL |
+	                                     CLOCAL;
+	serial_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
+	serial_driver.refcount = &serial_refcount;
+	serial_driver.table = serial_table;
+	serial_driver.termios = serial_termios;
+	serial_driver.termios_locked = serial_termios_locked;
+
+	serial_driver.open = dz_open;
+	serial_driver.close = dz_close;
+	serial_driver.write = dz_write;
+	serial_driver.flush_chars = dz_flush_chars;
+	serial_driver.write_room = dz_write_room;
+	serial_driver.chars_in_buffer = dz_chars_in_buffer;
+	serial_driver.flush_buffer = dz_flush_buffer;
+	serial_driver.ioctl = dz_ioctl;
+	serial_driver.throttle = dz_throttle;
+	serial_driver.unthrottle = dz_unthrottle;
+	serial_driver.send_xchar = dz_send_xchar;
+	serial_driver.set_termios = dz_set_termios;
+	serial_driver.stop = dz_stop;
+	serial_driver.start = dz_start;
+	serial_driver.hangup = dz_hangup;
+
+	/*
+	 * The callout device is just like normal device except for major
+	 * number and the subtype code.
+	 */
+	callout_driver = serial_driver;
+#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))
+	callout_driver.name = "cua";
+#else
+	callout_driver.name = "cua/%d";
+#endif
+	callout_driver.major = TTYAUX_MAJOR;
+	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
+
+	if (tty_register_driver (&serial_driver))
+		panic("Couldn't register serial driver\n");
+	if (tty_register_driver (&callout_driver))
+		panic("Couldn't register callout driver\n");
+
+	save_flags(flags); cli();
+	for (i=0; i < DZ_NB_PORT;  i++) {
+		info = &multi[i]; 
+		lines[i] = info;
+		info->magic = SERIAL_MAGIC;
+
+		if ((mips_machtype == MACH_DS23100) ||
+		    (mips_machtype == MACH_DS5100)) 
+			info->port = (unsigned long) KN01_DZ11_BASE;
+		else 
+			info->port = (unsigned long) KN02_DZ11_BASE;
+
+		info->line = i;
+		info->tty = 0;
+		info->close_delay = 50;
+		info->closing_wait = 3000;
+		info->x_char = 0;
+		info->event = 0;
+		info->count = 0;
+		info->blocked_open = 0;
+		info->tqueue.routine = do_softint;
+		info->tqueue.data = info;
+		info->tqueue_hangup.routine = do_serial_hangup;
+		info->tqueue_hangup.data = info;
+		info->callout_termios = callout_driver.init_termios;
+		info->normal_termios = serial_driver.init_termios;
+		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.
+		 */
+		if (! info->port)
+			return 0;
+
+		printk("ttyS%02d at 0x%08x (irq = %d)\n", info->line,
+		       info->port, SERIAL);
+
+		tty_register_devfs(&serial_driver, 0,
+		                   serial_driver.minor_start + info->line);
+		tty_register_devfs(&callout_driver, 0,
+		                   callout_driver.minor_start + info->line);
+	}
+
+	/* Reset the chip */
 #ifndef CONFIG_SERIAL_CONSOLE
-  dz_out(info, DZ_CSR, DZ_CLR);
-  while ((tmp = dz_in(info,DZ_CSR)) & DZ_CLR) ;
-  wbflush();
+	{
+		int tmp;
+		dz_out(info, DZ_CSR, DZ_CLR);
+		while ((tmp = dz_in(info,DZ_CSR)) & DZ_CLR);
+		wbflush();
   
-  /* enable scanning */
-   dz_out(info, DZ_CSR, DZ_MSE); 
+		/* Enable scanning */
+		dz_out(info, DZ_CSR, DZ_MSE); 
+	}
 #endif
   
-  /* order matters here... the trick is that flags
-     is updated... in request_irq - to immediatedly obliterate
-     it is unwise. */
-  restore_flags(flags);
- 
+	/*
+	 * Order matters here... the trick is that flags is updated... in
+	 * request_irq - to immediatedly obliterate it is unwise.
+	 */
+	restore_flags(flags);
 
-  if (request_irq (SERIAL, dz_interrupt, SA_INTERRUPT, "DZ", lines[0]))
-    panic ("Unable to register DZ interrupt\n");
+	if (request_irq(SERIAL, dz_interrupt, SA_INTERRUPT, "DZ", lines[0]))
+		panic("Unable to register DZ interrupt\n");
  
-  return 0;
+	return 0;
 }
 
 #ifdef CONFIG_SERIAL_CONSOLE
 static void dz_console_put_char (unsigned char ch)
 {
-  unsigned long flags;
-  int  loops = 2500;
-  unsigned short tmp = ch;
-  /* this code sends stuff out to serial device - spinning its
-      wheels and waiting. */
+	unsigned long flags;
+	int  loops = 2500;
+	unsigned short tmp = ch;
+	/*
+	 * this code sends stuff out to serial device - spinning its wheels and
+	 * waiting.
+	 */
 
-  /* force the issue - point it at lines[3]*/
-  dz_console=&multi[CONSOLE_LINE];
+	/* force the issue - point it at lines[3]*/
+	dz_console = &multi[CONSOLE_LINE];
 
-  save_flags(flags);
-  cli();
-  
+	save_and_cli(flags);
 
-  /* spin our wheels */
-  while (((dz_in(dz_console,DZ_CSR) & DZ_TRDY) != DZ_TRDY) &&  loops--)
-    ;
+	/* spin our wheels */
+	while (((dz_in(dz_console, DZ_CSR) & DZ_TRDY) != DZ_TRDY) &&  loops--)
+		;
   
-  /* Actually transmit the character. */
-  dz_out (dz_console, DZ_TDR, tmp);
+	/* Actually transmit the character. */
+	dz_out(dz_console, DZ_TDR, tmp);
 
-  restore_flags(flags); 
+	restore_flags(flags); 
 }
+
 /* 
  * -------------------------------------------------------------------
  * dz_console_print ()
@@ -1432,19 +1500,18 @@
 			      unsigned int count)
 {
 #ifdef DEBUG_DZ
-  prom_printf((char *)str);
+	prom_printf((char *)str);
 #endif
-  while (count--) 
-    {
-    if (*str == '\n')
-	dz_console_put_char ('\r');
-      dz_console_put_char (*str++);
-  }
+	while (count--) {
+		if (*str == '\n')
+			dz_console_put_char('\r');
+		dz_console_put_char(*str++);
+	}
 }
 
 static int dz_console_wait_key(struct console *co)
 {
-    return 0;
+	return 0;
 }
 
 static kdev_t dz_console_device(struct console *c)
@@ -1454,17 +1521,17 @@
 
 static int __init dz_console_setup(struct console *co, char *options)
 {
-  	int	baud = 9600;
-	int	bits = 8;
-	int	parity = 'n';
-	int	cflag = CREAD | HUPCL | CLOCAL;
-	char	*s;
+	int baud = 9600;
+	int bits = 8;
+	int parity = 'n';
+	int cflag = CREAD | HUPCL | CLOCAL;
+	char *s;
 	unsigned short mask,tmp;
 
 	if (options) {
 		baud = simple_strtoul(options, NULL, 10);
 		s = options;
-		while(*s >= '0' && *s <= '9')
+		while (*s >= '0' && *s <= '9')
 			s++;
 		if (*s)
 			parity = *s++;
@@ -1473,9 +1540,9 @@
 	}
 
 	/*
-	 *	Now construct a cflag setting.
+	 * Now construct a cflag setting.
 	 */
-	switch(baud) {
+	switch (baud) {
 	case 1200:
 		cflag |= DZ_B1200;
 		break;
@@ -1490,7 +1557,7 @@
 		cflag |= DZ_B9600;
 		break;
 	}
-	switch(bits) {
+	switch (bits) {
 	case 7:
 		cflag |= DZ_CS7;
 		break;
@@ -1499,11 +1566,13 @@
 		cflag |= DZ_CS8;
 		break;
 	}
-	switch(parity) {
-	case 'o': case 'O':
+	switch (parity) {
+	case 'o':
+	case 'O':
 		cflag |= DZ_PARODD;
 		break;
-	case 'e': case 'E':
+	case 'e':
+	case 'E':
 		cflag |= DZ_PARENB;
 		break;
 	}
@@ -1511,45 +1580,44 @@
 
 	/* 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; 
+	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... */
+	/*  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);
+	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 */
+	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); 
+		tmp |= mask;				/* set the TX flag */
+		dz_out (dz_console, DZ_TCR, tmp); 
 	}
-	
 
 	return 0;
 }
 
 static struct console dz_sercons = {
-	name:		"ttyS",
-	write:		dz_console_print,
-	device:		dz_console_device,
-	wait_key:	dz_console_wait_key,
-	setup:		dz_console_setup,
-	flags:		CON_CONSDEV | CON_PRINTBUFFER,
-	index:		CONSOLE_LINE,
+    name:	"ttyS",
+    write:	dz_console_print,
+    device:	dz_console_device,
+    wait_key:	dz_console_wait_key,
+    setup:	dz_console_setup,
+    flags:	CON_CONSDEV | CON_PRINTBUFFER,
+    index:	CONSOLE_LINE,
 };
 
 void __init dz_serial_console_init(void)
@@ -1559,3 +1627,4 @@
 
 #endif /* ifdef CONFIG_SERIAL_CONSOLE */
 
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.9/linux/drivers/char/epca.c linux/drivers/char/epca.c
--- v2.4.9/linux/drivers/char/epca.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/char/epca.c	Sun Sep  9 10:43:02 2001
@@ -610,9 +610,7 @@
 		                      ASYNC_CALLOUT_ACTIVE | ASYNC_CLOSING);
 		wake_up_interruptible(&ch->close_wait);
 
-#ifdef MODULE
 		MOD_DEC_USE_COUNT;
-#endif
 
 		restore_flags(flags);
 
@@ -700,10 +698,8 @@
 
 		shutdown(ch);
 
-#ifdef MODULE
 		if (ch->count)
 			MOD_DEC_USE_COUNT;
-#endif /* MODULE */
 		
 
 		ch->tty   = NULL;
@@ -1397,12 +1393,9 @@
 		return(-ENODEV);
 	}
 
-#ifdef MODULE
 
 	MOD_INC_USE_COUNT;
 
-#endif
-
 	ch = &digi_channels[line];
 	boardnum = ch->boardnum;
 
@@ -4106,3 +4099,5 @@
 } /* End init_PCI */
 
 #endif /* ENABLE_PCI */
+
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.9/linux/drivers/char/ite_gpio.c linux/drivers/char/ite_gpio.c
--- v2.4.9/linux/drivers/char/ite_gpio.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/ite_gpio.c	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,430 @@
+/*
+ * FILE NAME ite_gpio.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *  API for ITE GPIO device.
+ *  Driver for ITE GPIO device.
+ *
+ *  Author: MontaVista Software, Inc.  <source@mvista.com>
+ *          Hai-Pao Fan <haipao@mvista.com>
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ *  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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE	LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <asm/uaccess.h>
+#include <asm/addrspace.h>
+#include <asm/it8172/it8172_int.h>
+#include <linux/sched.h>
+#include <linux/ite_gpio.h>
+
+#define ite_gpio_base 0x14013800
+
+#define	ITE_GPADR	(*(volatile __u8 *)(0x14013800 + KSEG1))
+#define	ITE_GPBDR	(*(volatile __u8 *)(0x14013808 + KSEG1))
+#define	ITE_GPCDR	(*(volatile __u8 *)(0x14013810 + KSEG1))
+#define	ITE_GPACR	(*(volatile __u16 *)(0x14013802 + KSEG1))
+#define	ITE_GPBCR	(*(volatile __u16 *)(0x1401380a + KSEG1))
+#define	ITE_GPCCR	(*(volatile __u16 *)(0x14013812 + KSEG1))
+#define ITE_GPAICR	(*(volatile __u16 *)(0x14013804 + KSEG1))
+#define	ITE_GPBICR	(*(volatile __u16 *)(0x1401380c + KSEG1))
+#define	ITE_GPCICR	(*(volatile __u16 *)(0x14013814 + KSEG1))
+#define	ITE_GPAISR	(*(volatile __u8 *)(0x14013806 + KSEG1))
+#define	ITE_GPBISR	(*(volatile __u8 *)(0x1401380e + KSEG1))
+#define	ITE_GPCISR	(*(volatile __u8 *)(0x14013816 + KSEG1))
+#define	ITE_GCR		(*(volatile __u8 *)(0x14013818 + KSEG1))
+
+#define MAX_GPIO_LINE		21
+static int ite_gpio_irq=IT8172_GPIO_IRQ;
+
+static long ite_irq_counter[MAX_GPIO_LINE];
+wait_queue_head_t ite_gpio_wait[MAX_GPIO_LINE];
+static int ite_gpio_irq_pending[MAX_GPIO_LINE];
+
+static int ite_gpio_debug=0;
+#define DEB(x)  if (ite_gpio_debug>=1) x
+
+int ite_gpio_in(__u32 device, __u32 mask, volatile __u32 *data)
+{
+	DEB(printk("ite_gpio_in mask=0x%x\n",mask)); 
+
+	switch (device) {
+	case ITE_GPIO_PORTA:
+		ITE_GPACR = (__u16)mask;	/* 0xffff */
+		*data = ITE_GPADR;
+		break;
+	case ITE_GPIO_PORTB:
+		ITE_GPBCR = (__u16)mask;	/* 0xffff */
+		*data = ITE_GPBDR;
+		break;
+	case ITE_GPIO_PORTC:
+		ITE_GPCCR = (__u16)mask;	/* 0x03ff */
+		*data = ITE_GPCDR;
+		break;
+	default:
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+
+int ite_gpio_out(__u32 device, __u32 mask, __u32 data)
+{
+	switch (device) {
+	case ITE_GPIO_PORTA:
+		ITE_GPACR = (__u16)mask;	/* 0x5555 */
+		ITE_GPADR = (__u8)data;
+		break;
+	case ITE_GPIO_PORTB:
+		ITE_GPBCR = (__u16)mask;	/* 0x5555 */
+		ITE_GPBDR = (__u8)data;
+		break;
+	case ITE_GPIO_PORTC:
+		ITE_GPCCR = (__u16)mask;	/* 0x0155 */
+		ITE_GPCDR = (__u8)data;
+		break;
+	default:
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+int ite_gpio_int_ctrl(__u32 device, __u32 mask, __u32 data)
+{
+	switch (device) {
+	case ITE_GPIO_PORTA:
+		ITE_GPAICR = (ITE_GPAICR & ~mask) | (data & mask);
+		break;
+	case ITE_GPIO_PORTB:
+		ITE_GPBICR = (ITE_GPBICR & ~mask) | (data & mask);
+		break;
+	case ITE_GPIO_PORTC:
+		ITE_GPCICR = (ITE_GPCICR & ~mask) | (data & mask);
+		break;
+	default:
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+int ite_gpio_in_status(__u32 device, __u32 mask, volatile __u32 *data)
+{
+	int ret=-1;
+
+	if (MAX_GPIO_LINE > *data >= 0) 
+		ret=ite_gpio_irq_pending[*data];
+ 
+	DEB(printk("ite_gpio_in_status %d ret=%d\n",*data, ret));
+
+	switch (device) {
+	case ITE_GPIO_PORTA:
+		*data = ITE_GPAISR & mask;
+		break;
+	case ITE_GPIO_PORTB:
+		*data = ITE_GPBISR & mask;
+		break;
+	case ITE_GPIO_PORTC:
+		*data = ITE_GPCISR & mask;
+		break;
+	default:
+		return -EFAULT;
+	}
+
+	return ret;
+}
+
+int ite_gpio_out_status(__u32 device, __u32 mask, __u32 data)
+{
+	switch (device) {
+	case ITE_GPIO_PORTA:
+		ITE_GPAISR = (ITE_GPAISR & ~mask) | (data & mask);
+		break;
+	case ITE_GPIO_PORTB:
+		ITE_GPBISR = (ITE_GPBISR & ~mask) | (data & mask);
+		break;
+	case ITE_GPIO_PORTC:
+		ITE_GPCISR = (ITE_GPCISR & ~mask) | (data & mask);
+		break;
+	default:
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+int ite_gpio_gen_ctrl(__u32 device, __u32 mask, __u32 data)
+{
+	ITE_GCR = (ITE_GCR & ~mask) | (data & mask);
+
+	return 0;
+}
+
+int ite_gpio_int_wait (__u32 device, __u32 mask, __u32 data)
+{
+	int i,line=0, ret=0;
+	unsigned long flags;
+
+	switch (device) {
+	case ITE_GPIO_PORTA:
+		line = data & mask;
+		break;
+	case ITE_GPIO_PORTB:
+		line = (data & mask) <<8;
+		break;
+	case ITE_GPIO_PORTC:
+		line = (data & mask) <<16;
+		break;
+	}
+	for (i=MAX_GPIO_LINE-1; i >= 0; i--) {
+		if ( (line) & (1 << i))
+			break;
+	}
+
+	DEB(printk("wait device=0x%d mask=0x%x data=0x%x index %d\n", 
+		device, mask, data, i));
+
+	if (line & ~(1<<i))
+		return -EFAULT;
+
+	if (ite_gpio_irq_pending[i]==1)
+		return -EFAULT;
+
+	save_flags (flags);
+	cli();
+	ite_gpio_irq_pending[i] = 1;
+	ret = interruptible_sleep_on_timeout(&ite_gpio_wait[i], 3*HZ);
+	restore_flags (flags);
+	ite_gpio_irq_pending[i] = 0;
+
+	return ret;
+}
+
+EXPORT_SYMBOL(ite_gpio_in);
+EXPORT_SYMBOL(ite_gpio_out);
+EXPORT_SYMBOL(ite_gpio_int_ctrl);
+EXPORT_SYMBOL(ite_gpio_in_status);
+EXPORT_SYMBOL(ite_gpio_out_status);
+EXPORT_SYMBOL(ite_gpio_gen_ctrl);
+EXPORT_SYMBOL(ite_gpio_int_wait);
+
+static int ite_gpio_open(struct inode *inode, struct file *file)
+{
+	unsigned int minor = MINOR(inode->i_rdev); 
+	if (minor != GPIO_MINOR)
+		return -ENODEV;
+
+#ifdef MODULE
+	MOD_INC_USE_COUNT;
+#endif
+
+	return 0;
+}
+
+
+static int ite_gpio_release(struct inode *inode, struct file *file)
+{
+
+#ifdef MODULE
+	MOD_DEC_USE_COUNT;
+#endif
+
+	return 0;
+}
+
+
+static int ite_gpio_ioctl(struct inode *inode, struct file *file,
+	unsigned int cmd, unsigned long arg)
+{
+
+	static struct ite_gpio_ioctl_data ioctl_data;
+
+	if (copy_from_user(&ioctl_data, (struct ite_gpio_ioctl_data *)arg,
+			sizeof(ioctl_data)))
+		return -EFAULT;
+	if ((ioctl_data.device < ITE_GPIO_PORTA) ||
+			(ioctl_data.device > ITE_GPIO_PORTC) )
+				return -EFAULT;
+
+	switch(cmd) {
+		case ITE_GPIO_IN:
+			if (ite_gpio_in(ioctl_data.device, ioctl_data.mask,
+					   &ioctl_data.data))
+				return -EFAULT;
+
+			if (copy_to_user((struct ite_gpio_ioctl_data *)arg,
+					 &ioctl_data, sizeof(ioctl_data)))
+				return -EFAULT;
+			break;
+
+		case ITE_GPIO_OUT:
+			return ite_gpio_out(ioctl_data.device,
+					ioctl_data.mask, ioctl_data.data);
+			break;
+
+		case ITE_GPIO_INT_CTRL:
+			return ite_gpio_int_ctrl(ioctl_data.device,
+					ioctl_data.mask, ioctl_data.data);
+			break;
+
+		case ITE_GPIO_IN_STATUS:
+			if (ite_gpio_in_status(ioctl_data.device, ioctl_data.mask,
+					&ioctl_data.data))
+				return -EFAULT;
+			if (copy_to_user((struct ite_gpio_ioctl_data *)arg,
+					&ioctl_data, sizeof(ioctl_data))) 
+				return -EFAULT;
+			break;
+
+		case ITE_GPIO_OUT_STATUS:
+			return ite_gpio_out_status(ioctl_data.device,
+					ioctl_data.mask, ioctl_data.data);
+			break;
+
+		case ITE_GPIO_GEN_CTRL:
+			return ite_gpio_gen_ctrl(ioctl_data.device,
+					ioctl_data.mask, ioctl_data.data);
+			break;
+
+		case ITE_GPIO_INT_WAIT:
+			return ite_gpio_int_wait(ioctl_data.device,
+					ioctl_data.mask, ioctl_data.data);
+			break;
+
+		default:
+			return -ENOIOCTLCMD;
+
+	}
+	return 0;
+}
+
+static void ite_gpio_irq_handler(int this_irq, void *dev_id, struct pt_regs *regs)
+{
+	int i,line;
+
+	line = ITE_GPCISR & 0x1f;
+	for (i=4; i >=0; i--) {
+		if ( line & (1 << i)) { 
+			++ite_irq_counter[i+16];
+			ite_gpio_irq_pending[i+16] = 2;
+			wake_up_interruptible(&ite_gpio_wait[i+16]);
+
+DEB(printk("interrupt 0x%x %d\n", &ite_gpio_wait[i+16], i+16));
+
+			ITE_GPCISR = ITE_GPCISR & (1<<i);
+			return;
+		}
+	}
+	line = ITE_GPBISR;
+	for (i=7; i >= 0; i--) {
+		if ( line & (1 << i)) {
+			++ite_irq_counter[i+8];
+			ite_gpio_irq_pending[i+8] = 2;
+			wake_up_interruptible(&ite_gpio_wait[i+8]);
+
+DEB(printk("interrupt 0x%x %d\n",ITE_GPBISR, i+8));
+
+			ITE_GPBISR = ITE_GPBISR & (1<<i);
+			return;
+		}
+	}
+	line = ITE_GPAISR;
+	for (i=7; i >= 0; i--) {
+		if ( line & (1 << i)) {
+			++ite_irq_counter[i];
+			ite_gpio_irq_pending[i] = 2;
+			wake_up_interruptible(&ite_gpio_wait[i]);
+
+DEB(printk("interrupt 0x%x %d\n",ITE_GPAISR, i));
+
+			ITE_GPAISR = ITE_GPAISR & (1<<i);
+			return;
+		}
+	}
+}
+
+static struct file_operations ite_gpio_fops =
+{
+	owner:		THIS_MODULE,
+	ioctl:		ite_gpio_ioctl,
+	open:		ite_gpio_open,
+	release:	ite_gpio_release,
+};
+
+/* GPIO_MINOR in include/linux/miscdevice.h */
+static struct miscdevice ite_gpio_miscdev =
+{
+	GPIO_MINOR,
+	"ite_gpio",
+	&ite_gpio_fops
+};
+
+int __init ite_gpio_init(void)
+{
+	int i;
+
+	misc_register(&ite_gpio_miscdev);
+
+	if (check_region(ite_gpio_base, 0x1c) < 0 ) {
+           return -ENODEV;
+        } else {
+           request_region(ite_gpio_base, 0x1c, "ITE GPIO");
+        }     
+
+	/* initialize registers */
+        ITE_GPACR = 0xffff;
+        ITE_GPBCR = 0xffff;
+        ITE_GPCCR = 0xffff;
+        ITE_GPAICR = 0x00ff;
+        ITE_GPBICR = 0x00ff;
+        ITE_GPCICR = 0x00ff;
+        ITE_GCR = 0;
+
+	for (i = 0; i < MAX_GPIO_LINE; i++) {
+		ite_gpio_irq_pending[i]=0;	
+		init_waitqueue_head(&ite_gpio_wait[i]);
+	}
+	if (request_irq(ite_gpio_irq, ite_gpio_irq_handler, SA_SHIRQ, "gpio", 0) < 0)
+		return 0;
+	printk("GPIO at 0x%x (irq = %d)\n", ite_gpio_base, ite_gpio_irq);
+
+	return 0;
+}	
+
+void __exit ite_gpio_exit(void)
+{
+	misc_deregister(&ite_gpio_miscdev);
+}
+
+module_init(ite_gpio_init);
+module_exit(ite_gpio_exit);
+
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.9/linux/drivers/char/mem.c linux/drivers/char/mem.c
--- v2.4.9/linux/drivers/char/mem.c	Sun Aug 12 13:27:59 2001
+++ linux/drivers/char/mem.c	Sun Sep  9 10:52:35 2001
@@ -153,8 +153,6 @@
 	/* Use no-cache mode, serialized */
 	else if (MMU_IS_040 || MMU_IS_060)
 		prot = (prot & _CACHEMASK040) | _PAGE_NOCACHE_S;
-#elif defined(__mips__)
-	prot = (prot & ~_CACHE_MASK) | _CACHE_UNCACHED;
 #endif
 
 	return __pgprot(prot);
diff -u --recursive --new-file v2.4.9/linux/drivers/char/misc.c linux/drivers/char/misc.c
--- v2.4.9/linux/drivers/char/misc.c	Thu May 24 15:14:08 2001
+++ linux/drivers/char/misc.c	Fri Sep  7 09:28:38 2001
@@ -273,9 +273,6 @@
 #ifdef CONFIG_SGI_NEWPORT_GFX
 	gfx_register ();
 #endif
-#ifdef CONFIG_SGI
-	streamable_init ();
-#endif
 #ifdef CONFIG_TOSHIBA
 	tosh_init();
 #endif
diff -u --recursive --new-file v2.4.9/linux/drivers/char/moxa.c linux/drivers/char/moxa.c
--- v2.4.9/linux/drivers/char/moxa.c	Sun Aug 12 13:27:59 2001
+++ linux/drivers/char/moxa.c	Sun Sep  9 10:43:02 2001
@@ -205,6 +205,7 @@
 
 MODULE_AUTHOR("William Chen");
 MODULE_DESCRIPTION("MOXA Intellio Family Multiport Board Device Driver");
+MODULE_LICENSE("GPL");
 MODULE_PARM(type, "1-4i");
 MODULE_PARM(baseaddr, "1-4i");
 MODULE_PARM(numports, "1-4i");
@@ -212,6 +213,8 @@
 MODULE_PARM(calloutmajor, "i");
 MODULE_PARM(verbose, "i");
 
+EXPORT_NO_SYMBOLS;
+
 #endif				//MODULE
 
 static struct tty_driver moxaDriver;
@@ -1717,27 +1720,6 @@
 		if(copy_to_user((void *)arg, temp_queue, sizeof(struct moxaq_str) * MAX_PORTS))
 			return -EFAULT;
 		return (0);
-	case MOXA_LOAD_BIOS:
-		if(copy_from_user(&dltmp, (void *)arg, sizeof(struct dl_str)))
-			return -EFAULT;
-		i = moxaloadbios(dltmp.cardno, dltmp.buf, dltmp.len);
-		return (i);
-	case MOXA_FIND_BOARD:
-		if(copy_from_user(&dltmp, (void *)arg, sizeof(struct dl_str)))
-			return -EFAULT;
-		return moxafindcard(dltmp.cardno);
-	case MOXA_LOAD_C320B:
-		if(copy_from_user(&dltmp, (void *)arg, sizeof(struct dl_str)))
-			return -EFAULT;
-		moxaload320b(dltmp.cardno, dltmp.buf, dltmp.len);
-		return (0);
-	case MOXA_LOAD_CODE:
-		if(copy_from_user(&dltmp, (void *)arg, sizeof(struct dl_str)))
-			return -EFAULT; 
-		i = moxaloadcode(dltmp.cardno, dltmp.buf, dltmp.len);
-		if (i == -1)
-			return (-EFAULT);
-		return (i);
 	case MOXA_GET_OQUEUE:
 		i = MoxaPortTxQueue(port);
 		return put_user(i, (unsigned long *) arg);
@@ -1778,9 +1760,38 @@
 		if(copy_to_user((void *)arg, GMStatus, sizeof(struct mxser_mstatus) * MAX_PORTS))
 			return -EFAULT;
 		return 0;
+	default:
+		return (-ENOIOCTLCMD);
+	case MOXA_LOAD_BIOS:
+	case MOXA_FIND_BOARD:
+	case MOXA_LOAD_C320B:
+	case MOXA_LOAD_CODE:
+		break;
+	}
+
+	if(copy_from_user(&dltmp, (void *)arg, sizeof(struct dl_str)))
+		return -EFAULT;
+	if(dltmp.cardno < 0 || dltmp.cardno >= MAX_BOARDS)
+		return -EINVAL;
+
+	switch(cmd)
+	{
+	case MOXA_LOAD_BIOS:
+		i = moxaloadbios(dltmp.cardno, dltmp.buf, dltmp.len);
+		return (i);
+	case MOXA_FIND_BOARD:
+		return moxafindcard(dltmp.cardno);
+	case MOXA_LOAD_C320B:
+		moxaload320b(dltmp.cardno, dltmp.buf, dltmp.len);
+	default: /* to keep gcc happy */
+		return (0);
+	case MOXA_LOAD_CODE:
+		i = moxaloadcode(dltmp.cardno, dltmp.buf, dltmp.len);
+		if (i == -1)
+			return (-EFAULT);
+		return (i);
 
 	}
-	return (-ENOIOCTLCMD);
 }
 
 int MoxaDriverPoll(void)
diff -u --recursive --new-file v2.4.9/linux/drivers/char/pc110pad.c linux/drivers/char/pc110pad.c
--- v2.4.9/linux/drivers/char/pc110pad.c	Tue May 22 10:23:16 2001
+++ linux/drivers/char/pc110pad.c	Fri Sep  7 09:28:38 2001
@@ -798,7 +798,7 @@
  *	asked to open it by an application.
  */
 
-static const char banner[] __initdata = KERN_INFO "PC110 digitizer pad at 0x%X, irq %d.\n";
+static char banner[] __initdata = KERN_INFO "PC110 digitizer pad at 0x%X, irq %d.\n";
 
 static int __init pc110pad_init_driver(void)
 {
@@ -840,3 +840,9 @@
 
 module_init(pc110pad_init_driver);
 module_exit(pc110pad_exit_driver);
+
+MODULE_AUTHOR("Alan Cox, Robin O'Leary");
+MODULE_DESCRIPTION("Driver for the touchpad on the IBM PC110 palmtop");
+MODULE_LICENSE("GPL");
+
+EXPORT_NO_SYMBOLS;
diff -u --recursive --new-file v2.4.9/linux/drivers/char/pc_keyb.c linux/drivers/char/pc_keyb.c
--- v2.4.9/linux/drivers/char/pc_keyb.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/char/pc_keyb.c	Tue Aug 28 07:09:44 2001
@@ -31,6 +31,7 @@
 #include <linux/miscdevice.h>
 #include <linux/slab.h>
 #include <linux/kbd_kern.h>
+#include <linux/vt_kern.h>
 #include <linux/smp_lock.h>
 
 #include <asm/keyboard.h>
@@ -602,7 +603,7 @@
 		return 1;
 }
 
-int pckbd_rate(struct kbd_repeat *rep)
+static int pckbd_rate(struct kbd_repeat *rep)
 {
 	if (rep == NULL)
 		return -EINVAL;
@@ -834,6 +835,8 @@
 #if defined CONFIG_PSMOUSE
 	psaux_init();
 #endif
+
+	kbd_rate = pckbd_rate;
 
 	/* Ok, finally allocate the IRQ, and off we go.. */
 	kbd_request_irq(keyboard_interrupt);
diff -u --recursive --new-file v2.4.9/linux/drivers/char/qpmouse.c linux/drivers/char/qpmouse.c
--- v2.4.9/linux/drivers/char/qpmouse.c	Fri Apr 13 20:26:07 2001
+++ linux/drivers/char/qpmouse.c	Fri Sep  7 09:28:38 2001
@@ -338,8 +338,8 @@
 	return 1;
 }
 
-static const char msg_banner[] __initdata = KERN_INFO "82C710 type pointing device detected -- driver installed.\n";
-static const char msg_nomem[]  __initdata = KERN_ERR "qpmouse: no queue memory.\n";
+static char msg_banner[] __initdata = KERN_INFO "82C710 type pointing device detected -- driver installed.\n";
+static char msg_nomem[]  __initdata = KERN_ERR "qpmouse: no queue memory.\n";
 
 static int __init qpmouse_init_driver(void)
 {
@@ -371,3 +371,6 @@
 module_init(qpmouse_init_driver);
 module_exit(qpmouse_exit_driver);
 
+
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
diff -u --recursive --new-file v2.4.9/linux/drivers/char/qtronix.c linux/drivers/char/qtronix.c
--- v2.4.9/linux/drivers/char/qtronix.c	Fri Apr 13 20:26:07 2001
+++ linux/drivers/char/qtronix.c	Sun Sep  9 10:43:02 2001
@@ -6,7 +6,7 @@
  *
  * Copyright 2001 MontaVista Software Inc.
  * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or support@mvista.com
+ *         	ppopov@mvista.com or source@mvista.com
  *
  *
  *  The bottom portion of this driver was take from 
@@ -71,7 +71,7 @@
 #include <linux/random.h>
 #include <linux/poll.h>
 #include <linux/miscdevice.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/kbd_kern.h>
 #include <linux/smp_lock.h>
 #include <asm/io.h>
@@ -353,19 +353,19 @@
 static unsigned char handle_kbd_event(void);
 
 
-int pckbd_setkeycode(unsigned int scancode, unsigned int keycode)
+int kbd_setkeycode(unsigned int scancode, unsigned int keycode)
 {
-	printk("pckbd_setkeycode scancode %x keycode %x\n", scancode, keycode);
+	printk("kbd_setkeycode scancode %x keycode %x\n", scancode, keycode);
 	return 0;
 }
 
-int pckbd_getkeycode(unsigned int scancode)
+int kbd_getkeycode(unsigned int scancode)
 {
 	return scancode;
 }
 
 
-int pckbd_translate(unsigned char scancode, unsigned char *keycode,
+int kbd_translate(unsigned char scancode, unsigned char *keycode,
 		    char raw_mode)
 {
 	static int prev_scancode = 0;
@@ -406,9 +406,9 @@
  	return 1;
 }
 
-char pckbd_unexpected_up(unsigned char keycode)
+char kbd_unexpected_up(unsigned char keycode)
 {
-	//printk("pckbd_unexpected_up\n");
+	//printk("kbd_unexpected_up\n");
 	return 0;
 }
 
@@ -422,12 +422,12 @@
 }	
 
 
-void pckbd_leds(unsigned char leds)
+void kbd_leds(unsigned char leds)
 {
 }
 
 /* dummy */
-void pckbd_init_hw(void)
+void kbd_init_hw(void)
 {
 }
 
diff -u --recursive --new-file v2.4.9/linux/drivers/char/rio/rio_linux.c linux/drivers/char/rio/rio_linux.c
--- v2.4.9/linux/drivers/char/rio/rio_linux.c	Wed Jul 25 17:10:19 2001
+++ linux/drivers/char/rio/rio_linux.c	Fri Sep  7 09:28:38 2001
@@ -248,6 +248,7 @@
 #ifndef TWO_ZERO
 MODULE_AUTHOR("Rogier Wolff <R.E.Wolff@bitwizard.nl>, Patrick van de Lageweg <patrick@bitwizard.nl>");
 MODULE_DESCRIPTION("RIO driver");
+MODULE_LICENSE("GPL");
 MODULE_PARM(rio_poll, "i");
 MODULE_PARM(rio_debug, "i");
 MODULE_PARM(rio_irqmask, "i");
diff -u --recursive --new-file v2.4.9/linux/drivers/char/rio/riocmd.c linux/drivers/char/rio/riocmd.c
--- v2.4.9/linux/drivers/char/rio/riocmd.c	Wed Jul 25 17:10:19 2001
+++ linux/drivers/char/rio/riocmd.c	Fri Sep  7 09:28:38 2001
@@ -481,7 +481,7 @@
 	   			not freed. */
 			/* Call tmgr HANGUP HERE */
 			/* Fix this later when every thing works !!!! RAMRAJ */
-			gs_got_break (PortP);
+			gs_got_break (&PortP->gs);
 			break;
 
 		case COMPLETE:
diff -u --recursive --new-file v2.4.9/linux/drivers/char/rtc.c linux/drivers/char/rtc.c
--- v2.4.9/linux/drivers/char/rtc.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/char/rtc.c	Sun Sep  9 10:43:02 2001
@@ -40,9 +40,10 @@
  *	1.10b	Andrew Morton: SMP lock fix
  *	1.10c	Cesar Barros: SMP locking fixes and cleanup
  *	1.10d	Paul Gortmaker: delete paranoia check in rtc_exit
+ *	1.10e	Maciej W. Rozycki: Handle DECstation's year weirdness.
  */
 
-#define RTC_VERSION		"1.10d"
+#define RTC_VERSION		"1.10e"
 
 #define RTC_IO_EXTENT	0x10	/* Only really two ports, but...	*/
 
@@ -361,6 +362,9 @@
 		unsigned char mon, day, hrs, min, sec, leap_yr;
 		unsigned char save_control, save_freq_select;
 		unsigned int yrs;
+#ifdef CONFIG_DECSTATION
+		unsigned int real_yrs;
+#endif
 
 		if (!capable(CAP_SYS_TIME))
 			return -EACCES;
@@ -394,6 +398,20 @@
 			return -EINVAL;
 
 		spin_lock_irq(&rtc_lock);
+#ifdef CONFIG_DECSTATION
+		real_yrs = yrs;
+		yrs = 72;
+
+		/*
+		 * We want to keep the year set to 73 until March
+		 * for non-leap years, so that Feb, 29th is handled
+		 * correctly.
+		 */
+		if (!leap_yr && mon < 3) {
+			real_yrs--;
+			yrs = 73;
+		}
+#endif
 		if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY)
 		    || RTC_ALWAYS_BCD) {
 			if (yrs > 169) {
@@ -416,6 +434,9 @@
 		save_freq_select = CMOS_READ(RTC_FREQ_SELECT);
 		CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
 
+#ifdef CONFIG_DECSTATION
+		CMOS_WRITE(real_yrs, RTC_DEC_YEAR);
+#endif
 		CMOS_WRITE(yrs, RTC_YEAR);
 		CMOS_WRITE(mon, RTC_MONTH);
 		CMOS_WRITE(day, RTC_DAY_OF_MONTH);
@@ -469,7 +490,7 @@
 		spin_unlock_irq(&rtc_lock);
 		return 0;
 	}
-#elif !defined(CONFIG_DECSTATION)
+#endif
 	case RTC_EPOCH_READ:	/* Read the epoch.	*/
 	{
 		return put_user (epoch, (unsigned long *)arg);
@@ -488,7 +509,6 @@
 		epoch = arg;
 		return 0;
 	}
-#endif
 	default:
 		return -EINVAL;
 	}
@@ -709,12 +729,12 @@
 	} else if (year >= 20 && year < 48) {
 		epoch = 1980;
 		guess = "ARC console";
-	} else if (year >= 48 && year < 70) {
+	} else if (year >= 48 && year < 72) {
 		epoch = 1952;
 		guess = "Digital UNIX";
 #if defined(__mips__)
-	} else if (year >= 70 && year < 100) {
-		epoch = 1928;
+	} else if (year >= 72 && year < 74) {
+		epoch = 2000;
 		guess = "Digital DECstation";
 #else
 	} else if (year >= 70) {
@@ -911,6 +931,9 @@
 {
 	unsigned long uip_watchdog = jiffies;
 	unsigned char ctrl;
+#ifdef CONFIG_DECSTATION
+	unsigned int real_year;
+#endif
 
 	/*
 	 * read RTC once any update in progress is done. The update
@@ -939,6 +962,9 @@
 	rtc_tm->tm_mday = CMOS_READ(RTC_DAY_OF_MONTH);
 	rtc_tm->tm_mon = CMOS_READ(RTC_MONTH);
 	rtc_tm->tm_year = CMOS_READ(RTC_YEAR);
+#ifdef CONFIG_DECSTATION
+	real_year = CMOS_READ(RTC_DEC_YEAR);
+#endif
 	ctrl = CMOS_READ(RTC_CONTROL);
 	spin_unlock_irq(&rtc_lock);
 
@@ -952,6 +978,10 @@
 		BCD_TO_BIN(rtc_tm->tm_year);
 	}
 
+#ifdef CONFIG_DECSTATION
+	rtc_tm->tm_year += real_year - 72;
+#endif
+
 	/*
 	 * Account for differences between how the RTC uses the values
 	 * and how they are defined in a struct rtc_time;
@@ -1024,3 +1054,6 @@
 	spin_unlock_irq(&rtc_lock);
 }
 #endif
+
+MODULE_AUTHOR("Paul Gortmaker");
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.9/linux/drivers/char/selection.c linux/drivers/char/selection.c
--- v2.4.9/linux/drivers/char/selection.c	Fri Feb  9 11:30:22 2001
+++ linux/drivers/char/selection.c	Fri Sep  7 09:28:38 2001
@@ -96,11 +96,7 @@
 /* set inwordLut contents. Invoked by ioctl(). */
 int sel_loadlut(const unsigned long arg)
 {
-	int err = -EFAULT;
-
-	if (!copy_from_user(inwordLut, (u32 *)(arg+4), 32))
-		err = 0;
-	return err;
+	return copy_from_user(inwordLut, (u32 *)(arg+4), 32) ? -EFAULT : 0;
 }
 
 /* does screen address p correspond to character at LH/RH edge of screen? */
@@ -130,15 +126,13 @@
 
 	  args = (unsigned short *)(arg + 1);
 	  if (user) {
-	  	  int err;
-		  err = verify_area(VERIFY_READ, args, sizeof(short) * 5);
-		  if (err)
-		  	return err;
-		  get_user(xs, args++);
-		  get_user(ys, args++);
-		  get_user(xe, args++);
-		  get_user(ye, args++);
-		  get_user(sel_mode, args);
+		  if (verify_area(VERIFY_READ, args, sizeof(short) * 5))
+		  	return -EFAULT;
+		  __get_user(xs, args++);
+		  __get_user(ys, args++);
+		  __get_user(xe, args++);
+		  __get_user(ye, args++);
+		  __get_user(sel_mode, args);
 	  } else {
 		  xs = *(args++); /* set selection from kernel */
 		  ys = *(args++);
diff -u --recursive --new-file v2.4.9/linux/drivers/char/serial_tx3912.c linux/drivers/char/serial_tx3912.c
--- v2.4.9/linux/drivers/char/serial_tx3912.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/serial_tx3912.c	Fri Sep  7 09:28:38 2001
@@ -0,0 +1,1079 @@
+/*
+ *  drivers/char/serial_tx3912.c
+ *
+ *  Copyright (C) 1999 Harald Koerfgen
+ *  Copyright (C) 2000 Jim Pick <jim@jimpick.com>
+ *  Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com)
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *  
+ *  Serial driver for TMPR3912/05 and PR31700 processors
+ */
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/tty.h>
+#include <linux/major.h>
+#include <linux/ptrace.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/malloc.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/delay.h>
+#include <asm/wbflush.h>
+#include <asm/tx3912.h>
+#include "serial_tx3912.h"
+
+/*
+ * Forward declarations for serial routines
+ */
+static void rs_disable_tx_interrupts (void * ptr);
+static void rs_enable_tx_interrupts (void * ptr); 
+static void rs_disable_rx_interrupts (void * ptr); 
+static void rs_enable_rx_interrupts (void * ptr); 
+static int rs_get_CD (void * ptr); 
+static void rs_shutdown_port (void * ptr); 
+static int rs_set_real_termios (void *ptr);
+static int rs_chars_in_buffer (void * ptr); 
+static void rs_hungup (void *ptr);
+static void rs_close (void *ptr);
+
+/*
+ * Used by generic serial driver to access hardware
+ */
+static struct real_driver rs_real_driver = { 
+	disable_tx_interrupts: rs_disable_tx_interrupts, 
+	enable_tx_interrupts:  rs_enable_tx_interrupts, 
+	disable_rx_interrupts: rs_disable_rx_interrupts, 
+	enable_rx_interrupts:  rs_enable_rx_interrupts, 
+	get_CD:                rs_get_CD, 
+	shutdown_port:         rs_shutdown_port,  
+	set_real_termios:      rs_set_real_termios,  
+	chars_in_buffer:       rs_chars_in_buffer, 
+	close:                 rs_close, 
+	hungup:                rs_hungup,
+}; 
+
+/*
+ * Structures and such for TTY sessions and usage counts
+ */
+static struct tty_driver rs_driver, rs_callout_driver;
+static struct tty_struct * rs_table[TX3912_UART_NPORTS] = { NULL, };
+static struct termios ** rs_termios;
+static struct termios ** rs_termios_locked;
+struct rs_port *rs_ports;
+int rs_refcount;
+int rs_initialized = 0;
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * Here starts the interrupt handling routines.  All of the following
+ * subroutines are declared as inline and are folded into
+ * rs_interrupt().  They were separated out for readability's sake.
+ *
+ * Note: rs_interrupt() is a "fast" interrupt, which means that it
+ * runs with interrupts turned off.  People who may want to modify
+ * rs_interrupt() should try to keep the interrupt handler as fast as
+ * possible.  After you are done making modifications, it is not a bad
+ * idea to do:
+ * 
+ * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
+ *
+ * and look at the resulting assemble code in serial.s.
+ *
+ * 				- Ted Ts'o (tytso@mit.edu), 7-Mar-93
+ * -----------------------------------------------------------------------
+ */
+static inline void receive_char_pio(struct rs_port *port)
+{
+	struct tty_struct *tty = port->gs.tty;
+	unsigned char ch;
+	int counter = 2048;
+
+	/* While there are characters, get them ... */
+	while (counter>0) {
+		if (!(inl(port->base + TX3912_UART_CTRL1) & UART_RX_HOLD_FULL))
+			break;
+		ch = inb(port->base + TX3912_UART_DATA);
+		if (tty->flip.count < TTY_FLIPBUF_SIZE) {
+			*tty->flip.char_buf_ptr++ = ch;
+			*tty->flip.flag_buf_ptr++ = 0;
+			tty->flip.count++;
+		}
+		udelay(1); /* Allow things to happen - it take a while */
+		counter--;
+	}
+	if (!counter)
+		printk( "Ugh, looped in receive_char_pio!\n" );
+
+	tty_flip_buffer_push(tty);
+
+#if 0
+	/* Now handle error conditions */
+	if (*status & (INTTYPE(UART_RXOVERRUN_INT) |
+			INTTYPE(UART_FRAMEERR_INT) |
+			INTTYPE(UART_PARITYERR_INT) |
+			INTTYPE(UART_BREAK_INT))) {
+
+		/*
+		 * Now check to see if character should be
+		 * ignored, and mask off conditions which
+		 * should be ignored.
+	       	 */
+		if (*status & port->ignore_status_mask) {
+			goto ignore_char;
+		}
+		*status &= port->read_status_mask;
+		
+		if (*status & INTTYPE(UART_BREAK_INT)) {
+			rs_dprintk(TX3912_UART_DEBUG_INTERRUPTS, "handling break....");
+			*tty->flip.flag_buf_ptr = TTY_BREAK;
+		}
+		else if (*status & INTTYPE(UART_PARITYERR_INT)) {
+			*tty->flip.flag_buf_ptr = TTY_PARITY;
+		}
+		else if (*status & INTTYPE(UART_FRAMEERR_INT)) {
+			*tty->flip.flag_buf_ptr = TTY_FRAME;
+		}
+		if (*status & INTTYPE(UART_RXOVERRUN_INT)) {
+			/*
+			 * Overrun is special, since it's
+			 * reported immediately, and doesn't
+			 * affect the current character
+			 */
+			if (tty->flip.count < TTY_FLIPBUF_SIZE) {
+				tty->flip.count++;
+				tty->flip.flag_buf_ptr++;
+				tty->flip.char_buf_ptr++;
+				*tty->flip.flag_buf_ptr = TTY_OVERRUN;
+			}
+		}
+	}
+
+	tty->flip.flag_buf_ptr++;
+	tty->flip.char_buf_ptr++;
+	tty->flip.count++;
+
+ignore_char:
+	tty_flip_buffer_push(tty);
+#endif
+}
+
+static inline void transmit_char_pio(struct rs_port *port)
+{
+	/* While I'm able to transmit ... */
+	for (;;) {
+		if (!(inl(port->base + TX3912_UART_CTRL1) & UART_TX_EMPTY))
+			break;
+		else if (port->x_char) {
+			outb(port->x_char, port->base + TX3912_UART_DATA);
+			port->icount.tx++;
+			port->x_char = 0;
+		}
+		else if (port->gs.xmit_cnt <= 0 || port->gs.tty->stopped ||
+		    port->gs.tty->hw_stopped) {
+			break;
+		}
+		else {
+			outb(port->gs.xmit_buf[port->gs.xmit_tail++],
+				port->base + TX3912_UART_DATA);
+			port->icount.tx++;
+			port->gs.xmit_tail &= SERIAL_XMIT_SIZE-1;
+			if (--port->gs.xmit_cnt <= 0) {
+				break;
+			}
+		}
+		udelay(10); /* Allow things to happen - it take a while */
+	}
+
+	if (port->gs.xmit_cnt <= 0 || port->gs.tty->stopped ||
+	     port->gs.tty->hw_stopped) {
+		rs_disable_tx_interrupts(port);
+	}
+	
+        if (port->gs.xmit_cnt <= port->gs.wakeup_chars) {
+                if ((port->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+                    port->gs.tty->ldisc.write_wakeup)
+                        (port->gs.tty->ldisc.write_wakeup)(port->gs.tty);
+                rs_dprintk (TX3912_UART_DEBUG_TRANSMIT, "Waking up.... ldisc (%d)....\n",
+                            port->gs.wakeup_chars); 
+                wake_up_interruptible(&port->gs.tty->write_wait);
+       	}	
+}
+
+
+
+static inline void check_modem_status(struct rs_port *port)
+{
+        /* We don't have a carrier detect line - but just respond
+           like we had one anyways so that open() becomes unblocked */
+	wake_up_interruptible(&port->gs.open_wait);
+}
+
+int count = 0;
+
+/*
+ * This is the serial driver's interrupt routine (inlined, because
+ * there are two different versions of this, one for each serial port,
+ * differing only by the bits used in interrupt status 2 register)
+ */
+
+static inline void rs_rx_interrupt(int irq, void *dev_id,
+				  struct pt_regs * regs, int intshift)
+{
+	struct rs_port * port;
+	unsigned long int2status;
+	unsigned long flags;
+	unsigned long ints;
+
+	save_and_cli(flags);
+
+	port = (struct rs_port *)dev_id;
+	rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "rs_interrupt (port %p, shift %d)...", port, intshift);
+
+	/* Get the interrrupts we have enabled */
+	int2status = IntStatus2 & IntEnable2;
+
+	/* Get interrupts in easy to use form */
+	ints = int2status >> intshift;
+
+	/* Clear any interrupts we might be about to handle */
+	IntClear2 = int2status & (
+		(INTTYPE(UART_RXOVERRUN_INT) |
+		 INTTYPE(UART_FRAMEERR_INT) |
+		 INTTYPE(UART_BREAK_INT) |
+		 INTTYPE(UART_PARITYERR_INT) |
+		 INTTYPE(UART_RX_INT)) << intshift);
+
+	if (!port || !port->gs.tty) {
+		restore_flags(flags);
+		return;
+	}
+
+	/* RX Receiver Holding Register Overrun */
+	if (ints & INTTYPE(UART_RXOVERRUN_INT)) {
+		rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "overrun");
+		port->icount.overrun++;
+	}
+
+	/* RX Frame Error */
+	if (ints & INTTYPE(UART_FRAMEERR_INT)) {
+		rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "frame error");
+		port->icount.frame++;
+	}
+
+	/* Break signal received */
+	if (ints & INTTYPE(UART_BREAK_INT)) {
+		rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "break");
+		port->icount.brk++;
+      	}
+
+	/* RX Parity Error */
+	if (ints & INTTYPE(UART_PARITYERR_INT)) {
+		rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "parity error");
+		port->icount.parity++;
+	}
+
+	/* Receive byte (non-DMA) */
+	if (ints & INTTYPE(UART_RX_INT)) {
+		receive_char_pio(port);
+	}
+
+	restore_flags(flags);
+
+	rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "end.\n");
+}
+
+static inline void rs_tx_interrupt(int irq, void *dev_id,
+				  struct pt_regs * regs, int intshift)
+{
+	struct rs_port * port;
+	unsigned long int2status;
+	unsigned long flags;
+	unsigned long ints;
+
+	save_and_cli(flags);
+
+	port = (struct rs_port *)dev_id;
+	rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "rs_interrupt (port %p, shift %d)...", port, intshift);
+
+	/* Get the interrrupts we have enabled */
+	int2status = IntStatus2 & IntEnable2;
+
+	if (!port || !port->gs.tty) {
+		restore_flags(flags);
+		return;
+	}
+
+	/* Get interrupts in easy to use form */
+	ints = int2status >> intshift;
+
+	/* Clear any interrupts we might be about to handle */
+	IntClear2 = int2status & (
+		(INTTYPE(UART_TX_INT) |
+		 INTTYPE(UART_EMPTY_INT) |
+		 INTTYPE(UART_TXOVERRUN_INT)) << intshift);
+
+	/* TX holding register empty, so transmit byte (non-DMA) */
+	if (ints & (INTTYPE(UART_TX_INT) | INTTYPE(UART_EMPTY_INT))) {
+		transmit_char_pio(port);
+	}
+
+	/* TX Transmit Holding Register Overrun (shouldn't happen) */
+	if (ints & INTTYPE(UART_TXOVERRUN_INT)) {
+		printk ( "rs: TX overrun\n");
+	}
+
+	/*
+	check_modem_status();
+	*/
+
+	restore_flags(flags);
+
+	rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "end.\n");
+}
+
+static void rs_rx_interrupt_uarta(int irq, void *dev_id,
+					 struct pt_regs * regs)
+{
+	rs_rx_interrupt(irq, dev_id, regs, UARTA_SHIFT);
+}
+
+static void rs_tx_interrupt_uarta(int irq, void *dev_id,
+					 struct pt_regs * regs)
+{
+	rs_tx_interrupt(irq, dev_id, regs, UARTA_SHIFT);
+}
+
+/*
+ ***********************************************************************
+ *                Here are the routines that actually                  *
+ *              interface with the generic_serial driver               *
+ ***********************************************************************
+ */
+static void rs_disable_tx_interrupts (void * ptr) 
+{
+	struct rs_port *port = ptr; 
+	unsigned long flags;
+
+	save_and_cli(flags);
+        port->gs.flags &= ~GS_TX_INTEN;
+
+	IntEnable2 &= ~((INTTYPE(UART_TX_INT) |
+			INTTYPE(UART_EMPTY_INT) |
+			INTTYPE(UART_TXOVERRUN_INT)) << port->intshift);
+
+	IntClear2 = (INTTYPE(UART_TX_INT) |
+			INTTYPE(UART_EMPTY_INT) |
+			INTTYPE(UART_TXOVERRUN_INT)) << port->intshift;
+
+	restore_flags(flags);
+}
+
+static void rs_enable_tx_interrupts (void * ptr) 
+{
+	struct rs_port *port = ptr; 
+	unsigned long flags;
+
+	save_and_cli(flags);
+
+	IntClear2 = (INTTYPE(UART_TX_INT) |
+			INTTYPE(UART_EMPTY_INT) |
+			INTTYPE(UART_TXOVERRUN_INT)) << port->intshift;
+
+	IntEnable2 |= (INTTYPE(UART_TX_INT) |
+			INTTYPE(UART_EMPTY_INT) |
+			INTTYPE(UART_TXOVERRUN_INT)) << port->intshift;
+
+	/* Send a char to start TX interrupts happening */
+	transmit_char_pio(port);
+
+	restore_flags(flags);
+}
+
+static void rs_disable_rx_interrupts (void * ptr) 
+{
+	struct rs_port *port = ptr;
+	unsigned long flags;
+
+	save_and_cli(flags);
+
+	IntEnable2 &= ~((INTTYPE(UART_RX_INT) |
+			 INTTYPE(UART_RXOVERRUN_INT) |
+			 INTTYPE(UART_FRAMEERR_INT) |
+			 INTTYPE(UART_BREAK_INT) |
+			 INTTYPE(UART_PARITYERR_INT)) << port->intshift);
+
+	IntClear2 = (INTTYPE(UART_RX_INT) |
+			 INTTYPE(UART_RXOVERRUN_INT) |
+			 INTTYPE(UART_FRAMEERR_INT) |
+			 INTTYPE(UART_BREAK_INT) |
+			 INTTYPE(UART_PARITYERR_INT)) << port->intshift;
+
+	restore_flags(flags);
+}
+
+static void rs_enable_rx_interrupts (void * ptr) 
+{
+	struct rs_port *port = ptr;
+	unsigned long flags;
+
+	save_and_cli(flags);
+
+	IntEnable2 |= (INTTYPE(UART_RX_INT) |
+			 INTTYPE(UART_RXOVERRUN_INT) |
+			 INTTYPE(UART_FRAMEERR_INT) |
+			 INTTYPE(UART_BREAK_INT) |
+			 INTTYPE(UART_PARITYERR_INT)) << port->intshift;
+
+	/* Empty the input buffer - apparently this is *vital* */
+	while (inl(port->base + TX3912_UART_CTRL1) & UART_RX_HOLD_FULL) { 
+		inb(port->base + TX3912_UART_DATA);
+	}
+
+	IntClear2 = (INTTYPE(UART_RX_INT) |
+			 INTTYPE(UART_RXOVERRUN_INT) |
+			 INTTYPE(UART_FRAMEERR_INT) |
+			 INTTYPE(UART_BREAK_INT) |
+			 INTTYPE(UART_PARITYERR_INT)) << port->intshift;
+
+	restore_flags(flags);
+}
+
+
+static int rs_get_CD (void * ptr) 
+{
+	/* No Carried Detect in Hardware - just return true */
+	func_exit();
+	return (1);
+}
+
+static void rs_shutdown_port (void * ptr) 
+{
+	struct rs_port *port = ptr; 
+
+	func_enter();
+
+	port->gs.flags &= ~GS_ACTIVE;
+
+	func_exit();
+}
+
+static int rs_set_real_termios (void *ptr)
+{
+	struct rs_port *port = ptr;
+	int t;
+
+	switch (port->gs.baud) {
+		/* Save some typing work... */
+#define e(x) case x:t= TX3912_UART_CTRL2_B ## x ; break
+		e(300);e(600);e(1200);e(2400);e(4800);e(9600);
+		e(19200);e(38400);e(57600);e(76800);e(115200);e(230400);
+	case 0      :t = -1;
+		break;
+	default:
+		/* Can I return "invalid"? */
+		t = TX3912_UART_CTRL2_B9600;
+		printk (KERN_INFO "rs: unsupported baud rate: %d.\n", port->gs.baud);
+		break;
+	}
+#undef e
+	if (t >= 0) {
+		/* Jim: Set Hardware Baud rate - there is some good
+		   code in drivers/char/serial.c */
+
+	  	/* Program hardware for parity, data bits, stop bits (note: these are hardcoded to 8N1 */
+		UartA_Ctrl1 &= 0xf000000f;
+		UartA_Ctrl1 &= ~(UART_DIS_TXD | SER_SEVEN_BIT | SER_EVEN_PARITY | SER_TWO_STOP);
+
+#define CFLAG port->gs.tty->termios->c_cflag
+		if (C_PARENB(port->gs.tty)) {
+			if (!C_PARODD(port->gs.tty))
+				UartA_Ctrl1 |= SER_EVEN_PARITY;
+			else
+				UartA_Ctrl1 |= SER_ODD_PARITY;
+		}
+		if ((CFLAG & CSIZE)==CS6)
+			printk(KERN_ERR "6 bits not supported\n");
+		if ((CFLAG & CSIZE)==CS5)
+			printk(KERN_ERR "5 bits not supported\n");
+		if ((CFLAG & CSIZE)==CS7)
+			UartA_Ctrl1 |= SER_SEVEN_BIT;
+		if (C_CSTOPB(port->gs.tty))
+			UartA_Ctrl1 |= SER_TWO_STOP;
+
+		outl(t, port->base + TX3912_UART_CTRL2);
+		outl(0, port->base + TX3912_UART_DMA_CTRL1);
+		outl(0, port->base + TX3912_UART_DMA_CTRL2);
+        	UartA_Ctrl1 |= TX3912_UART_CTRL1_UARTON;
+
+        /* wait until UARTA is stable */
+        while (~UartA_Ctrl1 & TX3912_UART_CTRL1_UARTON);
+	}
+
+	func_exit ();
+        return 0;
+}
+
+static int rs_chars_in_buffer (void * ptr) 
+{
+	struct rs_port *port = ptr;
+	int scratch;
+
+	scratch = inl(port->base + TX3912_UART_CTRL1);
+
+	return ((scratch & UART_TX_EMPTY) ? 0 : 1);
+}
+
+/* ********************************************************************** *
+ *                Here are the routines that actually                     *
+ *               interface with the rest of the system                    *
+ * ********************************************************************** */
+static int rs_open  (struct tty_struct * tty, struct file * filp)
+{
+	struct rs_port *port;
+	int retval, line;
+
+	func_enter();
+
+	if (!rs_initialized) {
+		return -EIO;
+	}
+
+	line = MINOR(tty->device) - tty->driver.minor_start;
+	rs_dprintk (TX3912_UART_DEBUG_OPEN, "%d: opening line %d. tty=%p ctty=%p)\n", 
+	            (int) current->pid, line, tty, current->tty);
+
+	if ((line < 0) || (line >= TX3912_UART_NPORTS))
+		return -ENODEV;
+
+	/* Pre-initialized already */
+	port = & rs_ports[line];
+
+	rs_dprintk (TX3912_UART_DEBUG_OPEN, "port = %p\n", port);
+
+	tty->driver_data = port;
+	port->gs.tty = tty;
+	port->gs.count++;
+
+	rs_dprintk (TX3912_UART_DEBUG_OPEN, "starting port\n");
+
+	/*
+	 * Start up serial port
+	 */
+	retval = gs_init_port(&port->gs);
+	rs_dprintk (TX3912_UART_DEBUG_OPEN, "done gs_init\n");
+	if (retval) {
+		port->gs.count--;
+		return retval;
+	}
+
+	port->gs.flags |= GS_ACTIVE;
+
+	rs_dprintk (TX3912_UART_DEBUG_OPEN, "before inc_use_count (count=%d.\n", 
+	            port->gs.count);
+	if (port->gs.count == 1) {
+		MOD_INC_USE_COUNT;
+	}
+	rs_dprintk (TX3912_UART_DEBUG_OPEN, "after inc_use_count\n");
+
+	/* Jim: Initialize port hardware here */
+
+	/* Enable high-priority interrupts for UARTA */
+	IntEnable6 |= INT6_UARTARXINT; 
+	rs_enable_rx_interrupts(&rs_ports[0]); 
+
+	retval = gs_block_til_ready(&port->gs, filp);
+	rs_dprintk (TX3912_UART_DEBUG_OPEN, "Block til ready returned %d. Count=%d\n", 
+	            retval, port->gs.count);
+
+	if (retval) {
+		MOD_DEC_USE_COUNT;
+		port->gs.count--;
+		return retval;
+	}
+	/* tty->low_latency = 1; */
+
+	if ((port->gs.count == 1) && (port->gs.flags & ASYNC_SPLIT_TERMIOS)) {
+		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
+			*tty->termios = port->gs.normal_termios;
+		else 
+			*tty->termios = port->gs.callout_termios;
+		rs_set_real_termios (port);
+	}
+
+	port->gs.session = current->session;
+	port->gs.pgrp = current->pgrp;
+	func_exit();
+
+	/* Jim */
+/*	cli(); */
+
+	return 0;
+
+}
+
+
+
+static void rs_close (void *ptr)
+{
+	func_enter ();
+
+	/* Anything to do here? */
+
+	MOD_DEC_USE_COUNT;
+	func_exit ();
+}
+
+
+/* I haven't the foggiest why the decrement use count has to happen
+   here. The whole linux serial drivers stuff needs to be redesigned.
+   My guess is that this is a hack to minimize the impact of a bug
+   elsewhere. Thinking about it some more. (try it sometime) Try
+   running minicom on a serial port that is driven by a modularized
+   driver. Have the modem hangup. Then remove the driver module. Then
+   exit minicom.  I expect an "oops".  -- REW */
+static void rs_hungup (void *ptr)
+{
+	func_enter ();
+	MOD_DEC_USE_COUNT;
+	func_exit ();
+}
+
+static int rs_ioctl (struct tty_struct * tty, struct file * filp, 
+                     unsigned int cmd, unsigned long arg)
+{
+	int rc;
+	struct rs_port *port = tty->driver_data;
+	int ival;
+
+	rc = 0;
+	switch (cmd) {
+	case TIOCGSOFTCAR:
+		rc = put_user(((tty->termios->c_cflag & CLOCAL) ? 1 : 0),
+		              (unsigned int *) arg);
+		break;
+	case TIOCSSOFTCAR:
+		if ((rc = verify_area(VERIFY_READ, (void *) arg,
+		                      sizeof(int))) == 0) {
+			get_user(ival, (unsigned int *) arg);
+			tty->termios->c_cflag =
+				(tty->termios->c_cflag & ~CLOCAL) |
+				(ival ? CLOCAL : 0);
+		}
+		break;
+	case TIOCGSERIAL:
+		if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
+		                      sizeof(struct serial_struct))) == 0)
+			gs_getserial(&port->gs, (struct serial_struct *) arg);
+		break;
+	case TIOCSSERIAL:
+		if ((rc = verify_area(VERIFY_READ, (void *) arg,
+		                      sizeof(struct serial_struct))) == 0)
+			rc = gs_setserial(&port->gs, (struct serial_struct *) arg);
+		break;
+	default:
+		rc = -ENOIOCTLCMD;
+		break;
+	}
+
+	/* func_exit(); */
+	return rc;
+}
+
+
+/*
+ * This function is used to send a high-priority XON/XOFF character to
+ * the device
+ */
+static void rs_send_xchar(struct tty_struct * tty, char ch)
+{
+	struct rs_port *port = (struct rs_port *)tty->driver_data;
+	func_enter ();
+	
+	port->x_char = ch;
+	if (ch) {
+		/* Make sure transmit interrupts are on */
+		rs_enable_tx_interrupts(tty);
+	}
+
+	func_exit();
+}
+
+
+/*
+ * ------------------------------------------------------------
+ * rs_throttle()
+ * 
+ * This routine is called by the upper-layer tty layer to signal that
+ * incoming characters should be throttled.
+ * ------------------------------------------------------------
+ */
+static void rs_throttle(struct tty_struct * tty)
+{
+#ifdef TX3912_UART_DEBUG_THROTTLE
+	char	buf[64];
+	
+	printk("throttle %s: %d....\n", tty_name(tty, buf),
+	       tty->ldisc.chars_in_buffer(tty));
+#endif
+
+	func_enter ();
+	
+	if (I_IXOFF(tty))
+		rs_send_xchar(tty, STOP_CHAR(tty));
+
+	func_exit ();
+}
+
+static void rs_unthrottle(struct tty_struct * tty)
+{
+	struct rs_port *port = (struct rs_port *)tty->driver_data;
+#ifdef TX3912_UART_DEBUG_THROTTLE
+	char	buf[64];
+	
+	printk("unthrottle %s: %d....\n", tty_name(tty, buf),
+	       tty->ldisc.chars_in_buffer(tty));
+#endif
+
+	func_enter();
+	
+	if (I_IXOFF(tty)) {
+		if (port->x_char)
+			port->x_char = 0;
+		else
+			rs_send_xchar(tty, START_CHAR(tty));
+	}
+
+	func_exit();
+}
+
+
+
+
+
+/* ********************************************************************** *
+ *                    Here are the initialization routines.               *
+ * ********************************************************************** */
+
+void * ckmalloc (int size)
+{
+        void *p;
+
+        p = kmalloc(size, GFP_KERNEL);
+        if (p) 
+                memset(p, 0, size);
+        return p;
+}
+
+
+
+static int rs_init_portstructs(void)
+{
+	struct rs_port *port;
+	int i;
+
+	/* Debugging */
+	func_enter();
+
+	rs_ports          = ckmalloc(TX3912_UART_NPORTS * sizeof (struct rs_port));
+	if (!rs_ports)
+		return -ENOMEM;
+
+	rs_termios        = ckmalloc(TX3912_UART_NPORTS * sizeof (struct termios *));
+	if (!rs_termios) {
+		kfree (rs_ports);
+		return -ENOMEM;
+	}
+
+	rs_termios_locked = ckmalloc(TX3912_UART_NPORTS * sizeof (struct termios *));
+	if (!rs_termios_locked) {
+		kfree (rs_ports);
+		kfree (rs_termios);
+		return -ENOMEM;
+	}
+
+	/* Adjust the values in the "driver" */
+	rs_driver.termios = rs_termios;
+	rs_driver.termios_locked = rs_termios_locked;
+
+	port = rs_ports;
+	for (i=0; i < TX3912_UART_NPORTS;i++) {
+		rs_dprintk (TX3912_UART_DEBUG_INIT, "initing port %d\n", i);
+		port->gs.callout_termios = tty_std_termios;
+		port->gs.normal_termios	= tty_std_termios;
+		port->gs.magic = SERIAL_MAGIC;
+		port->gs.close_delay = HZ/2;
+		port->gs.closing_wait = 30 * HZ;
+		port->gs.rd = &rs_real_driver;
+#ifdef NEW_WRITE_LOCKING
+		port->gs.port_write_sem = MUTEX;
+#endif
+#ifdef DECLARE_WAITQUEUE
+		init_waitqueue_head(&port->gs.open_wait);
+		init_waitqueue_head(&port->gs.close_wait);
+#endif
+		port->base = (i == 0) ? TX3912_UARTA_BASE : TX3912_UARTB_BASE;
+		port->intshift = (i == 0) ? UARTA_SHIFT : UARTB_SHIFT;
+		rs_dprintk (TX3912_UART_DEBUG_INIT, "base 0x%08lx intshift %d\n",
+			    port->base, port->intshift);
+		port++;
+	}
+
+	func_exit();
+	return 0;
+}
+
+static int rs_init_drivers(void)
+{
+	int error;
+
+	func_enter();
+
+	memset(&rs_driver, 0, sizeof(rs_driver));
+	rs_driver.magic = TTY_DRIVER_MAGIC;
+	rs_driver.driver_name = "serial";
+	rs_driver.name = "ttyS";
+	rs_driver.major = TTY_MAJOR;
+	rs_driver.minor_start = 64;
+	rs_driver.num = TX3912_UART_NPORTS;
+	rs_driver.type = TTY_DRIVER_TYPE_SERIAL;
+	rs_driver.subtype = SERIAL_TYPE_NORMAL;
+	rs_driver.init_termios = tty_std_termios;
+	rs_driver.init_termios.c_cflag =
+		B115200 | CS8 | CREAD | HUPCL | CLOCAL;
+	rs_driver.refcount = &rs_refcount;
+	rs_driver.table = rs_table;
+	rs_driver.termios = rs_termios;
+	rs_driver.termios_locked = rs_termios_locked;
+
+	rs_driver.open	= rs_open;
+	rs_driver.close = gs_close;
+	rs_driver.write = gs_write;
+	rs_driver.put_char = gs_put_char; 
+	rs_driver.flush_chars = gs_flush_chars;
+	rs_driver.write_room = gs_write_room;
+	rs_driver.chars_in_buffer = gs_chars_in_buffer;
+	rs_driver.flush_buffer = gs_flush_buffer;
+	rs_driver.ioctl = rs_ioctl;
+	rs_driver.throttle = rs_throttle;
+	rs_driver.unthrottle = rs_unthrottle;
+	rs_driver.set_termios = gs_set_termios;
+	rs_driver.stop = gs_stop;
+	rs_driver.start = gs_start;
+	rs_driver.hangup = gs_hangup;
+
+	rs_callout_driver = rs_driver;
+	rs_callout_driver.name = "cua";
+	rs_callout_driver.major = TTYAUX_MAJOR;
+	rs_callout_driver.subtype = SERIAL_TYPE_CALLOUT;
+
+	if ((error = tty_register_driver(&rs_driver))) {
+		printk(KERN_ERR "Couldn't register serial driver, error = %d\n",
+		       error);
+		return 1;
+	}
+	if ((error = tty_register_driver(&rs_callout_driver))) {
+		tty_unregister_driver(&rs_driver);
+		printk(KERN_ERR "Couldn't register callout driver, error = %d\n",
+		       error);
+		return 1;
+	}
+
+	func_exit();
+	return 0;
+}
+
+
+void __init tx3912_rs_init(void)
+{
+	int rc;
+
+
+	func_enter();
+	rs_dprintk (TX3912_UART_DEBUG_INIT, "Initing serial module... (rs_debug=%d)\n", rs_debug);
+
+	rc = rs_init_portstructs ();
+	rs_init_drivers ();
+	if (request_irq(2, rs_tx_interrupt_uarta, SA_SHIRQ | SA_INTERRUPT,
+			"serial", &rs_ports[0])) {
+		printk(KERN_ERR "rs: Cannot allocate irq for UARTA.\n");
+		rc = 0;
+	}
+	if (request_irq(3, rs_rx_interrupt_uarta, SA_SHIRQ | SA_INTERRUPT,
+			"serial", &rs_ports[0])) {
+		printk(KERN_ERR "rs: Cannot allocate irq for UARTA.\n");
+		rc = 0;
+	}
+
+	IntEnable6 |= INT6_UARTARXINT; 
+	rs_enable_rx_interrupts(&rs_ports[0]); 
+
+#ifndef CONFIG_SERIAL_TX3912_CONSOLE
+{
+	unsigned int scratch = 0;
+
+	/* Setup master clock for UART */
+	scratch = inl(TX3912_CLK_CTRL_BASE);
+	scratch &= ~TX3912_CLK_CTRL_SIBMCLKDIV_MASK;
+	scratch |= ((0x2 << TX3912_CLK_CTRL_SIBMCLKDIV_SHIFT) &
+				TX3912_CLK_CTRL_SIBMCLKDIV_MASK)
+			| TX3912_CLK_CTRL_SIBMCLKDIR
+			| TX3912_CLK_CTRL_ENSIBMCLK
+			| TX3912_CLK_CTRL_CSERSEL;
+	outl(scratch, TX3912_CLK_CTRL_BASE);
+
+	/* Configure UARTA clock */
+	scratch = inl(TX3912_CLK_CTRL_BASE);
+	scratch |= ((0x3 << TX3912_CLK_CTRL_CSERDIV_SHIFT) &
+				TX3912_CLK_CTRL_CSERDIV_MASK)
+			| TX3912_CLK_CTRL_ENCSERCLK
+			| TX3912_CLK_CTRL_ENUARTACLK;
+	outl(scratch, TX3912_CLK_CTRL_BASE);
+		
+	/* Setup UARTA for 115200,8N1 */
+	outl(0, TX3912_UARTA_BASE + TX3912_UART_CTRL1);
+	outl(TX3912_UART_CTRL2_B115200, TX3912_UARTA_BASE + TX3912_UART_CTRL2);
+	outl(0, TX3912_UARTA_BASE + TX3912_UART_DMA_CTRL1);
+	outl(0, TX3912_UARTA_BASE + TX3912_UART_DMA_CTRL2);
+
+	/* Enable UARTA */
+	outl(TX3912_UART_CTRL1_ENUART, TX3912_UARTA_BASE + TX3912_UART_CTRL1);
+	while (~inl(TX3912_UARTA_BASE + TX3912_UART_CTRL1) &
+		TX3912_UART_CTRL1_UARTON);
+}
+#endif
+
+	/* Note: I didn't do anything to enable the second UART */
+	if (rc >= 0) 
+		rs_initialized++;
+
+	func_exit();
+}
+
+/*
+ * Begin serial console routines
+ */
+#ifdef CONFIG_SERIAL_TX3912_CONSOLE
+
+void serial_outc(unsigned char c)
+{
+	int i;
+	unsigned long int2;
+	#define BUSY_WAIT 10000
+
+	/*
+	 * Turn UARTA interrupts off
+	 */
+	int2 = IntEnable2;
+	IntEnable2 &=
+		~(INT2_UARTATXINT | INT2_UARTATXOVERRUN | INT2_UARTAEMPTY);
+
+	/*
+	 * The UART_TX_EMPTY bit in UartA_Ctrl1 seems
+	 * not to be very reliable :-(
+	 *
+	 * Wait for the Tx register to become empty
+	 */
+	for (i = 0; !(IntStatus2 & INT2_UARTATXINT) && (i < BUSY_WAIT); i++);
+
+	IntClear2 = INT2_UARTATXINT | INT2_UARTATXOVERRUN | INT2_UARTAEMPTY;
+	UartA_Data = c;
+	for (i = 0; !(IntStatus2 & INT2_UARTATXINT) && (i < BUSY_WAIT); i++);
+	IntClear2 = INT2_UARTATXINT | INT2_UARTATXOVERRUN | INT2_UARTAEMPTY;
+
+	IntEnable2 = int2;
+}
+
+static int serial_console_wait_key(struct console *co)
+{
+	unsigned int int2, res;
+
+	int2 = IntEnable2;
+	IntEnable2 = 0;
+
+	while (!(UartA_Ctrl1 & UART_RX_HOLD_FULL));
+	res = UartA_Data;
+	udelay(10);
+	
+	IntEnable2 = int2;
+	return res;
+}
+
+static void serial_console_write(struct console *co, const char *s,
+		unsigned count)
+{
+    	unsigned int i;
+
+	for (i = 0; i < count; i++) {
+		if (*s == '\n')
+			serial_outc('\r');
+		serial_outc(*s++);
+    	}
+}
+
+static kdev_t serial_console_device(struct console *c)
+{
+	return MKDEV(TTY_MAJOR, 64 + c->index);
+}
+
+static __init int serial_console_setup(struct console *co, char *options)
+{
+	unsigned int scratch = 0;
+
+	/* Setup master clock for UART */
+	scratch = inl(TX3912_CLK_CTRL_BASE);
+	scratch &= ~TX3912_CLK_CTRL_SIBMCLKDIV_MASK;
+	scratch |= ((0x2 << TX3912_CLK_CTRL_SIBMCLKDIV_SHIFT) &
+				TX3912_CLK_CTRL_SIBMCLKDIV_MASK)
+			| TX3912_CLK_CTRL_SIBMCLKDIR
+			| TX3912_CLK_CTRL_ENSIBMCLK
+			| TX3912_CLK_CTRL_CSERSEL;
+	outl(scratch, TX3912_CLK_CTRL_BASE);
+
+	/* Configure UARTA clock */
+	scratch = inl(TX3912_CLK_CTRL_BASE);
+	scratch |= ((0x3 << TX3912_CLK_CTRL_CSERDIV_SHIFT) &
+				TX3912_CLK_CTRL_CSERDIV_MASK)
+			| TX3912_CLK_CTRL_ENCSERCLK
+			| TX3912_CLK_CTRL_ENUARTACLK;
+	outl(scratch, TX3912_CLK_CTRL_BASE);
+		
+	/* Setup UARTA for 115200,8N1 */
+	outl(0, TX3912_UARTA_BASE + TX3912_UART_CTRL1);
+	outl(TX3912_UART_CTRL2_B115200, TX3912_UARTA_BASE + TX3912_UART_CTRL2);
+	outl(0, TX3912_UARTA_BASE + TX3912_UART_DMA_CTRL1);
+	outl(0, TX3912_UARTA_BASE + TX3912_UART_DMA_CTRL2);
+
+	/* Enable UARTA */
+	outl(TX3912_UART_CTRL1_ENUART, TX3912_UARTA_BASE + TX3912_UART_CTRL1);
+	while (~inl(TX3912_UARTA_BASE + TX3912_UART_CTRL1) &
+		TX3912_UART_CTRL1_UARTON);
+
+	return 0;
+}
+
+static struct console sercons = {
+	name:     "ttyS",
+	write:    serial_console_write,
+	device:   serial_console_device,
+	wait_key: serial_console_wait_key,
+	setup:    serial_console_setup,
+	flags:    CON_PRINTBUFFER,
+	index:    -1
+};
+
+void __init tx3912_console_init(void)
+{
+	register_console(&sercons);
+}
+
+#endif
diff -u --recursive --new-file v2.4.9/linux/drivers/char/serial_tx3912.h linux/drivers/char/serial_tx3912.h
--- v2.4.9/linux/drivers/char/serial_tx3912.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/serial_tx3912.h	Fri Sep  7 09:28:38 2001
@@ -0,0 +1,92 @@
+/*
+ *  drivers/char/serial_tx3912.h
+ *
+ *  Copyright (C) 1999 Harald Koerfgen
+ *  Copyright (C) 2000 Jim Pick <jim@jimpick.com>
+ *  Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Serial driver for TMPR3912/05 and PR31700 processors
+ */
+#include <linux/serialP.h>
+#include <linux/generic_serial.h>
+
+/* UART Interrupt (Interrupt 2) bits (UARTA,UARTB) */
+#define UART_RX_INT         9  /* receiver holding register full  (31, 21) */
+#define UART_RXOVERRUN_INT  8  /* receiver overrun error          (30, 20) */
+#define UART_FRAMEERR_INT   7  /* receiver frame error            (29, 19) */
+#define UART_BREAK_INT      6  /* received break signal           (28, 18) */
+#define UART_PARITYERR_INT  5  /* receiver parity error           (27, 17) */
+#define UART_TX_INT         4  /* transmit holding register empty (26, 16) */
+#define UART_TXOVERRUN_INT  3  /* transmit overrun error          (25, 15) */
+#define UART_EMPTY_INT      2  /* both trans/recv regs empty      (24, 14) */
+#define UART_DMAFULL_INT    1  /* DMA at end of buffer            (23, 13) */
+#define UART_DMAHALF_INT    0  /* DMA halfway through buffer */   (22, 12) */
+
+#define UARTA_SHIFT        22
+#define UARTB_SHIFT        12
+
+#define INTTYPE(interrupttype)            (1 << interrupttype)
+
+/* 
+ * This driver can spew a whole lot of debugging output at you. If you
+ * need maximum performance, you should disable the DEBUG define.
+ */
+#undef TX3912_UART_DEBUG
+
+#ifdef TX3912_UART_DEBUG
+#define TX3912_UART_DEBUG_OPEN		0x00000001
+#define TX3912_UART_DEBUG_SETTING	0x00000002
+#define TX3912_UART_DEBUG_FLOW		0x00000004
+#define TX3912_UART_DEBUG_MODEMSIGNALS	0x00000008
+#define TX3912_UART_DEBUG_TERMIOS	0x00000010
+#define TX3912_UART_DEBUG_TRANSMIT	0x00000020
+#define TX3912_UART_DEBUG_RECEIVE	0x00000040
+#define TX3912_UART_DEBUG_INTERRUPTS	0x00000080
+#define TX3912_UART_DEBUG_PROBE		0x00000100
+#define TX3912_UART_DEBUG_INIT		0x00000200
+#define TX3912_UART_DEBUG_CLEANUP	0x00000400
+#define TX3912_UART_DEBUG_CLOSE		0x00000800
+#define TX3912_UART_DEBUG_FIRMWARE	0x00001000
+#define TX3912_UART_DEBUG_MEMTEST	0x00002000
+#define TX3912_UART_DEBUG_THROTTLE	0x00004000
+#define TX3912_UART_DEBUG_ALL		0xffffffff
+
+int rs_debug = TX3912_UART_DEBUG_ALL & ~TX3912_UART_DEBUG_TRANSMIT;
+
+#define rs_dprintk(f, str...) if (rs_debug & f) printk (str)
+#define func_enter() rs_dprintk (TX3912_UART_DEBUG_FLOW,	\
+				"rs: enter " __FUNCTION__ "\n")
+#define func_exit() rs_dprintk (TX3912_UART_DEBUG_FLOW,	\
+				"rs: exit " __FUNCTION__ "\n")
+
+#else
+#define rs_dprintk(f, str...)
+#define func_enter()
+#define func_exit()
+
+#endif	/* TX3912_UART_DEBUG */
+
+/*
+ * Number of serial ports
+ */
+#define TX3912_UART_NPORTS  2
+
+/*
+ * Hardware specific serial port structure
+ */
+struct rs_port { 	
+	struct gs_port		gs;		/* Must be first field! */
+
+	unsigned long		base;
+	int			intshift;	/* Register shift */
+	struct wait_queue	*shutdown_wait; 
+	int			stat_flags;
+        struct async_icount	icount;		/* Counters for 4 input IRQs */
+	int			read_status_mask;
+	int			ignore_status_mask;
+	int			x_char;		/* XON/XOFF character */
+}; 
diff -u --recursive --new-file v2.4.9/linux/drivers/char/sh-sci.c linux/drivers/char/sh-sci.c
--- v2.4.9/linux/drivers/char/sh-sci.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/char/sh-sci.c	Sat Sep  8 12:29:09 2001
@@ -44,7 +44,7 @@
 
 #include <linux/generic_serial.h>
 
-#ifdef CONFIG_DEBUG_KERNEL_WITH_GDB_STUB
+#ifdef CONFIG_SH_STANDARD_BIOS
 #include <asm/sh_bios.h>
 #endif
 
@@ -94,6 +94,7 @@
 
 #define dprintk(x...) do { if (sci_debug) printk(x); } while(0)
 
+#ifdef CONFIG_SERIAL_CONSOLE
 static void put_char(struct sci_port *port, char c)
 {
 	unsigned long flags;
@@ -111,8 +112,9 @@
 
 	restore_flags(flags);
 }
+#endif
 
-#ifdef CONFIG_DEBUG_KERNEL_WITH_GDB_STUB
+#ifdef CONFIG_SH_STANDARD_BIOS
 
 static void handle_error(struct sci_port *port)
 {				/* Clear error flags */
@@ -161,12 +163,12 @@
  * This routine does not wait for a positive acknowledge.
  */
 
-static void put_string(struct sci_port *port,
-				  const char *buffer, int count)
+#ifdef CONFIG_SERIAL_CONSOLE
+static void put_string(struct sci_port *port, const char *buffer, int count)
 {
 	int i;
 	const unsigned char *p = buffer;
-#ifdef CONFIG_DEBUG_KERNEL_WITH_GDB_STUB
+#ifdef CONFIG_SH_STANDARD_BIOS
 	int checksum;
 
     	/* This call only does a trap the first time it is
@@ -202,7 +204,7 @@
 		put_char(port, *p++);
 	}
 }
-
+#endif
 
 
 static struct real_driver sci_real_driver = {
@@ -1159,7 +1161,7 @@
 
 	sci_init_drivers();
 
-#ifdef CONFIG_DEBUG_KERNEL_WITH_GDB_STUB
+#ifdef CONFIG_SH_STANDARD_BIOS
 	sh_bios_gdb_detach();
 #endif
 	return 0;		/* Return -EIO when not detected */
diff -u --recursive --new-file v2.4.9/linux/drivers/char/softdog.c linux/drivers/char/softdog.c
--- v2.4.9/linux/drivers/char/softdog.c	Sat May 19 17:43:05 2001
+++ linux/drivers/char/softdog.c	Fri Sep  7 09:28:38 2001
@@ -160,7 +160,7 @@
 	fops:		&softdog_fops,
 };
 
-static const char banner[] __initdata = KERN_INFO "Software Watchdog Timer: 0.05, timer margin: %d sec\n";
+static char banner[] __initdata = KERN_INFO "Software Watchdog Timer: 0.05, timer margin: %d sec\n";
 
 static int __init watchdog_init(void)
 {
diff -u --recursive --new-file v2.4.9/linux/drivers/char/sx.c linux/drivers/char/sx.c
--- v2.4.9/linux/drivers/char/sx.c	Wed Jul 25 17:10:20 2001
+++ linux/drivers/char/sx.c	Fri Sep  7 09:28:38 2001
@@ -365,6 +365,8 @@
 MODULE_PARM(sx_debug, "i");
 MODULE_PARM(sx_irqmask, "i");
 
+MODULE_LICENSE("GPL");
+
 static struct real_driver sx_real_driver = {
 	sx_disable_tx_interrupts,
 	sx_enable_tx_interrupts,
@@ -1139,7 +1141,7 @@
 		sx_dprintk (SX_DEBUG_MODEMSIGNALS, "got a break.\n");
 
 		sx_write_channel_byte (port, hi_state, hi_state);
-		gs_got_break (port);
+		gs_got_break (&port->gs);
 	}
 	if (hi_state & ST_DCD) {
 		hi_state &= ~ST_DCD;
@@ -1614,6 +1616,7 @@
 #define R0         if (read_sx_word (board, i) != 0x55aa) return 1
 #define R1         if (read_sx_word (board, i) != 0xaa55) return 1
 
+#if 0
 /* This memtest takes a human-noticable time. You normally only do it
    once a boot, so I guess that it is worth it. */
 static int do_memtest_w (struct sx_board *board, int min, int max)
@@ -1628,6 +1631,7 @@
 
 	return 0;
 }
+#endif
 
 
 static int sx_fw_ioctl (struct inode *inode, struct file *filp,
diff -u --recursive --new-file v2.4.9/linux/drivers/char/tpqic02.c linux/drivers/char/tpqic02.c
--- v2.4.9/linux/drivers/char/tpqic02.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/char/tpqic02.c	Fri Sep  7 09:28:38 2001
@@ -92,7 +92,7 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/smp_lock.h>
-#include <linux/devfs_fs_kernel.h> 
+#include <linux/devfs_fs_kernel.h>
 
 #include <asm/dma.h>
 #include <asm/system.h>
@@ -116,8 +116,8 @@
  * card+drive info if runtime configuration has been selected.
  */
 
-static struct mtconfiginfo qic02_tape_dynconf = 	/* user settable */
-    { 0, 0, BOGUS_IRQ, 0, 0, TPQD_DEFAULT_FLAGS, };
+static struct mtconfiginfo qic02_tape_dynconf =	/* user settable */
+{ 0, 0, BOGUS_IRQ, 0, 0, TPQD_DEFAULT_FLAGS, };
 static struct qic02_ccb qic02_tape_ccb;	/* private stuff */
 
 #else
@@ -127,11 +127,11 @@
 # if ((QIC02_TAPE_IFC!=WANGTEK) && (QIC02_TAPE_IFC!=ARCHIVE) && (QIC02_TAPE_IFC!=MOUNTAIN))
 #  error No valid interface card specified
 # endif
-#endif /* CONFIG_QIC02_DYNCONF */
+#endif				/* CONFIG_QIC02_DYNCONF */
 
-static volatile int ctlbits;     /* control reg bits for tape interface */
+static volatile int ctlbits;	/* control reg bits for tape interface */
 
-static wait_queue_head_t qic02_tape_transfer; /* sync rw with interrupts */
+static wait_queue_head_t qic02_tape_transfer;	/* sync rw with interrupts */
 
 static volatile struct mtget ioctl_status;	/* current generic status */
 
@@ -146,15 +146,15 @@
  * by an interrupt.
  */
 static volatile flag status_dead = YES;	/* device is legally dead until proven alive */
-static 		flag status_zombie = YES; /* it's `zombie' until irq/dma allocated */
+static flag status_zombie = YES;	/* it's `zombie' until irq/dma allocated */
 
 static volatile flag status_bytes_wr = NO;	/* write FM at close or not */
 static volatile flag status_bytes_rd = NO;	/* (rd|wr) used for rewinding */
 
-static volatile unsigned long status_cmd_pending; /* cmd in progress */
+static volatile unsigned long status_cmd_pending;	/* cmd in progress */
 static volatile flag status_expect_int = NO;	/* ready for interrupts */
-static volatile flag status_timer_on = NO; 	/* using time-out */
-static volatile int  status_error;		/* int handler may detect error */
+static volatile flag status_timer_on = NO;	/* using time-out */
+static volatile int status_error;	/* int handler may detect error */
 static volatile flag status_eof_detected = NO;	/* end of file */
 static volatile flag status_eom_detected = NO;	/* end of recorded media */
 static volatile flag status_eot_detected = NO;	/* end of tape */
@@ -163,8 +163,8 @@
 
 static volatile unsigned long dma_bytes_todo;
 static volatile unsigned long dma_bytes_done;
-static volatile unsigned dma_mode;		/* !=0 also means DMA in use */
-static 		flag need_rewind = YES;
+static volatile unsigned dma_mode;	/* !=0 also means DMA in use */
+static flag need_rewind = YES;
 
 static kdev_t current_tape_dev;
 static int extra_blocks_left = BLOCKS_BEYOND_EW;
@@ -198,7 +198,7 @@
  * mode is allowed as long as no actual writing has been done. After writing
  * the File Mark, repositioning and reading are allowed again.
  */
-static int  mode_access;	/* access mode: READ or WRITE */
+static int mode_access;		/* access mode: READ or WRITE */
 
 static int qic02_get_resources(void);
 static void qic02_release_resources(void);
@@ -210,17 +210,17 @@
  * must ensure that a large enough buffer is passed to the kernel, in order
  * to reduce tape repositioning wear and tear.
  */
-static void *buffaddr;	/* virtual address of buffer */
+static void *buffaddr;		/* virtual address of buffer */
 
 /* This translates minor numbers to the corresponding recording format: */
 static const char *format_names[] = {
-	"not set",	/* for dumb drives unable to handle format selection */
-	"11",		/* extinct */
+	"not set",		/* for dumb drives unable to handle format selection */
+	"11",			/* extinct */
 	"24",
 	"120",
 	"150",
-	"300",		/* untested. */
-	"600"		/* untested. */
+	"300",			/* untested. */
+	"600"			/* untested. */
 };
 
 
@@ -248,52 +248,72 @@
 	const char *msg;
 	/* EXC_nr attribute should match with tpqic02.h */
 } exception_list[] = {
-	{0, 0,
-		"Unknown exception status code",		/* extra: 0 */},
-	{~(0), TP_ST0|TP_CNI|TP_USL|TP_WRP,
-		"Drive not online"				/* 1 */},
-		/* Drive presence goes before cartridge presence. */
-	{~(TP_WRP|TP_USL), TP_ST0|TP_CNI,
-		/* My Wangtek 5150EQ sometimes reports a status code
-		 * of 0x00e0, which is not a valid exception code, but
-		 * I think it should be recognized as "NO CARTRIDGE".
-		 */
-		"Cartridge not in place"			/* 2 */},
-	{(unsigned short) ~(TP_ST1|TP_BOM), (TP_ST0|TP_WRP),
-		"Write protected cartridge"			/* 3 */},
-	{(unsigned short) ~(TP_ST1|TP_EOR), (TP_ST0|TP_EOM),
-		"End of media"					/* 4 */},
-	{~TP_WRP, TP_ST0|TP_UDA| TP_ST1|TP_BOM,
-		"Read or Write abort. Rewind tape."		/* 5 */},
-	{~TP_WRP, TP_ST0|TP_UDA,
-		"Read error. Bad block transferred."		/* 6 */},
-	{~TP_WRP, TP_ST0|TP_UDA|TP_BNL,
-		"Read error. Filler block transferred."		/* 7 */},
-	{~TP_WRP, TP_ST0|TP_UDA|TP_BNL |TP_ST1|TP_NDT,
-		"Read error. No data detected."			/* 8 */},
-	{~TP_WRP, TP_ST0|TP_EOM|TP_UDA|TP_BNL |TP_ST1|TP_NDT,
-		"Read error. No data detected. EOM."		/* 9 */},
-	{~(TP_WRP|TP_MBD|TP_PAR|TP_EOR), TP_ST0|TP_UDA|TP_BNL |TP_ST1|TP_NDT|TP_BOM,
-		"Read error. No data detected. BOM."		/* 10 */},
-	{~(TP_WRP|TP_EOM), TP_ST0|TP_FIL,
-		/* Status 0x0089 (EOM & FM) is viewed as an FM,
-		 * because it can only happen during a read.
-		 * EOM is checked separately for an FM condition.
-		 */
-		"File mark detected"				/* 11 */},
-	{~(TP_ST0|TP_CNI|TP_USL|TP_WRP|TP_BOM), TP_ST1|TP_ILL,
-		"Illegal command"				/* 12 */},
-	{~(TP_ST0|TP_CNI|TP_USL|TP_WRP|TP_BOM), TP_ST1|TP_POR,
-		"Reset occurred"					/* 13 */},
-	{~TP_WRP, TP_ST0|TP_FIL|TP_MBD,		/* NOTE: ST1 not set! */
-		"Marginal block detected"			/* 14 */},
-	{~(TP_ST0|TP_WRP|TP_EOM|TP_UDA|TP_BNL|TP_FIL |TP_NDT), TP_ST1|TP_EOR,
+	{
+	0, 0, "Unknown exception status code", /* extra: 0 */ },
+	{
+	~(0), TP_ST0 | TP_CNI | TP_USL | TP_WRP,
+		    "Drive not online" /* 1 */ },
+	    /* Drive presence goes before cartridge presence. */
+	{
+		~(TP_WRP | TP_USL), TP_ST0 | TP_CNI,
+		    /* My Wangtek 5150EQ sometimes reports a status code
+		     * of 0x00e0, which is not a valid exception code, but
+		     * I think it should be recognized as "NO CARTRIDGE".
+		     */
+	"Cartridge not in place" /* 2 */ },
+	{
+	(unsigned short) ~(TP_ST1 | TP_BOM), (TP_ST0 | TP_WRP),
+		    "Write protected cartridge" /* 3 */ },
+	{
+	(unsigned short) ~(TP_ST1 | TP_EOR), (TP_ST0 | TP_EOM),
+		    "End of media" /* 4 */ },
+	{
+	~TP_WRP, TP_ST0 | TP_UDA | TP_ST1 | TP_BOM,
+		    "Read or Write abort. Rewind tape." /* 5 */ },
+	{
+	~TP_WRP, TP_ST0 | TP_UDA,
+		    "Read error. Bad block transferred." /* 6 */ },
+	{
+	~TP_WRP, TP_ST0 | TP_UDA | TP_BNL,
+		    "Read error. Filler block transferred." /* 7 */ },
+	{
+	~TP_WRP, TP_ST0 | TP_UDA | TP_BNL | TP_ST1 | TP_NDT,
+		    "Read error. No data detected." /* 8 */ },
+	{
+	~TP_WRP,
+		    TP_ST0 | TP_EOM | TP_UDA | TP_BNL | TP_ST1 |
+		    TP_NDT, "Read error. No data detected. EOM." /* 9 */ },
+	{
+	~(TP_WRP | TP_MBD | TP_PAR | TP_EOR),
+		    TP_ST0 | TP_UDA | TP_BNL | TP_ST1 | TP_NDT |
+		    TP_BOM,
+		    "Read error. No data detected. BOM." /* 10 */ },
+	{
+		~(TP_WRP | TP_EOM), TP_ST0 | TP_FIL,
+		    /* Status 0x0089 (EOM & FM) is viewed as an FM,
+		     * because it can only happen during a read.
+		     * EOM is checked separately for an FM condition.
+		     */
+	"File mark detected" /* 11 */ },
+	{
+	~(TP_ST0 | TP_CNI | TP_USL | TP_WRP | TP_BOM),
+		    TP_ST1 | TP_ILL, "Illegal command" /* 12 */ },
+	{
+	~(TP_ST0 | TP_CNI | TP_USL | TP_WRP | TP_BOM),
+		    TP_ST1 | TP_POR, "Reset occurred" /* 13 */ },
+	{
+		~TP_WRP, TP_ST0 | TP_FIL | TP_MBD,	/* NOTE: ST1 not set! */
+	"Marginal block detected" /* 14 */ },
+	{
+		~(TP_ST0 | TP_WRP | TP_EOM | TP_UDA | TP_BNL | TP_FIL |
+		  TP_NDT), TP_ST1 | TP_EOR,
 		/********** Is the extra TP_NDT really needed Eddy? **********/
-		"End of recorded media"				/* extra: 15 */},
-		/* 15 is returned when SEEKEOD completes successfully */
-	{~(TP_WRP|TP_ST0), TP_ST1|TP_BOM,
-		"Beginning of media"				/* extra: 16 */}
+	"End of recorded media" /* extra: 15 */ },
+	    /* 15 is returned when SEEKEOD completes successfully */
+	{
+	~(TP_WRP | TP_ST0), TP_ST1 | TP_BOM, "Beginning of media" /* extra: 16 */ }
 };
+
 #define NR_OF_EXC	(sizeof(exception_list)/sizeof(struct exception_list_type))
 
 /* Compare expected struct size and actual struct size. This
@@ -310,7 +330,7 @@
 {
 	if ((flags & TPQD_ALWAYS) || (flags & QIC02_TAPE_DEBUG))
 		printk(TPQIC02_NAME ": %s\n", s);
-} /* tpqputs */
+}				/* tpqputs */
 
 
 /* Perform byte order swapping for a 16-bit word.
@@ -318,11 +338,10 @@
  * [FIXME] This should probably be in include/asm/
  * ([FIXME] i486 can do this faster)
  */
-static inline void byte_swap_w(volatile unsigned short * w)
+static inline void byte_swap_w(volatile unsigned short *w)
 {
 	int t = *w;
-
-	*w = (t>>8) | ((t & 0xff)<<8);
+	*w = (t >> 8) | ((t & 0xff) << 8);
 }
 
 
@@ -334,37 +353,32 @@
  */
 static void ifc_init(void)
 {
-    if (QIC02_TAPE_IFC == WANGTEK) /* || (QIC02_TAPE_IFC == EVEREX) */
-    {
-	ctlbits = WT_CTL_ONLINE;	/* online */
-	outb_p(ctlbits, QIC02_CTL_PORT);
-    }
-    else if (QIC02_TAPE_IFC == ARCHIVE)
-    {
-	ctlbits = 0;			/* no interrupts yet */
-	outb_p(ctlbits, QIC02_CTL_PORT);
-	outb_p(0, AR_RESET_DMA_PORT);	/* dummy write to reset DMA */
-    }
-    else /* MOUNTAIN */
-    {
-	ctlbits = MTN_CTL_ONLINE;       /* online, and logic enabled */
-	outb_p(ctlbits, QIC02_CTL_PORT);
-    }
-} /* ifc_init */
+	if (QIC02_TAPE_IFC == WANGTEK) {	/* || (QIC02_TAPE_IFC == EVEREX) */
+		ctlbits = WT_CTL_ONLINE;	/* online */
+		outb_p(ctlbits, QIC02_CTL_PORT);
+	} else if (QIC02_TAPE_IFC == ARCHIVE) {
+		ctlbits = 0;	/* no interrupts yet */
+		outb_p(ctlbits, QIC02_CTL_PORT);
+		outb_p(0, AR_RESET_DMA_PORT);	/* dummy write to reset DMA */
+	} else {		/* MOUNTAIN */
+
+		ctlbits = MTN_CTL_ONLINE;	/* online, and logic enabled */
+		outb_p(ctlbits, QIC02_CTL_PORT);
+	}
+}				/* ifc_init */
 
 
 static void report_qic_exception(unsigned n)
 {
-    if (n >= NR_OF_EXC)
-    {
-	tpqputs(TPQD_ALWAYS, "Oops -- report_qic_exception");
-	n = 0;
-    }
-    if (TPQDBG(SENSE_TEXT) || n==0)
-    {
-	printk(TPQIC02_NAME ": sense: %s\n", exception_list[n].msg);
-    }
-} /* report_qic_exception */
+	if (n >= NR_OF_EXC) {
+		tpqputs(TPQD_ALWAYS, "Oops -- report_qic_exception");
+		n = 0;
+	}
+	if (TPQDBG(SENSE_TEXT) || n == 0) {
+		printk(TPQIC02_NAME ": sense: %s\n",
+		       exception_list[n].msg);
+	}
+}				/* report_qic_exception */
 
 
 /* Try to map the drive-exception bits `s' to a predefined "exception number",
@@ -374,18 +388,18 @@
  */
 static int decode_qic_exception_nr(unsigned s)
 {
-    int i;
+	int i;
 
-    for (i=1; i<NR_OF_EXC; i++)
-    {
-	if ((s & exception_list[i].mask)==exception_list[i].code)
-	{
-	    return i;
+	for (i = 1; i < NR_OF_EXC; i++) {
+		if ((s & exception_list[i].mask) == exception_list[i].code) {
+			return i;
+		}
 	}
-    }
-    printk(TPQIC02_NAME ": decode_qic_exception_nr: exception(%x) not recognized\n", s);
-    return 0;
-} /* decode_qic_exception_nr */
+	printk(TPQIC02_NAME
+	       ": decode_qic_exception_nr: exception(%x) not recognized\n",
+	       s);
+	return 0;
+}				/* decode_qic_exception_nr */
 
 
 
@@ -394,44 +408,36 @@
  */
 static void handle_qic_exception(int exnr, int exbits)
 {
-    if (exnr==EXC_NCART)
-    {
-	/* Cartridge was changed. Redo sense().
-	 * EXC_NCART should be handled in open().
-	 * It is not permitted to remove the tape while
-	 * the tape driver has open files. 
-	 */
-	need_rewind = YES;
-	status_eof_detected = NO;
-	status_eom_detected = NO;
-    }
-    else if (exnr==EXC_XFILLER)
-    {
-	tpqputs(TPQD_ALWAYS, "[Bad block -- filler data transferred.]");
-    }
-    else if (exnr==EXC_XBAD)
-    {
-	tpqputs(TPQD_ALWAYS, "[CRC failed!]");
-    }
-    else if (exnr==EXC_MARGINAL)
-    {
-	/* A marginal block behaves much like a FM.
-	 * User may continue reading, if desired.
-	 */
-	tpqputs(TPQD_ALWAYS, "[Marginal block]");
-	doing_read = NO;
-    }
-    else if (exnr==EXC_FM)
-    {
-	doing_read = NO;
-    }
-} /* handle_qic_exception */
+	if (exnr == EXC_NCART) {
+		/* Cartridge was changed. Redo sense().
+		 * EXC_NCART should be handled in open().
+		 * It is not permitted to remove the tape while
+		 * the tape driver has open files. 
+		 */
+		need_rewind = YES;
+		status_eof_detected = NO;
+		status_eom_detected = NO;
+	} else if (exnr == EXC_XFILLER) {
+		tpqputs(TPQD_ALWAYS,
+			"[Bad block -- filler data transferred.]");
+	} else if (exnr == EXC_XBAD) {
+		tpqputs(TPQD_ALWAYS, "[CRC failed!]");
+	} else if (exnr == EXC_MARGINAL) {
+		/* A marginal block behaves much like a FM.
+		 * User may continue reading, if desired.
+		 */
+		tpqputs(TPQD_ALWAYS, "[Marginal block]");
+		doing_read = NO;
+	} else if (exnr == EXC_FM) {
+		doing_read = NO;
+	}
+}				/* handle_qic_exception */
 
 
 static inline int is_exception(void)
 {
-    return (inb(QIC02_STAT_PORT) & QIC02_STAT_EXCEPTION) == 0;
-} /* is_exception */
+	return (inb(QIC02_STAT_PORT) & QIC02_STAT_EXCEPTION) == 0;
+}				/* is_exception */
 
 
 /* Reset the tape drive and controller.
@@ -440,54 +446,49 @@
  */
 static int tape_reset(int verbose)
 {
-    ifc_init();				/* reset interface card */
+	ifc_init();		/* reset interface card */
 
-    /* assert reset */
-    if (QIC02_TAPE_IFC == MOUNTAIN)
-    {
-	outb_p(ctlbits & ~MTN_QIC02_CTL_RESET_NOT, QIC02_CTL_PORT);
-    }
-    else /* WANGTEK, ARCHIVE */
-    {
-	outb_p(ctlbits | QIC02_CTL_RESET, QIC02_CTL_PORT);
-    }
-    
-    /* Next, we need to wait >=25 usec. */
-    udelay(30);
-
-    /* after reset, we will be at BOT (modulo an automatic rewind) */
-    status_eof_detected = NO;
-    status_eom_detected = NO;
-    status_cmd_pending = 0;
-    need_rewind = YES;
-    doing_read = doing_write = NO;
-    ioctl_status.mt_fileno = ioctl_status.mt_blkno = 0;
-    
-    /* de-assert reset */
-    if (QIC02_TAPE_IFC == MOUNTAIN)
-    {
-	outb_p(ctlbits | MTN_QIC02_CTL_RESET_NOT, QIC02_CTL_PORT);
-    }
-    else
-    {
-	outb_p(ctlbits & ~QIC02_CTL_RESET, QIC02_CTL_PORT);
-    }
-    
-    /* KLUDGE FOR G++ BUG */
-    { int stat = inb_p(QIC02_STAT_PORT);
-	status_dead = ((stat & QIC02_STAT_RESETMASK) != QIC02_STAT_RESETVAL); }
-    /* if successful, inb(STAT) returned RESETVAL */
-    if (status_dead == YES)
-    {
-	printk(TPQIC02_NAME ": reset failed!\n");
-    }
-    else if (verbose)
-    {
-	printk(TPQIC02_NAME ": reset successful\n");
-    }
-    
-    return (status_dead == YES)? TE_DEAD : TE_OK;
-} /* tape_reset */
+	/* assert reset */
+	if (QIC02_TAPE_IFC == MOUNTAIN) {
+		outb_p(ctlbits & ~MTN_QIC02_CTL_RESET_NOT, QIC02_CTL_PORT);
+	} else {		/* WANGTEK, ARCHIVE */
+
+		outb_p(ctlbits | QIC02_CTL_RESET, QIC02_CTL_PORT);
+	}
+
+	/* Next, we need to wait >=25 usec. */
+	udelay(30);
+
+	/* after reset, we will be at BOT (modulo an automatic rewind) */
+	status_eof_detected = NO;
+	status_eom_detected = NO;
+	status_cmd_pending = 0;
+	need_rewind = YES;
+	doing_read = doing_write = NO;
+	ioctl_status.mt_fileno = ioctl_status.mt_blkno = 0;
+
+	/* de-assert reset */
+	if (QIC02_TAPE_IFC == MOUNTAIN) {
+		outb_p(ctlbits | MTN_QIC02_CTL_RESET_NOT, QIC02_CTL_PORT);
+	} else {
+		outb_p(ctlbits & ~QIC02_CTL_RESET, QIC02_CTL_PORT);
+	}
+
+	/* KLUDGE FOR G++ BUG */
+	{
+		int stat = inb_p(QIC02_STAT_PORT);
+		status_dead =
+		    ((stat & QIC02_STAT_RESETMASK) != QIC02_STAT_RESETVAL);
+	}
+	/* if successful, inb(STAT) returned RESETVAL */
+	if (status_dead == YES) {
+		printk(TPQIC02_NAME ": reset failed!\n");
+	} else if (verbose) {
+		printk(TPQIC02_NAME ": reset successful\n");
+	}
+
+	return (status_dead == YES) ? TE_DEAD : TE_OK;
+}				/* tape_reset */
 
 
 
@@ -504,7 +505,7 @@
 {
 	int i;
 
-	outb_p(cmd, QIC02_CMD_PORT);    /* output the command */
+	outb_p(cmd, QIC02_CMD_PORT);	/* output the command */
 
 	/* wait 1 usec before asserting /REQUEST */
 	udelay(1);
@@ -512,7 +513,7 @@
 	if ((!ignore_ex) && is_exception()) {
 		tpqputs(TPQD_ALWAYS, "*** exception detected in notify_cmd");
 		/** force a reset here **/
-		if (tape_reset(1)==TE_DEAD)
+		if (tape_reset(1) == TE_DEAD)
 			return TE_DEAD;
 		if (is_exception()) {
 			tpqputs(TPQD_ALWAYS, "exception persists after reset.");
@@ -520,33 +521,36 @@
 		}
 	}
 
-	outb_p(ctlbits | QIC02_CTL_REQUEST, QIC02_CTL_PORT);  /* set request bit */
+	outb_p(ctlbits | QIC02_CTL_REQUEST, QIC02_CTL_PORT);	/* set request bit */
 	i = TAPE_NOTIFY_TIMEOUT;
 	/* The specs say this takes about 500 usec, but there is no upper limit!
 	 * If the drive were busy retensioning or something like that,
 	 * it could be *much* longer!
 	 */
-	while ((inb_p(QIC02_STAT_PORT) & QIC02_STAT_READY) && (--i>0))
-		/*skip*/;			  /* wait for ready */
-	if (i==0) {
-		tpqputs(TPQD_ALWAYS, "timed out waiting for ready in notify_cmd");
+	while ((inb_p(QIC02_STAT_PORT) & QIC02_STAT_READY) && (--i > 0))
+		/*skip */ ;
+	/* wait for ready */
+	if (i == 0) {
+		tpqputs(TPQD_ALWAYS,
+			"timed out waiting for ready in notify_cmd");
 		status_dead = YES;
 		return TE_TIM;
 	}
 
-	outb_p(ctlbits & ~QIC02_CTL_REQUEST, QIC02_CTL_PORT); /* reset request bit */
+	outb_p(ctlbits & ~QIC02_CTL_REQUEST, QIC02_CTL_PORT);	/* reset request bit */
 	i = TAPE_NOTIFY_TIMEOUT;
 	/* according to the specs this one should never time-out */
-	while (((inb_p(QIC02_STAT_PORT) & QIC02_STAT_READY) == 0) && (--i>0))
-		/*skip*/;			  /* wait for not ready */
-	if (i==0) {
+	while (((inb_p(QIC02_STAT_PORT) & QIC02_STAT_READY) == 0) && (--i > 0))
+		/*skip */ ;
+	/* wait for not ready */
+	if (i == 0) {
 		tpqputs(TPQD_ALWAYS, "timed out waiting for !ready in notify_cmd");
 		status_dead = YES;
 		return TE_TIM;
 	}
 	/* command accepted */
 	return TE_OK;
-} /* notify_cmd */
+}				/* notify_cmd */
 
 
 
@@ -563,20 +567,22 @@
 	 * First, busy wait a few usec:
 	 */
 	spin_t = 50;
-	while (((stat = inb_p(QIC02_STAT_PORT) & QIC02_STAT_MASK) == QIC02_STAT_MASK) && (--spin_t>0))
+	while (((stat = inb_p(QIC02_STAT_PORT) & QIC02_STAT_MASK) == QIC02_STAT_MASK) && (--spin_t > 0))
 		/*SKIP*/;
 	if ((stat & QIC02_STAT_READY) == 0)
-		return TE_OK;			/* covers 99.99% of all calls */
+		return TE_OK;	/* covers 99.99% of all calls */
 
 	/* Then use schedule() a few times */
-	spin_t = 3;	/* max 0.03 sec busy waiting */
+	spin_t = 3;		/* max 0.03 sec busy waiting */
 	if (spin_t > timeout)
 		spin_t = timeout;
 	timeout -= spin_t;
 	spin_t += jiffies;
 
-	while (((stat = inb_p(QIC02_STAT_PORT) & QIC02_STAT_MASK) == QIC02_STAT_MASK) && time_before(jiffies, spin_t))
-		schedule();		/* don't waste all the CPU time */
+	/* FIXME...*/
+	while (((stat = inb_p(QIC02_STAT_PORT) & QIC02_STAT_MASK) == QIC02_STAT_MASK) 
+		&& time_before(jiffies, spin_t))
+		schedule();	/* don't waste all the CPU time */
 	if ((stat & QIC02_STAT_READY) == 0)
 		return TE_OK;
 
@@ -589,13 +595,13 @@
 	spin_t += timeout;
 	TPQDEB({printk("wait_for_ready: additional timeout: %d\n", spin_t);})
 
-		/* not ready and no exception && timeout not expired yet */
+	    /* not ready and no exception && timeout not expired yet */
 	while (((stat = inb_p(QIC02_STAT_PORT) & QIC02_STAT_MASK) == QIC02_STAT_MASK) && time_before(jiffies, spin_t)) {
 		/* be `nice` to other processes on long operations... */
 		current->state = TASK_INTERRUPTIBLE;
 		/* nap 0.30 sec between checks, */
 		/* but could be woken up earlier by signals... */
-		schedule_timeout(3*HZ/10);
+		schedule_timeout(3 * HZ / 10);
 	}
 
 	/* don't use jiffies for this test because it may have changed by now */
@@ -605,12 +611,13 @@
 	}
 
 	if ((stat & QIC02_STAT_EXCEPTION) == 0) {
-		tpqputs(TPQD_ALWAYS, "exception detected after waiting_for_ready");
+		tpqputs(TPQD_ALWAYS,
+			"exception detected after waiting_for_ready");
 		return TE_EX;
 	} else {
 		return TE_OK;
 	}
-} /* wait_for_ready */
+}				/* wait_for_ready */
 
 
 
@@ -619,7 +626,7 @@
 {
 	int i, stat;
 
-	for (i=0; i<size; i++) {
+	for (i = 0; i < size; i++) {
 
 		stat = wait_for_ready(TIM_S);
 		if (stat != TE_OK)
@@ -630,8 +637,8 @@
 			return stat;
 	}
 	return TE_OK;
-	
-} /* send_qic02_data */
+
+}				/* send_qic02_data */
 
 
 /* Send a QIC-02 command (`cmd') to the tape drive, with
@@ -650,7 +657,7 @@
 		tpqputs(TPQD_ALWAYS, "send_qic02_cmd: Exception!");
 		return TE_EX;
 	}
-	if (stat & QIC02_STAT_READY) {			/* if not ready */
+	if (stat & QIC02_STAT_READY) {	/* if not ready */
 		tpqputs(TPQD_ALWAYS, "send_qic02_cmd: not Ready!");
 		return TE_ERR;
 	}
@@ -662,8 +669,8 @@
 	 */
 	status_cmd_pending = cmd;
 
-	stat = notify_cmd(cmd, ignore_ex); /* tell drive new command was loaded, */
-					   /* inherit exception check. */
+	stat = notify_cmd(cmd, ignore_ex);	/* tell drive new command was loaded, */
+	/* inherit exception check. */
 	if (TP_HAVE_SEEK && (cmd == AR_QCMDV_SEEK_BLK)) {
 		/* This one needs to send 3 more bytes, MSB first */
 		stat = send_qic02_data(seek_addr_buf, sizeof(seek_addr_buf), ignore_ex);
@@ -673,7 +680,7 @@
 		tpqputs(TPQD_ALWAYS, "send_qic02_cmd failed");
 	}
 	return stat;
-} /* send_qic02_cmd */
+}				/* send_qic02_cmd */
 
 
 
@@ -683,8 +690,8 @@
  */
 static int rdstatus(char *stp, unsigned size, char qcmd)
 {
-	int	s, n;
-	char	*q = stp;
+	int s, n;
+	char *q = stp;
 
 	/* Try to busy-wait a few (700) usec, after that de-schedule.
 	 *
@@ -693,21 +700,22 @@
 	 * de-schedule immediately, we waste a lot of time because a
 	 * task switch is much longer than we usually have to wait here.
 	 */
-	n = 1000;	/* 500 is not enough on a 486/33 */
-	while ((n>0) && ((inb_p(QIC02_STAT_PORT) & QIC02_STAT_MASK) == QIC02_STAT_MASK))
-		n--;  /* wait for ready or exception or timeout */
-	if (n==0) {
+	n = 1000;		/* 500 is not enough on a 486/33 */
+	while ((n > 0) && ((inb_p(QIC02_STAT_PORT) & QIC02_STAT_MASK) == QIC02_STAT_MASK))
+		n--;		/* wait for ready or exception or timeout */
+	if (n == 0) {
 		/* n (above) should be chosen such that on your machine
 		 * you rarely ever see the message below, and it should
 		 * be small enough to give reasonable response time.]
 		 */
+	 	/* FIXME */
 		tpqputs(TPQD_ALWAYS, "waiting looong in rdstatus() -- drive dead?");
 		while ((inb_p(QIC02_STAT_PORT) & QIC02_STAT_MASK) == QIC02_STAT_MASK)
 			schedule();
 		tpqputs(TPQD_ALWAYS, "finished waiting in rdstatus()");
 	}
 
-	(void) notify_cmd(qcmd, 1);			/* send read status command */
+	(void) notify_cmd(qcmd, 1);	/* send read status command */
 	/* ignore return code -- should always be ok, STAT may contain 
 	 * exception flag from previous exception which we are trying to clear.
 	 */
@@ -715,21 +723,22 @@
 	if (TP_DIAGS(current_tape_dev))
 		printk(TPQIC02_NAME ": reading status bytes: ");
 
-	for (q=stp; q<stp+size; q++)
-	{
-		do s = inb_p(QIC02_STAT_PORT);
+	for (q = stp; q < stp + size; q++) {
+		do
+			s = inb_p(QIC02_STAT_PORT);
 		while ((s & QIC02_STAT_MASK) == QIC02_STAT_MASK);	/* wait for ready or exception */
 
-		if ((s & QIC02_STAT_EXCEPTION) == 0) {		/* if exception */
+		if ((s & QIC02_STAT_EXCEPTION) == 0) {	/* if exception */
 			tpqputs(TPQD_ALWAYS, "rdstatus: exception error");
-			ioctl_status.mt_erreg = 0;		/* dunno... */
-			return TE_NS;				/* error, shouldn't happen... */
+			ioctl_status.mt_erreg = 0;	/* dunno... */
+			return TE_NS;	/* error, shouldn't happen... */
 		}
 
-		*q = inb_p(QIC02_DATA_PORT);			/* read status byte */
+		*q = inb_p(QIC02_DATA_PORT);	/* read status byte */
 
 		if (TP_DIAGS(current_tape_dev))
-			printk("[%1d]=0x%x  ", q-stp, (unsigned) (*q) & 0xff);
+			printk("[%1d]=0x%x  ", q - stp,
+			       (unsigned) (*q) & 0xff);
 
 		outb_p(ctlbits | QIC02_CTL_REQUEST, QIC02_CTL_PORT);	/* set request */
 
@@ -745,13 +754,14 @@
 	 * My drive doesn't seem to need it here yet, but others do?
 	 */
 	while (inb_p(QIC02_STAT_PORT) & QIC02_STAT_READY)
-		/*skip*/;			  /* wait for ready */
+		/*skip */ ;
+	/* wait for ready */
 
 	if (TP_DIAGS(current_tape_dev))
 		printk("\n");
 
 	return TE_OK;
-} /* rdstatus */
+}				/* rdstatus */
 
 
 
@@ -769,7 +779,7 @@
 	/* should probably swap status bytes #definition */
 #endif
 	return stat;
-} /* get_status */
+}				/* get_status */
 
 
 #if 0
@@ -782,7 +792,7 @@
  */
 static int get_ext_status3(void)
 {
-	char vus[64];	/* vendor unique status */
+	char vus[64];		/* vendor unique status */
 	int stat, i;
 
 	tpqputs(TPQD_ALWAYS, "Attempting to read Extended Status 3...");
@@ -791,15 +801,15 @@
 		return stat;
 
 	tpqputs(TPQD_ALWAYS, "Returned status bytes:");
-	for (i=0; i<sizeof(vus); i++) {
-		if ( i % 8 == 0 )
+	for (i = 0; i < sizeof(vus); i++) {
+		if (i % 8 == 0)
 			printk("\n" TPQIC02_NAME ": %2d:");
 		printk(" %2x", vus[i] & 0xff);
 	}
 	printk("\n");
 
 	return TE_OK;
-} /* get_ext_status3 */
+}				/* get_ext_status3 */
 #endif
 
 
@@ -812,13 +822,14 @@
 	static void finish_rw(int cmd);
 
 	if (TPQDBG(SENSE_TEXT))
-		printk(TPQIC02_NAME ": tp_sense(ignore=0x%x) enter\n", ignore);
+		printk(TPQIC02_NAME ": tp_sense(ignore=0x%x) enter\n",
+		       ignore);
 
 	/* sense() is not allowed during a read or write cycle */
 	if (doing_write == YES)
 		tpqputs(TPQD_ALWAYS, "Warning: File Mark inserted because of sense() request");
 	/* The extra test is to avoid calling finish_rw during booting */
-	if ((doing_read!=NO) || (doing_write!=NO))
+	if ((doing_read != NO) || (doing_write != NO))
 		finish_rw(QCMD_RD_STAT);
 
 	if (get_status(&tperror) != TE_OK) {
@@ -827,27 +838,29 @@
 	}
 
 	err = tperror.exs;	/* get exception status bits */
-	if (err & (TP_ST0|TP_ST1))
+	if (err & (TP_ST0 | TP_ST1))
 		printk(TPQIC02_NAME ": tp_sense: status: %x, error count: %d, underruns: %d\n",
-			tperror.exs, tperror.dec, tperror.urc);
-	else if ((tperror.dec!=0) || (tperror.urc!=0) || TPQDBG(SENSE_CNTS))
-		printk(TPQIC02_NAME ": tp_sense: no hard errors, soft error count: %d, underruns: %d\n",
-			tperror.dec, tperror.urc);
+		       tperror.exs, tperror.dec, tperror.urc);
+	else if ((tperror.dec != 0) || (tperror.urc != 0)
+		 || TPQDBG(SENSE_CNTS))
+		printk(TPQIC02_NAME
+		       ": tp_sense: no hard errors, soft error count: %d, underruns: %d\n",
+		       tperror.dec, tperror.urc);
 
 	/* Set generic status. HP-UX defines these, but some extra would 
 	 * be useful. Problem is to remain compatible. [Do we want to be
 	 * compatible??]
 	 */
 	if (err & TP_ST0) {
-		if (err & TP_CNI)		/* no cartridge */
+		if (err & TP_CNI)	/* no cartridge */
 			gs |= GMT_DR_OPEN(-1);
 		if (status_dead == NO)
 			gs |= GMT_ONLINE(-1);	/* always online */
-		if (err & TP_USL)		/* not online */
+		if (err & TP_USL)	/* not online */
 			gs &= ~GMT_ONLINE(-1);
 		if (err & TP_WRP)
 			gs |= GMT_WR_PROT(-1);
-		if (err & TP_EOM) {		/* end of media */
+		if (err & TP_EOM) {	/* end of media */
 			gs |= GMT_EOT(-1);	/* not sure this is correct for writes */
 			status_eom_detected = YES;
 			/* I don't know whether drive always reports EOF at or before EOM. */
@@ -871,10 +884,10 @@
 	ioctl_status.mt_dsreg = tperror.exs;	/* "drive status" */
 	ioctl_status.mt_erreg = tperror.dec;	/* "sense key error" */
 
-	if (err & (TP_ST0|TP_ST1)) {
+	if (err & (TP_ST0 | TP_ST1)) {
 		/* My Wangtek occasionally reports `status' 1212 which should be ignored. */
 		exnr = decode_qic_exception_nr(err);
-		handle_qic_exception(exnr, err);		/* update driver state wrt drive status */
+		handle_qic_exception(exnr, err);	/* update driver state wrt drive status */
 		report_qic_exception(exnr);
 	}
 	err &= ~ignore;		/* mask unwanted errors -- not the correct way, use exception nrs?? */
@@ -882,7 +895,7 @@
 	    ((err & TP_ST1) && (err & REPORT_ERR1)))
 		return TE_ERR;
 	return TE_OK;
-} /* tp_sense */
+}				/* tp_sense */
 
 
 
@@ -895,15 +908,17 @@
 
 	stat = inb(QIC02_STAT_PORT) & QIC02_STAT_MASK;
 	if (TPQDBG(REWIND))
-		printk(TPQIC02_NAME ": Waiting for (re-)wind to finish: stat=0x%x\n", stat);
+		printk(TPQIC02_NAME
+		       ": Waiting for (re-)wind to finish: stat=0x%x\n",
+		       stat);
 
 	stat = wait_for_ready(timeout);
 
 	if (stat != TE_OK) {
-			tpqputs(TPQD_ALWAYS, "(re-) winding failed\n");
+		tpqputs(TPQD_ALWAYS, "(re-) winding failed\n");
 	}
 	return stat;
-} /* wait_for_rewind */
+}				/* wait_for_rewind */
 
 
 
@@ -919,22 +934,21 @@
 
 	if (status_dead == YES) {
 		tpqputs(TPQD_ALWAYS, "Drive is dead. Do a `mt reset`.");
-		return -ENXIO;			/* User should do an MTRESET. */
+		return -ENXIO;	/* User should do an MTRESET. */
 	}
 
-	stat = wait_for_ready(timeout);		/* wait for ready or exception */
+	stat = wait_for_ready(timeout);	/* wait for ready or exception */
 	if (stat == TE_EX) {
-		if (tp_sense(TP_WRP|TP_BOM|TP_EOM|TP_FIL)!=TE_OK)
+		if (tp_sense(TP_WRP | TP_BOM | TP_EOM | TP_FIL) != TE_OK)
 			return -EIO;
 		/* else nothing to worry about, I hope */
 		stat = TE_OK;
 	}
 	if (stat != TE_OK) {
-		printk(TPQIC02_NAME ": ll_do_qic_cmd(%x, %ld) failed\n", cmd, (long) timeout);
+		printk(TPQIC02_NAME ": ll_do_qic_cmd(%x, %ld) failed\n",
+		       cmd, (long) timeout);
 		return -EIO;
 	}
-
-
 #if OBSOLETE
 	/* wait for ready since it may not be active immediately after reading status */
 	while ((inb_p(QIC02_STAT_PORT) & QIC02_STAT_READY) != 0);
@@ -942,16 +956,17 @@
 
 	stat = send_qic02_cmd(cmd, timeout, 0);	/* (checks for exceptions) */
 
-	if (cmd==QCMD_RD_FM) {
+	if (cmd == QCMD_RD_FM) {
 		status_eof_detected = NO;
 		ioctl_status.mt_fileno++;
 		/* Should update block count as well, but can't.
 		 * Can do a `read address' for some drives, when MTNOP is done.
 		 */
-	} else if (cmd==QCMD_WRT_FM) {
+	} else if (cmd == QCMD_WRT_FM) {
 		status_eof_detected = NO;
 		ioctl_status.mt_fileno++;
-	} else if ((cmd==QCMD_REWIND) || (cmd==QCMD_ERASE) || (cmd==QCMD_RETEN)) {
+	} else if ((cmd == QCMD_REWIND) || (cmd == QCMD_ERASE)
+		   || (cmd == QCMD_RETEN)) {
 		status_eof_detected = NO;
 		status_eom_detected = NO;
 		status_eot_detected = NO;
@@ -964,16 +979,19 @@
 		reported_write_eof = NO;
 	}
 	/* sense() will set eof/eom as required */
-	if (stat==TE_EX) {
-		if (tp_sense(TP_WRP|TP_BOM|TP_EOM|TP_FIL)!=TE_OK) {
-			printk(TPQIC02_NAME ": Exception persist in ll_do_qic_cmd[1](%x, %ld)", cmd, (long) timeout);
+	if (stat == TE_EX) {
+		if (tp_sense(TP_WRP | TP_BOM | TP_EOM | TP_FIL) != TE_OK) {
+			printk(TPQIC02_NAME
+			       ": Exception persist in ll_do_qic_cmd[1](%x, %ld)",
+			       cmd, (long) timeout);
 			status_dead = YES;
 			return -ENXIO;
 			/* if rdstatus fails too, we're in trouble */
 		}
-	}
-	else if (stat!=TE_OK) {
-		printk(TPQIC02_NAME ": ll_do_qic_cmd: send_qic02_cmd failed, stat = 0x%x\n", stat);
+	} else if (stat != TE_OK) {
+		printk(TPQIC02_NAME
+		       ": ll_do_qic_cmd: send_qic02_cmd failed, stat = 0x%x\n",
+		       stat);
 		return -EIO;	/*** -EIO is probably not always appropriate */
 	}
 
@@ -983,23 +1001,27 @@
 	else
 		stat = wait_for_ready(timeout);
 
-	if (stat==TE_EX) {
-		if (tp_sense((cmd==QCMD_SEEK_EOD ?		/*****************************/
-		      TP_EOR|TP_NDT|TP_UDA|TP_BNL|TP_WRP|TP_BOM|TP_EOM|TP_FIL :
-		      TP_WRP|TP_BOM|TP_EOM|TP_FIL))!=TE_OK) {
-			printk(TPQIC02_NAME ": Exception persist in ll_do_qic_cmd[2](%x, %ld)\n", cmd, (long) timeout);
-			if (cmd!=QCMD_RD_FM)
+	if (stat == TE_EX) {
+		if (tp_sense((cmd == QCMD_SEEK_EOD ?		/*****************************/
+			      TP_EOR | TP_NDT | TP_UDA | TP_BNL | TP_WRP |
+			      TP_BOM | TP_EOM | TP_FIL : TP_WRP | TP_BOM |
+			      TP_EOM | TP_FIL)) != TE_OK) {
+			printk(TPQIC02_NAME
+			       ": Exception persist in ll_do_qic_cmd[2](%x, %ld)\n",
+			       cmd, (long) timeout);
+			if (cmd != QCMD_RD_FM)
 				status_dead = YES;
 			return -ENXIO;
 			/* if rdstatus fails too, we're in trouble */
 		}
-	}
-	else if (stat!=TE_OK) {
-		printk(TPQIC02_NAME ": ll_do_qic_cmd %x: wait failed, stat == 0x%x\n", cmd, stat);
+	} else if (stat != TE_OK) {
+		printk(TPQIC02_NAME
+		       ": ll_do_qic_cmd %x: wait failed, stat == 0x%x\n",
+		       cmd, stat);
 		return -EIO;
 	}
 	return 0;
-} /* ll_do_qic_cmd */
+}				/* ll_do_qic_cmd */
 
 
 /* 
@@ -1042,17 +1064,20 @@
 				/* Mountain reference says can terminate by de-asserting online */
 				ctlbits &= ~MTN_QIC02_CTL_ONLINE;
 			}
- 
-			if (tp_sense(TP_FIL|TP_EOM|TP_WRP) != TE_OK) {
-				tpqputs(TPQD_ALWAYS, "finish_rw[read1]: ignore the 2 lines above");
+
+			if (tp_sense(TP_FIL | TP_EOM | TP_WRP) != TE_OK) {
+				tpqputs(TPQD_ALWAYS,
+					"finish_rw[read1]: ignore the 2 lines above");
 				if (is_exception()) {
-					if (tp_sense(TP_ILL|TP_FIL|TP_EOM|TP_WRP) != TE_OK)
-						tpqputs(TPQD_ALWAYS, "finish_rw[read2]: read cycle error");
+					if (tp_sense
+					    (TP_ILL | TP_FIL | TP_EOM |
+					     TP_WRP) != TE_OK)
+						tpqputs(TPQD_ALWAYS,"finish_rw[read2]: read cycle error");
 				}
 			}
 		}
 	}
-} /* terminate_read */
+}				/* terminate_read */
 
 
 static void terminate_write(int cmd)
@@ -1066,28 +1091,30 @@
 			/* finish off write cycle */
 			stat = ll_do_qic_cmd(QCMD_WRT_FM, TIM_M);
 			if (stat != TE_OK)
-				tpqputs(TPQD_ALWAYS, "Couldn't finish write cycle properly");
+				tpqputs(TPQD_ALWAYS,
+					"Couldn't finish write cycle properly");
 			(void) tp_sense(0);
 		}
 		/* If there is an EOF token waiting to be returned to
 		 * the (writing) application, discard it now.
 		 * We could be at EOT, so don't reset return_write_eof.
 		 */
-		reported_write_eof=YES;
+		reported_write_eof = YES;
 	}
-} /* terminate_write */
+}				/* terminate_write */
 
 
 /* terminate read or write cycle because of command `cmd' */
 static void finish_rw(int cmd)
 {
 	if (wait_for_ready(TIM_S) != TE_OK) {
-		tpqputs(TPQD_ALWAYS, "error: drive not ready in finish_rw() !");
+		tpqputs(TPQD_ALWAYS,
+			"error: drive not ready in finish_rw() !");
 		return;
 	}
 	terminate_read(cmd);
 	terminate_write(cmd);
-} /* finish_rw */
+}				/* finish_rw */
 
 
 /* Perform a QIC command through ll_do_qic_cmd().
@@ -1109,12 +1136,12 @@
 			return stat;
 		}
 		need_rewind = NO;
-		if (cmd==QCMD_REWIND)	/* don't wind beyond BOT ;-) */
+		if (cmd == QCMD_REWIND)	/* don't wind beyond BOT ;-) */
 			return 0;
 	}
 
 	return ll_do_qic_cmd(cmd, timeout);
-} /* do_qic_cmd */
+}				/* do_qic_cmd */
 
 
 /* Not all ioctls are supported for all drives. Some rely on
@@ -1132,217 +1159,218 @@
 	 */
 
 	switch (cmd) {
-		case MTRESET:
-			/* reset verbose */
-			return (tape_reset(1)==TE_OK)? 0 : -EIO;
-
-		case MTFSF:
-			tpqputs(TPQD_IOCTLS, "MTFSF forward searching filemark");
-			if ((mode_access==WRITE) && status_bytes_wr)
+	case MTRESET:
+		/* reset verbose */
+		return (tape_reset(1) == TE_OK) ? 0 : -EIO;
+
+	case MTFSF:
+		tpqputs(TPQD_IOCTLS, "MTFSF forward searching filemark");
+		if ((mode_access == WRITE) && status_bytes_wr)
+			return -EACCES;
+		return do_qic_cmd(QCMD_RD_FM, TIM_F);
+
+	case MTBSF:
+		if (TP_HAVE_BSF) {
+			tpqputs(TPQD_IOCTLS,
+				"MTBSF backward searching filemark -- optional command");
+			if ((mode_access == WRITE) && status_bytes_wr)
 				return -EACCES;
-			return do_qic_cmd(QCMD_RD_FM, TIM_F);
-
-		case MTBSF:
-			if (TP_HAVE_BSF) {
-				tpqputs(TPQD_IOCTLS, "MTBSF backward searching filemark -- optional command");
-				if ((mode_access==WRITE) && status_bytes_wr)
-					return -EACCES;
-				stat = do_qic_cmd(QCMD_RD_FM_BCK, TIM_F);
-			} else {
-				stat = -ENXIO;
-			}
-			status_eom_detected = status_eof_detected = NO;
-			return stat;
-
-		case MTFSR:
-			if (TP_HAVE_FSR) { /* This is an optional QIC-02 command */
-				tpqputs(TPQD_IOCTLS, "MTFSR forward space record");
-				if ((mode_access==WRITE) && status_bytes_wr)
-					return -EACCES;
-				stat = do_qic_cmd(QCMD_SPACE_FWD, TIM_F);
-			} else {
-				/**** fake it by doing a read data block command? ******/
-				tpqputs(TPQD_IOCTLS, "MTFSR not supported");
-				stat = -ENXIO;
-			}
-			return stat;
-
-		case MTBSR:
-			if (TP_HAVE_BSR) { /* This is an optional QIC-02 command */
-				/* we need this for appending files with GNU tar!! */
-				tpqputs(TPQD_IOCTLS, "MTFSR backward space record");
-				if ((mode_access==WRITE) && status_bytes_wr)
-					return -EACCES;
-				stat = do_qic_cmd(QCMD_SPACE_BCK, TIM_F);
-			} else {
-				tpqputs(TPQD_IOCTLS, "MTBSR not supported");
-				stat = -ENXIO;
-			}
-			status_eom_detected = status_eof_detected = NO;
-			return stat;
+			stat = do_qic_cmd(QCMD_RD_FM_BCK, TIM_F);
+		} else {
+			stat = -ENXIO;
+		}
+		status_eom_detected = status_eof_detected = NO;
+		return stat;
 
-		case MTWEOF:
-			tpqputs(TPQD_IOCTLS, "MTWEOF write eof mark");
-			/* Plain GNU mt(1) 2.2 uses read-only mode for writing FM. :-( */
-			if (mode_access==READ)
+	case MTFSR:
+		if (TP_HAVE_FSR) {	/* This is an optional QIC-02 command */
+			tpqputs(TPQD_IOCTLS, "MTFSR forward space record");
+			if ((mode_access == WRITE) && status_bytes_wr)
 				return -EACCES;
+			stat = do_qic_cmd(QCMD_SPACE_FWD, TIM_F);
+		} else {
+				/**** fake it by doing a read data block command? ******/
+			tpqputs(TPQD_IOCTLS, "MTFSR not supported");
+			stat = -ENXIO;
+		}
+		return stat;
 
-			/* allow tape movement after writing FM */
-			status_bytes_rd = status_bytes_wr;	/* Kludge-O-Matic */
-			status_bytes_wr = NO;
-			return do_qic_cmd(QCMD_WRT_FM, TIM_M);
-			/* not sure what to do with status_bytes when WFM should fail */
-
-		case MTREW:
-			tpqputs(TPQD_IOCTLS, "MTREW rewinding tape");
-			if ((mode_access==WRITE) && status_bytes_wr)
+	case MTBSR:
+		if (TP_HAVE_BSR) {	/* This is an optional QIC-02 command */
+			/* we need this for appending files with GNU tar!! */
+			tpqputs(TPQD_IOCTLS, "MTFSR backward space record");
+			if ((mode_access == WRITE) && status_bytes_wr)
 				return -EACCES;
-			status_eom_detected = status_eof_detected = NO;
-			return do_qic_cmd(QCMD_REWIND, TIM_R);
+			stat = do_qic_cmd(QCMD_SPACE_BCK, TIM_F);
+		} else {
+			tpqputs(TPQD_IOCTLS, "MTBSR not supported");
+			stat = -ENXIO;
+		}
+		status_eom_detected = status_eof_detected = NO;
+		return stat;
 
-		case MTOFFL:
-			tpqputs(TPQD_IOCTLS, "MTOFFL rewinding & going offline");
-			/* Doing a drive select will clear (unlock) the current drive.
-			 * But that requires support for multiple drives and locking.
-			 */
-			if ((mode_access==WRITE) && status_bytes_wr)
-				return -EACCES;
-			status_eom_detected = status_eof_detected = NO;
+	case MTWEOF:
+		tpqputs(TPQD_IOCTLS, "MTWEOF write eof mark");
+		/* Plain GNU mt(1) 2.2 uses read-only mode for writing FM. :-( */
+		if (mode_access == READ)
+			return -EACCES;
+
+		/* allow tape movement after writing FM */
+		status_bytes_rd = status_bytes_wr;	/* Kludge-O-Matic */
+		status_bytes_wr = NO;
+		return do_qic_cmd(QCMD_WRT_FM, TIM_M);
+		/* not sure what to do with status_bytes when WFM should fail */
+
+	case MTREW:
+		tpqputs(TPQD_IOCTLS, "MTREW rewinding tape");
+		if ((mode_access == WRITE) && status_bytes_wr)
+			return -EACCES;
+		status_eom_detected = status_eof_detected = NO;
+		return do_qic_cmd(QCMD_REWIND, TIM_R);
+
+	case MTOFFL:
+		tpqputs(TPQD_IOCTLS, "MTOFFL rewinding & going offline");
+		/* Doing a drive select will clear (unlock) the current drive.
+		 * But that requires support for multiple drives and locking.
+		 */
+		if ((mode_access == WRITE) && status_bytes_wr)
+			return -EACCES;
+		status_eom_detected = status_eof_detected = NO;
 			/**** do rewind depending on minor bits??? ***/
-			stat = do_qic_cmd(QCMD_REWIND, TIM_R);
-			return stat;
+		stat = do_qic_cmd(QCMD_REWIND, TIM_R);
+		return stat;
 
-		case MTNOP:
-			tpqputs(TPQD_IOCTLS, "MTNOP setting status only");
+	case MTNOP:
+		tpqputs(TPQD_IOCTLS, "MTNOP setting status only");
 			/********** should do `read position' for drives that support it **********/
-			return (tp_sense(-1)==TE_OK)? 0 : -EIO;	/**** check return codes ****/
-
-		case MTRETEN:
-			tpqputs(TPQD_IOCTLS, "MTRETEN retension tape");
-			if ((mode_access==WRITE) && status_bytes_wr)
-				return -EACCES;
-			status_eom_detected = status_eof_detected = NO;
-			return do_qic_cmd(QCMD_RETEN, TIM_R);
+		return (tp_sense(-1) == TE_OK) ? 0 : -EIO;	/**** check return codes ****/
 
-		case MTBSFM:
-			/* Think think is like MTBSF, except that
-			 * we shouldn't skip the FM. Tricky.
-			 * Maybe use RD_FM_BCK, then do a SPACE_FWD?
-			 */
-			tpqputs(TPQD_IOCTLS, "MTBSFM not supported");
-			if ((mode_access==WRITE) && status_bytes_wr)
-				return -EACCES;
-			return -ENXIO;
+	case MTRETEN:
+		tpqputs(TPQD_IOCTLS, "MTRETEN retension tape");
+		if ((mode_access == WRITE) && status_bytes_wr)
+			return -EACCES;
+		status_eom_detected = status_eof_detected = NO;
+		return do_qic_cmd(QCMD_RETEN, TIM_R);
+
+	case MTBSFM:
+		/* Think think is like MTBSF, except that
+		 * we shouldn't skip the FM. Tricky.
+		 * Maybe use RD_FM_BCK, then do a SPACE_FWD?
+		 */
+		tpqputs(TPQD_IOCTLS, "MTBSFM not supported");
+		if ((mode_access == WRITE) && status_bytes_wr)
+			return -EACCES;
+		return -ENXIO;
 
-		case MTFSFM:
-			/* I think this is like MTFSF, except that
-			 * we shouldn't skip the FM. Tricky.
-			 * Maybe use QCMD_RD_DATA until we get a TP_FIL exception?
-			 * But then the FM will have been skipped...
-			 * Maybe use RD_FM, then RD_FM_BCK, but not all
-			 * drives will support that!
-			 */
-			tpqputs(TPQD_IOCTLS, "MTFSFM not supported");
-			if ((mode_access==WRITE) && status_bytes_wr)
-				return -EACCES;
-			return -ENXIO;
+	case MTFSFM:
+		/* I think this is like MTFSF, except that
+		 * we shouldn't skip the FM. Tricky.
+		 * Maybe use QCMD_RD_DATA until we get a TP_FIL exception?
+		 * But then the FM will have been skipped...
+		 * Maybe use RD_FM, then RD_FM_BCK, but not all
+		 * drives will support that!
+		 */
+		tpqputs(TPQD_IOCTLS, "MTFSFM not supported");
+		if ((mode_access == WRITE) && status_bytes_wr)
+			return -EACCES;
+		return -ENXIO;
 
-		case MTEOM:
-			/* This should leave the tape ready for appending
-			 * another file to the end, such that it would append
-			 * after the last FM on tape.
+	case MTEOM:
+		/* This should leave the tape ready for appending
+		 * another file to the end, such that it would append
+		 * after the last FM on tape.
+		 */
+		tpqputs(TPQD_IOCTLS, "MTEOM search for End Of recorded Media");
+		if ((mode_access == WRITE) && status_bytes_wr)
+			return -EACCES;
+		if (TP_HAVE_EOD) {
+			/* Use faster seeking when possible.
+			 * This requires the absence of data beyond the EOM.
+			 * It seems that my drive does not always perform the
+			 * SEEK_EOD correctly, unless it is preceded by a
+			 * rewind command.
 			 */
-			tpqputs(TPQD_IOCTLS, "MTEOM search for End Of recorded Media");
-			if ((mode_access==WRITE) && status_bytes_wr)
-				return -EACCES;
-			if (TP_HAVE_EOD) {
-				/* Use faster seeking when possible.
-				 * This requires the absence of data beyond the EOM.
-				 * It seems that my drive does not always perform the
-				 * SEEK_EOD correctly, unless it is preceded by a
-				 * rewind command.
-				 */
 # if 0
-				status_eom_detected = status_eof_detected = NO;
+			status_eom_detected = status_eof_detected = NO;
 # endif
-				stat = do_qic_cmd(QCMD_REWIND, TIM_R);
-				if (stat)
-					return stat;
-				stat = do_qic_cmd(QCMD_SEEK_EOD, TIM_F);
-				/* After a successful seek, TP_EOR should be returned */
-			} else {
-				/* else just seek until the drive returns exception "No Data" */
-				stat = 0;
-				while ((stat==0) && (!status_eom_detected)) {
-					stat = do_qic_cmd(QCMD_RD_FM, TIM_F); /***** should use MTFSFM here???? ******/
-				}
-				if (tperror.exs & TP_NDT)
-					return 0;
-			}
-			return stat;
-
-		case MTERASE:
-			tpqputs(TPQD_IOCTLS, "MTERASE -- ERASE TAPE !");
-			if  ((tperror.exs & TP_ST0) && (tperror.exs & TP_WRP)) {
-				tpqputs(TPQD_ALWAYS, "Cartridge is write-protected.");
-				return -EACCES;
-			} else {
-				time_t t = jiffies;
-
-				/* Plain GNU mt(1) 2.2 erases a tape in O_RDONLY. :-( */
-				if (mode_access==READ) 
-					return -EACCES;
-
-				/* give user a few seconds to pull out tape */
-				while (jiffies - t < 4*HZ)
-					schedule();
+			stat = do_qic_cmd(QCMD_REWIND, TIM_R);
+			if (stat)
+				return stat;
+			stat = do_qic_cmd(QCMD_SEEK_EOD, TIM_F);
+			/* After a successful seek, TP_EOR should be returned */
+		} else {
+			/* else just seek until the drive returns exception "No Data" */
+			stat = 0;
+			while ((stat == 0) && (!status_eom_detected)) {
+				stat = do_qic_cmd(QCMD_RD_FM, TIM_F);	      /***** should use MTFSFM here???? ******/
 			}
+			if (tperror.exs & TP_NDT)
+				return 0;
+		}
+		return stat;
 
-			/* don't bother writing filemark first */
-			status_eom_detected = status_eof_detected = NO;
-			return do_qic_cmd(QCMD_ERASE, TIM_R);
+	case MTERASE:
+		tpqputs(TPQD_IOCTLS, "MTERASE -- ERASE TAPE !");
+		if ((tperror.exs & TP_ST0) && (tperror.exs & TP_WRP)) {
+			tpqputs(TPQD_ALWAYS, "Cartridge is write-protected.");
+			return -EACCES;
+		} else {
+			time_t t = jiffies;
 
-		case MTRAS1:
-			if (TP_HAVE_RAS1) {
-				tpqputs(TPQD_IOCTLS, "MTRAS1: non-destructive self test");
-				stat = do_qic_cmd(QCMD_SELF_TST1, TIM_R);
-				if (stat != 0) {
-					tpqputs(TPQD_ALWAYS, "RAS1 failed");
-					return stat;
-				}
-				return (tp_sense(0)==TE_OK)? 0 : -EIO; /* get_ext_status3(); */
-			}
-			tpqputs(TPQD_IOCTLS, "RAS1 not supported");
-			return -ENXIO;
+			/* Plain GNU mt(1) 2.2 erases a tape in O_RDONLY. :-( */
+			if (mode_access == READ)
+				return -EACCES;
 
-		case MTRAS2:
-			if (TP_HAVE_RAS2) {
-				tpqputs(TPQD_IOCTLS, "MTRAS2: destructive self test");
-				stat = do_qic_cmd(QCMD_SELF_TST2, TIM_R);
-				if (stat != 0) {
-					tpqputs(TPQD_ALWAYS, "RAS2 failed");
-					return stat;
-				}
-				return (tp_sense(0)==TE_OK)? 0 : -EIO; /* get_ext_status3(); */
+			/* FIXME */
+			/* give user a few seconds to pull out tape */
+			while (jiffies - t < 4 * HZ)
+				schedule();
+		}
+
+		/* don't bother writing filemark first */
+		status_eom_detected = status_eof_detected = NO;
+		return do_qic_cmd(QCMD_ERASE, TIM_R);
+
+	case MTRAS1:
+		if (TP_HAVE_RAS1) {
+			tpqputs(TPQD_IOCTLS, "MTRAS1: non-destructive self test");
+			stat = do_qic_cmd(QCMD_SELF_TST1, TIM_R);
+			if (stat != 0) {
+				tpqputs(TPQD_ALWAYS, "RAS1 failed");
+				return stat;
 			}
-			tpqputs(TPQD_IOCTLS, "RAS2 not supported");
-			return -ENXIO;
+			return (tp_sense(0) == TE_OK) ? 0 : -EIO;	/* get_ext_status3(); */
+		}
+		tpqputs(TPQD_IOCTLS, "RAS1 not supported");
+		return -ENXIO;
 
-		case MTSEEK:
-			if (TP_HAVE_SEEK && (QIC02_TAPE_IFC==ARCHIVE)) {
-				tpqputs(TPQD_IOCTLS, "MTSEEK seeking block");
-				if ((mode_access==WRITE) && status_bytes_wr)
-					return -EACCES;
-				/* NOTE: address (24 bits) is in seek_addr_buf[] */
-				return do_qic_cmd(AR_QCMDV_SEEK_BLK, TIM_F);
+	case MTRAS2:
+		if (TP_HAVE_RAS2) {
+			tpqputs(TPQD_IOCTLS, "MTRAS2: destructive self test");
+			stat = do_qic_cmd(QCMD_SELF_TST2, TIM_R);
+			if (stat != 0) {
+				tpqputs(TPQD_ALWAYS, "RAS2 failed");
+				return stat;
 			}
-			else
-				return -ENOTTY;
+			return (tp_sense(0) == TE_OK) ? 0 : -EIO;	/* get_ext_status3(); */
+		}
+		tpqputs(TPQD_IOCTLS, "RAS2 not supported");
+		return -ENXIO;
 
-		default:
+	case MTSEEK:
+		if (TP_HAVE_SEEK && (QIC02_TAPE_IFC == ARCHIVE)) {
+			tpqputs(TPQD_IOCTLS, "MTSEEK seeking block");
+			if ((mode_access == WRITE) && status_bytes_wr)
+				return -EACCES;
+			/* NOTE: address (24 bits) is in seek_addr_buf[] */
+			return do_qic_cmd(AR_QCMDV_SEEK_BLK, TIM_F);
+		} else
 			return -ENOTTY;
+
+	default:
+		return -ENOTTY;
 	}
-} /* do_ioctl_cmd */
+}				/* do_ioctl_cmd */
 
 
 /* dma_transfer(): This routine is called for every 512 bytes to be read
@@ -1362,40 +1390,43 @@
  *	- adjust the timeout
  *	- tell the tape controller to start transferring
  * We assume the dma address and mode are, and remain, valid.
- */ 
+ */
 static inline void dma_transfer(void)
 {
 	unsigned long flags;
 
-	if (QIC02_TAPE_IFC == WANGTEK) /* or EVEREX */
+	if (QIC02_TAPE_IFC == WANGTEK)	/* or EVEREX */
 		outb_p(WT_CTL_ONLINE, QIC02_CTL_PORT);	/* back to normal */
 	else if (QIC02_TAPE_IFC == ARCHIVE)
 		outb_p(0, AR_RESET_DMA_PORT);
-	else /* QIC02_TAPE_IFC == MOUNTAIN */
+	else			/* QIC02_TAPE_IFC == MOUNTAIN */
 		outb_p(ctlbits, QIC02_CTL_PORT);
 
 
-	flags=claim_dma_lock();
+	flags = claim_dma_lock();
 	clear_dma_ff(QIC02_TAPE_DMA);
 	set_dma_mode(QIC02_TAPE_DMA, dma_mode);
-	set_dma_addr(QIC02_TAPE_DMA, virt_to_bus(buffaddr) + dma_bytes_done);
+	set_dma_addr(QIC02_TAPE_DMA,
+		     virt_to_bus(buffaddr) + dma_bytes_done);
 	set_dma_count(QIC02_TAPE_DMA, TAPE_BLKSIZE);
 
 	/* start tape DMA controller */
-	if (QIC02_TAPE_IFC == WANGTEK) /* or EVEREX */
-		outb_p(WT_CTL_DMA | WT_CTL_ONLINE, QIC02_CTL_PORT); /* trigger DMA transfer */
+	if (QIC02_TAPE_IFC == WANGTEK)	/* or EVEREX */
+		outb_p(WT_CTL_DMA | WT_CTL_ONLINE, QIC02_CTL_PORT);	/* trigger DMA transfer */
 
 	else if (QIC02_TAPE_IFC == ARCHIVE) {
-		outb_p(AR_CTL_IEN | AR_CTL_DNIEN, QIC02_CTL_PORT);  /* enable interrupts again */
-		outb_p(0, AR_START_DMA_PORT);			  /* start DMA transfer */
+		outb_p(AR_CTL_IEN | AR_CTL_DNIEN, QIC02_CTL_PORT);	/* enable interrupts again */
+		outb_p(0, AR_START_DMA_PORT);	/* start DMA transfer */
 		/* In dma_end() AR_RESET_DMA_PORT is written too. */
 
-	} else /* QIC02_TAPE_IFC == MOUNTAIN */ {
+	} else {		/* QIC02_TAPE_IFC == MOUNTAIN */
+
 		inb(MTN_R_DESELECT_DMA_PORT);
-		outb_p(ctlbits | (MTN_CTL_EXC_IEN | MTN_CTL_DNIEN), QIC02_CTL_PORT);
-		outb_p(0, MTN_W_SELECT_DMA_PORT);	 /* start DMA transfer */
+		outb_p(ctlbits | (MTN_CTL_EXC_IEN | MTN_CTL_DNIEN),
+		       QIC02_CTL_PORT);
+		outb_p(0, MTN_W_SELECT_DMA_PORT);	/* start DMA transfer */
 		if (dma_mode == DMA_MODE_WRITE)
-			outb_p(0, MTN_W_DMA_WRITE_PORT); /* start DMA transfer */
+			outb_p(0, MTN_W_DMA_WRITE_PORT);	/* start DMA transfer */
 	}
 
 	/* start computer DMA controller */
@@ -1406,7 +1437,7 @@
 	/* block transfer should start now, jumping to the 
 	 * interrupt routine when done or an exception was detected.
 	 */
-} /* dma_transfer */
+}				/* dma_transfer */
 
 
 /* start_dma() sets a DMA transfer up between the tape controller and
@@ -1421,15 +1452,16 @@
 {
 	int stat;
 	unsigned long flags;
-	
+
 	tpqputs(TPQD_DEBUG, "start_dma() enter");
-	TPQDEB({printk(TPQIC02_NAME ": doing_read==%d, doing_write==%d\n", doing_read, doing_write);})
+	TPQDEB( {printk(TPQIC02_NAME ": doing_read==%d, doing_write==%d\n",
+		      doing_read, doing_write);})
 
-	dma_bytes_done = 0;
+	    dma_bytes_done = 0;
 	dma_bytes_todo = bytes_todo;
 	status_error = NO;
 	/* dma_mode!=0 indicates that the dma controller is in use */
-	dma_mode = (mode == WRITE)? DMA_MODE_WRITE : DMA_MODE_READ;	
+	dma_mode = (mode == WRITE) ? DMA_MODE_WRITE : DMA_MODE_READ;
 
 	/* Only give READ/WRITE DATA command to tape drive if we haven't
 	 * done that already. Otherwise the drive will rewind to the beginning
@@ -1443,22 +1475,25 @@
 
 #if 0
 		/* Next dummy get status is to make sure CNI is valid,
-                   since we're only just starting a read/write it doesn't
-                   matter some exceptions are cleared by reading the status;
-                   we're only interested in CNI and WRP. -Eddy */
+		   since we're only just starting a read/write it doesn't
+		   matter some exceptions are cleared by reading the status;
+		   we're only interested in CNI and WRP. -Eddy */
 		get_status(&tperror);
 #else
 		/* TP_CNI should now be handled in open(). -Hennus */
 #endif
 
-		stat = tp_sense(((mode == WRITE)? 0 : TP_WRP) | TP_BOM | TP_FIL);
+		stat =
+		    tp_sense(((mode ==
+			       WRITE) ? 0 : TP_WRP) | TP_BOM | TP_FIL);
 		if (stat != TE_OK)
 			return stat;
 
 #if OBSOLETE
 		/************* not needed iff rd_status() would wait for ready!!!!!! **********/
 		if (wait_for_ready(TIM_S) != TE_OK) {	/*** not sure this is needed ***/
-			tpqputs(TPQD_ALWAYS, "wait_for_ready failed in start_dma");
+			tpqputs(TPQD_ALWAYS,
+				"wait_for_ready failed in start_dma");
 			return -EIO;
 		}
 #endif
@@ -1471,10 +1506,11 @@
 		/* Tell the controller the data direction */
 
 		/* r/w, timeout medium, check exceptions, sets status_cmd_pending. */
-		stat = send_qic02_cmd((mode == WRITE)? QCMD_WRT_DATA : QCMD_RD_DATA, TIM_M, 0);
-		if (stat!=TE_OK) {
+		stat = send_qic02_cmd((mode == WRITE) 
+					? QCMD_WRT_DATA : QCMD_RD_DATA, TIM_M, 0);
+		if (stat != TE_OK) {
 			printk(TPQIC02_NAME ": start_dma: init %s failed\n",
-				(mode == WRITE)? "write" : "read");
+			       (mode == WRITE) ? "write" : "read");
 			(void) tp_sense(0);
 			return stat;
 		}
@@ -1485,15 +1521,17 @@
 		if (wait_for_ready(TIM_M) != TE_OK)
 			return -EIO;
 		switch (mode) {
-			case READ:
-				doing_read = YES;
-				break;
-			case WRITE:
-				doing_write = YES;
-				break;
-			default:
-				printk(TPQIC02_NAME ": requested unknown mode %d\n", mode);
-				panic(TPQIC02_NAME ": invalid mode in start_dma()");
+		case READ:
+			doing_read = YES;
+			break;
+		case WRITE:
+			doing_write = YES;
+			break;
+		default:
+			printk(TPQIC02_NAME
+			       ": requested unknown mode %d\n", mode);
+			panic(TPQIC02_NAME
+			      ": invalid mode in start_dma()");
 		}
 
 	} else if (is_exception()) {
@@ -1502,7 +1540,8 @@
 		 *
 		 * ******** this also affects EOF/EOT handling! ************
 		 */
-		tpqputs(TPQD_ALWAYS, "detected exception in start_dma() while transfer in progress");
+		tpqputs(TPQD_ALWAYS,
+			"detected exception in start_dma() while transfer in progress");
 		status_error = YES;
 		return TE_END;
 	}
@@ -1513,7 +1552,7 @@
 	/* This assumes tape is already positioned, but these
 	 * semi-'intelligent' drives are unpredictable...
 	 */
-	TIMERON(TIM_M*2);
+	TIMERON(TIM_M * 2);
 
 	/* initiate first data block read from/write to the tape controller */
 
@@ -1524,7 +1563,7 @@
 
 	TPQPUTS("start_dma() end");
 	return TE_OK;
-} /* start_dma */
+}				/* start_dma */
 
 
 /* This cleans up after the dma transfer has completed
@@ -1533,7 +1572,7 @@
  * sense() will set `status_eof_detected' and
  * `status_eom_detected', as required.
  */
-static void end_dma(unsigned long * bytes_done)
+static void end_dma(unsigned long *bytes_done)
 {
 	int stat = TE_OK;
 	unsigned long flags;
@@ -1542,35 +1581,37 @@
 
 	TPQPUTS("end_dma() enter");
 
-	flags=claim_dma_lock();
-	
+	flags = claim_dma_lock();
+
 	disable_dma(QIC02_TAPE_DMA);
 	clear_dma_ff(QIC02_TAPE_DMA);
-	
+
 	release_dma_lock(flags);
 
-	if (QIC02_TAPE_IFC == WANGTEK) /* or EVEREX */
+	if (QIC02_TAPE_IFC == WANGTEK)	/* or EVEREX */
 		outb_p(WT_CTL_ONLINE, QIC02_CTL_PORT);	/* back to normal */
 	else if (QIC02_TAPE_IFC == ARCHIVE)
 		outb_p(0, AR_RESET_DMA_PORT);
-	else /* QIC02_TAPE_IFC == MOUNTAIN */ {
+	else {			/* QIC02_TAPE_IFC == MOUNTAIN */
+
 		/* Clear control bits, de-select ONLINE during tp_sense */
 		ctlbits &= ~MTN_QIC02_CTL_ONLINE;
 	}
 
 	stat = wait_for_ready(TIM_M);
-	if (status_error || (stat!=TE_OK)) {
+	if (status_error || (stat != TE_OK)) {
 		tpqputs(TPQD_DMAX, "DMA transfer exception");
-		stat = tp_sense((dma_mode==READ)? TP_WRP : 0);
+		stat = tp_sense((dma_mode == READ) ? TP_WRP : 0);
 		/* no return here -- got to clean up first! */
-	} else /* if (QIC02_TAPE_IFC == MOUNTAIN) */ {
+	} else {		/* if (QIC02_TAPE_IFC == MOUNTAIN) */
+
 		outb_p(ctlbits, QIC02_CTL_PORT);
 	}
 
 	if (QIC02_TAPE_IFC == MOUNTAIN)
 		inb(MTN_R_DESELECT_DMA_PORT);
 
- 	/* take the tape controller offline */
+	/* take the tape controller offline */
 
 	/* finish off DMA stuff */
 
@@ -1588,7 +1629,7 @@
 
 	TPQPUTS("end_dma() exit");
 	/*** could return stat here ***/
-} /* end_dma */
+}				/* end_dma */
 
 /*********** Below are the (public) OS-interface procedures ***********/
 
@@ -1602,7 +1643,7 @@
 static void qic02_tape_times_out(unsigned long dummy)
 {
 	printk("time-out in %s driver\n", TPQIC02_NAME);
-	if ((status_cmd_pending>0) || dma_mode) {
+	if ((status_cmd_pending > 0) || dma_mode) {
 		/* takes tooo long, shut it down */
 		status_dead = YES;
 		status_cmd_pending = 0;
@@ -1614,7 +1655,7 @@
 			wake_up(&qic02_tape_transfer);
 		}
 	}
-} /* qic02_tape_times_out */
+}				/* qic02_tape_times_out */
 
 /*
  * Interrupt handling:
@@ -1647,7 +1688,8 @@
  * When we are finished, set flags to indicate end, disable timer.
  * NOTE: This *must* be fast! 
  */
-static void qic02_tape_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static void qic02_tape_interrupt(int irq, void *dev_id,
+				 struct pt_regs *regs)
 {
 	int stat, r, i;
 	unsigned long flags;
@@ -1662,20 +1704,21 @@
 		stat = inb(QIC02_STAT_PORT);	/* Knock, knock */
 		if (QIC02_TAPE_IFC == ARCHIVE) {	/* "Who's there?" */
 			if (((stat & (AR_STAT_DMADONE)) == 0) &&
-        	              ((stat & (QIC02_STAT_EXCEPTION)) != 0)) {
+			    ((stat & (QIC02_STAT_EXCEPTION)) != 0)) {
 				TIMERCONT;
-				return;			/* "Linux with IRQ sharing" */
+				return;	/* "Linux with IRQ sharing" */
 			}
 		}
 
 		if ((stat & QIC02_STAT_EXCEPTION) == 0) {	/* exception occurred */
 			/* Possible causes for an exception during a transfer:
-			 * 	- during a write-cycle: end of tape (EW) hole detected.
-			 *	- during a read-cycle: filemark or EOD detected.
-			 *	- something went wrong
+			 *      - during a write-cycle: end of tape (EW) hole detected.
+			 *      - during a read-cycle: filemark or EOD detected.
+			 *      - something went wrong
 			 * So don't continue with the next block.
 			 */
-			tpqputs(TPQD_ALWAYS, "isr: exception on tape controller");
+			tpqputs(TPQD_ALWAYS,
+				"isr: exception on tape controller");
 			printk("      status %02x\n", stat);
 			status_error = TE_EX;
 
@@ -1691,25 +1734,27 @@
 		 */
 		r = 0;
 
-	    /* Skip next ready check for Archive controller because
-	     * it may be busy reading ahead. Weird. --hhb
-	     */
+		/* Skip next ready check for Archive controller because
+		 * it may be busy reading ahead. Weird. --hhb
+		 */
 		if (QIC02_TAPE_IFC == WANGTEK)	/* I think this is a drive-dependency, not IFC -- hhb */
-			if (stat & QIC02_STAT_READY) {		/* not ready */
-				tpqputs(TPQD_ALWAYS, "isr: ? Tape controller not ready");
+			if (stat & QIC02_STAT_READY) {	/* not ready */
+				tpqputs(TPQD_ALWAYS,
+					"isr: ? Tape controller not ready");
 				r = 1;
 			}
 
-		flags=claim_dma_lock();
-		
-		if ( (i = get_dma_residue(QIC02_TAPE_DMA)) != 0 ) {
-			printk(TPQIC02_NAME ": dma_residue == %x !!!\n", i);
+		flags = claim_dma_lock();
+
+		if ((i = get_dma_residue(QIC02_TAPE_DMA)) != 0) {
+			printk(TPQIC02_NAME ": dma_residue == %x !!!\n",
+			       i);
 			r = 1;	/* big trouble, but can't do much about it... */
 		}
-		
+
 		release_dma_lock(flags);
 
-		if (r) 
+		if (r)
 			return;
 
 		/* finish DMA cycle */
@@ -1724,14 +1769,14 @@
 			wake_up(&qic02_tape_transfer);
 		} else {
 			/* start next transfer, account for track-switching time */
-			mod_timer(&tp_timer, jiffies + 6*HZ);
+			mod_timer(&tp_timer, jiffies + 6 * HZ);
 			dma_transfer();
 		}
 	} else {
 		printk(TPQIC02_NAME ": Unexpected interrupt, stat == %x\n",
 		       inb(QIC02_STAT_PORT));
 	}
-} /* qic02_tape_interrupt */
+}				/* qic02_tape_interrupt */
 
 
 /* read/write routines:
@@ -1766,190 +1811,173 @@
  * request would return the EOF flag for the previous file.
  */
 
-static ssize_t qic02_tape_read(struct file * filp, char * buf, size_t count, loff_t *ppos)
+static ssize_t qic02_tape_read(struct file *filp, char *buf, size_t count,
+			       loff_t * ppos)
 {
-    int err;
-    kdev_t dev = filp->f_dentry->d_inode->i_rdev;
-    unsigned short flags = filp->f_flags;
-    unsigned long bytes_todo, bytes_done, total_bytes_done = 0;
-    int stat;
-
-    if (status_zombie==YES)
-    {
-	tpqputs(TPQD_ALWAYS, "configs not set");		
-	return -ENXIO;
-    }
-
-    if (TP_DIAGS(current_tape_dev))
-      /* can't print a ``long long'' (for filp->f_pos), so chop it */
-      printk(TPQIC02_NAME ": request READ, minor=%x, buf=%p, count=%lx"
-	                  ", pos=%lx, flags=%x\n",
-	     MINOR(dev), buf, (long) count,
-	     (unsigned long) filp->f_pos, flags);
-    
-    if (count % TAPE_BLKSIZE)	/* Only allow mod 512 bytes at a time. */
-    {
-	tpqputs(TPQD_BLKSZ, "Wrong block size");
-	return -EINVAL;
-    }
+	int err;
+	kdev_t dev = filp->f_dentry->d_inode->i_rdev;
+	unsigned short flags = filp->f_flags;
+	unsigned long bytes_todo, bytes_done, total_bytes_done = 0;
+	int stat;
+
+	if (status_zombie == YES) {
+		tpqputs(TPQD_ALWAYS, "configs not set");
+		return -ENXIO;
+	}
 
-    /* Just assume everything is ok. Controller will scream if not. */
+	if (TP_DIAGS(current_tape_dev))
+		/* can't print a ``long long'' (for filp->f_pos), so chop it */
+		printk(TPQIC02_NAME
+		       ": request READ, minor=%x, buf=%p, count=%lx"
+		       ", pos=%lx, flags=%x\n", MINOR(dev), buf,
+		       (long) count, (unsigned long) filp->f_pos, flags);
 
-    if (status_bytes_wr)	/* Once written, no more reads, 'till after WFM. */
-    {
-	return -EACCES;
-    }
-    
-    /* This is rather ugly because it has to implement a finite state
-     * machine in order to handle the EOF situations properly.
-     */
-    while ((signed)count>=0)
-    {
-	bytes_done = 0;
-	/* see how much fits in the kernel buffer */
-	bytes_todo = TPQBUF_SIZE;
-	if (bytes_todo>count)
-	{
-	    bytes_todo = count;
+	if (count % TAPE_BLKSIZE) {	/* Only allow mod 512 bytes at a time. */
+		tpqputs(TPQD_BLKSZ, "Wrong block size");
+		return -EINVAL;
 	}
-	
-	/* Must ensure that user program sees exactly one EOF token (==0) */
-	if (return_read_eof==YES)
-	{
-	    if (TPQDBG(DEBUG))
-	    {
-		printk("read: return_read_eof==%d, reported_read_eof==%d, total_bytes_done==%lu\n", return_read_eof, reported_read_eof, total_bytes_done);
-	    }
-	    
-	    if (reported_read_eof==NO)
-	    {
-		/* have not yet returned EOF to user program */
-		if (total_bytes_done>0)
-		{
-		    return total_bytes_done; /* next time return EOF */
-		}
-		else
-		{
-		    reported_read_eof = YES; /* move on next time */
-		    return 0;		 /* return EOF */
-		}				
-	    }
-	    else
-	    {
-		/* Application program has already received EOF
-		 * (above), now continue with next file on tape,
-		 * if possible.
-		 * When the FM is reached, EXCEPTION is set,
-		 * causing a sense(). Subsequent read/writes will
-		 * continue after the FM.
-		 */
+
+	/* Just assume everything is ok. Controller will scream if not. */
+
+	if (status_bytes_wr) {	/* Once written, no more reads, 'till after WFM. */
+		return -EACCES;
+	}
+
+	/* This is rather ugly because it has to implement a finite state
+	 * machine in order to handle the EOF situations properly.
+	 */
+	while ((signed) count >= 0) {
+		bytes_done = 0;
+		/* see how much fits in the kernel buffer */
+		bytes_todo = TPQBUF_SIZE;
+		if (bytes_todo > count) {
+			bytes_todo = count;
+		}
+
+		/* Must ensure that user program sees exactly one EOF token (==0) */
+		if (return_read_eof == YES) {
+			if (TPQDBG(DEBUG)) {
+				printk
+				    ("read: return_read_eof==%d, reported_read_eof==%d, total_bytes_done==%lu\n",
+				     return_read_eof, reported_read_eof,
+				     total_bytes_done);
+			}
+
+			if (reported_read_eof == NO) {
+				/* have not yet returned EOF to user program */
+				if (total_bytes_done > 0) {
+					return total_bytes_done;	/* next time return EOF */
+				} else {
+					reported_read_eof = YES;	/* move on next time */
+					return 0;	/* return EOF */
+				}
+			} else {
+				/* Application program has already received EOF
+				 * (above), now continue with next file on tape,
+				 * if possible.
+				 * When the FM is reached, EXCEPTION is set,
+				 * causing a sense(). Subsequent read/writes will
+				 * continue after the FM.
+				 */
 		/*********** ?????????? this should check for (EOD|NDT), not EOM, 'cause we can read past EW: ************/
-		if (status_eom_detected)
-		{
-		    /* If EOM, nothing left to read, so keep returning EOFs.
-		     *** should probably set some flag to avoid clearing
-		     *** status_eom_detected through ioctls or something
-		     */
-		    return 0;
-		}
-		else
-		{
-		    /* just eof, there may be more files ahead... */
-		    return_read_eof = NO;
-		    reported_read_eof = NO;
-		    status_eof_detected = NO; /* reset this too */
-		    /*fall through*/
+				if (status_eom_detected) {
+					/* If EOM, nothing left to read, so keep returning EOFs.
+					 *** should probably set some flag to avoid clearing
+					 *** status_eom_detected through ioctls or something
+					 */
+					return 0;
+				} else {
+					/* just eof, there may be more files ahead... */
+					return_read_eof = NO;
+					reported_read_eof = NO;
+					status_eof_detected = NO;	/* reset this too */
+					/*fall through */
+				}
+			}
 		}
-	    }
-	}
-	
+
 	/*****************************/
-	if (bytes_todo==0)
-	{
-	    return total_bytes_done;
-	}
-	
-	if (bytes_todo>0)
-	{
-	    /* start reading data */
-	    if (is_exception())	/****************************************/
-	    {
-		tpqputs(TPQD_DMAX, "is_exception() before start_dma()!");
-	    }
-	    
+		if (bytes_todo == 0) {
+			return total_bytes_done;
+		}
+
+		if (bytes_todo > 0) {
+			/* start reading data */
+			if (is_exception()) {
+/****************************************/
+				tpqputs(TPQD_DMAX,
+					"is_exception() before start_dma()!");
+			}
+
 /******************************************************************
  ***** if start_dma() fails because the head is positioned 0 bytes
  ***** before the FM, (causing EXCEPTION to be set) return_read_eof should
  ***** be set to YES, and we should return total_bytes_done, rather than -ENXIO.
  ***** The app should recognize this as an EOF condition.
  ***************************************************************************/
-	    stat = start_dma(READ, bytes_todo);
-	    if (stat == TE_OK)
-	    {
-		/* Wait for transfer to complete, interrupt should wake us */
-		while (dma_mode != 0)
-		{
-		    sleep_on(&qic02_tape_transfer);
-		}
-		if (status_error)
-		{
-		    return_read_eof = YES;
-		}
-		
-	    }
-	    else if (stat != TE_END)
-	    {
-		/* should do sense() on error here */
+			stat = start_dma(READ, bytes_todo);
+			if (stat == TE_OK) {
+				/* Wait for transfer to complete, interrupt should wake us */
+				while (dma_mode != 0) {
+					sleep_on(&qic02_tape_transfer);
+				}
+				if (status_error) {
+					return_read_eof = YES;
+				}
+
+			} else if (stat != TE_END) {
+				/* should do sense() on error here */
 #if 0
-		return -ENXIO;
+				return -ENXIO;
 #else
-		printk("Trouble: stat==%02x\n", stat);
-		return_read_eof = YES;
+				printk("Trouble: stat==%02x\n", stat);
+				return_read_eof = YES;
 		/*************** check EOF/EOT handling!!!!!! **/
 #endif
-	    }
-	    end_dma(&bytes_done);
-	    if (bytes_done>bytes_todo)
-	    {
-		tpqputs(TPQD_ALWAYS, "read: Oops, read more bytes than requested");
-		return -EIO;
-	    }
-	    /* copy buffer to user-space in one go */
-	    if (bytes_done>0)
-	    {
-		err = copy_to_user(buf, buffaddr, bytes_done);
-		if (err)
-		{
-		    return -EFAULT;
-		}
-	    }
+			}
+			end_dma(&bytes_done);
+			if (bytes_done > bytes_todo) {
+				tpqputs(TPQD_ALWAYS,
+					"read: Oops, read more bytes than requested");
+				return -EIO;
+			}
+			/* copy buffer to user-space in one go */
+			if (bytes_done > 0) {
+				err =
+				    copy_to_user(buf, buffaddr,
+						 bytes_done);
+				if (err) {
+					return -EFAULT;
+				}
+			}
 #if 1
-	    /* Checks Ton's patch below */
-	    if ((return_read_eof == NO) && (status_eof_detected == YES))
-	    {
-		printk(TPQIC02_NAME ": read(): return_read_eof=%d, status_eof_detected=YES. return_read_eof:=YES\n", return_read_eof);
-	    }
+			/* Checks Ton's patch below */
+			if ((return_read_eof == NO)
+			    && (status_eof_detected == YES)) {
+				printk(TPQIC02_NAME
+				       ": read(): return_read_eof=%d, status_eof_detected=YES. return_read_eof:=YES\n",
+				       return_read_eof);
+			}
 #endif
-	    if ((bytes_todo != bytes_done) || (status_eof_detected == YES))
-	    {
-		/* EOF or EOM detected. return EOF next time. */
-		return_read_eof = YES;
-	    }
-	    
-	} /* else: ignore read request for 0 bytes */
+			if ((bytes_todo != bytes_done)
+			    || (status_eof_detected == YES)) {
+				/* EOF or EOM detected. return EOF next time. */
+				return_read_eof = YES;
+			}
 
-	if (bytes_done>0)
-	{
-	    status_bytes_rd = YES;
-	    buf += bytes_done;
-	    *ppos += bytes_done;
-	    total_bytes_done += bytes_done;
-	    count -= bytes_done;
-	}
-    }
-    tpqputs(TPQD_ALWAYS, "read request for <0 bytes");
-    return -EINVAL;
-} /* qic02_tape_read */
+		}
+		/* else: ignore read request for 0 bytes */
+		if (bytes_done > 0) {
+			status_bytes_rd = YES;
+			buf += bytes_done;
+			*ppos += bytes_done;
+			total_bytes_done += bytes_done;
+			count -= bytes_done;
+		}
+	}
+	tpqputs(TPQD_ALWAYS, "read request for <0 bytes");
+	return -EINVAL;
+}				/* qic02_tape_read */
 
 
 
@@ -1981,100 +2009,85 @@
  * tape device again. The driver will detect an exception status in (No Cartridge)
  * and force a rewind. After that tar may continue writing.
  */
-static ssize_t qic02_tape_write( struct file * filp,  const char * buf, 
-		size_t count, loff_t *ppos)
+static ssize_t qic02_tape_write(struct file *filp, const char *buf,
+				size_t count, loff_t * ppos)
 {
-    int err;
-    kdev_t dev = filp->f_dentry->d_inode->i_rdev;
-    unsigned short flags = filp->f_flags;
-    unsigned long bytes_todo, bytes_done, total_bytes_done = 0;
-    
-    if (status_zombie==YES)
-    {
-	tpqputs(TPQD_ALWAYS, "configs not set");		
-	return -ENXIO;
-    }
-
-    if (TP_DIAGS(current_tape_dev))
-    {
-	/* can't print a ``long long'' (for filp->f_pos), so chop it */
-	printk(TPQIC02_NAME ": request WRITE, minor=%x, buf=%p"
-	                    ", count=%lx, pos=%lx, flags=%x\n",
-	       MINOR(dev), buf,
-	       (long) count, (unsigned long) filp->f_pos, flags);
-    }
-    
-    if (count % TAPE_BLKSIZE) 	/* only allow mod 512 bytes at a time */
-    {
-	tpqputs(TPQD_BLKSZ, "Wrong block size");
-	return -EINVAL;
-    }
+	int err;
+	kdev_t dev = filp->f_dentry->d_inode->i_rdev;
+	unsigned short flags = filp->f_flags;
+	unsigned long bytes_todo, bytes_done, total_bytes_done = 0;
 
-    if (mode_access==READ)
-    {
-	tpqputs(TPQD_ALWAYS, "Not in write mode");
-	return -EACCES;
-    }
-
-    /* open() does a sense() and we can assume the tape isn't changed
-     * between open() and release(), so the tperror.exs bits will still
-     * be valid.
-     */
-    if ((tperror.exs & TP_ST0) && (tperror.exs & TP_WRP))
-    {
-	tpqputs(TPQD_ALWAYS, "Cartridge is write-protected.");
-	return -EACCES;	/* don't even try when write protected */
-    }
-      
-    if (doing_read == YES)
-    {
-	terminate_read(0);
-    }
-    
-    while ((signed)count>=0)
-    {
-	/* see how much fits in the kernel buffer */
-	bytes_done = 0;
-	bytes_todo = TPQBUF_SIZE;
-	if (bytes_todo>count)
-	{
-	    bytes_todo = count;
+	if (status_zombie == YES) {
+		tpqputs(TPQD_ALWAYS, "configs not set");
+		return -ENXIO;
 	}
-	
-	if (return_write_eof == YES)
-	{
-	    /* return_write_eof should be reset on reverse tape movements. */
-	    
-	    if (reported_write_eof==NO)
-	    {
-		if (bytes_todo>0)
-		{
-		    tpqputs(TPQD_ALWAYS, "partial write");
-		    /* partial write signals EOF to user program */
-		}
-		reported_write_eof = YES;
-		return total_bytes_done;
-	    }
-	    else
-	    {
-		return -ENOSPC;		 /* return error */
-	    }	
-	}
-	
-	/* Quit when done. */
-	if (bytes_todo==0)
-	{
-	    return total_bytes_done;
+
+	if (TP_DIAGS(current_tape_dev)) {
+		/* can't print a ``long long'' (for filp->f_pos), so chop it */
+		printk(TPQIC02_NAME ": request WRITE, minor=%x, buf=%p"
+		       ", count=%lx, pos=%lx, flags=%x\n",
+		       MINOR(dev), buf,
+		       (long) count, (unsigned long) filp->f_pos, flags);
+	}
+
+	if (count % TAPE_BLKSIZE) {	/* only allow mod 512 bytes at a time */
+		tpqputs(TPQD_BLKSZ, "Wrong block size");
+		return -EINVAL;
+	}
+
+	if (mode_access == READ) {
+		tpqputs(TPQD_ALWAYS, "Not in write mode");
+		return -EACCES;
+	}
+
+	/* open() does a sense() and we can assume the tape isn't changed
+	 * between open() and release(), so the tperror.exs bits will still
+	 * be valid.
+	 */
+	if ((tperror.exs & TP_ST0) && (tperror.exs & TP_WRP)) {
+		tpqputs(TPQD_ALWAYS, "Cartridge is write-protected.");
+		return -EACCES;	/* don't even try when write protected */
+	}
+
+	if (doing_read == YES) {
+		terminate_read(0);
 	}
-	
-	/* copy from user to DMA buffer and initiate transfer. */
-	if (bytes_todo>0)
-	{
-	    err = copy_from_user(buffaddr, buf, bytes_todo);
-	    if (err)
-	    {
-		return -EFAULT;
-	    }
+
+	while ((signed) count >= 0) {
+		/* see how much fits in the kernel buffer */
+		bytes_done = 0;
+		bytes_todo = TPQBUF_SIZE;
+		if (bytes_todo > count) {
+			bytes_todo = count;
+		}
+
+		if (return_write_eof == YES) {
+			/* return_write_eof should be reset on reverse tape movements. */
+
+			if (reported_write_eof == NO) {
+				if (bytes_todo > 0) {
+					tpqputs(TPQD_ALWAYS,
+						"partial write");
+					/* partial write signals EOF to user program */
+				}
+				reported_write_eof = YES;
+				return total_bytes_done;
+			} else {
+				return -ENOSPC;	/* return error */
+			}
+		}
+
+		/* Quit when done. */
+		if (bytes_todo == 0) {
+			return total_bytes_done;
+		}
+
+		/* copy from user to DMA buffer and initiate transfer. */
+		if (bytes_todo > 0) {
+			err = copy_from_user(buffaddr, buf, bytes_todo);
+			if (err) {
+				return -EFAULT;
+			}
 
 /****************** similar problem with read() at FM could happen here at EOT.
  ******************/
@@ -2082,78 +2095,74 @@
 /***** if at EOT, 0 bytes can be written. start_dma() will
  ***** fail and write() will return ENXIO error
  *****/
-	    if (start_dma(WRITE, bytes_todo) != TE_OK)
-	    {
-		tpqputs(TPQD_ALWAYS, "write: start_dma() failed");
-		/* should do sense() on error here */
-		return -ENXIO;	/*********** FIXTHIS **************/
-	    }
-
-	    /* Wait for write to complete, interrupt should wake us. */
-	    while ((status_error == 0) && (dma_mode != 0))
-	    {
-		sleep_on(&qic02_tape_transfer);
-	    }
-
-	    end_dma(&bytes_done);
-	    if (bytes_done>bytes_todo)
-	    {
-		tpqputs(TPQD_ALWAYS, "write: Oops, wrote more bytes than requested");
-		return -EIO;
-	    }
-	    /* If the dma-transfer was aborted because of an exception,
-	     * status_error will have been set in the interrupt handler.
-	     * Then end_dma() will do a sense().
-	     * If the exception was EXC_EOM, the EW-hole was encountered
-	     * and two more blocks could be written. For the time being we'll
-	     * just consider this to be the EOT.
-	     * Otherwise, something Bad happened, such as the maximum number
-	     * of block-rewrites was exceeded. [e.g. A very bad spot on tape was
-	     * encountered. Normally short dropouts are compensated for by
-	     * rewriting the block in error, up to 16 times. I'm not sure
-	     * QIC-24 drives can do this.]
-	     */
-	    if (status_error)
-	    {
-		if (status_eom_detected == YES)
-		{
-		    tpqputs(TPQD_ALWAYS, "write: EW detected");
-		    return_write_eof = YES;
-		}
-		else
-		{
-		    /* probably EXC_RWA */
-		    tpqputs(TPQD_ALWAYS, "write: dma: error in writing");
-		    return -EIO;
-		}
-	    }
-	    if (bytes_todo != bytes_done)
-	    {
-		/* EOF or EOM detected. return EOT next time. */
-		return_write_eof = YES;
-	    }
-	}
-	/* else: ignore write request for 0 bytes. */
-	
-	if (bytes_done>0)
-	{
-	    status_bytes_wr = YES;
-	    buf += bytes_done;
-	    *ppos += bytes_done;
-	    total_bytes_done += bytes_done;
-	    count -= bytes_done;
-	}
-    }
-    
-    tpqputs(TPQD_ALWAYS, "write request for <0 bytes");
-    if (TPQDBG(DEBUG))
-    {
-	printk(TPQIC02_NAME ": status_bytes_wr %x, buf %p"
-	                    ", total_bytes_done %lx, count %lx\n",
-	       status_bytes_wr, buf, total_bytes_done, (long) count);
-    }
-    return -EINVAL;
-} /* qic02_tape_write */
+			if (start_dma(WRITE, bytes_todo) != TE_OK) {
+				tpqputs(TPQD_ALWAYS,
+					"write: start_dma() failed");
+				/* should do sense() on error here */
+				return -ENXIO;
+				/*********** FIXTHIS **************/
+			}
+
+			/* Wait for write to complete, interrupt should wake us. */
+			while ((status_error == 0) && (dma_mode != 0)) {
+				sleep_on(&qic02_tape_transfer);
+			}
+
+			end_dma(&bytes_done);
+			if (bytes_done > bytes_todo) {
+				tpqputs(TPQD_ALWAYS,
+					"write: Oops, wrote more bytes than requested");
+				return -EIO;
+			}
+			/* If the dma-transfer was aborted because of an exception,
+			 * status_error will have been set in the interrupt handler.
+			 * Then end_dma() will do a sense().
+			 * If the exception was EXC_EOM, the EW-hole was encountered
+			 * and two more blocks could be written. For the time being we'll
+			 * just consider this to be the EOT.
+			 * Otherwise, something Bad happened, such as the maximum number
+			 * of block-rewrites was exceeded. [e.g. A very bad spot on tape was
+			 * encountered. Normally short dropouts are compensated for by
+			 * rewriting the block in error, up to 16 times. I'm not sure
+			 * QIC-24 drives can do this.]
+			 */
+			if (status_error) {
+				if (status_eom_detected == YES) {
+					tpqputs(TPQD_ALWAYS,
+						"write: EW detected");
+					return_write_eof = YES;
+				} else {
+					/* probably EXC_RWA */
+					tpqputs(TPQD_ALWAYS,
+						"write: dma: error in writing");
+					return -EIO;
+				}
+			}
+			if (bytes_todo != bytes_done) {
+				/* EOF or EOM detected. return EOT next time. */
+				return_write_eof = YES;
+			}
+		}
+		/* else: ignore write request for 0 bytes. */
+
+		if (bytes_done > 0) {
+			status_bytes_wr = YES;
+			buf += bytes_done;
+			*ppos += bytes_done;
+			total_bytes_done += bytes_done;
+			count -= bytes_done;
+		}
+	}
+
+	tpqputs(TPQD_ALWAYS, "write request for <0 bytes");
+	if (TPQDBG(DEBUG)) {
+		printk(TPQIC02_NAME ": status_bytes_wr %x, buf %p"
+		       ", total_bytes_done %lx, count %lx\n",
+		       status_bytes_wr, buf, total_bytes_done,
+		       (long) count);
+	}
+	return -EINVAL;
+}				/* qic02_tape_write */
 
 
 
@@ -2169,846 +2178,810 @@
  * Don't rewind if the minor bits specify density 0.
  */
 
-static int qic02_tape_open(struct inode * inode, struct file * filp)
+static int qic02_tape_open(struct inode *inode, struct file *filp)
 {
-    static int qic02_tape_open_no_use_count(struct inode *, struct file *);
-    int open_error;
+	static int qic02_tape_open_no_use_count(struct inode *,
+						struct file *);
+	int open_error;
 
-    open_error = qic02_tape_open_no_use_count(inode, filp);
-    return open_error;
+	open_error = qic02_tape_open_no_use_count(inode, filp);
+	return open_error;
 }
 
-static int qic02_tape_open_no_use_count(struct inode * inode, struct file * filp)
+static int qic02_tape_open_no_use_count(struct inode *inode,
+					struct file *filp)
 {
-    kdev_t dev = inode->i_rdev;
-    unsigned short flags = filp->f_flags;
-    unsigned short dens = 0;
-    int s;
-
-
-    if (TP_DIAGS(dev))
-    {
-	printk("qic02_tape_open: dev=%s, flags=%x     ",
-	       kdevname(dev), flags);
-    }
-
-    if (MINOR(dev)==255)	/* special case for resetting */
-    {
-	if (capable(CAP_SYS_ADMIN))
-	{
-	    return (tape_reset(1)==TE_OK) ? -EAGAIN : -ENXIO;
+	kdev_t dev = inode->i_rdev;
+	unsigned short flags = filp->f_flags;
+	unsigned short dens = 0;
+	int s;
+
+
+	if (TP_DIAGS(dev)) {
+		printk("qic02_tape_open: dev=%s, flags=%x     ",
+		       kdevname(dev), flags);
 	}
-	else
-	{
-	    return -EPERM;
+
+	if (MINOR(dev) == 255) {	/* special case for resetting */
+		if (capable(CAP_SYS_ADMIN)) {
+			return (tape_reset(1) == TE_OK) ? -EAGAIN : -ENXIO;
+		} else {
+			return -EPERM;
+		}
 	}
-    }
-    
-    if (status_dead==YES)
-    {
-	/* Allow `mt reset' ioctl() even when already open()ed. */
-	return 0;
-    }
-    
+
+	if (status_dead == YES) {
+		/* Allow `mt reset' ioctl() even when already open()ed. */
+		return 0;
+	}
+
 	/* Only one at a time from here on... */
-    if (file_count(filp)>1) 	/* filp->f_count==1 for the first open() */
-    {
-	return -EBUSY;
-    }
-
-    if (status_zombie==YES)
-    {
-	/* no irq/dma/port stuff allocated yet, no reset done
-	 * yet, so return until MTSETCONFIG has been done.
+	if (file_count(filp) > 1) {	/* filp->f_count==1 for the first open() */
+		return -EBUSY;
+	}
+
+	if (status_zombie == YES) {
+		/* no irq/dma/port stuff allocated yet, no reset done
+		 * yet, so return until MTSETCONFIG has been done.
+		 */
+		return 0;
+	}
+
+	status_bytes_rd = NO;
+	status_bytes_wr = NO;
+
+	return_read_eof = NO;	/********????????????????*****/
+	return_write_eof = (status_eot_detected) ? YES : NO;
+
+	/* Clear this in case user app close()d before reading EOF token */
+	status_eof_detected = NO;
+
+	reported_read_eof = NO;
+	reported_write_eof = NO;
+
+
+	switch (flags & O_ACCMODE) {
+	case O_RDONLY:
+		mode_access = READ;
+		break;
+	case O_WRONLY:		/* Fallthru... Strictly speaking this is not correct... */
+	case O_RDWR:		/* Reads are allowed as long as nothing is written */
+		mode_access = WRITE;
+		break;
+	}
+
+	/* This is to avoid tape-changed problems (TP_CNI exception).
+	 *
+	 * Since removing the cartridge will not raise an exception,
+	 * we always do a tp_sense() to make sure we have the proper
+	 * CNI status, the 2150L may need an additional sense.... - Eddy
 	 */
-	return 0;
-    }
-    
-    status_bytes_rd = NO;
-    status_bytes_wr = NO;
-    
-    return_read_eof = NO;	/********????????????????*****/
-    return_write_eof = (status_eot_detected)? YES : NO;
-
-    /* Clear this in case user app close()d before reading EOF token */
-    status_eof_detected = NO;
-
-    reported_read_eof = NO;
-    reported_write_eof = NO;
-
-
-    switch (flags & O_ACCMODE)
-    {
-     case O_RDONLY:
-	mode_access = READ;
-	break;
-     case O_WRONLY:	/* Fallthru... Strictly speaking this is not correct... */
-     case O_RDWR:	/* Reads are allowed as long as nothing is written */
-	mode_access = WRITE;
-	break;
-    }
-    
-    /* This is to avoid tape-changed problems (TP_CNI exception).
-     *
-     * Since removing the cartridge will not raise an exception,
-     * we always do a tp_sense() to make sure we have the proper
-     * CNI status, the 2150L may need an additional sense.... - Eddy
-     */
-    s = tp_sense(TP_WRP|TP_EOM|TP_BOM|TP_CNI|TP_EOR);
-    
-    if (s == TE_OK)
-    {
-	/* Try to clear cartridge-changed status for Archive-2150L */
-	if ((tperror.exs & TP_ST0) && (tperror.exs & TP_CNI))
-	{
-	    s = tp_sense(TP_WRP|TP_EOM|TP_BOM|TP_CNI|TP_EOR);
+	s = tp_sense(TP_WRP | TP_EOM | TP_BOM | TP_CNI | TP_EOR);
+
+	if (s == TE_OK) {
+		/* Try to clear cartridge-changed status for Archive-2150L */
+		if ((tperror.exs & TP_ST0) && (tperror.exs & TP_CNI)) {
+			s = tp_sense(TP_WRP | TP_EOM | TP_BOM | TP_CNI |
+				     TP_EOR);
+		}
+	}
+
+	if (s != TE_OK) {
+		tpqputs(TPQD_ALWAYS, "open: sense() failed");
+		return -EIO;
 	}
-    }
-    
-    if (s != TE_OK)
-    {
-	tpqputs(TPQD_ALWAYS, "open: sense() failed");
-	return -EIO;
-    }
-
-    /* exception bits should be up-to-date now, so check for
-     * tape presence and exit if absent.
-     * Even `mt stat' will fail without a tape.
-     */
-    if ((tperror.exs & TP_ST0) && (tperror.exs & TP_CNI))
-    {
-	tpqputs(TPQD_ALWAYS, "No tape present.");
-	return -EIO;
-    }
-
-    /* At this point we can assume that a tape is present and
-     * that it will remain present until release() is called.
-     */
-
-    /* not allowed to do QCMD_DENS_* unless tape is rewound */
-    if ((TP_DENS(dev)!=0) && (TP_DENS(current_tape_dev) != TP_DENS(dev)))
-    {
-	/* force rewind if minor bits have changed,
-	 * i.e. user wants to use tape in different format.
-	 * [assuming single drive operation]
+
+	/* exception bits should be up-to-date now, so check for
+	 * tape presence and exit if absent.
+	 * Even `mt stat' will fail without a tape.
 	 */
-	if (TP_HAVE_DENS)
-	{
-	    tpqputs(TPQD_REWIND, "Density minor bits have changed. Forcing rewind.");
-	    need_rewind = YES;
+	if ((tperror.exs & TP_ST0) && (tperror.exs & TP_CNI)) {
+		tpqputs(TPQD_ALWAYS, "No tape present.");
+		return -EIO;
 	}
-    }
-    else
-    {
-	/* density bits still the same, but TP_DIAGS bit 
-	 * may have changed.
+
+	/* At this point we can assume that a tape is present and
+	 * that it will remain present until release() is called.
 	 */
-	current_tape_dev = dev;
-    }
-    
-    if (need_rewind == YES)  /***************** CHECK THIS!!!!!!!! **********/
-    {
-	s = do_qic_cmd(QCMD_REWIND, TIM_R);
-	if (s != 0)
-	{
-	    tpqputs(TPQD_ALWAYS, "open: rewind failed");
-	    return -EIO;
+
+	/* not allowed to do QCMD_DENS_* unless tape is rewound */
+	if ((TP_DENS(dev) != 0)
+	    && (TP_DENS(current_tape_dev) != TP_DENS(dev))) {
+		/* force rewind if minor bits have changed,
+		 * i.e. user wants to use tape in different format.
+		 * [assuming single drive operation]
+		 */
+		if (TP_HAVE_DENS) {
+			tpqputs(TPQD_REWIND,
+				"Density minor bits have changed. Forcing rewind.");
+			need_rewind = YES;
+		}
+	} else {
+		/* density bits still the same, but TP_DIAGS bit 
+		 * may have changed.
+		 */
+		current_tape_dev = dev;
+	}
+
+	if (need_rewind == YES) {
+/***************** CHECK THIS!!!!!!!! **********/
+		s = do_qic_cmd(QCMD_REWIND, TIM_R);
+		if (s != 0) {
+			tpqputs(TPQD_ALWAYS, "open: rewind failed");
+			return -EIO;
+		}
 	}
-    }
 
 
 /* Note: After a reset command, the controller will rewind the tape
  *	 just before performing any tape movement operation! ************ SO SET need_rewind flag!!!!!
- */ 
-    if (status_dead==YES)
-    {
-	tpqputs(TPQD_ALWAYS, "open: tape dead, attempting reset");
-	if (tape_reset(1)!=TE_OK)
-	{
-	    return -ENXIO;
+ */
+	if (status_dead == YES) {
+		tpqputs(TPQD_ALWAYS, "open: tape dead, attempting reset");
+		if (tape_reset(1) != TE_OK) {
+			return -ENXIO;
+		} else {
+			status_dead = NO;
+			if (tp_sense(~(TP_ST1 | TP_ILL)) != TE_OK) {
+				tpqputs(TPQD_ALWAYS,
+					"open: tp_sense() failed\n");
+				status_dead = YES;	/* try reset next time */
+				return -EIO;
+			}
+		}
 	}
-	else
-	{
-	    status_dead = NO;
-	    if (tp_sense(~(TP_ST1|TP_ILL)) != TE_OK)
-	    {
-		tpqputs(TPQD_ALWAYS, "open: tp_sense() failed\n");
-		status_dead = YES;	/* try reset next time */
+
+	/* things should be ok, once we get here */
+
+
+	/* set density: only allowed when TP_BOM status bit is set,
+	 * so we must have done a rewind by now. If not, just skip over.
+	 * Only give set density command when minor bits have changed.
+	 */
+	if (TP_DENS(current_tape_dev) == TP_DENS(dev)) {
+		return 0;
+	}
+
+	current_tape_dev = dev;
+	need_rewind = NO;
+	if (TP_HAVE_DENS) {
+		dens = TP_DENS(dev);
+	}
+
+	if (dens < sizeof(format_names) / sizeof(char *)) {
+		printk(TPQIC02_NAME ": format: %s%s\n",
+		       (dens != 0) ? "QIC-" : "", format_names[dens]);
+	} else {
+		tpqputs(TPQD_REWIND, "Wait for retensioning...");
+	}
+
+	switch (TP_DENS(dev)) {
+	case 0:		/* Minor 0 is for drives without set-density support */
+		s = 0;
+		break;
+	case 1:
+		s = do_qic_cmd(QCMD_DENS_11, TIM_S);
+		break;
+	case 2:
+		s = do_qic_cmd(QCMD_DENS_24, TIM_S);
+		break;
+	case 3:
+		s = do_qic_cmd(QCMD_DENS_120, TIM_S);
+		break;
+	case 4:
+		s = do_qic_cmd(QCMD_DENS_150, TIM_S);
+		break;
+	case 5:
+		s = do_qic_cmd(QCMD_DENS_300, TIM_S);
+		break;
+	case 6:
+		s = do_qic_cmd(QCMD_DENS_600, TIM_S);
+		break;
+	default:		/* otherwise do a retension before anything else */
+		s = do_qic_cmd(QCMD_RETEN, TIM_R);
+	}
+	if (s != 0) {
+		status_dead = YES;	/* force reset */
+		current_tape_dev = 0;	/* earlier 0xff80 */
 		return -EIO;
-	    }
 	}
-    }
-    
-    /* things should be ok, once we get here */
-    
-
-    /* set density: only allowed when TP_BOM status bit is set,
-     * so we must have done a rewind by now. If not, just skip over.
-     * Only give set density command when minor bits have changed.
-     */
-    if (TP_DENS(current_tape_dev) == TP_DENS(dev) )
-    {
+
 	return 0;
-    }
-    
-    current_tape_dev = dev;
-    need_rewind = NO;
-    if (TP_HAVE_DENS)
-    {
-	dens = TP_DENS(dev);
-    }
-    
-    if (dens < sizeof(format_names)/sizeof(char *))
-    {
-	printk(TPQIC02_NAME ": format: %s%s\n", (dens!=0)? "QIC-" : "", format_names[dens]);
-    }
-    else
-    {
-	tpqputs(TPQD_REWIND, "Wait for retensioning...");
-    }
-    
-    switch (TP_DENS(dev))
-    {
-     case 0: /* Minor 0 is for drives without set-density support */
-	s = 0;
-	break;
-     case 1:
-	s = do_qic_cmd(QCMD_DENS_11, TIM_S);
-	break;
-     case 2:
-	s = do_qic_cmd(QCMD_DENS_24, TIM_S);
-	break;
-     case 3:
-	s = do_qic_cmd(QCMD_DENS_120, TIM_S);
-	break;
-     case 4:
-	s = do_qic_cmd(QCMD_DENS_150, TIM_S);
-	break;
-     case 5:
-	s = do_qic_cmd(QCMD_DENS_300, TIM_S);
-	break;
-     case 6:
-	s = do_qic_cmd(QCMD_DENS_600, TIM_S);
-	break;
-     default:  /* otherwise do a retension before anything else */
-	s = do_qic_cmd(QCMD_RETEN, TIM_R);
-    }
-    if (s != 0)
-    {
-	status_dead = YES;	/* force reset */
-	current_tape_dev = 0; /* earlier 0xff80 */
-	return -EIO;
-    }
-    
-    return 0;
-} /* qic02_tape_open */
-
-
-static int qic02_tape_release(struct inode * inode, struct file * filp)
-{
-    kdev_t dev = inode->i_rdev;
-
-    lock_kernel();
-    if (TP_DIAGS(dev))
-    {
-	printk("qic02_tape_release: dev=%s\n",  kdevname(dev));
-    }
-    
-    if (status_zombie==NO)		/* don't rewind in zombie mode */
-    {
-	/* Terminate any pending write cycle. Terminating the read-cycle
-	 * is delayed until it is required to do so for a new command.
-	 */
-	terminate_write(-1);
-	
-	if (status_dead==YES)
-	{
-	    tpqputs(TPQD_ALWAYS, "release: device dead!?");
+}				/* qic02_tape_open */
+
+
+static int qic02_tape_release(struct inode *inode, struct file *filp)
+{
+	kdev_t dev = inode->i_rdev;
+
+	lock_kernel();
+	if (TP_DIAGS(dev)) {
+		printk("qic02_tape_release: dev=%s\n", kdevname(dev));
 	}
-	
-	/* Rewind only if minor number requires it AND 
-	 * read/writes have been done. ************* IS THIS CORRECT??????????
-	 */
-	if ((TP_REWCLOSE(dev)) && (status_bytes_rd | status_bytes_wr))
-	{
-	    tpqputs(TPQD_REWIND, "release: Doing rewind...");
-	    (void) do_qic_cmd(QCMD_REWIND, TIM_R);
+
+	if (status_zombie == NO) {	/* don't rewind in zombie mode */
+		/* Terminate any pending write cycle. Terminating the read-cycle
+		 * is delayed until it is required to do so for a new command.
+		 */
+		terminate_write(-1);
+
+		if (status_dead == YES) {
+			tpqputs(TPQD_ALWAYS, "release: device dead!?");
+		}
+
+		/* Rewind only if minor number requires it AND 
+		 * read/writes have been done. ************* IS THIS CORRECT??????????
+		 */
+		if ((TP_REWCLOSE(dev))
+		    && (status_bytes_rd | status_bytes_wr)) {
+			tpqputs(TPQD_REWIND, "release: Doing rewind...");
+			(void) do_qic_cmd(QCMD_REWIND, TIM_R);
+		}
 	}
-    }
-    unlock_kernel();
-    return 0;
-} /* qic02_tape_release */
+	unlock_kernel();
+	return 0;
+}				/* qic02_tape_release */
 
 
 #ifdef CONFIG_QIC02_DYNCONF
 /* Set masks etc. based on the interface card type. */
 static int update_ifc_masks(int ifc)
 {
-    QIC02_TAPE_IFC = ifc;
+	QIC02_TAPE_IFC = ifc;
 
-    if ((QIC02_TAPE_IFC == WANGTEK) || (QIC02_TAPE_IFC == EVEREX))
-    {
-	QIC02_STAT_PORT = QIC02_TAPE_PORT;
-	QIC02_CTL_PORT = QIC02_TAPE_PORT;
-	QIC02_CMD_PORT = QIC02_TAPE_PORT+1;
-	QIC02_DATA_PORT = QIC02_TAPE_PORT+1;
-	QIC02_STAT_READY = WT_QIC02_STAT_READY;
-	QIC02_STAT_EXCEPTION = WT_QIC02_STAT_EXCEPTION;
-	QIC02_STAT_MASK = WT_QIC02_STAT_MASK;
-	
-	QIC02_STAT_RESETMASK = WT_QIC02_STAT_RESETMASK;
-	QIC02_STAT_RESETVAL = WT_QIC02_STAT_RESETVAL;
-	
-	QIC02_CTL_RESET = WT_QIC02_CTL_RESET;
-	QIC02_CTL_REQUEST = WT_QIC02_CTL_REQUEST;
- 
-	if (QIC02_TAPE_DMA == 3)
-	{
-	    WT_CTL_DMA = WT_CTL_DMA3;
-	}
-	else if (QIC02_TAPE_DMA == 1)
-	{
-	    WT_CTL_DMA = WT_CTL_DMA1;
-	}
-	else
-	{
-	    tpqputs(TPQD_ALWAYS, "Unsupported or incorrect DMA channel");
-	    return -EIO;
-	} 
+	if ((QIC02_TAPE_IFC == WANGTEK) || (QIC02_TAPE_IFC == EVEREX)) {
+		QIC02_STAT_PORT = QIC02_TAPE_PORT;
+		QIC02_CTL_PORT = QIC02_TAPE_PORT;
+		QIC02_CMD_PORT = QIC02_TAPE_PORT + 1;
+		QIC02_DATA_PORT = QIC02_TAPE_PORT + 1;
+		QIC02_STAT_READY = WT_QIC02_STAT_READY;
+		QIC02_STAT_EXCEPTION = WT_QIC02_STAT_EXCEPTION;
+		QIC02_STAT_MASK = WT_QIC02_STAT_MASK;
+
+		QIC02_STAT_RESETMASK = WT_QIC02_STAT_RESETMASK;
+		QIC02_STAT_RESETVAL = WT_QIC02_STAT_RESETVAL;
+
+		QIC02_CTL_RESET = WT_QIC02_CTL_RESET;
+		QIC02_CTL_REQUEST = WT_QIC02_CTL_REQUEST;
+
+		if (QIC02_TAPE_DMA == 3) {
+			WT_CTL_DMA = WT_CTL_DMA3;
+		} else if (QIC02_TAPE_DMA == 1) {
+			WT_CTL_DMA = WT_CTL_DMA1;
+		} else {
+			tpqputs(TPQD_ALWAYS,
+				"Unsupported or incorrect DMA channel");
+			return -EIO;
+		}
 
-	if (QIC02_TAPE_IFC == EVEREX)
-	{
-	    /* Everex is a special case for Wangtek (actually
-	     * it's the other way 'round, but I saw Wangtek first)
-	     */
-	    if (QIC02_TAPE_DMA==3)
-	    {
-		WT_CTL_DMA = WT_CTL_DMA1;
-	    }
-	    
-	    /* Fixup the kernel copy of the IFC type to that
-	     * we don't have to distinguish between Wangtek and
-	     * and Everex at runtime.
-	     */
-	    QIC02_TAPE_IFC = WANGTEK;
-	}
-    }
-    else if (QIC02_TAPE_IFC == ARCHIVE)
-    {
-	QIC02_STAT_PORT = QIC02_TAPE_PORT+1;
-	QIC02_CTL_PORT = QIC02_TAPE_PORT+1;
-	QIC02_CMD_PORT = QIC02_TAPE_PORT;
-	QIC02_DATA_PORT = QIC02_TAPE_PORT;
-	QIC02_STAT_READY = AR_QIC02_STAT_READY;
-	QIC02_STAT_EXCEPTION  = AR_QIC02_STAT_EXCEPTION;
-	QIC02_STAT_MASK = AR_QIC02_STAT_MASK;
-	
-	QIC02_STAT_RESETMASK = AR_QIC02_STAT_RESETMASK;
-	QIC02_STAT_RESETVAL = AR_QIC02_STAT_RESETVAL;
-	
-	QIC02_CTL_RESET = AR_QIC02_CTL_RESET;
-	QIC02_CTL_REQUEST = AR_QIC02_CTL_REQUEST;
-	
-	if (QIC02_TAPE_DMA > 3)
-	{
-	    tpqputs(TPQD_ALWAYS, "Unsupported or incorrect DMA channel");
-	    return -EIO;
-	} 
-    }
-    else if (QIC02_TAPE_IFC == MOUNTAIN)
-    {
-	QIC02_STAT_PORT = QIC02_TAPE_PORT+1;
-	QIC02_CTL_PORT = QIC02_TAPE_PORT+1;
-	QIC02_CMD_PORT = QIC02_TAPE_PORT;
-	QIC02_DATA_PORT = QIC02_TAPE_PORT;
-	
-	QIC02_STAT_READY = MTN_QIC02_STAT_READY;
-	QIC02_STAT_EXCEPTION  = MTN_QIC02_STAT_EXCEPTION;
-	QIC02_STAT_MASK = MTN_QIC02_STAT_MASK;
-	
-	QIC02_STAT_RESETMASK = MTN_QIC02_STAT_RESETMASK;
-	QIC02_STAT_RESETVAL = MTN_QIC02_STAT_RESETVAL;
-	
-	QIC02_CTL_RESET = MTN_QIC02_CTL_RESET;
-	QIC02_CTL_REQUEST = MTN_QIC02_CTL_REQUEST;
-	
-	if (QIC02_TAPE_DMA > 3)
-	{
-	    tpqputs(TPQD_ALWAYS, "Unsupported or incorrect DMA channel");
-	    return -EIO;
-	} 
-    }
-    else
-    {
-	tpqputs(TPQD_ALWAYS, "Invalid interface type");
-	return -ENXIO;
-    }
-    return qic02_get_resources();
-} /* update_ifc_masks */
+		if (QIC02_TAPE_IFC == EVEREX) {
+			/* Everex is a special case for Wangtek (actually
+			 * it's the other way 'round, but I saw Wangtek first)
+			 */
+			if (QIC02_TAPE_DMA == 3) {
+				WT_CTL_DMA = WT_CTL_DMA1;
+			}
+
+			/* Fixup the kernel copy of the IFC type to that
+			 * we don't have to distinguish between Wangtek and
+			 * and Everex at runtime.
+			 */
+			QIC02_TAPE_IFC = WANGTEK;
+		}
+	} else if (QIC02_TAPE_IFC == ARCHIVE) {
+		QIC02_STAT_PORT = QIC02_TAPE_PORT + 1;
+		QIC02_CTL_PORT = QIC02_TAPE_PORT + 1;
+		QIC02_CMD_PORT = QIC02_TAPE_PORT;
+		QIC02_DATA_PORT = QIC02_TAPE_PORT;
+		QIC02_STAT_READY = AR_QIC02_STAT_READY;
+		QIC02_STAT_EXCEPTION = AR_QIC02_STAT_EXCEPTION;
+		QIC02_STAT_MASK = AR_QIC02_STAT_MASK;
+
+		QIC02_STAT_RESETMASK = AR_QIC02_STAT_RESETMASK;
+		QIC02_STAT_RESETVAL = AR_QIC02_STAT_RESETVAL;
+
+		QIC02_CTL_RESET = AR_QIC02_CTL_RESET;
+		QIC02_CTL_REQUEST = AR_QIC02_CTL_REQUEST;
+
+		if (QIC02_TAPE_DMA > 3) {
+			tpqputs(TPQD_ALWAYS,
+				"Unsupported or incorrect DMA channel");
+			return -EIO;
+		}
+	} else if (QIC02_TAPE_IFC == MOUNTAIN) {
+		QIC02_STAT_PORT = QIC02_TAPE_PORT + 1;
+		QIC02_CTL_PORT = QIC02_TAPE_PORT + 1;
+		QIC02_CMD_PORT = QIC02_TAPE_PORT;
+		QIC02_DATA_PORT = QIC02_TAPE_PORT;
+
+		QIC02_STAT_READY = MTN_QIC02_STAT_READY;
+		QIC02_STAT_EXCEPTION = MTN_QIC02_STAT_EXCEPTION;
+		QIC02_STAT_MASK = MTN_QIC02_STAT_MASK;
+
+		QIC02_STAT_RESETMASK = MTN_QIC02_STAT_RESETMASK;
+		QIC02_STAT_RESETVAL = MTN_QIC02_STAT_RESETVAL;
+
+		QIC02_CTL_RESET = MTN_QIC02_CTL_RESET;
+		QIC02_CTL_REQUEST = MTN_QIC02_CTL_REQUEST;
+
+		if (QIC02_TAPE_DMA > 3) {
+			tpqputs(TPQD_ALWAYS,
+				"Unsupported or incorrect DMA channel");
+			return -EIO;
+		}
+	} else {
+		tpqputs(TPQD_ALWAYS, "Invalid interface type");
+		return -ENXIO;
+	}
+	return qic02_get_resources();
+}				/* update_ifc_masks */
 #endif
 
 
 /* ioctl allows user programs to rewind the tape and stuff like that */
-static int qic02_tape_ioctl(struct inode * inode, struct file * filp, 
-		     unsigned int iocmd, unsigned long ioarg)
+static int qic02_tape_ioctl(struct inode *inode, struct file *filp,
+			    unsigned int iocmd, unsigned long ioarg)
 {
-    int error;
-    int dev_maj = MAJOR(inode->i_rdev);
-    int c;
-    struct mtop operation;
-    unsigned char blk_addr[6];
-    struct mtpos ioctl_tell;
-    
-
-    if (TP_DIAGS(current_tape_dev))
-    {
-	printk(TPQIC02_NAME ": ioctl(%4x, %4x, %4lx)\n", dev_maj, iocmd, ioarg);
-    }
-    
-    if (!inode || !ioarg)
-    {
-	return -EINVAL;
-    }
-    
-    /* check iocmd first */
-
-    if (dev_maj != QIC02_TAPE_MAJOR)
-    {
-	printk(TPQIC02_NAME ": Oops! Wrong device?\n");
-	/* A panic() would be appropriate here */
-	return -ENODEV;
-    }
-
-    c = _IOC_NR(iocmd);
+	int error;
+	int dev_maj = MAJOR(inode->i_rdev);
+	int c;
+	struct mtop operation;
+	unsigned char blk_addr[6];
+	struct mtpos ioctl_tell;
 
-#ifdef CONFIG_QIC02_DYNCONF
-    if (c == _IOC_NR(MTIOCGETCONFIG))
-    {
-	CHECK_IOC_SIZE(mtconfiginfo);
 
-	if (copy_to_user((char *) ioarg, (char *) &qic02_tape_dynconf, sizeof(qic02_tape_dynconf)))
-	{
-	    return -EFAULT;
+	if (TP_DIAGS(current_tape_dev)) {
+		printk(TPQIC02_NAME ": ioctl(%4x, %4x, %4lx)\n", dev_maj,
+		       iocmd, ioarg);
 	}
-	return 0;
 
-    }
-    else if (c == _IOC_NR(MTIOCSETCONFIG))
-    {
-	/* One should always do a MTIOCGETCONFIG first, then update
-	 * user-settings, then write back with MTIOCSETCONFIG.
-	 * The qic02conf program should re-open() the device before actual
-	 * use, to make sure everything is initialized.
-	 */
-	
-	CHECK_IOC_SIZE(mtconfiginfo);
-	
-	if (!capable(CAP_SYS_ADMIN))
-	{
-	    return -EPERM;
+	if (!inode || !ioarg) {
+		return -EINVAL;
 	}
-	
-	if ((doing_read!=NO) || (doing_write!=NO))
-	{
-	    return -EBUSY;
+
+	/* check iocmd first */
+
+	if (dev_maj != QIC02_TAPE_MAJOR) {
+		printk(TPQIC02_NAME ": Oops! Wrong device?\n");
+		/* A panic() would be appropriate here */
+		return -ENODEV;
 	}
-	
-	if (status_zombie==NO)
-	{
-	    qic02_release_resources();	/* and go zombie */
+
+	c = _IOC_NR(iocmd);
+
+#ifdef CONFIG_QIC02_DYNCONF
+	if (c == _IOC_NR(MTIOCGETCONFIG)) {
+		CHECK_IOC_SIZE(mtconfiginfo);
+
+		if (copy_to_user
+		    ((char *) ioarg, (char *) &qic02_tape_dynconf,
+		     sizeof(qic02_tape_dynconf))) {
+			return -EFAULT;
+		}
+		return 0;
+
+	} else if (c == _IOC_NR(MTIOCSETCONFIG)) {
+		/* One should always do a MTIOCGETCONFIG first, then update
+		 * user-settings, then write back with MTIOCSETCONFIG.
+		 * The qic02conf program should re-open() the device before actual
+		 * use, to make sure everything is initialized.
+		 */
+
+		CHECK_IOC_SIZE(mtconfiginfo);
+
+		if (!capable(CAP_SYS_ADMIN)) {
+			return -EPERM;
+		}
+
+		if ((doing_read != NO) || (doing_write != NO)) {
+			return -EBUSY;
+		}
+
+		if (status_zombie == NO) {
+			qic02_release_resources();	/* and go zombie */
+		}
+
+		/* copy struct from user space to kernel space */
+		if (copy_from_user
+		    ((char *) &qic02_tape_dynconf, (char *) ioarg,
+		     sizeof(qic02_tape_dynconf))) {
+			return -EFAULT;
+		}
+		return update_ifc_masks(qic02_tape_dynconf.ifc_type);
 	}
-	
-	/* copy struct from user space to kernel space */
-	if (copy_from_user((char *) &qic02_tape_dynconf, (char *) ioarg, sizeof(qic02_tape_dynconf)))
-	{
-	    return -EFAULT;
+	if (status_zombie == YES) {
+		tpqputs(TPQD_ALWAYS, "Configs not set");
+		return -ENXIO;
 	}
-	return update_ifc_masks(qic02_tape_dynconf.ifc_type);
-    }
-    if (status_zombie==YES)
-    {
-	tpqputs(TPQD_ALWAYS, "Configs not set");
-	return -ENXIO;
-    }
 #endif
-    if (c == _IOC_NR(MTIOCTOP))
-    {
-	CHECK_IOC_SIZE(mtop);
+	if (c == _IOC_NR(MTIOCTOP)) {
+		CHECK_IOC_SIZE(mtop);
 
-	/* copy mtop struct from user space to kernel space */
-	if (copy_from_user((char *) &operation, (char *) ioarg, sizeof(operation)))
-	{
-	    return -EFAULT;
-	}
+		/* copy mtop struct from user space to kernel space */
+		if (copy_from_user
+		    ((char *) &operation, (char *) ioarg,
+		     sizeof(operation))) {
+			return -EFAULT;
+		}
 
-	/* ---note: mt_count is signed, negative seeks must be
-	 * ---	    translated to seeks in opposite direction!
-	 * (only needed for Sun-programs, I think.)
-	 */
-	/* ---note: MTFSF with count 0 should position the
-	 * ---	    tape at the beginning of the current file.
-	 */
+		/* ---note: mt_count is signed, negative seeks must be
+		 * ---      translated to seeks in opposite direction!
+		 * (only needed for Sun-programs, I think.)
+		 */
+		/* ---note: MTFSF with count 0 should position the
+		 * ---      tape at the beginning of the current file.
+		 */
 
-	if (TP_DIAGS(current_tape_dev))
-	{
-	    printk("OP op=%4x, count=%4x\n", operation.mt_op, operation.mt_count);
-	}
-	
-	if (operation.mt_count < 0)
-	{
-	    tpqputs(TPQD_ALWAYS, "Warning: negative mt_count ignored");
-	}
-	
-	ioctl_status.mt_resid = operation.mt_count;
-	if (operation.mt_op == MTSEEK)
-	{
-	    if (!TP_HAVE_SEEK)
-	    {
-		return -ENOTTY;
-	    }
-	    
-	    seek_addr_buf[0] = (operation.mt_count>>16)&0xff;
-	    seek_addr_buf[1] = (operation.mt_count>>8)&0xff;
-	    seek_addr_buf[2] = (operation.mt_count)&0xff;
-	    if (operation.mt_count>>24)
-	    {
-		return -EINVAL;
-	    }
-	    if ((error = do_ioctl_cmd(operation.mt_op)) != 0)
-	    {
-		return error;
-	    }
-	    
-	    ioctl_status.mt_resid = 0;
-	}
-	else
-	{
-	    while (operation.mt_count > 0)
-	    {
-		operation.mt_count--;
-		if ((error = do_ioctl_cmd(operation.mt_op)) != 0)
-		{
-		    return error;
+		if (TP_DIAGS(current_tape_dev)) {
+			printk("OP op=%4x, count=%4x\n", operation.mt_op,
+			       operation.mt_count);
+		}
+
+		if (operation.mt_count < 0) {
+			tpqputs(TPQD_ALWAYS,
+				"Warning: negative mt_count ignored");
 		}
-		
+
 		ioctl_status.mt_resid = operation.mt_count;
-	    }
-	}
-	return 0;
-	
-    }
-    else if (c == _IOC_NR(MTIOCGET))
-    {
-	if (TP_DIAGS(current_tape_dev))
-	{
-	    printk("GET ");
-	}
-	
-	CHECK_IOC_SIZE(mtget);
+		if (operation.mt_op == MTSEEK) {
+			if (!TP_HAVE_SEEK) {
+				return -ENOTTY;
+			}
 
-	/* It appears (gmt(1)) that it is normal behaviour to
-	 * first set the status with MTNOP, and then to read
-	 * it out with MTIOCGET
-	 */
+			seek_addr_buf[0] =
+			    (operation.mt_count >> 16) & 0xff;
+			seek_addr_buf[1] =
+			    (operation.mt_count >> 8) & 0xff;
+			seek_addr_buf[2] = (operation.mt_count) & 0xff;
+			if (operation.mt_count >> 24) {
+				return -EINVAL;
+			}
+			if ((error = do_ioctl_cmd(operation.mt_op)) != 0) {
+				return error;
+			}
 
-	/* copy results to user space */
-	if (copy_to_user((char *) ioarg, (char *) &ioctl_status, sizeof(ioctl_status)))
-	{
-	    return -EFAULT;
-	}	
-	return 0;
-    }
-    else if (TP_HAVE_TELL && (c == _IOC_NR(MTIOCPOS)))
-    {
-	if (TP_DIAGS(current_tape_dev))
-	{
-	    printk("POS ");
-	}
-	
-	CHECK_IOC_SIZE(mtpos);
-	
-	tpqputs(TPQD_IOCTLS, "MTTELL reading block address");
-	if ((doing_read==YES) || (doing_write==YES))
-	{
-	    finish_rw(AR_QCMDV_TELL_BLK);
-	}
-	
-	c = rdstatus((char *) blk_addr, sizeof(blk_addr), AR_QCMDV_TELL_BLK);
-	if (c!=TE_OK)
-	{
-	    return -EIO;
-	}
-	
-	ioctl_tell.mt_blkno = (blk_addr[3] << 16) | (blk_addr[4] << 8) | blk_addr[5];
+			ioctl_status.mt_resid = 0;
+		} else {
+			while (operation.mt_count > 0) {
+				operation.mt_count--;
+				if ((error =
+				     do_ioctl_cmd(operation.mt_op)) != 0) {
+					return error;
+				}
 
-	/* copy results to user space */
-	if (copy_to_user((char *) ioarg, (char *) &ioctl_tell, sizeof(ioctl_tell)))
-	{
-	    return -EFAULT;
-	}
-	return 0;
+				ioctl_status.mt_resid = operation.mt_count;
+			}
+		}
+		return 0;
+
+	} else if (c == _IOC_NR(MTIOCGET)) {
+		if (TP_DIAGS(current_tape_dev)) {
+			printk("GET ");
+		}
+
+		CHECK_IOC_SIZE(mtget);
 
-    }
-    else
-    {
-	return -ENOTTY;	/* Other cmds not supported. */
-    }
-} /* qic02_tape_ioctl */
+		/* It appears (gmt(1)) that it is normal behaviour to
+		 * first set the status with MTNOP, and then to read
+		 * it out with MTIOCGET
+		 */
+
+		/* copy results to user space */
+		if (copy_to_user
+		    ((char *) ioarg, (char *) &ioctl_status,
+		     sizeof(ioctl_status))) {
+			return -EFAULT;
+		}
+		return 0;
+	} else if (TP_HAVE_TELL && (c == _IOC_NR(MTIOCPOS))) {
+		if (TP_DIAGS(current_tape_dev)) {
+			printk("POS ");
+		}
+
+		CHECK_IOC_SIZE(mtpos);
+
+		tpqputs(TPQD_IOCTLS, "MTTELL reading block address");
+		if ((doing_read == YES) || (doing_write == YES)) {
+			finish_rw(AR_QCMDV_TELL_BLK);
+		}
+
+		c = rdstatus((char *) blk_addr, sizeof(blk_addr),
+			     AR_QCMDV_TELL_BLK);
+		if (c != TE_OK) {
+			return -EIO;
+		}
+
+		ioctl_tell.mt_blkno =
+		    (blk_addr[3] << 16) | (blk_addr[4] << 8) | blk_addr[5];
+
+		/* copy results to user space */
+		if (copy_to_user
+		    ((char *) ioarg, (char *) &ioctl_tell,
+		     sizeof(ioctl_tell))) {
+			return -EFAULT;
+		}
+		return 0;
+
+	} else {
+		return -ENOTTY;	/* Other cmds not supported. */
+	}
+}				/* qic02_tape_ioctl */
 
 
 
 /* These are (most) of the interface functions: */
 static struct file_operations qic02_tape_fops = {
-	owner:		THIS_MODULE,
-	llseek:		no_llseek,
-	read:		qic02_tape_read,
-	write:		qic02_tape_write,
-	ioctl:		qic02_tape_ioctl,
-	open:		qic02_tape_open,
-	release:	qic02_tape_release,
+	owner:THIS_MODULE,
+	llseek:no_llseek,
+	read:qic02_tape_read,
+	write:qic02_tape_write,
+	ioctl:qic02_tape_ioctl,
+	open:qic02_tape_open,
+	release:qic02_tape_release,
 };
 
 
 static void qic02_release_resources(void)
 {
-    free_irq(QIC02_TAPE_IRQ, NULL);
-    free_dma(QIC02_TAPE_DMA);
-    release_region(QIC02_TAPE_PORT, QIC02_TAPE_PORT_RANGE);
-    if (buffaddr)
-    {
-	free_pages((unsigned long)buffaddr, get_order(TPQBUF_SIZE));
-    }
-    buffaddr = 0; /* Better to cause a panic than overwite someone else */
-    status_zombie = YES;
-} /* qic02_release_resources */
+	free_irq(QIC02_TAPE_IRQ, NULL);
+	free_dma(QIC02_TAPE_DMA);
+	release_region(QIC02_TAPE_PORT, QIC02_TAPE_PORT_RANGE);
+	if (buffaddr) {
+		free_pages((unsigned long) buffaddr,
+			   get_order(TPQBUF_SIZE));
+	}
+	buffaddr = 0;		/* Better to cause a panic than overwite someone else */
+	status_zombie = YES;
+}				/* qic02_release_resources */
 
 
 static int qic02_get_resources(void)
 {
-    /* First perform some checks. If one of them fails,
-     * the tape driver will not be registered to the system.
-     */
-    if (QIC02_TAPE_IRQ>16)
-    {
-	tpqputs(TPQD_ALWAYS, "Bogus interrupt number.");
-	return -ENXIO;
-    }
-
-    /* for DYNCONF, allocating IO, DMA and IRQ should not be done until 
-     * the config parameters have been set using MTSETCONFIG.
-     */
-
-    if (check_region(QIC02_TAPE_PORT, QIC02_TAPE_PORT_RANGE))
-    {
-	printk(TPQIC02_NAME ": IO space at 0x%x [%d ports] already reserved\n",
-	       QIC02_TAPE_PORT, QIC02_TAPE_PORT_RANGE);
-	return -ENXIO;
-    }
-
-    /* get IRQ */
-    if (request_irq(QIC02_TAPE_IRQ, qic02_tape_interrupt, SA_INTERRUPT, "QIC-02", NULL))
-    {
-	printk(TPQIC02_NAME ": can't allocate IRQ%d for QIC-02 tape\n",
-	       QIC02_TAPE_IRQ);
-	return -EBUSY;
-    }
-
-    /* After IRQ, allocate DMA channel */
-    if (request_dma(QIC02_TAPE_DMA,"QIC-02"))
-    {
-	printk(TPQIC02_NAME ": can't allocate DMA%d for QIC-02 tape\n",
-	       QIC02_TAPE_DMA);
-	free_irq(QIC02_TAPE_IRQ, NULL);
-	return -EBUSY;
-    }
+	/* First perform some checks. If one of them fails,
+	 * the tape driver will not be registered to the system.
+	 */
+	if (QIC02_TAPE_IRQ > 16) {
+		tpqputs(TPQD_ALWAYS, "Bogus interrupt number.");
+		return -ENXIO;
+	}
+
+	/* for DYNCONF, allocating IO, DMA and IRQ should not be done until 
+	 * the config parameters have been set using MTSETCONFIG.
+	 */
 
-    /* Grab the IO region. We already made sure it's available. */
-    request_region(QIC02_TAPE_PORT, QIC02_TAPE_PORT_RANGE, TPQIC02_NAME);
-    
-    /* Setup the page-address for the dma transfer. */
-    buffaddr = (void *)__get_dma_pages(GFP_KERNEL, get_order(TPQBUF_SIZE));
-    
-    if (!buffaddr)
-    {
-	qic02_release_resources();
-	return -EBUSY; /* Not ideal, EAGAIN perhaps? */
-    }
-    
-    memset(buffaddr, 0, TPQBUF_SIZE);
-    
-    printk(TPQIC02_NAME ": Settings: IRQ %d, DMA %d, IO 0x%x, IFC %s\n",
-	   QIC02_TAPE_IRQ, QIC02_TAPE_DMA,
-	   ((QIC02_TAPE_IFC==ARCHIVE) || (QIC02_TAPE_IFC==MOUNTAIN))?
-	   QIC02_CMD_PORT : QIC02_STAT_PORT,
-	   (QIC02_TAPE_IFC==MOUNTAIN)? "Mountain" :
-	   ((QIC02_TAPE_IFC==ARCHIVE)? "Archive" : "Wangtek"));
-    
-    if (tape_reset(0)!=TE_OK || tp_sense(TP_WRP|TP_POR|TP_CNI)!=TE_OK)
-    {
-	/* No drive detected, so vanish */
-	tpqputs(TPQD_ALWAYS, "No drive detected -- releasing IO/IRQ/DMA.");
-	status_dead = YES;
-	qic02_release_resources();
-	return -EIO;
-    }
-
-    /* All should be ok now */
-    status_zombie = NO;
-    return 0;
-} /* qic02_get_resources */
+	if (check_region(QIC02_TAPE_PORT, QIC02_TAPE_PORT_RANGE)) {
+		printk(TPQIC02_NAME
+		       ": IO space at 0x%x [%d ports] already reserved\n",
+		       QIC02_TAPE_PORT, QIC02_TAPE_PORT_RANGE);
+		return -ENXIO;
+	}
+
+	/* get IRQ */
+	if (request_irq
+	    (QIC02_TAPE_IRQ, qic02_tape_interrupt, SA_INTERRUPT, "QIC-02",
+	     NULL)) {
+		printk(TPQIC02_NAME
+		       ": can't allocate IRQ%d for QIC-02 tape\n",
+		       QIC02_TAPE_IRQ);
+		return -EBUSY;
+	}
+
+	/* After IRQ, allocate DMA channel */
+	if (request_dma(QIC02_TAPE_DMA, "QIC-02")) {
+		printk(TPQIC02_NAME
+		       ": can't allocate DMA%d for QIC-02 tape\n",
+		       QIC02_TAPE_DMA);
+		free_irq(QIC02_TAPE_IRQ, NULL);
+		return -EBUSY;
+	}
+
+	/* Grab the IO region. We already made sure it's available. */
+	request_region(QIC02_TAPE_PORT, QIC02_TAPE_PORT_RANGE,
+		       TPQIC02_NAME);
+
+	/* Setup the page-address for the dma transfer. */
+	buffaddr =
+	    (void *) __get_dma_pages(GFP_KERNEL, get_order(TPQBUF_SIZE));
+
+	if (!buffaddr) {
+		qic02_release_resources();
+		return -EBUSY;	/* Not ideal, EAGAIN perhaps? */
+	}
+
+	memset(buffaddr, 0, TPQBUF_SIZE);
+
+	printk(TPQIC02_NAME
+	       ": Settings: IRQ %d, DMA %d, IO 0x%x, IFC %s\n",
+	       QIC02_TAPE_IRQ, QIC02_TAPE_DMA, ((QIC02_TAPE_IFC == ARCHIVE)
+						|| (QIC02_TAPE_IFC ==
+						    MOUNTAIN)) ?
+	       QIC02_CMD_PORT : QIC02_STAT_PORT,
+	       (QIC02_TAPE_IFC ==
+		MOUNTAIN) ? "Mountain" : ((QIC02_TAPE_IFC ==
+					   ARCHIVE) ? "Archive" :
+					  "Wangtek"));
+
+	if (tape_reset(0) != TE_OK
+	    || tp_sense(TP_WRP | TP_POR | TP_CNI) != TE_OK) {
+		/* No drive detected, so vanish */
+		tpqputs(TPQD_ALWAYS,
+			"No drive detected -- releasing IO/IRQ/DMA.");
+		status_dead = YES;
+		qic02_release_resources();
+		return -EIO;
+	}
+
+	/* All should be ok now */
+	status_zombie = NO;
+	return 0;
+}				/* qic02_get_resources */
 
 int __init qic02_tape_init(void)
 {
-    if (TPSTATSIZE != 6)
-    {
-	printk(TPQIC02_NAME ": internal error: tpstatus struct incorrect!\n");
-	return -ENODEV;
-    }
-    if ((TPQBUF_SIZE<512) || (TPQBUF_SIZE>=0x10000))
-    {
-	printk(TPQIC02_NAME ": internal error: DMA buffer size out of range\n");
-	return -ENODEV;
-    }
+	if (TPSTATSIZE != 6) {
+		printk(TPQIC02_NAME
+		       ": internal error: tpstatus struct incorrect!\n");
+		return -ENODEV;
+	}
+	if ((TPQBUF_SIZE < 512) || (TPQBUF_SIZE >= 0x10000)) {
+		printk(TPQIC02_NAME
+		       ": internal error: DMA buffer size out of range\n");
+		return -ENODEV;
+	}
 
-    current_tape_dev = MKDEV(QIC02_TAPE_MAJOR, 0);
+	current_tape_dev = MKDEV(QIC02_TAPE_MAJOR, 0);
 
 #ifndef CONFIG_QIC02_DYNCONF
-    printk(TPQIC02_NAME ": IRQ %d, DMA %d, IO 0x%x, IFC %s, %s, %s\n",
-	   QIC02_TAPE_IRQ, QIC02_TAPE_DMA,
+	printk(TPQIC02_NAME ": IRQ %d, DMA %d, IO 0x%x, IFC %s, %s, %s\n",
+	       QIC02_TAPE_IRQ, QIC02_TAPE_DMA,
 # if QIC02_TAPE_IFC == WANGTEK
-	   QIC02_STAT_PORT, "Wangtek",
+	       QIC02_STAT_PORT, "Wangtek",
 # elif QIC02_TAPE_IFC == ARCHIVE
-	   QIC02_CMD_PORT, "Archive",
+	       QIC02_CMD_PORT, "Archive",
 # elif QIC02_TAPE_IFC == MOUNTAIN
-	   QIC02_CMD_PORT, "Mountain",
+	       QIC02_CMD_PORT, "Mountain",
 # else
 #  error
 # endif
-	   rcs_revision, rcs_date);
-    if (qic02_get_resources())
-    {
-	return -ENODEV;
-    }
+	       rcs_revision, rcs_date);
+	if (qic02_get_resources()) {
+		return -ENODEV;
+	}
 #else
-    printk(TPQIC02_NAME ": Runtime config, %s, %s\n", 
-	   rcs_revision, rcs_date);
+	printk(TPQIC02_NAME ": Runtime config, %s, %s\n",
+	       rcs_revision, rcs_date);
 #endif
-    printk(TPQIC02_NAME ": DMA buffers: %u blocks\n", NR_BLK_BUF);
-    /* If we got this far, install driver functions */
-    if (devfs_register_chrdev(QIC02_TAPE_MAJOR, TPQIC02_NAME, &qic02_tape_fops))
-    {
-	printk(TPQIC02_NAME ": Unable to get chrdev major %d\n", QIC02_TAPE_MAJOR);
+	printk(TPQIC02_NAME ": DMA buffers: %u blocks\n", NR_BLK_BUF);
+	/* If we got this far, install driver functions */
+	if (devfs_register_chrdev
+	    (QIC02_TAPE_MAJOR, TPQIC02_NAME, &qic02_tape_fops)) {
+		printk(TPQIC02_NAME ": Unable to get chrdev major %d\n",
+		       QIC02_TAPE_MAJOR);
 #ifndef CONFIG_QIC02_DYNCONF
-	qic02_release_resources();
+		qic02_release_resources();
 #endif
-	return -ENODEV;
-    }
-    devfs_register (NULL, "ntpqic11", DEVFS_FL_DEFAULT,
-		    QIC02_TAPE_MAJOR, 2,
-		    S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
-		    &qic02_tape_fops, NULL);
-    devfs_register (NULL, "tpqic11", DEVFS_FL_DEFAULT,
-		    QIC02_TAPE_MAJOR, 3,
-		    S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
-		    &qic02_tape_fops, NULL);
-    devfs_register (NULL, "ntpqic24", DEVFS_FL_DEFAULT,
-		    QIC02_TAPE_MAJOR, 4,
-		    S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
-		    &qic02_tape_fops, NULL);
-    devfs_register (NULL, "tpqic24", DEVFS_FL_DEFAULT,
-		    QIC02_TAPE_MAJOR, 5,
-		    S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
-		    &qic02_tape_fops, NULL);
-    devfs_register (NULL, "ntpqic120", DEVFS_FL_DEFAULT,
-		    QIC02_TAPE_MAJOR, 6,
-		    S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
-		    &qic02_tape_fops, NULL);
-    devfs_register (NULL, "tpqic120", DEVFS_FL_DEFAULT,
-		    QIC02_TAPE_MAJOR, 7,
-		    S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
-		    &qic02_tape_fops, NULL);
-    devfs_register (NULL, "ntpqic150", DEVFS_FL_DEFAULT,
-		    QIC02_TAPE_MAJOR, 8,
-		    S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
-		    &qic02_tape_fops, NULL);
-    devfs_register (NULL, "tpqic150", DEVFS_FL_DEFAULT,
-		    QIC02_TAPE_MAJOR, 9,
-		    S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
-		    &qic02_tape_fops, NULL);
-    init_waitqueue_head(&qic02_tape_transfer);
-    /* prepare timer */
-    TIMEROFF;
-    init_timer(&tp_timer);
-    tp_timer.function = qic02_tape_times_out;
-    
+		return -ENODEV;
+	}
+	devfs_register(NULL, "ntpqic11", DEVFS_FL_DEFAULT,
+		       QIC02_TAPE_MAJOR, 2,
+		       S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
+		       &qic02_tape_fops, NULL);
+	devfs_register(NULL, "tpqic11", DEVFS_FL_DEFAULT,
+		       QIC02_TAPE_MAJOR, 3,
+		       S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
+		       &qic02_tape_fops, NULL);
+	devfs_register(NULL, "ntpqic24", DEVFS_FL_DEFAULT,
+		       QIC02_TAPE_MAJOR, 4,
+		       S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
+		       &qic02_tape_fops, NULL);
+	devfs_register(NULL, "tpqic24", DEVFS_FL_DEFAULT,
+		       QIC02_TAPE_MAJOR, 5,
+		       S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
+		       &qic02_tape_fops, NULL);
+	devfs_register(NULL, "ntpqic120", DEVFS_FL_DEFAULT,
+		       QIC02_TAPE_MAJOR, 6,
+		       S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
+		       &qic02_tape_fops, NULL);
+	devfs_register(NULL, "tpqic120", DEVFS_FL_DEFAULT,
+		       QIC02_TAPE_MAJOR, 7,
+		       S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
+		       &qic02_tape_fops, NULL);
+	devfs_register(NULL, "ntpqic150", DEVFS_FL_DEFAULT,
+		       QIC02_TAPE_MAJOR, 8,
+		       S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
+		       &qic02_tape_fops, NULL);
+	devfs_register(NULL, "tpqic150", DEVFS_FL_DEFAULT,
+		       QIC02_TAPE_MAJOR, 9,
+		       S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
+		       &qic02_tape_fops, NULL);
+	init_waitqueue_head(&qic02_tape_transfer);
+	/* prepare timer */
+	TIMEROFF;
+	init_timer(&tp_timer);
+	tp_timer.function = qic02_tape_times_out;
+
 #ifndef CONFIG_QIC02_DYNCONF
-    if (tape_reset(0)!=TE_OK || tp_sense(TP_WRP|TP_POR|TP_CNI)!=TE_OK)
-    {
-	/* No drive detected, so vanish */
-	tpqputs(TPQD_ALWAYS, "No drive detected -- driver going on vacation...");
-	qic02_release_resources();
-	status_dead = YES;
-	return -ENODEV;
-    }
-    else
-    {
-	if (is_exception())
-	{
-	    tpqputs(TPQD_ALWAYS, "exception detected\n");
-	    (void) tp_sense(TP_WRP|TP_POR|TP_CNI);
+	if (tape_reset(0) != TE_OK
+	    || tp_sense(TP_WRP | TP_POR | TP_CNI) != TE_OK) {
+		/* No drive detected, so vanish */
+		tpqputs(TPQD_ALWAYS,
+			"No drive detected -- driver going on vacation...");
+		qic02_release_resources();
+		status_dead = YES;
+		return -ENODEV;
+	} else {
+		if (is_exception()) {
+			tpqputs(TPQD_ALWAYS, "exception detected\n");
+			(void) tp_sense(TP_WRP | TP_POR | TP_CNI);
+		}
 	}
-    }
 #endif
 
-    /* initialize generic status for ioctl requests */
-    
-    ioctl_status.mt_type	= QIC02_TAPE_DRIVE;	/* MT_IS* id nr */
-    
-    ioctl_status.mt_resid	= 0;	/* ---residual count */
-    ioctl_status.mt_gstat	= 0;	/* ---generic status */
-    ioctl_status.mt_erreg	= 0;	/* not used */
-    ioctl_status.mt_fileno	= 0;	/* number of current file on tape */
-    ioctl_status.mt_blkno	= 0;	/* number of current (logical) block */
+	/* initialize generic status for ioctl requests */
+
+	ioctl_status.mt_type = QIC02_TAPE_DRIVE;	/* MT_IS* id nr */
 
-    return 0;
-} /* qic02_tape_init */
+	ioctl_status.mt_resid = 0;	/* ---residual count */
+	ioctl_status.mt_gstat = 0;	/* ---generic status */
+	ioctl_status.mt_erreg = 0;	/* not used */
+	ioctl_status.mt_fileno = 0;	/* number of current file on tape */
+	ioctl_status.mt_blkno = 0;	/* number of current (logical) block */
+
+	return 0;
+}				/* qic02_tape_init */
 
 #ifdef MODULE
 
 void cleanup_module(void)
 {
-    if (status_zombie == NO)
-    {
-	qic02_release_resources();
-    }
-    devfs_unregister_chrdev(QIC02_TAPE_MAJOR, TPQIC02_NAME);
-    devfs_unregister(devfs_find_handle(NULL, "ntpqic11", QIC02_TAPE_MAJOR, 2, DEVFS_SPECIAL_CHR, 0));
-    devfs_unregister(devfs_find_handle(NULL, "tpqic11", QIC02_TAPE_MAJOR, 3, DEVFS_SPECIAL_CHR, 0));
-    devfs_unregister(devfs_find_handle(NULL, "ntpqic24", QIC02_TAPE_MAJOR, 4, DEVFS_SPECIAL_CHR, 0));
-    devfs_unregister(devfs_find_handle(NULL, "tpqic24", QIC02_TAPE_MAJOR, 5, DEVFS_SPECIAL_CHR, 0));
-    devfs_unregister(devfs_find_handle(NULL, "ntpqic120", QIC02_TAPE_MAJOR, 6, DEVFS_SPECIAL_CHR, 0));
-    devfs_unregister(devfs_find_handle(NULL, "tpqic120", QIC02_TAPE_MAJOR, 7, DEVFS_SPECIAL_CHR, 0));
-    devfs_unregister(devfs_find_handle(NULL, "ntpqic150", QIC02_TAPE_MAJOR, 8, DEVFS_SPECIAL_CHR, 0));
-    devfs_unregister(devfs_find_handle(NULL, "tpqic150", QIC02_TAPE_MAJOR, 9, DEVFS_SPECIAL_CHR, 0));
+	if (status_zombie == NO) {
+		qic02_release_resources();
+	}
+	devfs_unregister_chrdev(QIC02_TAPE_MAJOR, TPQIC02_NAME);
+	devfs_unregister(devfs_find_handle
+			 (NULL, "ntpqic11", QIC02_TAPE_MAJOR, 2,
+			  DEVFS_SPECIAL_CHR, 0));
+	devfs_unregister(devfs_find_handle
+			 (NULL, "tpqic11", QIC02_TAPE_MAJOR, 3,
+			  DEVFS_SPECIAL_CHR, 0));
+	devfs_unregister(devfs_find_handle
+			 (NULL, "ntpqic24", QIC02_TAPE_MAJOR, 4,
+			  DEVFS_SPECIAL_CHR, 0));
+	devfs_unregister(devfs_find_handle
+			 (NULL, "tpqic24", QIC02_TAPE_MAJOR, 5,
+			  DEVFS_SPECIAL_CHR, 0));
+	devfs_unregister(devfs_find_handle
+			 (NULL, "ntpqic120", QIC02_TAPE_MAJOR, 6,
+			  DEVFS_SPECIAL_CHR, 0));
+	devfs_unregister(devfs_find_handle
+			 (NULL, "tpqic120", QIC02_TAPE_MAJOR, 7,
+			  DEVFS_SPECIAL_CHR, 0));
+	devfs_unregister(devfs_find_handle
+			 (NULL, "ntpqic150", QIC02_TAPE_MAJOR, 8,
+			  DEVFS_SPECIAL_CHR, 0));
+	devfs_unregister(devfs_find_handle
+			 (NULL, "tpqic150", QIC02_TAPE_MAJOR, 9,
+			  DEVFS_SPECIAL_CHR, 0));
 }
 
 int init_module(void)
 {
-    int retval;
-    retval=qic02_tape_init();
+	int retval;
+	retval = qic02_tape_init();
 # ifdef CONFIG_QIC02_DYNCONF
-    /* This allows the dynamic config program to setup the card
-     * by presetting qic02_tape_dynconf via insmod
-     */
-    if (!retval && qic02_tape_dynconf.ifc_type)
-    {
-	retval=update_ifc_masks(qic02_tape_dynconf.ifc_type);
-	if (retval)
-	{
-	  cleanup_module();
+	/* This allows the dynamic config program to setup the card
+	 * by presetting qic02_tape_dynconf via insmod
+	 */
+	if (!retval && qic02_tape_dynconf.ifc_type) {
+		retval = update_ifc_masks(qic02_tape_dynconf.ifc_type);
+		if (retval) {
+			cleanup_module();
+		}
 	}
-    }
 # endif
-    return retval;
+	return retval;
 }
 #endif
+
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
diff -u --recursive --new-file v2.4.9/linux/drivers/char/tty_io.c linux/drivers/char/tty_io.c
--- v2.4.9/linux/drivers/char/tty_io.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/char/tty_io.c	Fri Sep  7 10:53:59 2001
@@ -442,8 +442,6 @@
 	file_list_lock();
 	for (l = tty->tty_files.next; l != &tty->tty_files; l = l->next) {
 		struct file * filp = list_entry(l, struct file, f_list);
-		if (!filp->f_dentry)
-			continue;
 		if (filp->f_dentry->d_inode->i_rdev == CONSOLE_DEV ||
 		    filp->f_dentry->d_inode->i_rdev == SYSCONS_DEV) {
 			cons_filp = filp;
diff -u --recursive --new-file v2.4.9/linux/drivers/char/vino.h linux/drivers/char/vino.h
--- v2.4.9/linux/drivers/char/vino.h	Fri Jun 25 17:39:14 1999
+++ linux/drivers/char/vino.h	Wed Dec 31 16:00:00 1969
@@ -1,118 +0,0 @@
-/* $Id: vino.h,v 1.2 1999/02/09 23:03:53 ulfc Exp $
- * drivers/sgi/vino.h
- *
- * Copyright (C) 1999 Ulf Carlsson (ulfc@bun.falkenberg.se)
- */
-
-#define VINO_BASE		0x0008000
-
-#define VINO_REVID		0x0000
-#define VINO_CTRL		0x0008
-#define VINO_INTSTAT		0x0010	/* Interrupt status */
-#define VINO_I2C_CTRL		0x0018
-#define VINO_I2C_DATA		0x0020
-#define VINO_A_ALPHA		0x0028	/* Channel A ... */
-#define VINO_A_CLIPS		0x0030	/* Clipping start */
-#define VINO_A_CLIPE		0x0038	/* Clipping end */
-#define VINO_A_FRAMERT		0x0040	/* Framerate */
-#define VINO_A_FLDCNT		0x0048	/* Field counter */
-#define VINO_A_LNSZ		0x0050
-#define VINO_A_LNCNT		0x0058
-#define VINO_A_PGIX		0x0060	/* Page index */
-#define VINO_A_DESC_PTR		0x0068	/* Ptr to next four descriptors */
-#define VINO_A_DESC_TLB_PTR	0x0070	/* Ptr to start of descriptor table */
-#define VINO_A_DESC_DATA0	0x0078	/* Descriptor data 0 */
-#define VINO_A_DESC_DATA1	0x0080	/* ... */
-#define VINO_A_DESC_DATA2	0x0088
-#define VINO_A_DESC_DATA3	0x0090
-#define VINO_A_FIFO_THRESHOLD	0x0098	/* FIFO threshold */
-#define VINO_A_FIFO_RP		0x00a0
-#define VINO_A_FIFO_WP		0x00a8
-#define VINO_B_ALPHA		0x00b0	/* Channel B ... */
-#define VINO_B_CLIPS		0x00b8
-#define VINO_B_CLIPE		0x00c0
-#define VINO_B_FRAMERT		0x00c8
-#define VINO_B_FLDCNT		0x00d0
-#define VINO_B_LNSZ		0x00d8
-#define VINO_B_LNCNT		0x00e0
-#define VINO_B_PGIX		0x00e8
-#define VINO_B_DESC_PTR		0x00f0
-#define VINO_B_DESC_TLB_PTR	0x00f8
-#define VINO_B_DESC_DATA0	0x0100
-#define VINO_B_DESC_DATA1	0x0108
-#define VINO_B_DESC_DATA2	0x0110
-#define VINO_B_DESC_DATA3	0x0118
-#define VINO_B_FIFO_THRESHOLD	0x0120
-#define VINO_B_FIFO_RP		0x0128
-#define VINO_B_FIFO_WP		0x0130
-
-/* Bits in the VINO_REVID register */
-
-#define VINO_REVID_REV_MASK		0x000f	/* bits 0:3 */
-#define VINO_REVID_ID_MASK		0x00f0	/* bits 4:7 */
-
-/* Bits in the VINO_CTRL register */
-
-#define VINO_CTRL_LITTLE_ENDIAN		(1<<0)
-#define VINO_CTRL_A_FIELD_TRANS_INT	(1<<1)	/* Field transferred int */
-#define VINO_CTRL_A_FIFO_OF_INT		(1<<2)	/* FIFO overflow int */
-#define VINO_CTRL_A_END_DESC_TBL_INT	(1<<3)	/* End of desc table int */
-#define VINO_CTRL_B_FIELD_TRANS_INT	(1<<4)	/* Field transferred int */
-#define VINO_CTRL_B_FIFO_OF_INT		(1<<5)	/* FIFO overflow int */
-#define VINO_CTRL_B_END_DESC_TLB_INT	(1<<6)	/* End of desc table int */
-#define VINO_CTRL_A_DMA_ENBL		(1<<7)
-#define VINO_CTRL_A_INTERLEAVE_ENBL	(1<<8)
-#define VINO_CTRL_A_SYNC_ENBL		(1<<9)
-#define VINO_CTRL_A_SELECT		(1<<10)	/* 1=D1 0=Philips */
-#define VINO_CTRL_A_RGB			(1<<11)	/* 1=RGB 0=YUV */
-#define VINO_CTRL_A_LUMA_ONLY		(1<<12)
-#define VINO_CTRL_A_DEC_ENBL		(1<<13)	/* Decimation */
-#define VINO_CTRL_A_DEC_SCALE_MASK	0x1c000	/* bits 14:17 */
-#define VINO_CTRL_A_DEC_HOR_ONLY	(1<<17)	/* Horizontal only */
-#define VINO_CTRL_A_DITHER		(1<<18)	/* 24 -> 8 bit dither */
-#define VINO_CTRL_B_DMA_ENBL		(1<<19)
-#define VINO_CTRL_B_INTERLEAVE_ENBL	(1<<20)
-#define VINO_CTRL_B_SYNC_ENBL		(1<<21)
-#define VINO_CTRL_B_SELECT		(1<<22)	/* 1=D1 0=Philips */
-#define VINO_CTRL_B_RGB			(1<<22)	/* 1=RGB 0=YUV */
-#define VINO_CTRL_B_LUMA_ONLY		(1<<23)
-#define VINO_CTRL_B_DEC_ENBL		(1<<24)	/* Decimation */
-#define VINO_CTRL_B_DEC_SCALE_MASK	0x1c000000	/* bits 25:28 */
-#define VINO_CTRL_B_DEC_HOR_ONLY	(1<<29)	/* Decimation horizontal only */
-#define VINO_CTRL_B_DITHER		(1<<30)	/* ChanB 24 -> 8 bit dither */
-
-/* Bits in the Interrupt and Status register */
-
-#define VINO_INTSTAT_A_FIELD_TRANS	(1<<0)	/* Field transferred int */
-#define VINO_INTSTAT_A_FIFO_OF		(1<<1)	/* FIFO overflow int */
-#define VINO_INTSTAT_A_END_DESC_TBL	(1<<2)	/* End of desc table int */
-#define VINO_INTSTAT_B_FIELD_TRANS	(1<<3)	/* Field transferred int */
-#define VINO_INTSTAT_B_FIFO_OF		(1<<4)	/* FIFO overflow int */
-#define VINO_INTSTAT_B_END_DESC_TBL	(1<<5)	/* End of desc table int */
-
-/* Bits in the Clipping Start register */
-
-#define VINO_CLIPS_START		0x3ff		/* bits 0:9 */
-#define VINO_CLIPS_ODD_MASK		0x7fc00		/* bits 10:18 */
-#define VINO_CLIPS_EVEN_MASK		0xff80000	/* bits 19:27 */
-
-/* Bits in the Clipping End register */
-
-#define VINO_CLIPE_END			0x3ff		/* bits 0:9 */
-#define VINO_CLIPE_ODD_MASK		0x7fc00		/* bits 10:18 */
-#define VINO_CLIPE_EVEN_MASK		0xff80000	/* bits 19:27 */
-
-/* Bits in the Frame Rate register */
-
-#define VINO_FRAMERT_PAL		(1<<0)	/* 0=NTSC 1=PAL */
-#define VINO_FRAMERT_RT_MASK		0x1ffe		/* bits 1:12 */
-
-/* Bits in the VINO_I2C_CTRL */
-
-#define VINO_CTRL_I2C_IDLE		(1<<0)	/* write: 0=force idle
-						 * read: 0=idle 1=not idle */
-#define VINO_CTRL_I2C_DIR		(1<<1)	/* 0=read 1=write */
-#define VINO_CTRL_I2C_MORE_BYTES	(1<<2)	/* 0=last byte 1=more bytes */
-#define VINO_CTRL_I2C_TRANS_BUSY	(1<<4)	/* 0=trans done 1=trans busy */
-#define VINO_CTRL_I2C_ACK		(1<<5)	/* 0=ack received 1=ack not */
-#define VINO_CTRL_I2C_BUS_ERROR		(1<<7)	/* 0=no bus err 1=bus err */
diff -u --recursive --new-file v2.4.9/linux/drivers/char/vt.c linux/drivers/char/vt.c
--- v2.4.9/linux/drivers/char/vt.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/char/vt.c	Tue Aug 28 07:09:44 2001
@@ -28,7 +28,6 @@
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
-#include <asm/keyboard.h>
 
 #include <linux/kbd_kern.h>
 #include <linux/vt_kern.h>
@@ -145,8 +144,13 @@
 
 #endif
 
-void (*kd_mksound)(unsigned int hz, unsigned int ticks) = _kd_mksound;
+int _kbd_rate(struct kbd_repeat *rep)
+{
+	return -EINVAL;
+}
 
+void (*kd_mksound)(unsigned int hz, unsigned int ticks) = _kd_mksound;
+int (*kbd_rate)(struct kbd_repeat *rep) = _kbd_rate;
 
 #define i (tmp.kb_index)
 #define s (tmp.kb_table)
@@ -504,7 +508,6 @@
 	{
 		struct kbd_repeat kbrep;
 		
-		if (!kbd_rate) return( -EINVAL );
 		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
 
diff -u --recursive --new-file v2.4.9/linux/drivers/char/wdt.c linux/drivers/char/wdt.c
--- v2.4.9/linux/drivers/char/wdt.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/char/wdt.c	Fri Sep  7 09:28:38 2001
@@ -538,3 +538,7 @@
 module_init(wdt_init);
 module_exit(wdt_exit);
 
+MODULE_AUTHOR("Alan Cox");
+MODULE_DESCRIPTION("Driver for ISA ICS watchdog cards (WDT500/501)");
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
diff -u --recursive --new-file v2.4.9/linux/drivers/char/wdt285.c linux/drivers/char/wdt285.c
--- v2.4.9/linux/drivers/char/wdt285.c	Sat May 19 17:43:05 2001
+++ linux/drivers/char/wdt285.c	Fri Sep  7 09:28:38 2001
@@ -190,6 +190,7 @@
 
 MODULE_AUTHOR("Phil Blundell <pb@nexus.co.uk>");
 MODULE_DESCRIPTION("21285 watchdog driver");
+MODULE_LICENSE("GPL");
 
 MODULE_PARM(soft_margin,"i");
 MODULE_PARM_DESC(soft_margin,"Watchdog timeout in seconds");
diff -u --recursive --new-file v2.4.9/linux/drivers/char/wdt977.c linux/drivers/char/wdt977.c
--- v2.4.9/linux/drivers/char/wdt977.c	Mon Oct 16 12:58:51 2000
+++ linux/drivers/char/wdt977.c	Fri Sep  7 09:28:38 2001
@@ -199,3 +199,5 @@
 
 module_init(nwwatchdog_init);
 module_exit(nwwatchdog_exit);
+
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.9/linux/drivers/char/wdt_pci.c linux/drivers/char/wdt_pci.c
--- v2.4.9/linux/drivers/char/wdt_pci.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/char/wdt_pci.c	Fri Sep  7 09:28:38 2001
@@ -626,3 +626,9 @@
 
 module_init(wdtpci_init);
 module_exit(wdtpci_cleanup);
+
+MODULE_AUTHOR("JP Nollmann, Alan Cox");
+MODULE_DESCRIPTION("Driver for the ICS PCI watchdog cards");
+MODULE_LICENSE("GPL");
+
+EXPORT_NO_SYMBOLS;
diff -u --recursive --new-file v2.4.9/linux/drivers/i2c/i2c-adap-ite.c linux/drivers/i2c/i2c-adap-ite.c
--- v2.4.9/linux/drivers/i2c/i2c-adap-ite.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/i2c/i2c-adap-ite.c	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,319 @@
+/*
+   -------------------------------------------------------------------------
+   i2c-adap-ite.c i2c-hw access for the IIC peripheral on the ITE MIPS system
+   -------------------------------------------------------------------------
+   Hai-Pao Fan, MontaVista Software, Inc.
+   hpfan@mvista.com or source@mvista.com
+
+   Copyright 2001 MontaVista Software Inc.
+
+   ----------------------------------------------------------------------------
+   This file was highly leveraged from i2c-elektor.c, which was created
+   by Simon G. Vogl and Hans Berglund:
+
+ 
+     Copyright (C) 1995-97 Simon G. Vogl
+                   1998-99 Hans Berglund
+
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.		     */
+/* ------------------------------------------------------------------------- */
+
+/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
+   Frodo Looijaard <frodol@dds.nl> */
+
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/malloc.h>
+#include <linux/version.h>
+#include <linux/init.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <linux/i2c.h>
+#include <linux/i2c-algo-ite.h>
+#include <linux/i2c-adap-ite.h>
+#include "i2c-ite.h"
+
+#define DEFAULT_BASE  0x14014030
+#define ITE_IIC_IO_SIZE	0x40
+#define DEFAULT_IRQ   0
+#define DEFAULT_CLOCK 0x1b0e	/* default 16MHz/(27+14) = 400KHz */
+#define DEFAULT_OWN   0x55
+
+static int base  = 0;
+static int irq   = 0;
+static int clock = 0;
+static int own   = 0;
+
+static int i2c_debug=0;
+static struct iic_ite gpi;
+#if (LINUX_VERSION_CODE < 0x020301)
+static struct wait_queue *iic_wait = NULL;
+#else
+static wait_queue_head_t iic_wait;
+#endif
+static int iic_pending;
+
+/* ----- global defines -----------------------------------------------	*/
+#define DEB(x)	if (i2c_debug>=1) x
+#define DEB2(x) if (i2c_debug>=2) x
+#define DEB3(x) if (i2c_debug>=3) x
+#define DEBE(x)	x	/* error messages 				*/
+
+
+/* ----- local functions ----------------------------------------------	*/
+
+static void iic_ite_setiic(void *data, int ctl, short val)
+{
+        unsigned long j = jiffies + 10;
+
+	DEB3(printk(" Write 0x%02x to 0x%x\n",(unsigned short)val, ctl&0xff));
+	DEB3({while (jiffies < j) schedule();}) 
+	outw(val,ctl);
+}
+
+static short iic_ite_getiic(void *data, int ctl)
+{
+	short val;
+
+	val = inw(ctl);
+	DEB3(printk("Read 0x%02x from 0x%x\n",(unsigned short)val, ctl&0xff));  
+	return (val);
+}
+
+/* Return our slave address.  This is the address
+ * put on the I2C bus when another master on the bus wants to address us
+ * as a slave
+ */
+static int iic_ite_getown(void *data)
+{
+	return (gpi.iic_own);
+}
+
+
+static int iic_ite_getclock(void *data)
+{
+	return (gpi.iic_clock);
+}
+
+
+#if 0
+static void iic_ite_sleep(unsigned long timeout)
+{
+	schedule_timeout( timeout * HZ);
+}
+#endif
+
+
+/* Put this process to sleep.  We will wake up when the
+ * IIC controller interrupts.
+ */
+static void iic_ite_waitforpin(void) {
+
+   int timeout = 2;
+
+   /* If interrupts are enabled (which they are), then put the process to
+    * sleep.  This process will be awakened by two events -- either the
+    * the IIC peripheral interrupts or the timeout expires. 
+    * If interrupts are not enabled then delay for a reasonable amount 
+    * of time and return.
+    */
+   if (gpi.iic_irq > 0) {
+	cli();
+	if (iic_pending == 0) {
+		interruptible_sleep_on_timeout(&iic_wait, timeout*HZ );
+	} else
+		iic_pending = 0;
+	sti();
+   } else {
+      udelay(100);
+   }
+}
+
+
+static void iic_ite_handler(int this_irq, void *dev_id, struct pt_regs *regs) 
+{
+	
+   iic_pending = 1;
+
+   DEB2(printk("iic_ite_handler: in interrupt handler\n"));
+   wake_up_interruptible(&iic_wait);
+}
+
+
+/* Lock the region of memory where I/O registers exist.  Request our
+ * interrupt line and register its associated handler.
+ */
+static int iic_hw_resrc_init(void)
+{
+  	if (check_region(gpi.iic_base, ITE_IIC_IO_SIZE) < 0 ) {
+   	   return -ENODEV;
+  	} else {
+  	   request_region(gpi.iic_base, ITE_IIC_IO_SIZE, 
+		"i2c (i2c bus adapter)");
+  	}
+	if (gpi.iic_irq > 0) {
+	   if (request_irq(gpi.iic_irq, iic_ite_handler, 0, "ITE IIC", 0) < 0) {
+	      gpi.iic_irq = 0;
+	   } else
+	      DEB3(printk("Enabled IIC IRQ %d\n", gpi.iic_irq));
+	      enable_irq(gpi.iic_irq);
+	}
+	return 0;
+}
+
+
+static void iic_ite_release(void)
+{
+	if (gpi.iic_irq > 0) {
+		disable_irq(gpi.iic_irq);
+		free_irq(gpi.iic_irq, 0);
+	}
+	release_region(gpi.iic_base , 2);
+}
+
+
+static int iic_ite_reg(struct i2c_client *client)
+{
+	return 0;
+}
+
+
+static int iic_ite_unreg(struct i2c_client *client)
+{
+	return 0;
+}
+
+
+static void iic_ite_inc_use(struct i2c_adapter *adap)
+{
+#ifdef MODULE
+	MOD_INC_USE_COUNT;
+#endif
+}
+
+
+static void iic_ite_dec_use(struct i2c_adapter *adap)
+{
+#ifdef MODULE
+	MOD_DEC_USE_COUNT;
+#endif
+}
+
+
+/* ------------------------------------------------------------------------
+ * Encapsulate the above functions in the correct operations structure.
+ * This is only done when more than one hardware adapter is supported.
+ */
+static struct i2c_algo_iic_data iic_ite_data = {
+	NULL,
+	iic_ite_setiic,
+	iic_ite_getiic,
+	iic_ite_getown,
+	iic_ite_getclock,
+	iic_ite_waitforpin,
+	80, 80, 100,		/*	waits, timeout */
+};
+
+static struct i2c_adapter iic_ite_ops = {
+	"ITE IIC adapter",
+	I2C_HW_I_IIC,
+	NULL,
+	&iic_ite_data,
+	iic_ite_inc_use,
+	iic_ite_dec_use,
+	iic_ite_reg,
+	iic_ite_unreg,
+};
+
+/* Called when the module is loaded.  This function starts the
+ * cascade of calls up through the heirarchy of i2c modules (i.e. up to the
+ *  algorithm layer and into to the core layer)
+ */
+static int __init iic_ite_init(void) 
+{
+
+	struct iic_ite *piic = &gpi;
+
+	printk(KERN_INFO "Initialize ITE IIC adapter module\n");
+	if (base == 0)
+		piic->iic_base = DEFAULT_BASE;
+	else
+		piic->iic_base = base;
+
+	if (irq == 0)
+		piic->iic_irq = DEFAULT_IRQ;
+	else
+		piic->iic_irq = irq;
+
+	if (clock == 0)
+		piic->iic_clock = DEFAULT_CLOCK;
+	else
+		piic->iic_clock = clock;
+
+	if (own == 0)
+		piic->iic_own = DEFAULT_OWN;
+	else
+		piic->iic_own = own;
+
+	iic_ite_data.data = (void *)piic;
+#if (LINUX_VERSION_CODE >= 0x020301)
+	init_waitqueue_head(&iic_wait);
+#endif
+	if (iic_hw_resrc_init() == 0) {
+		if (i2c_iic_add_bus(&iic_ite_ops) < 0)
+			return -ENODEV;
+	} else {
+		return -ENODEV;
+	}
+	printk(KERN_INFO " found device at %#x irq %d.\n", 
+		piic->iic_base, piic->iic_irq);
+	return 0;
+}
+
+
+static void iic_ite_exit(void)
+{
+	i2c_iic_del_bus(&iic_ite_ops);
+        iic_ite_release();
+}
+
+EXPORT_NO_SYMBOLS;
+
+/* If modules is NOT defined when this file is compiled, then the MODULE_*
+ * macros will resolve to nothing
+ */
+MODULE_AUTHOR("MontaVista Software <www.mvista.com>");
+MODULE_DESCRIPTION("I2C-Bus adapter routines for ITE IIC bus adapter");
+
+MODULE_PARM(base, "i");
+MODULE_PARM(irq, "i");
+MODULE_PARM(clock, "i");
+MODULE_PARM(own, "i");
+MODULE_PARM(i2c_debug,"i");
+
+
+/* Called when module is loaded or when kernel is intialized.
+ * If MODULES is defined when this file is compiled, then this function will
+ * resolve to init_module (the function called when insmod is invoked for a
+ * module).  Otherwise, this function is called early in the boot, when the
+ * kernel is intialized.  Check out /include/init.h to see how this works.
+ */
+module_init(iic_ite_init);
+
+/* Resolves to module_cleanup when MODULES is defined. */
+module_exit(iic_ite_exit); 
diff -u --recursive --new-file v2.4.9/linux/drivers/i2c/i2c-algo-ite.c linux/drivers/i2c/i2c-algo-ite.c
--- v2.4.9/linux/drivers/i2c/i2c-algo-ite.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/i2c/i2c-algo-ite.c	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,872 @@
+/*
+   -------------------------------------------------------------------------
+   i2c-algo-ite.c i2c driver algorithms for ITE adapters	    
+   
+   Hai-Pao Fan, MontaVista Software, Inc.
+   hpfan@mvista.com or source@mvista.com
+
+   Copyright 2000 MontaVista Software Inc.
+
+   ---------------------------------------------------------------------------
+   This file was highly leveraged from i2c-algo-pcf.c, which was created
+   by Simon G. Vogl and Hans Berglund:
+
+
+     Copyright (C) 1995-1997 Simon G. Vogl
+                   1998-2000 Hans Berglund
+
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.		     */
+/* ------------------------------------------------------------------------- */
+
+/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and 
+   Frodo Looijaard <frodol@dds.nl> ,and also from Martin Bailey
+   <mbailey@littlefeet-inc.com> */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/malloc.h>
+#include <linux/version.h>
+#include <linux/init.h>
+#include <asm/uaccess.h>
+#include <linux/ioport.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+
+#include <linux/i2c.h>
+#include <linux/i2c-algo-ite.h>
+#include "i2c-ite.h"
+
+#define	PM_DSR		IT8172_PCI_IO_BASE + IT_PM_DSR
+#define	PM_IBSR		IT8172_PCI_IO_BASE + IT_PM_DSR + 0x04 
+#define GPIO_CCR	IT8172_PCI_IO_BASE + IT_GPCCR
+
+/* ----- global defines ----------------------------------------------- */
+#define DEB(x) if (i2c_debug>=1) x
+#define DEB2(x) if (i2c_debug>=2) x
+#define DEB3(x) if (i2c_debug>=3) x /* print several statistical values*/
+#define DEBPROTO(x) if (i2c_debug>=9) x;
+ 	/* debug the protocol by showing transferred bits */
+#define DEF_TIMEOUT 16
+
+/* debugging - slow down transfer to have a look at the data .. 	*/
+/* I use this with two leds&resistors, each one connected to sda,scl 	*/
+/* respectively. This makes sure that the algorithm works. Some chips   */
+/* might not like this, as they have an internal timeout of some mils	*/
+/*
+#define SLO_IO      jif=jiffies;while(jiffies<=jif+i2c_table[minor].veryslow)\
+                        if (need_resched) schedule();
+*/
+
+
+/* ----- global variables ---------------------------------------------	*/
+
+#ifdef SLO_IO
+	int jif;
+#endif
+
+/* module parameters:
+ */
+static int i2c_debug=1;
+static int iic_test=0;	/* see if the line-setting functions work	*/
+static int iic_scan=0;	/* have a look at what's hanging 'round		*/
+
+/* --- setting states on the bus with the right timing: ---------------	*/
+
+#define get_clock(adap) adap->getclock(adap->data)
+#define iic_outw(adap, reg, val) adap->setiic(adap->data, reg, val)
+#define iic_inw(adap, reg) adap->getiic(adap->data, reg)
+
+
+/* --- other auxiliary functions --------------------------------------	*/
+
+static void iic_start(struct i2c_algo_iic_data *adap)
+{
+	iic_outw(adap,ITE_I2CHCR,ITE_CMD);
+}
+
+static void iic_stop(struct i2c_algo_iic_data *adap)
+{
+	iic_outw(adap,ITE_I2CHCR,0);
+	iic_outw(adap,ITE_I2CHSR,ITE_I2CHSR_TDI);
+}
+
+static void iic_reset(struct i2c_algo_iic_data *adap)
+{
+	iic_outw(adap, PM_IBSR, iic_inw(adap, PM_IBSR) | 0x80);
+}
+
+
+static int wait_for_bb(struct i2c_algo_iic_data *adap)
+{
+	int timeout = DEF_TIMEOUT;
+	short status;
+
+	status = iic_inw(adap, ITE_I2CHSR);
+#ifndef STUB_I2C
+	while (timeout-- && (status & ITE_I2CHSR_HB)) {
+		udelay(1000); /* How much is this? */
+		status = iic_inw(adap, ITE_I2CHSR);
+	}
+#endif
+	if (timeout<=0) {
+		printk(KERN_ERR "Timeout, host is busy\n");
+		iic_reset(adap);
+	}
+	return(timeout<=0);
+}
+
+/*
+ * Puts this process to sleep for a period equal to timeout 
+ */
+static inline void iic_sleep(unsigned long timeout)
+{
+	schedule_timeout( timeout * HZ);
+}
+
+/* After we issue a transaction on the IIC bus, this function
+ * is called.  It puts this process to sleep until we get an interrupt from
+ * from the controller telling us that the transaction we requested in complete.
+ */
+static int wait_for_pin(struct i2c_algo_iic_data *adap, short *status) {
+
+	int timeout = DEF_TIMEOUT;
+	
+	timeout = wait_for_bb(adap);
+	if (timeout) {
+  		DEB2(printk("Timeout waiting for host not busy\n");)
+  		return -EIO;
+	}                           
+	timeout = DEF_TIMEOUT;
+
+	*status = iic_inw(adap, ITE_I2CHSR);
+#ifndef STUB_I2C
+	while (timeout-- && !(*status & ITE_I2CHSR_TDI)) {
+	   adap->waitforpin();
+	   *status = iic_inw(adap, ITE_I2CHSR);
+	}
+#endif
+	if (timeout <= 0)
+		return(-1);
+	else
+		return(0);
+}
+
+static int wait_for_fe(struct i2c_algo_iic_data *adap, short *status)
+{
+	int timeout = DEF_TIMEOUT;
+
+	*status = iic_inw(adap, ITE_I2CFSR);
+#ifndef STUB_I2C 
+	while (timeout-- && (*status & ITE_I2CFSR_FE)) {
+		udelay(1000);
+		iic_inw(adap, ITE_I2CFSR);
+	}
+#endif
+	if (timeout <= 0) 
+		return(-1);
+	else
+		return(0);
+}
+
+static int iic_init (struct i2c_algo_iic_data *adap)
+{
+	short i;
+
+	/* Clear bit 7 to set I2C to normal operation mode */
+	i=iic_inw(adap, PM_DSR)& 0xff7f;
+	iic_outw(adap, PM_DSR, i);
+
+	/* set IT_GPCCR port C bit 2&3 as function 2 */
+	i = iic_inw(adap, GPIO_CCR) & 0xfc0f;
+	iic_outw(adap,GPIO_CCR,i);
+
+	/* Clear slave address/sub-address */
+	iic_outw(adap,ITE_I2CSAR, 0);
+	iic_outw(adap,ITE_I2CSSAR, 0);
+
+	/* Set clock counter register */
+	iic_outw(adap,ITE_I2CCKCNT, get_clock(adap));
+
+	/* Set START/reSTART/STOP time registers */
+	iic_outw(adap,ITE_I2CSHDR, 0x0a);
+	iic_outw(adap,ITE_I2CRSUR, 0x0a);
+	iic_outw(adap,ITE_I2CPSUR, 0x0a);
+
+	/* Enable interrupts on completing the current transaction */
+	iic_outw(adap,ITE_I2CHCR, ITE_I2CHCR_IE | ITE_I2CHCR_HCE);
+
+	/* Clear transfer count */
+	iic_outw(adap,ITE_I2CFBCR, 0x0);
+
+	DEB2(printk("iic_init: Initialized IIC on ITE 0x%x\n",
+		iic_inw(adap, ITE_I2CHSR)));
+	return 0;
+}
+
+
+/*
+ * Sanity check for the adapter hardware - check the reaction of
+ * the bus lines only if it seems to be idle.
+ */
+static int test_bus(struct i2c_algo_iic_data *adap, char *name) {
+#if 0
+	int scl,sda;
+	sda=getsda(adap);
+	if (adap->getscl==NULL) {
+		printk("test_bus: Warning: Adapter can't read from clock line - skipping test.\n");
+		return 0;		
+	}
+	scl=getscl(adap);
+	printk("test_bus: Adapter: %s scl: %d  sda: %d -- testing...\n",
+	name,getscl(adap),getsda(adap));
+	if (!scl || !sda ) {
+		printk("test_bus: %s seems to be busy.\n",adap->name);
+		goto bailout;
+	}
+	sdalo(adap);
+	printk("test_bus:1 scl: %d  sda: %d \n",getscl(adap),
+	       getsda(adap));
+	if ( 0 != getsda(adap) ) {
+		printk("test_bus: %s SDA stuck high!\n",name);
+		sdahi(adap);
+		goto bailout;
+	}
+	if ( 0 == getscl(adap) ) {
+		printk("test_bus: %s SCL unexpected low while pulling SDA low!\n",
+			name);
+		goto bailout;
+	}		
+	sdahi(adap);
+	printk("test_bus:2 scl: %d  sda: %d \n",getscl(adap),
+	       getsda(adap));
+	if ( 0 == getsda(adap) ) {
+		printk("test_bus: %s SDA stuck low!\n",name);
+		sdahi(adap);
+		goto bailout;
+	}
+	if ( 0 == getscl(adap) ) {
+		printk("test_bus: %s SCL unexpected low while SDA high!\n",
+		       adap->name);
+	goto bailout;
+	}
+	scllo(adap);
+	printk("test_bus:3 scl: %d  sda: %d \n",getscl(adap),
+	       getsda(adap));
+	if ( 0 != getscl(adap) ) {
+
+		sclhi(adap);
+		goto bailout;
+	}
+	if ( 0 == getsda(adap) ) {
+		printk("test_bus: %s SDA unexpected low while pulling SCL low!\n",
+			name);
+		goto bailout;
+	}
+	sclhi(adap);
+	printk("test_bus:4 scl: %d  sda: %d \n",getscl(adap),
+	       getsda(adap));
+	if ( 0 == getscl(adap) ) {
+		printk("test_bus: %s SCL stuck low!\n",name);
+		sclhi(adap);
+		goto bailout;
+	}
+	if ( 0 == getsda(adap) ) {
+		printk("test_bus: %s SDA unexpected low while SCL high!\n",
+			name);
+		goto bailout;
+	}
+	printk("test_bus: %s passed test.\n",name);
+	return 0;
+bailout:
+	sdahi(adap);
+	sclhi(adap);
+	return -ENODEV;
+#endif
+	return (0);
+}
+
+/* ----- Utility functions
+ */
+
+
+/* Verify the device we want to talk to on the IIC bus really exists. */
+static inline int try_address(struct i2c_algo_iic_data *adap,
+		       unsigned int addr, int retries)
+{
+	int i, ret = -1;
+	short status;
+
+	for (i=0;i<retries;i++) {
+		iic_outw(adap, ITE_I2CSAR, addr);
+		iic_start(adap);
+		if (wait_for_pin(adap, &status) == 0) {
+			if ((status & ITE_I2CHSR_DNE) == 0) { 
+				iic_stop(adap);
+				iic_outw(adap, ITE_I2CFCR, ITE_I2CFCR_FLUSH);
+				ret=1;
+				break;	/* success! */
+			}
+		}
+		iic_stop(adap);
+		udelay(adap->udelay);
+	}
+	DEB2(if (i) printk("try_address: needed %d retries for 0x%x\n",i,
+	                   addr));
+	return ret;
+}
+
+
+static int iic_sendbytes(struct i2c_adapter *i2c_adap,const char *buf,
+                         int count)
+{
+	struct i2c_algo_iic_data *adap = i2c_adap->algo_data;
+	int wrcount=0, timeout;
+	short status;
+	int loops, remainder, i, j;
+	union {
+		char byte[2];
+		unsigned short word;
+	} tmp;
+   
+	iic_outw(adap, ITE_I2CSSAR, (unsigned short)buf[wrcount++]);
+	count--;
+	if (count == 0)
+		return -EIO;
+
+	loops =  count / 32;		/* 32-byte FIFO */
+	remainder = count % 32;
+
+	if(loops) {
+		for(i=0; i<loops; i++) {
+
+			iic_outw(adap, ITE_I2CFBCR, 32);
+			for(j=0; j<32/2; j++) {
+				tmp.byte[1] = buf[wrcount++];
+				tmp.byte[0] = buf[wrcount++];
+				iic_outw(adap, ITE_I2CFDR, tmp.word); 
+			}
+
+			/* status FIFO overrun */
+			iic_inw(adap, ITE_I2CFSR);
+			iic_inw(adap, ITE_I2CFBCR);
+
+			iic_outw(adap, ITE_I2CHCR, ITE_WRITE);	/* Issue WRITE command */
+
+			/* Wait for transmission to complete */
+			timeout = wait_for_pin(adap, &status);
+			if(timeout) {
+				iic_stop(adap);
+				printk("iic_sendbytes: %s write timeout.\n", i2c_adap->name);
+				return -EREMOTEIO; /* got a better one ?? */
+     	}
+			if (status & ITE_I2CHSR_DB) {
+				iic_stop(adap);
+				printk("iic_sendbytes: %s write error - no ack.\n", i2c_adap->name);
+				return -EREMOTEIO; /* got a better one ?? */
+			}
+		}
+	}
+	if(remainder) {
+		iic_outw(adap, ITE_I2CFBCR, remainder);
+		for(i=0; i<remainder/2; i++) {
+			tmp.byte[1] = buf[wrcount++];
+			tmp.byte[0] = buf[wrcount++];
+			iic_outw(adap, ITE_I2CFDR, tmp.word);
+		}
+
+		/* status FIFO overrun */
+		iic_inw(adap, ITE_I2CFSR);
+		iic_inw(adap, ITE_I2CFBCR);
+
+		iic_outw(adap, ITE_I2CHCR, ITE_WRITE);  /* Issue WRITE command */
+
+		timeout = wait_for_pin(adap, &status);
+		if(timeout) {
+			iic_stop(adap);
+			printk("iic_sendbytes: %s write timeout.\n", i2c_adap->name);
+			return -EREMOTEIO; /* got a better one ?? */
+		}
+#ifndef STUB_I2C
+		if (status & ITE_I2CHSR_DB) { 
+			iic_stop(adap);
+			printk("iic_sendbytes: %s write error - no ack.\n", i2c_adap->name);
+			return -EREMOTEIO; /* got a better one ?? */
+		}
+#endif
+	}
+	iic_stop(adap);
+	return wrcount;
+}
+
+
+static int iic_readbytes(struct i2c_adapter *i2c_adap, char *buf, int count,
+	int sread)
+{
+	int rdcount=0, i, timeout;
+	short status;
+	struct i2c_algo_iic_data *adap = i2c_adap->algo_data;
+	int loops, remainder, j;
+	union {
+		char byte[2];
+		unsigned short word;
+	} tmp;
+		
+	loops = count / 32;				/* 32-byte FIFO */
+	remainder = count % 32;
+
+	if(loops) {
+		for(i=0; i<loops; i++) {
+			iic_outw(adap, ITE_I2CFBCR, 32);
+			if (sread)
+				iic_outw(adap, ITE_I2CHCR, ITE_SREAD);
+			else
+				iic_outw(adap, ITE_I2CHCR, ITE_READ);		/* Issue READ command */
+
+			timeout = wait_for_pin(adap, &status);
+			if(timeout) {
+				iic_stop(adap);
+				printk("iic_readbytes:  %s read timeout.\n", i2c_adap->name);
+				return (-1);
+			}
+#ifndef STUB_I2C
+			if (status & ITE_I2CHSR_DB) {
+				iic_stop(adap);
+				printk("iic_readbytes: %s read error - no ack.\n", i2c_adap->name);
+				return (-1);
+			}
+#endif
+
+			timeout = wait_for_fe(adap, &status);
+			if(timeout) {
+				iic_stop(adap);
+				printk("iic_readbytes:  %s FIFO is empty\n", i2c_adap->name);
+				return (-1); 
+			}
+
+			for(j=0; j<32/2; j++) {
+				tmp.word = iic_inw(adap, ITE_I2CFDR);
+				buf[rdcount++] = tmp.byte[1];
+				buf[rdcount++] = tmp.byte[0];
+			}
+
+			/* status FIFO underrun */
+			iic_inw(adap, ITE_I2CFSR);
+
+		}
+	}
+
+
+	if(remainder) {
+		remainder=(remainder+1)/2 * 2;
+		iic_outw(adap, ITE_I2CFBCR, remainder);
+		if (sread)
+			iic_outw(adap, ITE_I2CHCR, ITE_SREAD);
+		else
+		iic_outw(adap, ITE_I2CHCR, ITE_READ);		/* Issue READ command */
+
+		timeout = wait_for_pin(adap, &status);
+		if(timeout) {
+			iic_stop(adap);
+			printk("iic_readbytes:  %s read timeout.\n", i2c_adap->name);
+			return (-1);
+		}
+#ifndef STUB_I2C
+		if (status & ITE_I2CHSR_DB) {
+			iic_stop(adap);
+			printk("iic_readbytes: %s read error - no ack.\n", i2c_adap->name);
+			return (-1);
+		}
+#endif
+		timeout = wait_for_fe(adap, &status);
+		if(timeout) {
+			iic_stop(adap);
+			printk("iic_readbytes:  %s FIFO is empty\n", i2c_adap->name);
+			return (-1);
+		}         
+
+		for(i=0; i<(remainder+1)/2; i++) {
+			tmp.word = iic_inw(adap, ITE_I2CFDR);
+			buf[rdcount++] = tmp.byte[1];
+			buf[rdcount++] = tmp.byte[0];
+		}
+
+		/* status FIFO underrun */
+		iic_inw(adap, ITE_I2CFSR);
+
+	}
+
+	iic_stop(adap);
+	return rdcount;
+}
+
+
+/* This function implements combined transactions.  Combined
+ * transactions consist of combinations of reading and writing blocks of data.
+ * Each transfer (i.e. a read or a write) is separated by a repeated start
+ * condition.
+ */
+#if 0
+static int iic_combined_transaction(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) 
+{
+   int i;
+   struct i2c_msg *pmsg;
+   int ret;
+
+   DEB2(printk("Beginning combined transaction\n"));
+
+   for(i=0; i<(num-1); i++) {
+      pmsg = &msgs[i];
+      if(pmsg->flags & I2C_M_RD) {
+         DEB2(printk("  This one is a read\n"));
+         ret = iic_readbytes(i2c_adap, pmsg->buf, pmsg->len, IIC_COMBINED_XFER);
+      }
+      else if(!(pmsg->flags & I2C_M_RD)) {
+         DEB2(printk("This one is a write\n"));
+         ret = iic_sendbytes(i2c_adap, pmsg->buf, pmsg->len, IIC_COMBINED_XFER);
+      }
+   }
+   /* Last read or write segment needs to be terminated with a stop */
+   pmsg = &msgs[i];
+
+   if(pmsg->flags & I2C_M_RD) {
+      DEB2(printk("Doing the last read\n"));
+      ret = iic_readbytes(i2c_adap, pmsg->buf, pmsg->len, IIC_SINGLE_XFER);
+   }
+   else if(!(pmsg->flags & I2C_M_RD)) {
+      DEB2(printk("Doing the last write\n"));
+      ret = iic_sendbytes(i2c_adap, pmsg->buf, pmsg->len, IIC_SINGLE_XFER);
+   }
+
+   return ret;
+}
+#endif
+
+
+/* Whenever we initiate a transaction, the first byte clocked
+ * onto the bus after the start condition is the address (7 bit) of the
+ * device we want to talk to.  This function manipulates the address specified
+ * so that it makes sense to the hardware when written to the IIC peripheral.
+ *
+ * Note: 10 bit addresses are not supported in this driver, although they are
+ * supported by the hardware.  This functionality needs to be implemented.
+ */
+static inline int iic_doAddress(struct i2c_algo_iic_data *adap,
+                                struct i2c_msg *msg, int retries) 
+{
+	unsigned short flags = msg->flags;
+	unsigned int addr;
+	int ret;
+
+/* Ten bit addresses not supported right now */
+	if ( (flags & I2C_M_TEN)  ) { 
+#if 0
+		addr = 0xf0 | (( msg->addr >> 7) & 0x03);
+		DEB2(printk("addr0: %d\n",addr));
+		ret = try_address(adap, addr, retries);
+		if (ret!=1) {
+			printk("iic_doAddress: died at extended address code.\n");
+			return -EREMOTEIO;
+		}
+		iic_outw(adap,msg->addr & 0x7f);
+		if (ret != 1) {
+			printk("iic_doAddress: died at 2nd address code.\n");
+			return -EREMOTEIO;
+		}
+		if ( flags & I2C_M_RD ) {
+			i2c_repstart(adap);
+			addr |= 0x01;
+			ret = try_address(adap, addr, retries);
+			if (ret!=1) {
+				printk("iic_doAddress: died at extended address code.\n");
+				return -EREMOTEIO;
+			}
+		}
+#endif
+	} else {
+
+		addr = ( msg->addr << 1 );
+
+#if 0
+		if (flags & I2C_M_RD )
+			addr |= 1;
+		if (flags & I2C_M_REV_DIR_ADDR )
+			addr ^= 1;
+#endif
+
+		if (iic_inw(adap, ITE_I2CSAR) != addr) {
+			iic_outw(adap, ITE_I2CSAR, addr);
+			ret = try_address(adap, addr, retries);
+			if (ret!=1) {
+				printk("iic_doAddress: died at address code.\n");
+				return -EREMOTEIO;
+			}
+		}
+
+  }
+
+	return 0;
+}
+
+
+/* Description: Prepares the controller for a transaction (clearing status
+ * registers, data buffers, etc), and then calls either iic_readbytes or
+ * iic_sendbytes to do the actual transaction.
+ *
+ * still to be done: Before we issue a transaction, we should
+ * verify that the bus is not busy or in some unknown state.
+ */
+static int iic_xfer(struct i2c_adapter *i2c_adap,
+		    struct i2c_msg msgs[], 
+		    int num)
+{
+	struct i2c_algo_iic_data *adap = i2c_adap->algo_data;
+	struct i2c_msg *pmsg;
+	int i = 0;
+	int ret, timeout;
+    
+	pmsg = &msgs[i];
+
+	if(!pmsg->len) {
+		DEB2(printk("iic_xfer: read/write length is 0\n");)
+		return -EIO;
+	}
+	if(!(pmsg->flags & I2C_M_RD) && (!(pmsg->len)%2) ) {
+		DEB2(printk("iic_xfer: write buffer length is not odd\n");)
+		return -EIO; 
+	}
+
+	/* Wait for any pending transfers to complete */
+	timeout = wait_for_bb(adap);
+	if (timeout) {
+		DEB2(printk("iic_xfer: Timeout waiting for host not busy\n");)
+		return -EIO;
+	}
+
+	/* Flush FIFO */
+	iic_outw(adap, ITE_I2CFCR, ITE_I2CFCR_FLUSH);
+
+	/* Load address */
+	ret = iic_doAddress(adap, pmsg, i2c_adap->retries);
+	if (ret)
+		return -EIO;
+
+#if 0
+	/* Combined transaction (read and write) */
+	if(num > 1) {
+           DEB2(printk("iic_xfer: Call combined transaction\n"));
+           ret = iic_combined_transaction(i2c_adap, msgs, num);
+  }
+#endif
+
+	DEB3(printk("iic_xfer: Msg %d, addr=0x%x, flags=0x%x, len=%d\n",
+		i, msgs[i].addr, msgs[i].flags, msgs[i].len);)
+
+	if(pmsg->flags & I2C_M_RD) 		/* Read */
+		ret = iic_readbytes(i2c_adap, pmsg->buf, pmsg->len, 0);
+	else {													/* Write */ 
+		udelay(1000);
+		ret = iic_sendbytes(i2c_adap, pmsg->buf, pmsg->len);
+	}
+
+	if (ret != pmsg->len)
+		DEB3(printk("iic_xfer: error or fail on read/write %d bytes.\n",ret)); 
+	else
+		DEB3(printk("iic_xfer: read/write %d bytes.\n",ret));
+
+	return ret;
+}
+
+
+/* Implements device specific ioctls.  Higher level ioctls can
+ * be found in i2c-core.c and are typical of any i2c controller (specifying
+ * slave address, timeouts, etc).  These ioctls take advantage of any hardware
+ * features built into the controller for which this algorithm-adapter set
+ * was written.  These ioctls allow you to take control of the data and clock
+ * lines and set the either high or low,
+ * similar to a GPIO pin.
+ */
+static int algo_control(struct i2c_adapter *adapter, 
+	unsigned int cmd, unsigned long arg)
+{
+
+  struct i2c_algo_iic_data *adap = adapter->algo_data;
+  struct i2c_iic_msg s_msg;
+  char *buf;
+	int ret;
+
+  if (cmd == I2C_SREAD) {
+		if(copy_from_user(&s_msg, (struct i2c_iic_msg *)arg, 
+				sizeof(struct i2c_iic_msg))) 
+			return -EFAULT;
+		buf = kmalloc(s_msg.len, GFP_KERNEL);
+		if (buf== NULL)
+			return -ENOMEM;
+
+		/* Flush FIFO */
+		iic_outw(adap, ITE_I2CFCR, ITE_I2CFCR_FLUSH);
+
+		/* Load address */
+		iic_outw(adap, ITE_I2CSAR,s_msg.addr<<1);
+		iic_outw(adap, ITE_I2CSSAR,s_msg.waddr & 0xff);
+
+		ret = iic_readbytes(adapter, buf, s_msg.len, 1);
+		if (ret>=0) {
+			if(copy_to_user( s_msg.buf, buf, s_msg.len) ) 
+				ret = -EFAULT;
+		}
+		kfree(buf);
+	}
+	return 0;
+}
+
+
+static u32 iic_func(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | 
+	       I2C_FUNC_PROTOCOL_MANGLING; 
+}
+
+/* -----exported algorithm data: -------------------------------------	*/
+
+static struct i2c_algorithm iic_algo = {
+	"ITE IIC algorithm",
+	I2C_ALGO_IIC,
+	iic_xfer,		/* master_xfer	*/
+	NULL,				/* smbus_xfer	*/
+	NULL,				/* slave_xmit		*/
+	NULL,				/* slave_recv		*/
+	algo_control,			/* ioctl		*/
+	iic_func,			/* functionality	*/
+};
+
+
+/* 
+ * registering functions to load algorithms at runtime 
+ */
+int i2c_iic_add_bus(struct i2c_adapter *adap)
+{
+	int i;
+	short status;
+	struct i2c_algo_iic_data *iic_adap = adap->algo_data;
+
+	if (iic_test) {
+		int ret = test_bus(iic_adap, adap->name);
+		if (ret<0)
+			return -ENODEV;
+	}
+
+	DEB2(printk("i2c-algo-ite: hw routines for %s registered.\n",
+	            adap->name));
+
+	/* register new adapter to i2c module... */
+
+	adap->id |= iic_algo.id;
+	adap->algo = &iic_algo;
+
+	adap->timeout = 100;	/* default values, should	*/
+	adap->retries = 3;		/* be replaced by defines	*/
+	adap->flags = 0;
+
+#ifdef MODULE
+	MOD_INC_USE_COUNT;
+#endif
+
+	i2c_add_adapter(adap);
+	iic_init(iic_adap);
+
+	/* scan bus */
+	/* By default scanning the bus is turned off. */
+	if (iic_scan) {
+		printk(KERN_INFO " i2c-algo-ite: scanning bus %s.\n",
+		       adap->name);
+		for (i = 0x00; i < 0xff; i+=2) {
+			iic_outw(iic_adap, ITE_I2CSAR, i);
+			iic_start(iic_adap);
+			if ( (wait_for_pin(iic_adap, &status) == 0) && 
+			    ((status & ITE_I2CHSR_DNE) == 0) ) { 
+				printk(KERN_INFO "\n(%02x)\n",i>>1); 
+			} else {
+				printk(KERN_INFO "."); 
+				iic_reset(iic_adap);
+			}
+			udelay(iic_adap->udelay);
+		}
+	}
+	return 0;
+}
+
+
+int i2c_iic_del_bus(struct i2c_adapter *adap)
+{
+	int res;
+	if ((res = i2c_del_adapter(adap)) < 0)
+		return res;
+	DEB2(printk("i2c-algo-ite: adapter unregistered: %s\n",adap->name));
+
+#ifdef MODULE
+	MOD_DEC_USE_COUNT;
+#endif
+	return 0;
+}
+
+
+int __init i2c_algo_iic_init (void)
+{
+	printk(KERN_INFO "ITE iic (i2c) algorithm module\n");
+	return 0;
+}
+
+
+void i2c_algo_iic_exit(void)
+{
+	return;
+}
+
+
+EXPORT_SYMBOL(i2c_iic_add_bus);
+EXPORT_SYMBOL(i2c_iic_del_bus);
+
+/* The MODULE_* macros resolve to nothing if MODULES is not defined
+ * when this file is compiled.
+ */
+MODULE_AUTHOR("MontaVista Software <www.mvista.com>");
+MODULE_DESCRIPTION("ITE iic algorithm");
+
+MODULE_PARM(iic_test, "i");
+MODULE_PARM(iic_scan, "i");
+MODULE_PARM(i2c_debug,"i");
+
+MODULE_PARM_DESC(iic_test, "Test if the I2C bus is available");
+MODULE_PARM_DESC(iic_scan, "Scan for active chips on the bus");
+MODULE_PARM_DESC(i2c_debug,
+        "debug level - 0 off; 1 normal; 2,3 more verbose; 9 iic-protocol");
+
+
+/* This function resolves to init_module (the function invoked when a module
+ * is loaded via insmod) when this file is compiled with MODULES defined.
+ * Otherwise (i.e. if you want this driver statically linked to the kernel),
+ * a pointer to this function is stored in a table and called
+ * during the intialization of the kernel (in do_basic_setup in /init/main.c) 
+ *
+ * All this functionality is complements of the macros defined in linux/init.h
+ */
+module_init(i2c_algo_iic_init);
+
+
+/* If MODULES is defined when this file is compiled, then this function will
+ * resolved to cleanup_module.
+ */
+module_exit(i2c_algo_iic_exit);
diff -u --recursive --new-file v2.4.9/linux/drivers/i2c/i2c-ite.h linux/drivers/i2c/i2c-ite.h
--- v2.4.9/linux/drivers/i2c/i2c-ite.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/i2c/i2c-ite.h	Sun Sep  9 10:43:02 2001
@@ -0,0 +1,117 @@
+/*
+   --------------------------------------------------------------------
+   i2c-ite.h: Global defines for the I2C controller on board the    
+                 ITE MIPS processor.                                
+   --------------------------------------------------------------------
+   Hai-Pao Fan, MontaVista Software, Inc.
+   hpfan@mvista.com or source@mvista.com
+
+   Copyright 2001 MontaVista Software Inc.
+
+ *  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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+
+#ifndef I2C_ITE_H
+#define I2C_ITE_H 1
+
+#include <asm/it8172/it8172.h>
+
+/* I2C Registers */
+#define ITE_I2CHCR	IT8172_PCI_IO_BASE + IT_I2C_BASE + 0x30
+#define ITE_I2CHSR	IT8172_PCI_IO_BASE + IT_I2C_BASE + 0x34
+#define ITE_I2CSAR	IT8172_PCI_IO_BASE + IT_I2C_BASE + 0x38
+#define ITE_I2CSSAR	IT8172_PCI_IO_BASE + IT_I2C_BASE + 0x3c
+#define ITE_I2CCKCNT	IT8172_PCI_IO_BASE + IT_I2C_BASE + 0x48
+#define ITE_I2CSHDR	IT8172_PCI_IO_BASE + IT_I2C_BASE + 0x4c
+#define ITE_I2CRSUR	IT8172_PCI_IO_BASE + IT_I2C_BASE + 0x50
+#define ITE_I2CPSUR	IT8172_PCI_IO_BASE + IT_I2C_BASE + 0x54
+
+#define ITE_I2CFDR	IT8172_PCI_IO_BASE + IT_I2C_BASE + 0x70
+#define ITE_I2CFBCR	IT8172_PCI_IO_BASE + IT_I2C_BASE + 0x74
+#define ITE_I2CFCR	IT8172_PCI_IO_BASE + IT_I2C_BASE + 0x78
+#define ITE_I2CFSR	IT8172_PCI_IO_BASE + IT_I2C_BASE + 0x7c
+
+
+/* Host Control Register ITE_I2CHCR */
+#define	ITE_I2CHCR_HCE	0x01	/* Enable I2C Host Controller */
+#define	ITE_I2CHCR_IE	0x02	/* Enable the interrupt after completing
+				   the current transaction */
+#define ITE_I2CHCR_CP_W	0x00	/* bit2-4 000 - Write */
+#define	ITE_I2CHCR_CP_R	0x08	/*	  010 - Current address read */
+#define	ITE_I2CHCR_CP_S	0x10	/*	  100 - Sequential read */
+#define ITE_I2CHCR_ST	0x20	/* Initiates the I2C host controller to execute
+				   the command and send the data programmed in
+				   all required registers to I2C bus */
+#define ITE_CMD		ITE_I2CHCR_HCE | ITE_I2CHCR_IE | ITE_I2CHCR_ST
+#define ITE_WRITE	ITE_CMD | ITE_I2CHCR_CP_W
+#define ITE_READ	ITE_CMD | ITE_I2CHCR_CP_R
+#define ITE_SREAD	ITE_CMD | ITE_I2CHCR_CP_S
+
+/* Host Status Register ITE_I2CHSR */
+#define	ITE_I2CHSR_DB	0x01	/* Device is busy, receives NACK response except
+				   in the first and last bytes */
+#define	ITE_I2CHSR_DNE	0x02	/* Target address on I2C bus does not exist */
+#define	ITE_I2CHSR_TDI	0x04	/* R/W Transaction on I2C bus was completed */
+#define	ITE_I2CHSR_HB	0x08	/* Host controller is processing transactions */
+#define	ITE_I2CHSR_FER	0x10	/* Error occurs in the FIFO */
+
+/* Slave Address Register ITE_I2CSAR */
+#define	ITE_I2CSAR_SA_MASK	0xfe	/* Target I2C device address */
+#define	ITE_I2CSAR_ASO		0x0100	/* Output 1/0 to I2CAS port when the
+					   next slave address is addressed */
+
+/* Slave Sub-address Register ITE_I2CSSAR */
+#define	ITE_I2CSSAR_SUBA_MASK	0xff	/* Target I2C device sub-address */
+
+/* Clock Counter Register ITE_I2CCKCNT */
+#define	ITE_I2CCKCNT_STOP	0x00	/* stop I2C clock */
+#define	ITE_I2CCKCNT_HPCC_MASK	0x7f	/* SCL high period counter */
+#define	ITE_I2CCKCNT_LPCC_MASK	0x7f00	/* SCL low period counter */
+
+/* START Hold Time Register ITE_I2CSHDR */
+/* value is counted based on 16 MHz internal clock */
+#define ITE_I2CSHDR_FM	0x0a	/* START condition at fast mode */
+#define	ITE_I2CSHDR_SM	0x47	/* START contition at standard mode */
+
+/* (Repeated) START Setup Time Register ITE_I2CRSUR */
+/* value is counted based on 16 MHz internal clock */
+#define	ITE_I2CRSUR_FM	0x0a	/* repeated START condition at fast mode */
+#define	ITE_I2CRSUR_SM	0x50	/* repeated START condition at standard mode */
+
+/* STOP setup Time Register ITE_I2CPSUR */
+
+/* FIFO Data Register ITE_I2CFDR */
+#define	ITE_I2CFDR_MASK		0xff
+
+/* FIFO Byte Count Register ITE_I2CFBCR */
+#define ITE_I2CFBCR_MASK	0x3f
+
+/* FIFO Control Register ITE_I2CFCR */
+#define	ITE_I2CFCR_FLUSH	0x01	/* Flush FIFO and reset the FIFO point
+					   and I2CFSR */
+/* FIFO Status Register ITE_I2CFSR */
+#define	ITE_I2CFSR_FO	0x01	/* FIFO is overrun when write */
+#define	ITE_I2CFSR_FU	0x02	/* FIFO is underrun when read */
+#define	ITE_I2CFSR_FF	0x04	/* FIFO is full when write */
+#define	ITE_I2CFSR_FE	0x08	/* FIFO is empty when read */
+
+#endif  /* I2C_ITE_H */
diff -u --recursive --new-file v2.4.9/linux/drivers/i2o/i2o_block.c linux/drivers/i2o/i2o_block.c
--- v2.4.9/linux/drivers/i2o/i2o_block.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/i2o/i2o_block.c	Sun Sep  9 16:27:47 2001
@@ -1195,9 +1195,6 @@
 	if(!dev->i2odev)
 		return 0;
 
-	/* Sync the device so we don't get errors */
-	fsync_dev(inode->i_rdev);
-
 	if (dev->refcnt <= 0)
 		printk(KERN_ALERT "i2ob_release: refcount(%d) <= 0\n", dev->refcnt);
 	dev->refcnt--;
@@ -1857,16 +1854,14 @@
 
 static struct gendisk i2ob_gendisk = 
 {
-	MAJOR_NR,
-	"i2o/hd",
-	4,
-	1<<4,
-	i2ob,
-	i2ob_sizes,
-	MAX_I2OB,
-	NULL,
-	NULL,
-	&i2ob_fops,
+	major:		MAJOR_NR,
+	major_name:	"i2o/hd",
+	minor_shift:	4,
+	max_p:		1<<4,
+	part:		i2ob,
+	sizes:		i2ob_sizes,
+	nr_real:	MAX_I2OB,
+	fops:		&i2ob_fops,
 };
 
 
@@ -1978,9 +1973,8 @@
 
 	/*
 	 *	Adding i2ob_gendisk into the gendisk list.
-	 */	
-	i2ob_gendisk.next = gendisk_head;
-	gendisk_head = &i2ob_gendisk;
+	 */
+	add_gendisk(&i2ob_gendisk);
 
 	return 0;
 }
@@ -2050,20 +2044,6 @@
 	 */
 	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
 
-	/*
-	 *	Why isnt register/unregister gendisk in the kernel ???
-	 */
-
-	if (gendisk_head == &i2ob_gendisk) {
-		gendisk_head = i2ob_gendisk.next;
-		}
-	else {
-		for (gdp = gendisk_head; gdp; gdp = gdp->next)
-			if (gdp->next == &i2ob_gendisk)
-			{
-				gdp->next = i2ob_gendisk.next;
-				break;
-			}
-	}
+	del_gendisk(&i2ob_gendisk);
 }
 #endif
diff -u --recursive --new-file v2.4.9/linux/drivers/ide/Config.in linux/drivers/ide/Config.in
--- v2.4.9/linux/drivers/ide/Config.in	Mon Aug 27 12:41:41 2001
+++ linux/drivers/ide/Config.in	Fri Sep  7 09:28:38 2001
@@ -135,7 +135,7 @@
 	 if [ "$CONFIG_BLK_DEV_IDEDISK" = "y" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then
 	    bool '    PROMISE DC4030 support (EXPERIMENTAL)' CONFIG_BLK_DEV_PDC4030
 	 fi
-	 bool '    QDI QD6580 support' CONFIG_BLK_DEV_QD6580
+	 bool '    QDI QD65xx support' CONFIG_BLK_DEV_QD65XX
 	 bool '    UMC-8672 support' CONFIG_BLK_DEV_UMC8672
       fi
    fi
diff -u --recursive --new-file v2.4.9/linux/drivers/ide/Makefile linux/drivers/ide/Makefile
--- v2.4.9/linux/drivers/ide/Makefile	Mon Aug 27 12:41:41 2001
+++ linux/drivers/ide/Makefile	Fri Sep  7 09:28:38 2001
@@ -56,7 +56,7 @@
 ide-obj-$(CONFIG_BLK_DEV_PDC4030)	+= pdc4030.o
 ide-obj-$(CONFIG_BLK_DEV_PDC_ADMA)	+= pdcadma.o
 ide-obj-$(CONFIG_BLK_DEV_PIIX)		+= piix.o
-ide-obj-$(CONFIG_BLK_DEV_QD6580)	+= qd6580.o
+ide-obj-$(CONFIG_BLK_DEV_QD65XX)	+= qd65xx.o
 ide-obj-$(CONFIG_BLK_DEV_IDE_RAPIDE)	+= rapide.o
 ide-obj-$(CONFIG_BLK_DEV_RZ1000)	+= rz1000.o
 ide-obj-$(CONFIG_BLK_DEV_SIS5513)	+= sis5513.o
diff -u --recursive --new-file v2.4.9/linux/drivers/ide/amd7409.c linux/drivers/ide/amd7409.c
--- v2.4.9/linux/drivers/ide/amd7409.c	Sat May 19 17:43:06 2001
+++ linux/drivers/ide/amd7409.c	Wed Dec 31 16:00:00 1969
@@ -1,471 +0,0 @@
-/*
- * linux/drivers/ide/amd7409.c		Version 0.05	June 9, 2000
- *
- * Copyright (C) 1999-2000		Andre Hedrick <andre@linux-ide.org>
- * May be copied or modified under the terms of the GNU General Public License
- *
- */
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
-#include <linux/ioport.h>
-#include <linux/blkdev.h>
-#include <linux/hdreg.h>
-
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/ide.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-
-#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 = pci_resource_start(bmide_dev, 4);
-	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);
-
-static unsigned int amd7409_swdma_check (struct pci_dev *dev)
-{
-	unsigned int class_rev;
-	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
-	class_rev &= 0xff;
-	return ((int) (class_rev >= 7) ? 1 : 0);
-}
-
-static int amd7409_swdma_error(ide_drive_t *drive)
-{
-	printk("%s: single-word DMA not support (revision < C4)\n", drive->name);
-	return 0;
-}
-
-/*
- * Here is where all the hard work goes to program the chipset.
- *
- */
-static int amd7409_tune_chipset (ide_drive_t *drive, byte speed)
-{
-	ide_hwif_t *hwif	= HWIF(drive);
-	struct pci_dev *dev	= hwif->pci_dev;
-	int err			= 0;
-	byte unit		= (drive->select.b.unit & 0x01);
-#ifdef CONFIG_BLK_DEV_IDEDMA
-	unsigned long dma_base	= hwif->dma_base;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
-	byte drive_pci		= 0x00;
-	byte drive_pci2		= 0x00;
-	byte ultra_timing	= 0x00;
-	byte dma_pio_timing	= 0x00;
-	byte pio_timing		= 0x00;
-
-        switch (drive->dn) {
-		case 0: drive_pci = 0x53; drive_pci2 = 0x4b; break;
-		case 1: drive_pci = 0x52; drive_pci2 = 0x4a; break;
-		case 2: drive_pci = 0x51; drive_pci2 = 0x49; break;
-		case 3: drive_pci = 0x50; drive_pci2 = 0x48; break;
-		default:
-                        return -1;
-        }
-
-	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
-
-	ultra_timing &= ~0xC7;
-	dma_pio_timing &= ~0xFF;
-	pio_timing &= ~(0x03 << drive->dn);
-
-#ifdef DEBUG
-	printk(":: UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x ",
-		ultra_timing, dma_pio_timing, pio_timing);
-#endif
-
-	switch(speed) {
-#ifdef CONFIG_BLK_DEV_IDEDMA
-		case XFER_UDMA_4:
-			ultra_timing |= 0x45;
-			dma_pio_timing |= 0x20;
-			break;
-		case XFER_UDMA_3:
-			ultra_timing |= 0x44;
-			dma_pio_timing |= 0x20;
-			break;
-		case XFER_UDMA_2:
-			ultra_timing |= 0x40;
-			dma_pio_timing |= 0x20;
-			break;
-		case XFER_UDMA_1:
-			ultra_timing |= 0x41;
-			dma_pio_timing |= 0x20;
-			break;
-		case XFER_UDMA_0:
-			ultra_timing |= 0x42;
-			dma_pio_timing |= 0x20;
-			break;
-		case XFER_MW_DMA_2:
-			dma_pio_timing |= 0x20;
-			break;
-		case XFER_MW_DMA_1:
-			dma_pio_timing |= 0x21;
-			break;
-		case XFER_MW_DMA_0:
-			dma_pio_timing |= 0x77;
-			break;
-		case XFER_SW_DMA_2:
-			if (!amd7409_swdma_check(dev))
-				return amd7409_swdma_error(drive);
-			dma_pio_timing |= 0x42;
-			break;
-		case XFER_SW_DMA_1:
-			if (!amd7409_swdma_check(dev))
-				return amd7409_swdma_error(drive);
-			dma_pio_timing |= 0x65;
-			break;
-		case XFER_SW_DMA_0:
-			if (!amd7409_swdma_check(dev))
-				return amd7409_swdma_error(drive);
-			dma_pio_timing |= 0xA8;
-			break;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
-		case XFER_PIO_4:
-			dma_pio_timing |= 0x20;
-			break;
-		case XFER_PIO_3:
-			dma_pio_timing |= 0x22;
-			break;
-		case XFER_PIO_2:
-			dma_pio_timing |= 0x42;
-			break;
-		case XFER_PIO_1:
-			dma_pio_timing |= 0x65;
-			break;
-		case XFER_PIO_0:
-		default:
-			dma_pio_timing |= 0xA8;
-			break;
-        }
-
-	pio_timing |= (0x03 << drive->dn);
-
-	if (!drive->init_speed)
-		drive->init_speed = speed;
-
-#ifdef CONFIG_BLK_DEV_IDEDMA
-	pci_write_config_byte(dev, drive_pci, ultra_timing);
-#endif /* CONFIG_BLK_DEV_IDEDMA */
-	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
-
-#ifdef CONFIG_BLK_DEV_IDEDMA
-	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);
-	}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
-
-	err = ide_config_drive_speed(drive, speed);
-	drive->current_speed = speed;
-	return (err);
-}
-
-static void config_chipset_for_pio (ide_drive_t *drive)
-{
-	unsigned short eide_pio_timing[6] = {960, 480, 240, 180, 120, 90};
-	unsigned short xfer_pio	= drive->id->eide_pio_modes;
-	byte			timing, speed, pio;
-
-	pio = ide_get_best_pio_mode(drive, 255, 5, NULL);
-
-	if (xfer_pio> 4)
-		xfer_pio = 0;
-
-	if (drive->id->eide_pio_iordy > 0) {
-		for (xfer_pio = 5;
-			xfer_pio>0 &&
-			drive->id->eide_pio_iordy>eide_pio_timing[xfer_pio];
-			xfer_pio--);
-	} else {
-		xfer_pio = (drive->id->eide_pio_modes & 4) ? 0x05 :
-			   (drive->id->eide_pio_modes & 2) ? 0x04 :
-			   (drive->id->eide_pio_modes & 1) ? 0x03 :
-			   (drive->id->tPIO & 2) ? 0x02 :
-			   (drive->id->tPIO & 1) ? 0x01 : xfer_pio;
-	}
-
-	timing = (xfer_pio >= pio) ? xfer_pio : pio;
-
-	switch(timing) {
-		case 4: speed = XFER_PIO_4;break;
-		case 3: speed = XFER_PIO_3;break;
-		case 2: speed = XFER_PIO_2;break;
-		case 1: speed = XFER_PIO_1;break;
-		default:
-			speed = (!drive->id->tPIO) ? XFER_PIO_0 : XFER_PIO_SLOW;
-			break;
-	}
-	(void) amd7409_tune_chipset(drive, speed);
-	drive->current_speed = speed;
-}
-
-static void amd7409_tune_drive (ide_drive_t *drive, byte pio)
-{
-	byte speed;
-	switch(pio) {
-		case 4:		speed = XFER_PIO_4;break;
-		case 3:		speed = XFER_PIO_3;break;
-		case 2:		speed = XFER_PIO_2;break;
-		case 1:		speed = XFER_PIO_1;break;
-		default:	speed = XFER_PIO_0;break;
-	}
-	(void) amd7409_tune_chipset(drive, speed);
-}
-
-#ifdef CONFIG_BLK_DEV_IDEDMA
-/*
- * This allows the configuration of ide_pci chipset registers
- * for cards that learn about the drive's UDMA, DMA, PIO capabilities
- * after the drive is reported by the OS.
- */
-static int config_chipset_for_dma (ide_drive_t *drive)
-{
-	struct hd_driveid *id	= drive->id;
-	byte udma_66		= eighty_ninty_three(drive);
-	byte udma_100		= 0;
-	byte speed		= 0x00;
-	int  rval;
-
-	if ((id->dma_ultra & 0x0020) && (udma_66)&& (udma_100)) {
-		speed = XFER_UDMA_5;
-	} else if ((id->dma_ultra & 0x0010) && (udma_66)) {
-		speed = XFER_UDMA_4;
-	} else if ((id->dma_ultra & 0x0008) && (udma_66)) {
-		speed = XFER_UDMA_3;
-	} else if (id->dma_ultra & 0x0004) {
-		speed = XFER_UDMA_2;
-	} else if (id->dma_ultra & 0x0002) {
-		speed = XFER_UDMA_1;
-	} else if (id->dma_ultra & 0x0001) {
-		speed = XFER_UDMA_0;
-	} else if (id->dma_mword & 0x0004) {
-		speed = XFER_MW_DMA_2;
-	} else if (id->dma_mword & 0x0002) {
-		speed = XFER_MW_DMA_1;
-	} else if (id->dma_mword & 0x0001) {
-		speed = XFER_MW_DMA_0;
-	} else {
-		return ((int) ide_dma_off_quietly);
-	}
-
-	(void) amd7409_tune_chipset(drive, speed);
-
-	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 :
-						     ide_dma_off_quietly);
-
-	return rval;
-}
-
-
-
-static int config_drive_xfer_rate (ide_drive_t *drive)
-{
-	struct hd_driveid *id = drive->id;
-	ide_dma_action_t dma_func = ide_dma_on;
-
-	if (id && (id->capability & 1) && HWIF(drive)->autodma) {
-		/* Consult the list of known "bad" drives */
-		if (ide_dmaproc(ide_dma_bad_drive, drive)) {
-			dma_func = ide_dma_off;
-			goto fast_ata_pio;
-		}
-		dma_func = ide_dma_off_quietly;
-		if (id->field_valid & 4) {
-			if (id->dma_ultra & 0x002F) {
-				/* Force if Capable UltraDMA */
-				dma_func = config_chipset_for_dma(drive);
-				if ((id->field_valid & 2) &&
-				    (dma_func != ide_dma_on))
-					goto try_dma_modes;
-			}
-		} else if (id->field_valid & 2) {
-try_dma_modes:
-			if ((id->dma_mword & 0x0007) ||
-			    ((id->dma_1word & 0x007) &&
-			     (amd7409_swdma_check(HWIF(drive)->pci_dev)))) {
-				/* Force if Capable regular DMA modes */
-				dma_func = config_chipset_for_dma(drive);
-				if (dma_func != ide_dma_on)
-					goto no_dma_set;
-			}
-			
-		} else if (ide_dmaproc(ide_dma_good_drive, drive)) {
-			if (id->eide_dma_time > 150) {
-				goto no_dma_set;
-			}
-			/* Consult the list of known "good" drives */
-			dma_func = config_chipset_for_dma(drive);
-			if (dma_func != ide_dma_on)
-				goto no_dma_set;
-		} else {
-			goto fast_ata_pio;
-		}
-	} else if ((id->capability & 8) || (id->field_valid & 2)) {
-fast_ata_pio:
-		dma_func = ide_dma_off_quietly;
-no_dma_set:
-
-		config_chipset_for_pio(drive);
-	}
-	return HWIF(drive)->dmaproc(dma_func, drive);
-}
-
-/*
- * amd7409_dmaproc() initiates/aborts (U)DMA read/write operations on a drive.
- */
-
-int amd7409_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
-{
-	switch (func) {
-		case ide_dma_check:
-			return config_drive_xfer_rate(drive);
-		default:
-			break;
-	}
-	return ide_dmaproc(func, drive);	/* use standard DMA stuff */
-}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
-
-unsigned int __init pci_init_amd7409 (struct pci_dev *dev, const char *name)
-{
-	unsigned long fixdma_base = pci_resource_start(dev, 4);
-
-#ifdef CONFIG_BLK_DEV_IDEDMA
-	if (!amd7409_swdma_check(dev))
-		printk("%s: disabling single-word DMA support (revision < C4)\n", name);
-#endif /* CONFIG_BLK_DEV_IDEDMA */
-
-	if (!fixdma_base) {
-		/*
-		 *
-		 */
-	} 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)
-	if (!amd7409_proc) {
-		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)
-{
-#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);
-#endif
-	return ata66;
-}
-
-void __init ide_init_amd7409 (ide_hwif_t *hwif)
-{
-	hwif->tuneproc = &amd7409_tune_drive;
-	hwif->speedproc = &amd7409_tune_chipset;
-
-#ifndef CONFIG_BLK_DEV_IDEDMA
-	hwif->drives[0].autotune = 1;
-	hwif->drives[1].autotune = 1;
-	hwif->autodma = 0;
-	return;
-#else
-
-	if (hwif->dma_base) {
-		hwif->dmaproc = &amd7409_dmaproc;
-		if (!noautodma)
-			hwif->autodma = 1;
-	} else {
-		hwif->autodma = 0;
-		hwif->drives[0].autotune = 1;
-		hwif->drives[1].autotune = 1;
-	}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
-}
-
-void __init ide_dmacapable_amd7409 (ide_hwif_t *hwif, unsigned long dmabase)
-{
-	ide_setup_dma(hwif, dmabase, 8);
-}
diff -u --recursive --new-file v2.4.9/linux/drivers/ide/hd.c linux/drivers/ide/hd.c
--- v2.4.9/linux/drivers/ide/hd.c	Sat Apr 28 11:27:53 2001
+++ linux/drivers/ide/hd.c	Sun Sep  9 18:59:43 2001
@@ -688,16 +688,13 @@
 extern struct block_device_operations hd_fops;
 
 static struct gendisk hd_gendisk = {
-	MAJOR_NR,	/* Major number */	
-	"hd",		/* Major name */
-	6,		/* Bits to shift to get real from partition */
-	1 << 6,		/* Number of partitions per real */
-	hd,		/* hd struct */
-	hd_sizes,	/* block sizes */
-	0,		/* number */
-	NULL,		/* internal use, not presently used */
-	NULL,		/* next */
-	&hd_fops,       /* file operations */
+	major:		MAJOR_NR,
+	major_name:	"hd",
+	minor_shift:	6,
+	max_p:		1 << 6,
+	part:		hd,
+	sizes:		hd_sizes,
+	fops:		&hd_fops,
 };
 	
 static void hd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
@@ -842,8 +839,7 @@
 	}
 	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
 	read_ahead[MAJOR_NR] = 8;		/* 8 sector (4kB) read-ahead */
-	hd_gendisk.next = gendisk_head;
-	gendisk_head = &hd_gendisk;
+	add_gendisk(&hd_gendisk);
 	init_timer(&device_timer);
 	device_timer.function = hd_times_out;
 	hd_geninit();
diff -u --recursive --new-file v2.4.9/linux/drivers/ide/ide-dma.c linux/drivers/ide/ide-dma.c
--- v2.4.9/linux/drivers/ide/ide-dma.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/ide/ide-dma.c	Sun Sep  9 10:43:02 2001
@@ -130,10 +130,30 @@
 	{ "WDC AC23200L"	,	"21.10N21"	},
 	{ "Compaq CRD-8241B"	,	"ALL"		},
 	{ "CRD-8400B"		,	"ALL"		},
+	{ "CRD-8480B",			"ALL"		},
+	{ "CRD-8480C",			"ALL"		},
+	{ "CRD-8482B",			"ALL"		},
+ 	{ "CRD-84"		,	"ALL"		},
+	{ "SanDisk SDP3B"	,	"ALL"		},
+	{ "SanDisk SDP3B-64"	,	"ALL"		},
+	{ "SANYO CD-ROM CRD"	,	"ALL"		},
+	{ "HITACHI CDR-8"	,	"ALL"		},
+	{ "HITACHI CDR-8335"	,	"ALL"		},
+	{ "HITACHI CDR-8435"	,	"ALL"		},
+	{ "Toshiba CD-ROM XM-6202B"	,	"ALL"		},
+	{ "CD-532E-A"		,	"ALL"		},
+	{ "E-IDE CD-ROM CR-840",	"ALL"		},
+	{ "CD-ROM Drive/F5A",	"ALL"		},
+	{ "RICOH CD-R/RW MP7083A",	"ALL"		},
+	{ "WPI CDD-820",		"ALL"		},
+	{ "SAMSUNG CD-ROM SC-148C",	"ALL"		},
+	{ "SAMSUNG CD-ROM SC-148F",	"ALL"		},
+	{ "SAMSUNG CD-ROM SC",	"ALL"		},
 	{ "SanDisk SDP3B-64"	,	"ALL"		},
 	{ "SAMSUNG CD-ROM SN-124",	"ALL"		},
 	{ "PLEXTOR CD-R PX-W8432T",	"ALL"		},
 	{ "ATAPI CD-ROM DRIVE 40X MAXIMUM",	"ALL"		},
+	{ "_NEC DV5800A",               "ALL"           },  
 	{ 0			,	0		}
 
 };
diff -u --recursive --new-file v2.4.9/linux/drivers/ide/ide-floppy.c linux/drivers/ide/ide-floppy.c
--- v2.4.9/linux/drivers/ide/ide-floppy.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/ide/ide-floppy.c	Fri Sep  7 09:28:38 2001
@@ -1,7 +1,8 @@
 /*
- * linux/drivers/ide/ide-floppy.c	Version 0.9.sv	Jan 6 2001
+ * linux/drivers/ide/ide-floppy.c	Version 0.97.sv	Jan 14 2001
  *
  * Copyright (C) 1996 - 1999 Gadi Oxman <gadio@netvision.net.il>
+ * Copyright (C) 2000 - 2001 Paul Bristow <paul@paulbristow.net>
  */
 
 /*
@@ -10,6 +11,12 @@
  * The driver currently doesn't have any fancy features, just the bare
  * minimum read/write support.
  *
+ * This driver supports the following IDE floppy drives:
+ *
+ * LS-120 SuperDisk
+ * Iomega Zip 100/250
+ * Iomega PC Card Clik!/PocketZip
+ *
  * Many thanks to Lode Leroy <Lode.Leroy@www.ibase.be>, who tested so many
  * ALPHA patches to this driver on an EASYSTOR LS-120 ATAPI floppy drive.
  *
@@ -38,6 +45,20 @@
  *                       mode page.  Implemented four IOCTLs in order to
  *                       implement formatting.  IOCTls begin with 0x4600,
  *                       0x46 is 'F' as in Format.
+ *            Jan 9 01   Userland option to select format verify.
+ *                       Added PC_SUPPRESS_ERROR flag - some idefloppy drives
+ *                       do not implement IDEFLOPPY_CAPABILITIES_PAGE, and
+ *                       return a sense error.  Suppress error reporting in
+ *                       this particular case in order to avoid spurious
+ *                       errors in syslog.  The culprit is
+ *                       idefloppy_get_capability_page(), so move it to
+ *                       idefloppy_begin_format() so that it's not used
+ *                       unless absolutely necessary.
+ *                       If drive does not support format progress indication
+ *                       monitor the dsc bit in the status register.
+ *                       Also, O_NDELAY on open will allow the device to be
+ *                       opened without a disk available.  This can be used to
+ *                       open an unformatted disk, or get the device capacity.
  * Ver 0.91  Dec 11 99   Added IOMEGA Clik! drive support by 
  *     		   <paul@paulbristow.net>
  * Ver 0.92  Oct 22 00   Paul Bristow became official maintainer for this 
@@ -49,9 +70,10 @@
  * Ver 0.96  Jan  7 01   Actually in line with release version of 2.4.0
  *                       including set_bit patch from Rusty Russel
  * Ver 0.97  Jul 22 01   Merge 0.91-0.96 onto 0.9.sv for ac series
+ * Ver 0.97.sv Aug 3 01  Backported from 2.4.7-ac3
  */
 
-#define IDEFLOPPY_VERSION "0.97"
+#define IDEFLOPPY_VERSION "0.97.sv"
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -140,6 +162,8 @@
 #define	PC_DMA_ERROR			4	/* 1 when encountered problem during DMA */
 #define	PC_WRITING			5	/* Data direction */
 
+#define	PC_SUPPRESS_ERROR		6	/* Suppress error reporting */
+
 /*
  *	Removable Block Access Capabilities Page
  */
@@ -1022,8 +1046,11 @@
 		 *	a legitimate error code was received.
 		 */
 		if (!test_bit (PC_ABORT, &pc->flags)) {
-			printk (KERN_ERR "ide-floppy: %s: I/O error, pc = %2x, key = %2x, asc = %2x, ascq = %2x\n",
+			if (!test_bit (PC_SUPPRESS_ERROR, &pc->flags)) {
+				;
+      printk( KERN_ERR "ide-floppy: %s: I/O error, pc = %2x, key = %2x, asc = %2x, ascq = %2x\n",
 				drive->name, pc->c[0], floppy->sense_key, floppy->asc, floppy->ascq);
+			}
 			pc->error = IDEFLOPPY_ERROR_GENERAL;		/* Giving up */
 		}
 		floppy->failed_pc=NULL;
@@ -1101,14 +1128,19 @@
 	pc->request_transfer = 255;
 }
 
-static void idefloppy_create_format_unit_cmd (idefloppy_pc_t *pc, int b, int l)
+static void idefloppy_create_format_unit_cmd (idefloppy_pc_t *pc, int b, int l,
+					      int flags)
 {
 	idefloppy_init_pc (pc);
 	pc->c[0] = IDEFLOPPY_FORMAT_UNIT_CMD;
 	pc->c[1] = 0x17;
 
 	memset(pc->buffer, 0, 12);
-	pc->buffer[1] = 0xA2;	/* Format list header, byte 1: FOV/DCRT/IMM */
+	pc->buffer[1] = 0xA2;
+	/* Default format list header, byte 1: FOV/DCRT/IMM bits set */
+
+	if (flags & 1)				/* Verify bit on... */
+		pc->buffer[1] ^= 0x20;		/* ... turn off DCRT bit */
 	pc->buffer[3] = 8;
 
 	put_unaligned(htonl(b), (unsigned int *)(&pc->buffer[4]));
@@ -1300,9 +1332,12 @@
 	floppy->srfp=0;
 	idefloppy_create_mode_sense_cmd (&pc, IDEFLOPPY_CAPABILITIES_PAGE,
 						 MODE_SENSE_CURRENT);
+
+	set_bit(PC_SUPPRESS_ERROR, &pc.flags);
 	if (idefloppy_queue_pc_tail (drive,&pc)) {
 		return 1;
 	}
+
 	header = (idefloppy_mode_parameter_header_t *) pc.buffer;
 	page= (idefloppy_capabilities_page_t *)(header+1);
 	floppy->srfp=page->srfp;
@@ -1378,7 +1413,6 @@
         if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags))
 	{
 		(void) idefloppy_get_flexible_disk_page (drive);
-		(void) idefloppy_get_capability_page (drive);
 	}
 
 	drive->part[0].nr_sects = floppy->blocks * floppy->bs_factor;
@@ -1478,7 +1512,12 @@
 ** struct idefloppy_format_command {
 **        int nblocks;
 **        int blocksize;
+**        int flags;
 **        } ;
+**
+** flags is a bitmask, currently, the only defined flag is:
+**
+**        0x01 - verify media after format.
 */
 
 static int idefloppy_begin_format(ide_drive_t *drive,
@@ -1488,15 +1527,18 @@
 {
 	int blocks;
 	int length;
+	int flags;
 	idefloppy_pc_t pc;
 
 	if (get_user(blocks, arg)
-	    || get_user(length, arg+1))
+	    || get_user(length, arg+1)
+	    || get_user(flags, arg+2))
 	{
 		return (-EFAULT);
 	}
 
-	idefloppy_create_format_unit_cmd(&pc, blocks, length);
+	(void) idefloppy_get_capability_page (drive);	/* Get the SFRP bit */
+	idefloppy_create_format_unit_cmd(&pc, blocks, length, flags);
 	if (idefloppy_queue_pc_tail (drive, &pc))
 	{
                 return (-EIO);
@@ -1510,8 +1552,8 @@
 ** Userland gives a pointer to an int.  The int is set to a progresss
 ** indicator 0-65536, with 65536=100%.
 **
-** If the drive does not support format progress indication, we just return
-** a 65536, screw it.
+** If the drive does not support format progress indication, we just check
+** the dsc bit, and return either 0 or 65536.
 */
 
 static int idefloppy_get_format_progress(ide_drive_t *drive,
@@ -1536,8 +1578,21 @@
 		{
 			progress_indication=floppy->progress_indication;
 		}
+		/* Else assume format_unit has finished, and we're
+		** at 0x10000 */
 	}
+	else
+	{
+		idefloppy_status_reg_t status;
+		unsigned long flags;
 
+		__save_flags(flags);
+		__cli();
+		status.all=GET_STAT();
+		__restore_flags(flags);
+
+		progress_indication= !status.b.dsc ? 0:0x10000;
+	}
 	if (put_user(progress_indication, arg))
 		return (-EFAULT);
 
@@ -1587,8 +1642,6 @@
 		{
 			idefloppy_floppy_t *floppy = drive->driver_data;
 
-			set_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags);
-
 			if (drive->usage > 1)
 			{
 				/* Don't format if someone is using the disk */
@@ -1599,7 +1652,12 @@
 			}
 			else
 			{
-				int rc=idefloppy_begin_format(drive, inode,
+				int rc;
+
+				set_bit(IDEFLOPPY_FORMAT_IN_PROGRESS,
+					&floppy->flags);
+
+				rc=idefloppy_begin_format(drive, inode,
 							      file,
 							      (int *)arg);
 
@@ -1637,7 +1695,6 @@
 
 	MOD_INC_USE_COUNT;
 	if (drive->usage == 1) {
-
 		clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags);
 		/* Just in case */
 
@@ -1647,7 +1704,14 @@
 			(void) idefloppy_queue_pc_tail (drive, &pc);
 		}
 
-		if (idefloppy_get_capacity (drive)) {
+		if (idefloppy_get_capacity (drive)
+		   && (filp->f_flags & O_NDELAY) == 0
+		    /*
+		    ** Allow O_NDELAY to open a drive without a disk, or with
+		    ** an unreadable disk, so that we can get the format
+		    ** capacity of the drive or begin the format - Sam
+		    */
+		    ) {
 			drive->usage--;
 			MOD_DEC_USE_COUNT;
 			return -EIO;
@@ -1893,6 +1957,17 @@
 		for (i = 0; i < 1 << PARTN_BITS; i++)
 			max_sectors[major][minor + i] = 64;
 	}
+  /*
+   *      Guess what?  The IOMEGA Clik! drive also needs the
+   *      above fix.  It makes nasty clicking noises without
+   *      it, so please don't remove this.
+   */
+  if (strcmp(drive->id->model, "IOMEGA Clik! 40 CZ ATAPI") == 0)
+  {
+    for (i = 0; i < 1 << PARTN_BITS; i++)
+      max_sectors[major][minor + i] = 64;
+    set_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags);
+  }
 
 	/*
 	*      Guess what?  The IOMEGA Clik! drive also needs the
diff -u --recursive --new-file v2.4.9/linux/drivers/ide/ide-pci.c linux/drivers/ide/ide-pci.c
--- v2.4.9/linux/drivers/ide/ide-pci.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/ide/ide-pci.c	Sun Sep  9 10:43:02 2001
@@ -38,6 +38,7 @@
 #define DEVID_PIIX4U3	((ide_pci_devid_t){PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82801BA_9})
 #define DEVID_PIIX4U4	((ide_pci_devid_t){PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82801BA_8})
 #define DEVID_VIA_IDE	((ide_pci_devid_t){PCI_VENDOR_ID_VIA,     PCI_DEVICE_ID_VIA_82C561})
+#define DEVID_MR_IDE	((ide_pci_devid_t){PCI_VENDOR_ID_VIA,     PCI_DEVICE_ID_VIA_82C576_1})
 #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})
 #define DEVID_PDC20262	((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20262})
@@ -385,6 +386,7 @@
 	{DEVID_PIIX4U3,	"PIIX4",	PCI_PIIX,	ATA66_PIIX,	INIT_PIIX,	NULL,		{{0x41,0x80,0x80}, {0x43,0x80,0x80}},	ON_BOARD,	0 },
 	{DEVID_PIIX4U4, "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_MR_IDE,	"VP_IDE",	PCI_VIA82CXXX,	ATA66_VIA82CXXX,INIT_VIA82CXXX,	DMA_VIA82CXXX,	{{0x40,0x02,0x02}, {0x40,0x01,0x01}}, 	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 },
 #ifdef CONFIG_PDC202XX_FORCE
         {DEVID_PDC20246,"PDC20246",	PCI_PDC202XX,	NULL,		INIT_PDC202XX,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	OFF_BOARD,	16 },
@@ -758,6 +760,7 @@
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_PIIX4NX) ||
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT34X)  ||
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_VIA_IDE) ||
+		    IDE_PCI_DEVID_EQ(d->devid, DEVID_MR_IDE)  ||
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_VP_IDE))
 			autodma = 0;
 		if (autodma)
@@ -767,6 +770,7 @@
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20265) ||
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20267) ||
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20268) ||
+		    IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20268R) ||
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6210) ||
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6260) ||
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6260R) ||
diff -u --recursive --new-file v2.4.9/linux/drivers/ide/ide-probe.c linux/drivers/ide/ide-probe.c
--- v2.4.9/linux/drivers/ide/ide-probe.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/ide/ide-probe.c	Sat Sep  8 12:02:32 2001
@@ -747,7 +747,7 @@
  */
 static void init_gendisk (ide_hwif_t *hwif)
 {
-	struct gendisk *gd, **gdp;
+	struct gendisk *gd;
 	unsigned int unit, units, minors;
 	int *bs, *max_sect, *max_ra;
 	extern devfs_handle_t ide_devfs_handle;
@@ -800,8 +800,8 @@
 	if (gd->flags)
 		memset (gd->flags, 0, sizeof *gd->flags * units);
 
-	for (gdp = &gendisk_head; *gdp; gdp = &((*gdp)->next)) ;
-	hwif->gd = *gdp = gd;			/* link onto tail of list */
+	hwif->gd = gd;
+	add_gendisk(gd);
 
 	for (unit = 0; unit < units; ++unit) {
 		if (hwif->drives[unit].present) {
diff -u --recursive --new-file v2.4.9/linux/drivers/ide/ide-proc.c linux/drivers/ide/ide-proc.c
--- v2.4.9/linux/drivers/ide/ide-proc.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/ide/ide-proc.c	Fri Sep  7 09:28:38 2001
@@ -404,7 +404,7 @@
 		case ide_cmd640:	name = "cmd640";	break;
 		case ide_dtc2278:	name = "dtc2278";	break;
 		case ide_ali14xx:	name = "ali14xx";	break;
-		case ide_qd6580:	name = "qd6580";	break;
+		case ide_qd65xx:	name = "qd65xx";	break;
 		case ide_umc8672:	name = "umc8672";	break;
 		case ide_ht6560b:	name = "ht6560b";	break;
 		case ide_pdc4030:	name = "pdc4030";	break;
diff -u --recursive --new-file v2.4.9/linux/drivers/ide/ide.c linux/drivers/ide/ide.c
--- v2.4.9/linux/drivers/ide/ide.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/ide/ide.c	Sat Sep  8 12:02:32 2001
@@ -2059,7 +2059,7 @@
 
 void ide_unregister (unsigned int index)
 {
-	struct gendisk *gd, **gdp;
+	struct gendisk *gd;
 	ide_drive_t *drive, *d;
 	ide_hwif_t *hwif, *g;
 	ide_hwgroup_t *hwgroup;
@@ -2179,13 +2179,9 @@
 	blk_dev[hwif->major].data = NULL;
 	blk_dev[hwif->major].queue = NULL;
 	blksize_size[hwif->major] = NULL;
-	for (gdp = &gendisk_head; *gdp; gdp = &((*gdp)->next))
-		if (*gdp == hwif->gd)
-			break;
-	if (*gdp == NULL)
-		printk("gd not in disk chain!\n");
-	else {
-		gd = *gdp; *gdp = gd->next;
+	gd = hwif->gd;
+	if (gd) {
+		del_gendisk(gd);
 		kfree(gd->sizes);
 		kfree(gd->part);
 		if (gd->de_arr)
@@ -2193,6 +2189,7 @@
 		if (gd->flags)
 			kfree (gd->flags);
 		kfree(gd);
+		hwif->gd = NULL;
 	}
 	old_hwif		= *hwif;
 	init_hwif_data (index);	/* restore hwif data to pristine status */
@@ -2788,6 +2785,8 @@
 		case BLKPG:
 		case BLKELVGET:
 		case BLKELVSET:
+		case BLKBSZGET:
+		case BLKBSZSET:
 			return blk_ioctl(inode->i_rdev, cmd, arg);
 
 		case HDIO_GET_BUSSTATE:
@@ -2987,7 +2986,7 @@
  * "ide0=ht6560b"	: probe/support HT6560B interface
  * "ide0=cmd640_vlb"	: *REQUIRED* for VLB cards with the CMD640 chip
  *			  (not for PCI -- automatically detected)
- * "ide0=qd6580"	: probe/support qd6580 interface
+ * "ide0=qd65xx"	: probe/support qd65xx interface
  * "ide0=ali14xx"	: probe/support ali14xx chipsets (ALI M1439, M1443, M1445)
  * "ide0=umc8672"	: probe/support umc8672 chipsets
  * "idex=dc4030"	: probe/support Promise DC4030VL interface
@@ -3155,7 +3154,7 @@
 		const char *ide_words[] = {
 			"noprobe", "serialize", "autotune", "noautotune", "reset", "dma", "ata66",
 			"minus8", "minus9", "minus10",
-			"four", "qd6580", "ht6560b", "cmd640_vlb", "dtc2278", "umc8672", "ali14xx", "dc4030", NULL };
+			"four", "qd65xx", "ht6560b", "cmd640_vlb", "dtc2278", "umc8672", "ali14xx", "dc4030", NULL };
 		hw = s[3] - '0';
 		hwif = &ide_hwifs[hw];
 		i = match_parm(&s[4], ide_words, vals, 3);
@@ -3222,14 +3221,14 @@
 				goto done;
 			}
 #endif /* CONFIG_BLK_DEV_HT6560B */
-#if CONFIG_BLK_DEV_QD6580
-			case -12: /* "qd6580" */
+#if CONFIG_BLK_DEV_QD65XX
+			case -12: /* "qd65xx" */
 			{
-				extern void init_qd6580 (void);
-				init_qd6580();
+				extern void init_qd65xx (void);
+				init_qd65xx();
 				goto done;
 			}
-#endif /* CONFIG_BLK_DEV_QD6580 */
+#endif /* CONFIG_BLK_DEV_QD65XX */
 #ifdef CONFIG_BLK_DEV_4DRIVES
 			case -11: /* "four" drives on one set of ports */
 			{
diff -u --recursive --new-file v2.4.9/linux/drivers/ide/it8172.c linux/drivers/ide/it8172.c
--- v2.4.9/linux/drivers/ide/it8172.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/ide/it8172.c	Fri Sep  7 09:28:38 2001
@@ -5,7 +5,7 @@
  *
  * Copyright 2000 MontaVista Software Inc.
  * Author: MontaVista Software, Inc.
- *              stevel@mvista.com or support@mvista.com
+ *              stevel@mvista.com or source@mvista.com
  *
  *  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
@@ -57,50 +57,41 @@
 void __init ide_init_it8172 (ide_hwif_t *hwif);
 
 
-/*
- *  Based on settings done by AMI BIOS
- *  (might be usefull if drive is not registered in CMOS for any reason).
- */
 static void it8172_tune_drive (ide_drive_t *drive, byte pio)
 {
     unsigned long flags;
     u16 master_data;
-    byte slave_data;
+    u32 slave_data;
     int is_slave	= (&HWIF(drive)->drives[1] == drive);
-    int master_port	= HWIF(drive)->index ? 0x42 : 0x40;
-    int slave_port	= 0x44;
-    /* ISP  RTC */
-    byte timings[][2]	= { { 0, 0 },
-			    { 0, 0 },
-			    { 1, 0 },
-			    { 2, 1 },
-			    { 2, 3 }, };
-
+    int master_port	= 0x40;
+    int slave_port      = 0x44;
+    
     pio = ide_get_best_pio_mode(drive, pio, 5, NULL);
     pci_read_config_word(HWIF(drive)->pci_dev, master_port, &master_data);
+    pci_read_config_dword(HWIF(drive)->pci_dev, slave_port, &slave_data);
+
+    /*
+     * FIX! The DIOR/DIOW pulse width and recovery times in port 0x44
+     * are being left at the default values of 8 PCI clocks (242 nsec
+     * for a 33 MHz clock). These can be safely shortened at higher
+     * PIO modes.
+     */
+    
     if (is_slave) {
-	master_data = master_data | 0x4000;
+	master_data |= 0x4000;
 	if (pio > 1)
-	    /* enable PPE, IE and TIME */
-	    master_data = master_data | 0x0070;
-	pci_read_config_byte(HWIF(drive)->pci_dev, slave_port, &slave_data);
-	slave_data = slave_data & (HWIF(drive)->index ? 0x0f : 0xf0);
-	slave_data = slave_data |
-	    ((timings[pio][0] << 2) | (timings[pio][1]
-				       << (HWIF(drive)->index ? 4 : 0)));
+	    /* enable PPE and IE */
+	    master_data |= 0x0060;
     } else {
-	master_data = master_data & 0xccf8;
+	master_data &= 0xc060;
 	if (pio > 1)
-	    /* enable PPE, IE and TIME */
-	    master_data = master_data | 0x0007;
-	master_data = master_data | (timings[pio][0] << 12) |
-	    (timings[pio][1] << 8);
+	    /* enable PPE and IE */
+	    master_data |= 0x0006;
     }
+
     save_flags(flags);
     cli();
     pci_write_config_word(HWIF(drive)->pci_dev, master_port, master_data);
-    if (is_slave)
-	pci_write_config_byte(HWIF(drive)->pci_dev, slave_port, slave_data);
     restore_flags(flags);
 }
 
@@ -150,12 +141,22 @@
     pci_read_config_byte(dev, 0x48, &reg48);
     pci_read_config_byte(dev, 0x4a, &reg4a);
 
+    /*
+     * Setting the DMA cycle time to 2 or 3 PCI clocks (60 and 91 nsec
+     * at 33 MHz PCI clock) seems to cause BadCRC errors during DMA
+     * transfers on some drives, even though both numbers meet the minimum
+     * ATAPI-4 spec of 73 and 54 nsec for UDMA 1 and 2 respectively.
+     * So the faster times are just commented out here. The good news is
+     * that the slower cycle time has very little affect on transfer
+     * performance.
+     */
+    
     switch(speed) {
     case XFER_UDMA_4:
-    case XFER_UDMA_2:	u_speed = 2 << (drive->dn * 4); break;
+    case XFER_UDMA_2:	//u_speed = 2 << (drive->dn * 4); break;
     case XFER_UDMA_5:
     case XFER_UDMA_3:
-    case XFER_UDMA_1:	u_speed = 1 << (drive->dn * 4); break;
+    case XFER_UDMA_1:	//u_speed = 1 << (drive->dn * 4); break;
     case XFER_UDMA_0:	u_speed = 0 << (drive->dn * 4); break;
     case XFER_MW_DMA_2:
     case XFER_MW_DMA_1:
@@ -164,25 +165,16 @@
     }
 
     if (speed >= XFER_UDMA_0) {
-	if (!(reg48 & u_flag))
-	    pci_write_config_byte(dev, 0x48, reg48|u_flag);
-	if (!(reg4a & u_speed)) {
-	    pci_write_config_byte(dev, 0x4a, reg4a & ~a_speed);
-	    pci_write_config_byte(dev, 0x4a, reg4a|u_speed);
-	}
-    }
-    if (speed < XFER_UDMA_0) {
-	if (reg48 & u_flag)
-	    pci_write_config_byte(dev, 0x48, reg48 & ~u_flag);
-	if (reg4a & a_speed)
-	    pci_write_config_byte(dev, 0x4a, reg4a & ~a_speed);
+	pci_write_config_byte(dev, 0x48, reg48 | u_flag);
+	reg4a &= ~a_speed;
+	pci_write_config_byte(dev, 0x4a, reg4a | u_speed);
+    } else {
+	pci_write_config_byte(dev, 0x48, reg48 & ~u_flag);
+	pci_write_config_byte(dev, 0x4a, reg4a & ~a_speed);
     }
 
     it8172_tune_drive(drive, it8172_dma_2_pio(speed));
 
-#if IT8172_DEBUG
-    printk("%s: %s drive%d\n", drive->name, ide_xfer_verbose(speed), drive->dn);
-#endif
     if (!drive->init_speed)
 	drive->init_speed = speed;
     err = ide_config_drive_speed(drive, speed);
@@ -236,7 +228,9 @@
     /* Other cases are done by generic IDE-DMA code. */
     return ide_dmaproc(func, drive);
 }
+
 #endif /* defined(CONFIG_BLK_DEV_IDEDMA) && (CONFIG_IT8172_TUNING) */
+
 
 unsigned int __init pci_init_it8172 (struct pci_dev *dev, const char *name)
 {
diff -u --recursive --new-file v2.4.9/linux/drivers/ide/pdc202xx.c linux/drivers/ide/pdc202xx.c
--- v2.4.9/linux/drivers/ide/pdc202xx.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/ide/pdc202xx.c	Fri Sep  7 09:28:38 2001
@@ -133,6 +133,7 @@
 
 	switch(dev->device) {
 		case PCI_DEVICE_ID_PROMISE_20268:
+		case PCI_DEVICE_ID_PROMISE_20268R:
 			p += sprintf(p, "\n                                PDC20268 TX2 Chipset.\n");
 			invalid_data_set = 1;
 			break;
diff -u --recursive --new-file v2.4.9/linux/drivers/ide/qd6580.c linux/drivers/ide/qd6580.c
--- v2.4.9/linux/drivers/ide/qd6580.c	Tue Jun 20 07:52:36 2000
+++ linux/drivers/ide/qd6580.c	Wed Dec 31 16:00:00 1969
@@ -1,410 +0,0 @@
-/*
- *  linux/drivers/ide/qd6580.c		Version 0.04	June 4, 2000
- *
- *  Copyright (C) 1996-2000  Linus Torvalds & author (see below)
- */
-
-/*
- *  Version 0.03	Cleaned auto-tune, added probe
- *  Version 0.04	Added second channel tuning
- *
- * QDI QD6580 EIDE controller fast support
- *
- * To activate controller support use kernel parameter "ide0=qd6580"
- * To enable tuning use kernel parameter "ide0=autotune"
- * To enable tuning second channel (not really tested),
- *    use parameter "ide1=autotune"
- */
-
-/* 
- * Rewritten from the work of Colten Edwards <pje120@cs.usask.ca> by
- * Samuel Thibault <samuel.thibault@fnac.net>
- */
-
-#undef REALLY_SLOW_IO           /* most systems can safely undef this */
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
-#include <linux/ioport.h>
-#include <linux/blkdev.h>
-#include <linux/hdreg.h>
-#include <linux/ide.h>
-#include <linux/init.h>
-
-#include <asm/io.h>
-
-#include "ide_modes.h"
-
-/*
- * I/O ports are 0xb0-0xb3
- *            or 0x30-0x33
- *	-- this is a dual IDE interface with I/O chips
- *
- * More research on qd6580 being done by willmore@cig.mot.com (David)
- * More Information given by Petr Sourcek (petr@ryston.cz)
- * http://www.ryston.cz/petr/vlb
- */
-
-/*
- * 0xb0: Timer1
- *
- *
- * 0xb1: Config
- *
- * bit 0: ide baseport: 1 = 0x1f0 ; 0 = 0x170
- *   (? Strange: the Dos driver uses it, and then forces baseport to 0x1f0 ?)
- * bit 1: qd baseport: 1 = 0xb0 ; 0 = 0x30
- * bit 2: ID3: bus speed: 1 = <=33MHz ; 0 = >33MHz
- * bit 3: 1 for qd6580
- * upper nibble is either 1010 or 0101, or else it isn't a qd6580
- *
- *
- * 0xb2: Timer2
- *
- *
- * 0xb3: Control
- *
- * bits 0-3 must always be set 1
- * bit 4 must be set 1, but is set 0 by dos driver while measuring vlb clock
- * bit 0 : 1 = Only primary port enabled : channel 0 for hda, channel 1 for hdb
- *         0 = Primary and Secondary ports enabled : channel 0 for hda & hdb
- *                                                   channel 1 for hdc & hdd
- * bit 1 : 1 = only disks on primary port
- *         0 = disks & ATAPI devices on primary port
- * bit 2-4 : always 0
- * bit 5 : status, but of what ?
- * bit 6 : always set 1 by dos driver
- * bit 7 : set 1 for non-ATAPI devices (read-ahead and post-write buffer ?)
- */
-
-/* truncates a in [b,c] */
-#define IDE_IN(a,b,c)   ( ((a)<(b)) ? (b) : ( (a)>(c) ? (c) : (a)) )
-
-typedef struct ide_hd_timings_s {
-	int active_time;		/* Active pulse (ns) minimum */
-	int recovery_time;		/* Recovery pulse (ns) minimum */
-} ide_hd_timings_t;
-
-static int basePort;		/* base port address (0x30 or 0xb0) */
-static byte config;			/* config register of qd6580 */
-static byte control;		/* control register of qd6580 */
-
-static int bus_clock;		/* Vesa local bus clock (ns) */
-static int tuned=0;			/* to remember whether we've already been tuned */
-static int snd_tuned=0;		/* to remember whether we've already been tuned */
-static int nb_disks_prim=0;	/* number of disk drives on primary port */
-
-/*
- * write_reg
- *
- * writes the specified byte on the specified register
- */
-
-static void write_reg ( byte content, byte reg )
-{
-	unsigned long flags;
-
-	save_flags(flags);		/* all CPUs */
-	cli();					/* all CPUs */
-	outb_p(content,reg);
-	inb(0x3f6);
-	restore_flags(flags);	/* all CPUs */
-}
-
-/*
- * tune_drive
- *
- * Finds timings for the specified drive, returns it in struct t
- */
-
-static void tune_drive ( ide_drive_t *drive, byte pio, ide_hd_timings_t *t )
-{
-	ide_pio_data_t d;
-
-	t->active_time   = 175;
-	t->recovery_time = 415; /* worst cases values from the dos driver */
-
-	if (!drive->present) {	/* not present : free to give any timing */
-		t->active_time = 0;
-		t->recovery_time = 0;
-		return;
-	}
-
-	pio = ide_get_best_pio_mode(drive, pio, 255, &d);
-	pio = IDE_MIN(pio,4);
-
-	switch (pio) {
-		case 0: break;
-		case 3:
-			if (d.cycle_time >= 110) {
-				t->active_time = 86;
-				t->recovery_time = d.cycle_time-102;
-			} else {
-				printk("%s: Strange recovery time !\n",drive->name);
-				return;
-			}
-			break;
-		case 4:
-			if (d.cycle_time >= 69) {
-				t->active_time = 70;
-				t->recovery_time = d.cycle_time-61;
-			} else {
-				printk("%s: Strange recovery time !\n",drive->name);
-				return;
-			}
-			break;
-		default:
-			if (d.cycle_time >= 180) {
-				t->active_time = 110;
-				t->recovery_time = d.cycle_time - 120;
-			} else {
-				t->active_time = ide_pio_timings[pio].active_time;
-				t->recovery_time = d.cycle_time
-						-t->active_time;
-			}
-	}
-	printk("%s: PIO mode%d, tim1=%dns tim2=%dns\n", drive->name, pio, t->active_time, t->recovery_time);
-
-	if (drive->media == ide_disk)
-		nb_disks_prim++;
-	else {
-/* need to disable read-ahead FIFO and post-write buffer for ATAPI drives*/
-		write_reg(0x5f,basePort+0x03);
-		printk("%s: Warning: please try to connect this drive to secondary IDE port\nto improve data transfer rate on primary IDE port.\n",drive->name);
-	}
-}
-
-/*
- * tune_snd_drive
- *
- * Finds timings for the specified drive, using second channel rules
- */
-
-static void tune_snd_drive ( ide_drive_t *drive, byte pio, ide_hd_timings_t *t )
-{
-	ide_pio_data_t d;
-
-	t->active_time   = 175;
-	t->recovery_time = 415;
-
-	if (!drive->present) {	/* not present : free to give any timing */
-		t->active_time = 0;
-		t->recovery_time = 0;
-		return;
-	}
-
-	pio = ide_get_best_pio_mode(drive, pio, 255, &d);
-
-	if ((pio) && (d.cycle_time >= 180)) {
-		t->active_time = 115;
-		t->recovery_time = d.cycle_time - 115;
-	}
-	printk("%s: PIO mode%d, tim1=%dns tim2=%dns\n", drive->name, pio, t->active_time, t->recovery_time);
-
-	if ((drive->media == ide_disk) && (nb_disks_prim<2)) {
-/* a disk drive on secondary port while there's room on primary, which is the
- * only one that has read-ahead fifo and post-write buffer ? What a waste !*/
-		printk("%s: Warning: please try to connect this drive to primary IDE port\nto improve data transfer rate.\n",drive->name);
-	}
-}
-
-/*
- * compute_timing
- *
- * computes the timing value where
- *    lower nibble is active time,   in count of VLB clocks, 17-(from 2 to 17)
- *    upper nibble is recovery time, in count of VLB clocks, 15-(from 2 to 15)
- */
-
-static byte compute_timing ( char name[6], ide_hd_timings_t *t )
-{
-	byte active_cycle;
-	byte recovery_cycle;
-	byte parameter;
-
-	active_cycle   = 17-IDE_IN(t->active_time   / bus_clock + 1, 2, 17);
-	recovery_cycle = 15-IDE_IN(t->recovery_time / bus_clock + 1, 2, 15);
-
-	parameter = active_cycle | (recovery_cycle<<4);
-
-	printk("%s: tim1=%dns tim2=%dns => %#x\n", name, t[0].active_time, t[0].recovery_time, parameter);
-	return(parameter);
-}
-
-/*
- * tune_ide
- *
- * Tunes the whole hwif, ie tunes each drives, and in case we have to share,
- * takes the worse timings to tune qd6580
- */
-
-static void tune_ide ( ide_hwif_t *hwif, byte pio )
-{
-	unsigned long flags;
-	ide_hd_timings_t t[2]={{0,0},{0,0}};
-	int bus_speed = ide_system_bus_speed ();
-
-	bus_clock = 1000 / bus_speed;
-
-	save_flags(flags);		/* all CPUs */
-	cli();					/* all CPUs */
-	outb( (bus_clock<30) ? 0x0 : 0x0a, basePort + 0x02);
-	outb( 0x40 | ((control & 0x02) ? 0x9f:0x1f), basePort+0x03);
-	restore_flags(flags);
-
-	tune_drive (&hwif->drives[0], pio, &t[0]);
-	tune_drive (&hwif->drives[1], pio, &t[1]);
-
-	if (control & 0x01) { /* only primary port enabled, can tune separately */
-		write_reg(compute_timing (hwif->drives[0].name, &t[0]),basePort);
-		write_reg(compute_timing (hwif->drives[1].name, &t[1]),basePort+0x02);
-	} else {			  /* both ports enabled, we have to share */
-
-		t[0].active_time   = IDE_MAX(t[0].active_time,  t[1].active_time);
-		t[0].recovery_time = IDE_MAX(t[0].recovery_time,t[1].recovery_time);
-		write_reg(compute_timing (hwif->name, &t[0]),basePort);
-	}
-}
-
-/*
- * tune_snd_ide
- *
- * Tunes the whole secondary hwif, ie tunes each drives, and takes the worse
- * timings to tune qd6580
- */
-
-static void tune_snd_ide ( ide_hwif_t *hwif, byte pio )
-{
-	ide_hd_timings_t t[2]={{0,0},{0,0}};
-
-	tune_snd_drive (&hwif->drives[0], pio, &t[0]);
-	tune_snd_drive (&hwif->drives[1], pio, &t[1]);
-
-	t[0].active_time   = IDE_MAX(t[0].active_time,  t[1].active_time);
-	t[0].recovery_time = IDE_MAX(t[0].recovery_time,t[1].recovery_time);
-
-	write_reg(compute_timing (hwif->name, &t[0]),basePort+0x02);
-}
-
-/*
- * tune_qd6580
- *
- * tunes the hwif if not tuned
- */
-
-static void tune_qd6580 (ide_drive_t *drive, byte pio)
-{
-	if (! tuned) {
-		tune_ide(HWIF(drive), pio);
-		tuned = 1;
-	}
-}
-
-/*
- * tune_snd_qd6580
- *
- * tunes the second hwif if not tuned
- */
-
-static void tune_snd_qd6580 (ide_drive_t *drive, byte pio)
-{
-	if (! snd_tuned) {
-		tune_snd_ide(HWIF(drive), pio);
-		snd_tuned = 1;
-	}
-}
-
-/*
- * testreg
- *
- * tests if the given port is a register
- */
-
-static int __init testreg(int port)
-{
-	byte savereg;
-	byte readreg;
-	unsigned long flags;
-
-	save_flags(flags);		/* all CPUs */
-	cli();					/* all CPUs */
-	savereg = inb(port);
-	outb_p(0x15,port);		/* safe value */
-	readreg = inb_p(port);
-	outb(savereg,port);
-	restore_flags(flags);	/* all CPUs */
-
-	if (savereg == 0x15) {
-		printk("Outch ! the probe for qd6580 isn't reliable !\n");
-		printk("Please contact maintainers to tell about your hardware\n");
-		printk("Assuming qd6580 is not present.\n");
-		return 0;
-	}
-
-	return (readreg == 0x15);
-}
-
-/*
- * trybase:
- *
- * tries to find a qd6580 at the given base and save it if found
- */
-
-static int __init trybase (int base)
-{
-	unsigned long flags;
-
-	save_flags(flags);		/* all CPUs */
-	cli();					/* all CPUs */
-	config = inb(base+0x01);
-	control = inb(base+0x03);
-	restore_flags(flags);	/* all CPUs */
-
-	if (((config & 0xf0) != 0x50) && ((config & 0xf0) != 0xa0)) return(0);
-	if (! ( ((config & 0x02) == 0x0) == (base == 0x30) ) ) return (0);
-
-	/* Seems to be OK, let's use it */
-
-	basePort = base;
-	return(testreg(base));
-}
-
-/*
- * probe:
- *
- * probes qd6580 at 0xb0 (the default) or 0x30
- */
-
-static int __init probe (void)
-{
-	return (trybase(0xb0) ? 1 : trybase(0x30));
-}
-
-/*
- * init_qd6580:
- *
- * called at the very beginning of initialization ; should just probe and link
- */
-
-void __init init_qd6580 (void)
-{
-	if (! probe()) {
-		printk("qd6580: not found\n");
-		return;
-	}
-
-	printk("qd6580: base=%#x, config=%#x, control=%#x\n", basePort, config, control);
-
-	ide_hwifs[0].chipset = ide_qd6580;
-	ide_hwifs[0].tuneproc = &tune_qd6580;
-	if (!(control & 0x01)) {
-		ide_hwifs[1].chipset = ide_qd6580;
-		ide_hwifs[1].tuneproc = &tune_snd_qd6580;
-		ide_hwifs[0].mate = &ide_hwifs[1];
-		ide_hwifs[1].mate = &ide_hwifs[0];
-		ide_hwifs[1].channel = 1;
-	}
-}
diff -u --recursive --new-file v2.4.9/linux/drivers/ide/qd65xx.c linux/drivers/ide/qd65xx.c
--- v2.4.9/linux/drivers/ide/qd65xx.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/ide/qd65xx.c	Fri Sep  7 09:28:38 2001
@@ -0,0 +1,453 @@
+/*
+ *  linux/drivers/ide/qd65xx.c		Version 0.06	Aug 3, 2000
+ *
+ *  Copyright (C) 1996-2000  Linus Torvalds & author (see below)
+ */
+
+/*
+ *  Version 0.03	Cleaned auto-tune, added probe
+ *  Version 0.04	Added second channel tuning
+ *  Version 0.05	Enhanced tuning ; added qd6500 support
+ *  Version 0.06	added dos driver's list
+ *
+ * QDI QD6500/QD6580 EIDE controller fast support
+ *
+ * Please set local bus speed using kernel parameter idebus
+ * 	for example, "idebus=33" stands for 33Mhz VLbus
+ * To activate controller support, use "ide0=qd65xx"
+ * To enable tuning, use "ide0=autotune"
+ * To enable second channel tuning (qd6580 only), use "ide1=autotune"
+ */
+
+/*
+ * Rewritten from the work of Colten Edwards <pje120@cs.usask.ca> by
+ * Samuel Thibault <samuel.thibault@fnac.net>
+ */
+
+#undef REALLY_SLOW_IO		/* most systems can safely undef this */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/mm.h>
+#include <linux/ioport.h>
+#include <linux/blkdev.h>
+#include <linux/hdreg.h>
+#include <linux/ide.h>
+#include <linux/init.h>
+#include <asm/io.h>
+
+#include "ide_modes.h"
+#include "qd65xx.h"
+
+/*
+ * I/O ports are 0x30-0x31 (and 0x32-0x33 for qd6580)
+ *            or 0xb0-0xb1 (and 0xb2-0xb3 for qd6580)
+ *	-- qd6500 is a single IDE interface
+ *	-- qd6580 is a dual IDE interface
+ *
+ * More research on qd6580 being done by willmore@cig.mot.com (David)
+ * More Information given by Petr Soucek (petr@ryston.cz)
+ * http://www.ryston.cz/petr/vlb
+ */
+
+/*
+ * base: Timer1
+ *
+ *
+ * base+0x01: Config (R/O)
+ *
+ * bit 0: ide baseport: 1 = 0x1f0 ; 0 = 0x170 (only useful for qd6500)
+ * bit 1: qd65xx baseport: 1 = 0xb0 ; 0 = 0x30
+ * bit 2: ID3: bus speed: 1 = <=33MHz ; 0 = >33MHz
+ * bit 3: qd6500: 1 = disabled, 0 = enabled
+ *        qd6580: 1
+ * upper nibble:
+ *        qd6500: 1100
+ *        qd6580: either 1010 or 0101
+ *
+ * base+0x02: Timer2 (qd6580 only)
+ *
+ *
+ * base+0x03: Control (qd6580 only)
+ *
+ * bits 0-3 must always be set 1
+ * bit 4 must be set 1, but is set 0 by dos driver while measuring vlb clock
+ * bit 0 : 1 = Only primary port enabled : channel 0 for hda, channel 1 for hdb
+ *         0 = Primary and Secondary ports enabled : channel 0 for hda & hdb
+ *                                                   channel 1 for hdc & hdd
+ * bit 1 : 1 = only disks on primary port
+ *         0 = disks & ATAPI devices on primary port
+ * bit 2-4 : always 0
+ * bit 5 : status, but of what ?
+ * bit 6 : always set 1 by dos driver
+ * bit 7 : set 1 for non-ATAPI devices on primary port
+ * 	(maybe read-ahead and post-write buffer ?)
+ */
+
+static int timings[4]={-1,-1,-1,-1}; /* stores current timing for each timer */
+
+static void qd_write_reg (byte content, byte reg)
+{
+	unsigned long flags;
+
+	save_flags(flags);	/* all CPUs */
+	cli();			/* all CPUs */
+	outb(content,reg);
+	restore_flags(flags);	/* all CPUs */
+}
+
+byte __init qd_read_reg (byte reg)
+{
+	unsigned long flags;
+	byte read;
+
+	save_flags(flags);	/* all CPUs */
+	cli();			/* all CPUs */
+	read = inb(reg);
+	restore_flags(flags);	/* all CPUs */
+	return read;
+}
+
+/*
+ * qd_select:
+ *
+ * This routine is invoked from ide.c to prepare for access to a given drive.
+ */
+
+static void qd_select (ide_drive_t *drive)
+{
+	byte index = (( (QD_TIMREG(drive)) & 0x80 ) >> 7) |
+			(QD_TIMREG(drive) & 0x02);
+
+	if (timings[index] != QD_TIMING(drive))
+		qd_write_reg(timings[index] = QD_TIMING(drive), QD_TIMREG(drive));
+}
+
+/*
+ * qd6500_compute_timing
+ *
+ * computes the timing value where
+ * 	lower nibble represents active time,   in count of VLB clocks
+ * 	upper nibble represents recovery time, in count of VLB clocks
+ */
+
+static byte qd6500_compute_timing (ide_hwif_t *hwif, int active_time, int recovery_time)
+{
+	byte active_cycle,recovery_cycle;
+
+	if (system_bus_clock()<=33) {
+		active_cycle =   9  - IDE_IN(active_time   * system_bus_clock() / 1000 + 1, 2, 9);
+		recovery_cycle = 15 - IDE_IN(recovery_time * system_bus_clock() / 1000 + 1, 0, 15);
+	} else {
+		active_cycle =   8  - IDE_IN(active_time   * system_bus_clock() / 1000 + 1, 1, 8);
+		recovery_cycle = 18 - IDE_IN(recovery_time * system_bus_clock() / 1000 + 1, 3, 18);
+	}
+
+	return((recovery_cycle<<4) | 0x08 | active_cycle);
+}
+
+/*
+ * qd6580_compute_timing
+ *
+ * idem for qd6580
+ */
+
+static byte qd6580_compute_timing (int active_time, int recovery_time)
+{
+	byte active_cycle   = 17-IDE_IN(active_time   * system_bus_clock() / 1000 + 1, 2, 17);
+	byte recovery_cycle = 15-IDE_IN(recovery_time * system_bus_clock() / 1000 + 1, 2, 15);
+
+	return((recovery_cycle<<4) | active_cycle);
+}
+
+/*
+ * qd_find_disk_type
+ *
+ * tries to find timing from dos driver's table
+ */
+
+static int qd_find_disk_type (ide_drive_t *drive,
+		int *active_time, int *recovery_time)
+{
+	struct qd65xx_timing_s *p;
+	char model[40];
+
+	if (!*drive->id->model) return 0;
+
+	strncpy(model,drive->id->model,40);
+	ide_fixstring(model,40,1); /* byte-swap */
+
+	for (p = qd65xx_timing ; p->offset != -1 ; p++) {
+		if (!strncmp(p->model, model+p->offset,4)) {
+			printk(KERN_DEBUG "%s: listed !\n",drive->name);
+			*active_time = p->active;
+			*recovery_time = p->recovery;
+			return 1;
+		}
+	}
+	return 0;
+}
+
+/*
+ * qd_timing_ok:
+ *
+ * check whether timings don't conflict
+ */
+
+static int qd_timing_ok (ide_drive_t drives[])
+{
+	return (IDE_IMPLY(drives[0].present && drives[1].present,
+			IDE_IMPLY(QD_TIMREG(drives) == QD_TIMREG(drives+1),
+			          QD_TIMING(drives) == QD_TIMING(drives+1))));
+	/* if same timing register, must be same timing */
+}
+
+/*
+ * qd_set_timing:
+ *
+ * records the timing, and enables selectproc as needed
+ */
+
+static void qd_set_timing (ide_drive_t *drive, byte timing)
+{
+	ide_hwif_t *hwif = HWIF(drive);
+
+	drive->drive_data &= 0xff00;
+	drive->drive_data |= timing;
+	if (qd_timing_ok(hwif->drives)) {
+		qd_select(drive); /* selects once */
+		hwif->selectproc = NULL;
+	} else
+		hwif->selectproc = &qd_select;
+
+	printk(KERN_DEBUG "%s: %#x\n",drive->name,timing);
+}
+
+/*
+ * qd6500_tune_drive
+ */
+
+static void qd6500_tune_drive (ide_drive_t *drive, byte pio)
+{
+	int active_time   = 175;
+	int recovery_time = 415; /* worst case values from the dos driver */
+
+	if (drive->id && !qd_find_disk_type(drive,&active_time,&recovery_time)
+		&& drive->id->tPIO && (drive->id->field_valid & 0x02)
+		&& drive->id->eide_pio >= 240) {
+
+		printk(KERN_INFO "%s: PIO mode%d\n", drive->name,
+				drive->id->tPIO);
+		active_time = 110;
+		recovery_time = drive->id->eide_pio - 120;
+	}
+
+	qd_set_timing(drive,qd6500_compute_timing(HWIF(drive),active_time,recovery_time));
+}
+
+/*
+ * qd6580_tune_drive
+ */
+
+static void qd6580_tune_drive (ide_drive_t *drive, byte pio)
+{
+	ide_pio_data_t d;
+	int base = HWIF(drive)->select_data;
+	int active_time   = 175;
+	int recovery_time = 415; /* worst case values from the dos driver */
+
+	if (drive->id && !qd_find_disk_type(drive,&active_time,&recovery_time)) {
+		pio = ide_get_best_pio_mode(drive, pio, 255, &d);
+		pio = IDE_MIN(pio,4);
+
+		switch (pio) {
+			case 0: break;
+			case 3:
+				if (d.cycle_time >= 110) {
+					active_time = 86;
+					recovery_time = d.cycle_time-102;
+				} else
+					printk(KERN_WARNING "%s: Strange recovery time !\n",drive->name);
+				break;
+			case 4:
+				if (d.cycle_time >= 69) {
+					active_time = 70;
+					recovery_time = d.cycle_time-61;
+				} else
+					printk(KERN_WARNING "%s: Strange recovery time !\n",drive->name);
+				break;
+			default:
+				if (d.cycle_time >= 180) {
+					active_time = 110;
+					recovery_time = d.cycle_time - 120;
+				} else {
+					active_time = ide_pio_timings[pio].active_time;
+					recovery_time = d.cycle_time
+							-active_time;
+				}
+		}
+		printk(KERN_INFO "%s: PIO mode%d\n",drive->name,pio);
+	}
+
+	if (!HWIF(drive)->channel && drive->media != ide_disk) {
+		qd_write_reg(0x5f,QD_CONTROL_PORT);
+		printk(KERN_WARNING "%s: ATAPI: disabled read-ahead FIFO and post-write buffer on %s.\n",drive->name,HWIF(drive)->name);
+	}
+
+	qd_set_timing(drive,qd6580_compute_timing(active_time,recovery_time));
+}
+
+/*
+ * qd_testreg
+ *
+ * tests if the given port is a register
+ */
+
+static int __init qd_testreg(int port)
+{
+	byte savereg;
+	byte readreg;
+	unsigned long flags;
+
+	save_flags(flags);	/* all CPUs */
+	cli();			/* all CPUs */
+	savereg = inb_p(port);
+	outb_p(QD_TESTVAL,port);	/* safe value */
+	readreg = inb_p(port);
+	outb(savereg,port);
+	restore_flags(flags);	/* all CPUs */
+
+	if (savereg == QD_TESTVAL) {
+		printk(KERN_ERR "Outch ! the probe for qd65xx isn't reliable !\n");
+		printk(KERN_ERR "Please contact maintainers to tell about your hardware\n");
+		printk(KERN_ERR "Assuming qd65xx is not present.\n");
+		return 1;
+	}
+
+	return (readreg != QD_TESTVAL);
+}
+
+/*
+ * probe:
+ *
+ * looks at the specified baseport, and if qd found, registers & initialises it
+ * return 1 if another qd may be probed
+ */
+
+int __init probe (int base)
+{
+	byte config;
+	byte index;
+
+	config = qd_read_reg(QD_CONFIG_PORT);
+
+	if (! ((config & QD_CONFIG_BASEPORT) >> 1 == (base == 0xb0)) ) return 1;
+
+	index = ! (config & QD_CONFIG_IDE_BASEPORT);
+
+	if ((config & 0xf0) == QD_CONFIG_QD6500) {
+		ide_hwif_t *hwif = &ide_hwifs[index];
+
+		if (qd_testreg(base)) return 1;		/* bad register */
+
+			/* qd6500 found */
+
+		printk(KERN_NOTICE "%s: qd6500 at %#x\n",
+			ide_hwifs[index].name, base);
+		
+		printk(KERN_DEBUG "qd6500: config=%#x, ID3=%u\n",
+			config, QD_ID3);
+		
+		if (config & QD_CONFIG_DISABLED) {
+			printk(KERN_WARNING "qd6500 is disabled !\n");
+			return 1;
+		}
+
+		hwif->chipset = ide_qd65xx;
+		hwif->select_data = base;
+		hwif->config_data = config;
+		hwif->drives[0].drive_data =
+		hwif->drives[1].drive_data = QD6500_DEF_DATA;
+		hwif->drives[0].io_32bit =
+		hwif->drives[1].io_32bit = 1;
+		hwif->tuneproc = &qd6500_tune_drive;
+		return 1;
+	}
+
+	if (((config & 0xf0) == QD_CONFIG_QD6580_A) || ((config & 0xf0) == QD_CONFIG_QD6580_B)) {
+
+		byte control;
+
+		if (qd_testreg(base) || qd_testreg(base+0x02)) return 1;
+			/* bad registers */
+
+			/* qd6580 found */
+
+		control = qd_read_reg(QD_CONTROL_PORT);
+
+		printk(KERN_NOTICE "qd6580 at %#x\n", base);
+		printk(KERN_DEBUG "qd6580: config=%#x, control=%#x, ID3=%u\n",
+			config, control, QD_ID3);
+
+		if (control & QD_CONTR_SEC_DISABLED) {
+			ide_hwif_t *hwif = &ide_hwifs[index];
+
+			/* secondary disabled */
+			printk(KERN_INFO "%s: qd6580: single IDE board\n",
+					ide_hwifs[index].name);
+
+			hwif->chipset = ide_qd65xx;
+			hwif->select_data = base;
+			hwif->config_data = config | (control <<8);
+			hwif->drives[0].drive_data =
+			hwif->drives[1].drive_data = QD6580_DEF_DATA;
+			hwif->drives[0].io_32bit =
+			hwif->drives[1].io_32bit = 1;
+			hwif->tuneproc = &qd6580_tune_drive;
+
+			qd_write_reg(QD_DEF_CONTR,QD_CONTROL_PORT);
+
+			return 1;
+		} else {
+			int i,j;
+			/* secondary enabled */
+			printk(KERN_INFO "%s&%s: qd6580: dual IDE board\n",
+					ide_hwifs[0].name,ide_hwifs[1].name);
+
+			for (i=0;i<2;i++) {
+
+				ide_hwifs[i].chipset = ide_qd65xx;
+				ide_hwifs[i].mate = &ide_hwifs[i^1];
+				ide_hwifs[i].channel = i;
+
+				ide_hwifs[i].select_data = base;
+				ide_hwifs[i].config_data = config | (control <<8);
+				ide_hwifs[i].tuneproc = &qd6580_tune_drive;
+
+				for (j=0;j<2;j++) {
+					ide_hwifs[i].drives[j].drive_data = QD6580_DEF_DATA;
+					ide_hwifs[i].drives[j].io_32bit = 1;
+				}
+			}
+
+			qd_write_reg(QD_DEF_CONTR,QD_CONTROL_PORT);
+
+			return 0; /* no other qd65xx possible */
+		}
+	}
+	/* no qd65xx found */
+	return 1;
+}
+
+/*
+ * init_qd65xx:
+ *
+ * called at the very beginning of initialization ; should just probe and link
+ */
+
+void __init init_qd65xx (void)
+{
+	if (probe(0x30)) probe(0xb0);
+}
diff -u --recursive --new-file v2.4.9/linux/drivers/ide/qd65xx.h linux/drivers/ide/qd65xx.h
--- v2.4.9/linux/drivers/ide/qd65xx.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/ide/qd65xx.h	Fri Sep  7 09:28:38 2001
@@ -0,0 +1,139 @@
+/*
+ * linux/drivers/ide/qd65xx.h
+ *
+ * Copyright (c) 2000	Linus Torvalds & authors
+ */
+
+/*
+ * Authors:	Petr Soucek <petr@ryston.cz>
+ * 		Samuel Thibault <samuel.thibault@fnac.net>
+ */
+
+/* truncates a in [b,c] */
+#define IDE_IN(a,b,c)   ( ((a)<(b)) ? (b) : ( (a)>(c) ? (c) : (a)) )
+
+#define IDE_IMPLY(a,b)	((!(a)) || (b))
+
+#define QD_TIM1_PORT		(base)
+#define QD_CONFIG_PORT		(base+0x01)
+#define QD_TIM2_PORT		(base+0x02)
+#define QD_CONTROL_PORT		(base+0x03)
+
+#define QD_CONFIG_IDE_BASEPORT	0x01
+#define QD_CONFIG_BASEPORT	0x02
+#define QD_CONFIG_ID3		0x04
+#define QD_CONFIG_DISABLED	0x08
+#define QD_CONFIG_QD6500	0xc0
+#define QD_CONFIG_QD6580_A	0xa0
+#define QD_CONFIG_QD6580_B	0x50
+
+#define QD_CONTR_SEC_DISABLED	0x01
+
+#define QD_ID3			(config & QD_CONFIG_ID3)
+
+#define QD_CONFIG(hwif)		((hwif)->config_data & 0x00ff)
+#define QD_CONTROL(hwif)	(((hwif)->config_data & 0xff00) >> 8)
+
+#define QD_TIMING(drive)	(byte)(((drive)->drive_data) & 0x00ff)
+#define QD_TIMREG(drive)	(byte)((((drive)->drive_data) & 0xff00) >> 8)
+
+#define QD6500_DEF_DATA		((QD_TIM1_PORT<<8) | (QD_ID3 ? 0x0c : 0x08))
+#define QD6580_DEF_DATA		((QD_TIM1_PORT<<8) | (QD_ID3 ? 0x0a : 0x00))
+#define QD_DEF_CONTR		(0x40 | ((control & 0x02) ? 0x9f : 0x1f))
+
+#define QD_TESTVAL		0x19	/* safe value */
+
+/* Drive specific timing taken from DOS driver v3.7 */
+
+struct qd65xx_timing_s {
+	char	offset;   /* ofset from the beginning of Model Number" */
+	char	model[4];    /* 4 chars from Model number, no conversion */
+	short	active;   /* active time */
+	short	recovery; /* recovery time */
+} qd65xx_timing [] = {
+	{ 30, "2040", 110, 225 },  /* Conner CP30204			*/
+	{ 30, "2045", 135, 225 },  /* Conner CP30254			*/
+	{ 30, "1040", 155, 325 },  /* Conner CP30104			*/
+	{ 30, "1047", 135, 265 },  /* Conner CP30174			*/
+	{ 30, "5344", 135, 225 },  /* Conner CP3544			*/
+	{ 30, "01 4", 175, 405 },  /* Conner CP-3104			*/
+	{ 27, "C030", 175, 375 },  /* Conner CP3000			*/
+	{  8, "PL42", 110, 295 },  /* Quantum LP240			*/
+	{  8, "PL21", 110, 315 },  /* Quantum LP120			*/
+	{  8, "PL25", 175, 385 },  /* Quantum LP52			*/
+	{  4, "PA24", 110, 285 },  /* WD Piranha SP4200			*/
+	{  6, "2200", 110, 260 },  /* WD Caviar AC2200			*/
+	{  6, "3204", 110, 235 },  /* WD Caviar AC2340			*/
+	{  6, "1202", 110, 265 },  /* WD Caviar AC2120			*/
+	{  0, "DS3-", 135, 315 },  /* Teac SD340			*/
+	{  8, "KM32", 175, 355 },  /* Toshiba MK234			*/
+	{  2, "53A1", 175, 355 },  /* Seagate ST351A			*/
+	{  2, "4108", 175, 295 },  /* Seagate ST1480A			*/
+	{  2, "1344", 175, 335 },  /* Seagate ST3144A			*/
+	{  6, "7 12", 110, 225 },  /* Maxtor 7213A			*/
+	{ 30, "02F4", 145, 295 },  /* Conner 3204F			*/
+	{  2, "1302", 175, 335 },  /* Seagate ST3120A			*/
+	{  2, "2334", 145, 265 },  /* Seagate ST3243A			*/
+	{  2, "2338", 145, 275 },  /* Seagate ST3283A			*/
+	{  2, "3309", 145, 275 },  /* Seagate ST3390A			*/
+	{  2, "5305", 145, 275 },  /* Seagate ST3550A			*/
+	{  2, "4100", 175, 295 },  /* Seagate ST1400A			*/
+	{  2, "4110", 175, 295 },  /* Seagate ST1401A			*/
+	{  2, "6300", 135, 265 },  /* Seagate ST3600A			*/
+	{  2, "5300", 135, 265 },  /* Seagate ST3500A			*/
+	{  6, "7 31", 135, 225 },  /* Maxtor 7131 AT			*/
+	{  6, "7 43", 115, 265 },  /* Maxtor 7345 AT			*/
+	{  6, "7 42", 110, 255 },  /* Maxtor 7245 AT			*/
+	{  6, "3 04", 135, 265 },  /* Maxtor 340 AT			*/
+	{  6, "61 0", 135, 285 },  /* WD AC160				*/
+	{  6, "1107", 135, 235 },  /* WD AC1170				*/
+	{  6, "2101", 110, 220 },  /* WD AC1210				*/
+	{  6, "4202", 135, 245 },  /* WD AC2420				*/
+	{  6, "41 0", 175, 355 },  /* WD Caviar 140			*/
+	{  6, "82 0", 175, 355 },  /* WD Caviar 280			*/
+	{  8, "PL01", 175, 375 },  /* Quantum LP105			*/
+	{  8, "PL25", 110, 295 },  /* Quantum LP525			*/
+	{ 10, "4S 2", 175, 385 },  /* Quantum ELS42			*/
+	{ 10, "8S 5", 175, 385 },  /* Quantum ELS85			*/
+	{ 10, "1S72", 175, 385 },  /* Quantum ELS127			*/
+	{ 10, "1S07", 175, 385 },  /* Quantum ELS170			*/
+	{  8, "ZE42", 135, 295 },  /* Quantum EZ240			*/
+	{  8, "ZE21", 175, 385 },  /* Quantum EZ127			*/
+	{  8, "ZE58", 175, 385 },  /* Quantum EZ85			*/
+	{  8, "ZE24", 175, 385 },  /* Quantum EZ42			*/
+	{ 27, "C036", 155, 325 },  /* Conner CP30064			*/
+	{ 27, "C038", 155, 325 },  /* Conner CP30084			*/
+	{  6, "2205", 110, 255 },  /* WDC AC2250			*/
+	{  2, " CHA", 140, 415 },  /* WDC AH series; WDC AH260, WDC	*/
+	{  2, " CLA", 140, 415 },  /* WDC AL series: WDC AL2120, 2170,	*/
+	{  4, "UC41", 140, 415 },  /* WDC CU140				*/
+	{  6, "1207", 130, 275 },  /* WDC AC2170			*/
+	{  6, "2107", 130, 275 },  /* WDC AC1270			*/
+	{  6, "5204", 130, 275 },  /* WDC AC2540			*/
+	{ 30, "3004", 110, 235 },  /* Conner CP30340			*/
+	{ 30, "0345", 135, 255 },  /* Conner CP30544			*/
+	{ 12, "12A3", 175, 320 },  /* MAXTOR LXT-213A			*/
+	{ 12, "43A0", 145, 240 },  /* MAXTOR LXT-340A			*/
+	{  6, "7 21", 180, 290 },  /* Maxtor 7120 AT			*/
+	{  6, "7 71", 135, 240 },  /* Maxtor 7170 AT			*/
+	{ 12, "45\0000", 110, 205 },   /* MAXTOR MXT-540		*/
+	{  8, "PL11", 180, 290 },  /* QUANTUM LP110A			*/
+	{  8, "OG21", 150, 275 },  /* QUANTUM GO120			*/
+	{ 12, "42A5", 175, 320 },  /* MAXTOR LXT-245A			*/
+	{  2, "2309", 175, 295 },  /* ST3290A				*/
+	{  2, "3358", 180, 310 },  /* ST3385A				*/
+	{  2, "6355", 180, 310 },  /* ST3655A				*/
+	{  2, "1900", 175, 270 },  /* ST9100A				*/
+	{  2, "1954", 175, 270 },  /* ST9145A				*/
+	{  2, "1909", 175, 270 },  /* ST9190AG				*/
+	{  2, "2953", 175, 270 },  /* ST9235A				*/
+	{  2, "1359", 175, 270 },  /* ST3195A				*/
+	{ 24, "3R11", 175, 290 },  /* ALPS ELECTRIC Co.,LTD, DR311C	*/
+	{  0, "2M26", 175, 215 },  /* M262XT-0Ah			*/
+	{  4, "2253", 175, 300 },  /* HP C2235A				*/
+	{  4, "-32A", 145, 245 },  /* H3133-A2				*/
+	{ 30, "0326", 150, 270 },  /* Samsung Electronics 120MB		*/
+	{ 30, "3044", 110, 195 },  /* Conner CFA340A			*/
+	{ 30, "43A0", 110, 195 },  /* Conner CFA340A			*/
+	{ -1, "    ", 175, 415 }   /* unknown disk name			*/
+};
diff -u --recursive --new-file v2.4.9/linux/drivers/ide/serverworks.c linux/drivers/ide/serverworks.c
--- v2.4.9/linux/drivers/ide/serverworks.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/ide/serverworks.c	Sun Sep  9 10:43:02 2001
@@ -544,8 +544,33 @@
 	return 0;
 }
 
+/* On Dell PowerEdge servers with a CSB5, the top two bits of the subsystem
+ * device ID indicate presence of an 80-pin cable.
+ * Bit 15 clear = secondary IDE channel does not have 80-pin cable.
+ * Bit 15 set   = secondary IDE channel has 80-pin cable.
+ * Bit 14 clear = primary IDE channel does not have 80-pin cable.
+ * Bit 14 set   = primary IDE channel has 80-pin cable.
+ */
+
+static unsigned int __init ata66_svwks_dell (ide_hwif_t *hwif)
+{
+	struct pci_dev *dev	= hwif->pci_dev;
+	if (dev->subsystem_vendor == PCI_VENDOR_ID_DELL        &&
+	    dev->vendor           == PCI_VENDOR_ID_SERVERWORKS &&
+	    dev->device           == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE)
+		return ((1 << (hwif->channel + 14)) &
+			dev->subsystem_device) ? 1 : 0;
+
+	return 0;
+
+}
+
 unsigned int __init ata66_svwks (ide_hwif_t *hwif)
 {
+	struct pci_dev *dev	= hwif->pci_dev;
+	if (dev->subsystem_vendor == PCI_VENDOR_ID_DELL)
+		return ata66_svwks_dell (hwif);
+	
 	return 0;
 }
 
diff -u --recursive --new-file v2.4.9/linux/drivers/ide/sis5513.c linux/drivers/ide/sis5513.c
--- v2.4.9/linux/drivers/ide/sis5513.c	Sun Aug 12 13:27:59 2001
+++ linux/drivers/ide/sis5513.c	Fri Sep  7 09:28:38 2001
@@ -96,7 +96,7 @@
 	{ 4, "Mode 2" }, 
 	{ 3, "Mode 3" },
 	{ 2, "Mode 4" },
-	{ 0, "Undefined" }
+	{ 0, "Mode 5" }
 };
 
 static __inline__ char * find_udma_mode (byte cycle_time)
@@ -135,7 +135,7 @@
 };
 
 static char * cycle_time [] = {
-	"Undefined", "2 CLCK",
+	"2 CLK", "2 CLK",
 	"3 CLK", "4 CLK",
 	"5 CLK", "6 CLK",
 	"7 CLK", "8 CLK"
@@ -495,7 +495,7 @@
 	printk("%s: %s drive%d\n", drive->name, ide_xfer_verbose(speed), drive->dn);
 #endif /* SIS5513_DEBUG_DRIVE_INFO */
 
-	return ((int)	((id->dma_ultra >> 11) & 3) ? ide_dma_on :
+	return ((int)	((id->dma_ultra >> 11) & 7) ? 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 :
@@ -515,7 +515,7 @@
 		}
 		dma_func = ide_dma_off_quietly;
 		if (id->field_valid & 4) {
-			if (id->dma_ultra & 0x001F) {
+			if (id->dma_ultra & 0x003F) {
 				/* Force if Capable UltraDMA */
 				dma_func = config_chipset_for_dma(drive, 1);
 				if ((id->field_valid & 2) &&
diff -u --recursive --new-file v2.4.9/linux/drivers/ide/sl82c105.c linux/drivers/ide/sl82c105.c
--- v2.4.9/linux/drivers/ide/sl82c105.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/ide/sl82c105.c	Fri Sep  7 10:45:30 2001
@@ -28,7 +28,6 @@
 
 extern char *ide_xfer_verbose (byte xfer_rate);
 
-#ifdef CONFIG_ARCH_NETWINDER
 /*
  * Convert a PIO mode and cycle time to the required on/off
  * times for the interface.  This has protection against run-away
@@ -272,37 +271,4 @@
 {
 	hwif->tuneproc = tune_sl82c105;
 }
-
-#else
-
-unsigned int pci_init_sl82c105(struct pci_dev *dev, const char *msg)
-{
-	return ide_special_settings(dev, msg);
-}
-
-void dma_init_sl82c105(ide_hwif_t *hwif, unsigned long dma_base)
-{
-	ide_setup_dma(hwif, dma_base, 8);
-}
-
-void __init ide_init_sl82c105(ide_hwif_t *hwif)
-{
-	struct pci_dev *dev = hwif->pci_dev;
-	unsigned short t16;
-	unsigned int t32;
-	pci_read_config_word(dev, PCI_COMMAND, &t16);
-	printk("SL82C105 command word: %x\n",t16);
-        t16 |= PCI_COMMAND_IO;
-        pci_write_config_word(dev, PCI_COMMAND, t16);
-	/* IDE timing */
-	pci_read_config_dword(dev, 0x44, &t32);
-	printk("IDE timing: %08x, resetting to PIO0 timing\n",t32);
-	pci_write_config_dword(dev, 0x44, 0x03e4);
-#ifndef CONFIG_MBX
-	pci_read_config_dword(dev, 0x40, &t32);
-	printk("IDE control/status register: %08x\n",t32);
-	pci_write_config_dword(dev, 0x40, 0x10ff08a1);
-#endif /* CONFIG_MBX */
-}
-#endif
 
diff -u --recursive --new-file v2.4.9/linux/drivers/ide/via82cxxx.c linux/drivers/ide/via82cxxx.c
--- v2.4.9/linux/drivers/ide/via82cxxx.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/ide/via82cxxx.c	Fri Sep  7 09:28:38 2001
@@ -1,5 +1,5 @@
 /*
- * $Id: via82cxxx.c,v 3.23 2001/03/09 09:30:00 vojtech Exp $
+ * $Id: via82cxxx.c,v 3.28 2001/09/01 21:10:00 vojtech Exp $
  *
  *  Copyright (c) 2000-2001 Vojtech Pavlik
  *
@@ -14,17 +14,20 @@
 /*
  * VIA IDE driver for Linux. Supports
  *
- *   vt82c586, vt82c586a, vt82c586b, vt82c596a, vt82c596b,
+ *   vt82c576, vt82c586, vt82c586a, vt82c586b, vt82c596a, vt82c596b,
  *   vt82c686, vt82c686a, vt82c686b, vt8231, vt8233
  *
  * southbridges, which can be found in
  *
- *  VIA Apollo VP, VPX, VPX/97, VP2, VP2/97, VP3, MVP3, MVP4, P6, Pro,
- *  Pro Plus, Pro 133, Pro 133A, ProMedia PM601, ProSavage PM133, PLE133,
- *  Pro 266, KX133, KT133, ProSavage KM133, KT133A, KT266
- *  PC-Chips VXPro, VXPro+, TXPro-III, TXPro-AGP, ViaGra, BXToo, BXTel
- *  AMD 640, 640 AGP, 750 IronGate
- *  ETEQ 6618, 6628, 6638
+ *  VIA Apollo Master, VP, VP2, VP2/97, VP3, VPX, VPX/97, MVP3, MVP4, P6, Pro,
+ *    ProII, ProPlus, Pro133, Pro133+, Pro133A, Pro133A Dual, Pro133T, Pro133Z,
+ *    PLE133, PLE133T, Pro266, Pro266T, ProP4X266, PM601, PM133, PN133, PL133T,
+ *    PX266, PM266, KX133, KT133, KT133A, KLE133, KT266, KX266, KM133, KM133A,
+ *    KL133, KN133, KM266
+ *  PC-Chips VXPro, VXPro+, VXTwo, TXPro-III, TXPro-AGP, AGPPro, ViaGra, BXToo,
+ *    BXTel, BXpert
+ *  AMD 640, 640 AGP, 750 IronGate, 760, 760MP
+ *  ETEQ 6618, 6628, 6629, 6638
  *  Micron Samurai
  *
  * chipsets. Supports
@@ -88,7 +91,6 @@
 #define VIA_BAD_CLK66		0x020	/* 66 MHz clock doesn't work correctly */
 #define VIA_SET_FIFO		0x040	/* Needs to have FIFO split set */
 #define VIA_SET_THRESH		0x080	/* Needs to have FIFO thresholds set */
-#define VIA_BAD_PIO		0x100	/* Always uses 26 PCICLK/xfer regardles of PIO mode */
 
 /*
  * VIA SouthBridge chips.
@@ -101,19 +103,24 @@
 	unsigned char rev_max;
 	unsigned short flags;
 } via_isa_bridges[] = {
-#ifdef VIA_NEW_BRIDGES_TESTED
-	{ "vt8233",	PCI_DEVICE_ID_VIA_8233_0,   0x00, 0x2f, VIA_UDMA_100 },
-	{ "vt8231",	PCI_DEVICE_ID_VIA_8231,     0x00, 0x2f, VIA_UDMA_66 },
+#ifdef FUTURE_BRIDGES
+	{ "vt8237",	PCI_DEVICE_ID_VIA_8237,     0x00, 0x2f, VIA_UDMA_100 },
+	{ "vt8235",	PCI_DEVICE_ID_VIA_8235,     0x00, 0x2f, VIA_UDMA_100 },
+	{ "vt8233c",	PCI_DEVICE_ID_VIA_8233C,    0x30, 0x4f, VIA_UDMA_100 },
 #endif
-	{ "vt82c686b",	PCI_DEVICE_ID_VIA_82C686,   0x40, 0x4f, VIA_UDMA_100 | VIA_BAD_PIO },
+	{ "vt8233",	PCI_DEVICE_ID_VIA_8233_0,   0x00, 0x2f, VIA_UDMA_100 },
+	{ "vt8231",	PCI_DEVICE_ID_VIA_8231,     0x00, 0x2f, VIA_UDMA_100 },
+	{ "vt82c686b",	PCI_DEVICE_ID_VIA_82C686,   0x40, 0x4f, VIA_UDMA_100 },
 	{ "vt82c686a",	PCI_DEVICE_ID_VIA_82C686,   0x10, 0x2f, VIA_UDMA_66 },
 	{ "vt82c686",	PCI_DEVICE_ID_VIA_82C686,   0x00, 0x0f, VIA_UDMA_33 | VIA_BAD_CLK66 },
 	{ "vt82c596b",	PCI_DEVICE_ID_VIA_82C596,   0x10, 0x2f, VIA_UDMA_66 },
 	{ "vt82c596a",	PCI_DEVICE_ID_VIA_82C596,   0x00, 0x0f, VIA_UDMA_33 | VIA_BAD_CLK66 },
-	{ "vt82c586b",	PCI_DEVICE_ID_VIA_82C586_0, 0x40, 0x4f, VIA_UDMA_33 | VIA_SET_FIFO | VIA_BAD_PREQ },
+	{ "vt82c586b",	PCI_DEVICE_ID_VIA_82C586_0, 0x47, 0x4f, VIA_UDMA_33 | VIA_SET_FIFO },
+	{ "vt82c586b",	PCI_DEVICE_ID_VIA_82C586_0, 0x40, 0x46, VIA_UDMA_33 | VIA_SET_FIFO | VIA_BAD_PREQ },
 	{ "vt82c586b",	PCI_DEVICE_ID_VIA_82C586_0, 0x30, 0x3f, VIA_UDMA_33 | VIA_SET_FIFO },
 	{ "vt82c586a",	PCI_DEVICE_ID_VIA_82C586_0, 0x20, 0x2f, VIA_UDMA_33 | VIA_SET_FIFO },
 	{ "vt82c586",	PCI_DEVICE_ID_VIA_82C586_0, 0x00, 0x0f, VIA_UDMA_NONE | VIA_SET_FIFO },
+	{ "vt82c576",	PCI_DEVICE_ID_VIA_82C576,   0x00, 0x2f, VIA_UDMA_NONE | VIA_SET_FIFO },
 	{ NULL }
 };
 
@@ -154,7 +161,7 @@
 
 	via_print("----------VIA BusMastering IDE Configuration----------------");
 
-	via_print("Driver Version:                     3.23");
+	via_print("Driver Version:                     3.27");
 	via_print("South Bridge:                       VIA %s", via_config->name);
 
 	pci_read_config_byte(isa_dev, PCI_REVISION_ID, &t);
@@ -220,8 +227,8 @@
 		switch (via_config->flags & VIA_UDMA) {
 			
 			case VIA_UDMA_100:
-				speed[i] = 2000 / udma[i];
-				cycle[i] = 10 * udma[i];
+				speed[i] = 60 * via_clock / udma[i];
+				cycle[i] = 333 / via_clock * udma[i];
 				break;
 
 			case VIA_UDMA_66:
@@ -301,7 +308,7 @@
 	switch (via_config->flags & VIA_UDMA) {
 		case VIA_UDMA_33:   UT = T;   break;
 		case VIA_UDMA_66:   UT = T/2; break;
-		case VIA_UDMA_100:  UT = 10;  break;
+		case VIA_UDMA_100:  UT = T/3; break;
 		default:	    UT = T;   break;
 	}
 
diff -u --recursive --new-file v2.4.9/linux/drivers/ieee1394/highlevel.c linux/drivers/ieee1394/highlevel.c
--- v2.4.9/linux/drivers/ieee1394/highlevel.c	Wed Jul 25 17:10:20 2001
+++ linux/drivers/ieee1394/highlevel.c	Fri Sep  7 09:28:38 2001
@@ -157,15 +157,16 @@
 #define DEFINE_MULTIPLEXER(Function) \
 void highlevel_##Function(struct hpsb_host *host) \
 { \
-        struct list_head *entry; \
+        struct list_head *entry,*next; \
         void (*funcptr)(struct hpsb_host*); \
         read_lock(&hl_drivers_lock); \
         entry = hl_drivers.next; \
         while (entry != &hl_drivers) { \
+        	next = entry->next; \
                 funcptr = list_entry(entry, struct hpsb_highlevel, hl_list) \
                           ->op->Function; \
                 if (funcptr) funcptr(host); \
-                entry = entry->next; \
+                entry = next; \
         } \
         read_unlock(&hl_drivers_lock); \
 }
diff -u --recursive --new-file v2.4.9/linux/drivers/ieee1394/ieee1394_core.c linux/drivers/ieee1394/ieee1394_core.c
--- v2.4.9/linux/drivers/ieee1394/ieee1394_core.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/ieee1394/ieee1394_core.c	Fri Sep  7 09:28:38 2001
@@ -352,7 +352,7 @@
         }
 
         if (ackcode != ACK_PENDING || !packet->expect_response) {
-                packet->state = complete;
+                packet->state = completed;
                 up(&packet->state_change);
                 up(&packet->state_change);
                 run_task_queue(&packet->complete_tq);
@@ -503,7 +503,7 @@
                 break;
         }
 
-        packet->state = complete;
+        packet->state = completed;
         up(&packet->state_change);
         run_task_queue(&packet->complete_tq);
 }
@@ -720,7 +720,7 @@
 
         list_for_each(lh, &llist) {
                 packet = list_entry(lh, struct hpsb_packet, list);
-                packet->state = complete;
+                packet->state = completed;
                 packet->ack_code = ACKX_ABORTED;
                 up(&packet->state_change);
                 run_task_queue(&packet->complete_tq);
@@ -761,7 +761,7 @@
 
         list_for_each(lh, &expiredlist) {
                 packet = list_entry(lh, struct hpsb_packet, list);
-                packet->state = complete;
+                packet->state = completed;
                 packet->ack_code = ACKX_TIMEOUT;
                 up(&packet->state_change);
                 run_task_queue(&packet->complete_tq);
diff -u --recursive --new-file v2.4.9/linux/drivers/ieee1394/ieee1394_core.h linux/drivers/ieee1394/ieee1394_core.h
--- v2.4.9/linux/drivers/ieee1394/ieee1394_core.h	Mon Aug 27 12:41:41 2001
+++ linux/drivers/ieee1394/ieee1394_core.h	Fri Sep  7 09:28:38 2001
@@ -25,11 +25,11 @@
         /* Okay, this is core internal and a no care for hosts.
          * queued   = queued for sending
          * pending  = sent, waiting for response
-         * complete = processing completed, successful or not
+         * completed = processing completed, successful or not
          * incoming = incoming packet
          */
         enum { 
-                unused, queued, pending, complete, incoming 
+                unused, queued, pending, completed, incoming 
         } __attribute__((packed)) state;
 
         /* These are core internal. */
diff -u --recursive --new-file v2.4.9/linux/drivers/isdn/Config.in linux/drivers/isdn/Config.in
--- v2.4.9/linux/drivers/isdn/Config.in	Mon Aug 27 12:41:41 2001
+++ linux/drivers/isdn/Config.in	Sun Sep  9 10:45:43 2001
@@ -76,8 +76,11 @@
 	 bool '  Am7930' CONFIG_HISAX_AMD7930
       fi
    fi
+   bool '  HiSax debugging' CONFIG_HISAX_DEBUG
+
    dep_tristate 'Sedlbauer PCMCIA cards' CONFIG_HISAX_SEDLBAUER_CS $CONFIG_PCMCIA
    dep_tristate 'ELSA PCMCIA MicroLink cards' CONFIG_HISAX_ELSA_CS $CONFIG_PCMCIA
+   dep_tristate 'ST5481 USB ISDN modem (EXPERIMENTAL)' CONFIG_HISAX_ST5481 $CONFIG_HISAX $CONFIG_USB $CONFIG_EXPERIMENTAL
 fi
 endmenu
 
diff -u --recursive --new-file v2.4.9/linux/drivers/isdn/act2000/act2000_isa.c linux/drivers/isdn/act2000/act2000_isa.c
--- v2.4.9/linux/drivers/isdn/act2000/act2000_isa.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/isdn/act2000/act2000_isa.c	Sun Sep  9 10:43:02 2001
@@ -418,7 +418,7 @@
 int
 act2000_isa_download(act2000_card * card, act2000_ddef * cb)
 {
-        int length;
+        unsigned int length;
         int ret;
         int l;
         int c;
@@ -431,9 +431,8 @@
         if (!act2000_isa_reset(card->port))
                 return -ENXIO;
         act2000_isa_delay(HZ / 2);
-        if ((ret = verify_area(VERIFY_READ, (void *) cb, sizeof(cblock))))
-                return ret;
-        copy_from_user(&cblock, (char *) cb, sizeof(cblock));
+        if(copy_from_user(&cblock, (char *) cb, sizeof(cblock)))
+        	return -EFAULT;
         length = cblock.length;
         p = cblock.buffer;
         if ((ret = verify_area(VERIFY_READ, (void *) p, length)))
diff -u --recursive --new-file v2.4.9/linux/drivers/isdn/eicon/idi.c linux/drivers/isdn/eicon/idi.c
--- v2.4.9/linux/drivers/isdn/eicon/idi.c	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/eicon/idi.c	Sun Sep  9 10:45:43 2001
@@ -431,7 +431,9 @@
     i = this->XCurrent;
     X = PTR_X(a,this);
     while(i<this->XNum && length<270) {
-      clength = MIN((word)(270-length),X[i].PLength-this->XOffset);
+      clength = (word)(270-length);
+      if (clength > X[i].PLength-this->XOffset)
+	      clength = X[i].PLength-this->XOffset;
       a->ram_out_buffer(a,
                         &ReqOut->XBuffer.P[length],
                         PTR_P(a,this,&X[i].P[this->XOffset]),
@@ -837,8 +839,9 @@
         this->ROffset = 0;
         this->RCurrent++;
       }
-      clength = MIN(a->ram_inw(a, &RBuffer->length)-offset,
-                    R[this->RCurrent].PLength-this->ROffset);
+      clength = a->ram_inw(a, &RBuffer->length)-offset;
+      if (clength > R[this->RCurrent].PLength-this->ROffset)
+	      clength = R[this->RCurrent].PLength-this->ROffset;
       if(R[this->RCurrent].P) {
         a->ram_in_buffer(a,
                          &RBuffer->P[offset],
diff -u --recursive --new-file v2.4.9/linux/drivers/isdn/eicon/kprintf.c linux/drivers/isdn/eicon/kprintf.c
--- v2.4.9/linux/drivers/isdn/eicon/kprintf.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/isdn/eicon/kprintf.c	Sun Sep  9 10:45:43 2001
@@ -30,8 +30,6 @@
 #include "eicon.h"
 #include "sys.h"
 #include <stdarg.h>
-#undef MAX
-#undef MIN
 
 #include "divas.h"
 #include "divalog.h"
diff -u --recursive --new-file v2.4.9/linux/drivers/isdn/eicon/pc.h linux/drivers/isdn/eicon/pc.h
--- v2.4.9/linux/drivers/isdn/eicon/pc.h	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/eicon/pc.h	Sun Sep  9 10:45:43 2001
@@ -29,12 +29,6 @@
 #define byte unsigned char
 #define word unsigned short
 #define dword unsigned long
-#if !defined(MIN)
-#define MIN(a,b) ((a)>(b) ? (b) : (a))
-#endif
-#if !defined(MAX)
-#define MAX(a,b) ((a)>(b) ? (a) : (b))
-#endif
 
 /*------------------------------------------------------------------*/
 /* buffer definition                                                */
diff -u --recursive --new-file v2.4.9/linux/drivers/isdn/eicon/sys.h linux/drivers/isdn/eicon/sys.h
--- v2.4.9/linux/drivers/isdn/eicon/sys.h	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/eicon/sys.h	Sun Sep  9 10:45:43 2001
@@ -54,15 +54,6 @@
 #define NULL    ((void *) 0)
 #endif
 
-/* MIN and MAX */
-
-#if !defined(MIN)
-#define MIN(a,b) ((a)>(b) ? (b) : (a))
-#endif
-#if !defined(MAX)
-#define MAX(a,b) ((a)>(b) ? (a) : (b))
-#endif
-
 /* Return the dimension of an array */
 
 #if !defined(DIM)
@@ -85,6 +76,8 @@
 /* void HwAssert(char *file, int line, char *condition); */
 
 #include <linux/kernel.h>
+#include <linux/string.h>
+
 #define _PRINTK printk
 
 #define _PRINTF	DivasPrintf
diff -u --recursive --new-file v2.4.9/linux/drivers/isdn/hisax/Makefile linux/drivers/isdn/hisax/Makefile
--- v2.4.9/linux/drivers/isdn/hisax/Makefile	Sun Aug 12 13:27:59 2001
+++ linux/drivers/isdn/hisax/Makefile	Sun Sep  9 10:45:43 2001
@@ -2,20 +2,21 @@
 
 # The target object and module list name.
 
-O_TARGET	:= vmlinux-obj.o
+O_TARGET	  := vmlinux-obj.o
 
 # Objects that export symbols.
 
-export-objs	:= config.o
+export-objs	  := config.o fsm.o
 
 # Multipart objects.
 
-list-multi	:= hisax.o
-hisax-objs	:= config.o isdnl1.o tei.o isdnl2.o isdnl3.o \
-		   lmgr.o q931.o callc.o fsm.o cert.o
+list-multi	  := hisax.o hisax_st5481.o
+hisax-objs	  := config.o isdnl1.o tei.o isdnl2.o isdnl3.o \
+		     lmgr.o q931.o callc.o fsm.o cert.o
+hisax_st5481-objs := st5481_init.o st5481_usb.o st5481_d.o st5481_b.o \
+		     st5481_hdlc.o
 
 # Optional parts of multipart objects.
-
 hisax-objs-$(CONFIG_HISAX_EURO) += l3dss1.o
 hisax-objs-$(CONFIG_HISAX_NI1) += l3ni1.o
 hisax-objs-$(CONFIG_HISAX_1TR6) += l3_1tr6.o
@@ -27,7 +28,6 @@
 hisax-objs-$(CONFIG_HISAX_AVM_A1) += avm_a1.o isac.o arcofi.o hscx.o
 hisax-objs-$(CONFIG_HISAX_AVM_A1_PCMCIA) += avm_a1p.o isac.o arcofi.o hscx.o
 hisax-objs-$(CONFIG_HISAX_FRITZPCI) += avm_pci.o isac.o arcofi.o
-hisax-objs-$(CONFIG_HISAX_AVM_A1) += avm_a1.o isac.o arcofi.o hscx.o
 hisax-objs-$(CONFIG_HISAX_ELSA) += elsa.o isac.o arcofi.o hscx.o
 hisax-objs-$(CONFIG_HISAX_IX1MICROR2) += ix1_micro.o isac.o arcofi.o hscx.o
 hisax-objs-$(CONFIG_HISAX_DIEHLDIVA) += diva.o isac.o arcofi.o hscx.o
@@ -54,9 +54,10 @@
 
 # Each configuration option enables a list of files.
 
-obj-$(CONFIG_ISDN_DRV_HISAX)	+= hisax.o
+obj-$(CONFIG_ISDN_DRV_HISAX)		+= hisax.o
 obj-$(CONFIG_HISAX_SEDLBAUER_CS)	+= sedlbauer_cs.o
-obj-$(CONFIG_HISAX_ELSA_CS)	+= elsa_cs.o
+obj-$(CONFIG_HISAX_ELSA_CS)		+= elsa_cs.o
+obj-$(CONFIG_HISAX_ST5481)		+= hisax_st5481.o
 
 CERT := $(shell md5sum -c md5sums.asc >> /dev/null;echo $$?)
 CFLAGS_cert.o := -DCERTIFICATION=$(CERT)
@@ -67,3 +68,6 @@
 
 hisax.o: $(hisax-objs)
 	$(LD) -r -o $@ $(hisax-objs)
+
+hisax_st5481.o: $(hisax_st5481-objs)
+	$(LD) -r -o $@ $(hisax_st5481-objs)
diff -u --recursive --new-file v2.4.9/linux/drivers/isdn/hisax/callc.c linux/drivers/isdn/hisax/callc.c
--- v2.4.9/linux/drivers/isdn/hisax/callc.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/hisax/callc.c	Sun Sep  9 10:45:43 2001
@@ -1,4 +1,4 @@
-/* $Id: callc.c,v 2.51.6.4 2001/06/09 15:14:17 kai Exp $
+/* $Id: callc.c,v 2.51.6.5 2001/08/23 19:44:23 kai Exp $
  *
  * Author       Karsten Keil (keil@isdn4linux.de)
  *              based on the teles driver from Jan den Ouden
@@ -20,12 +20,12 @@
 #define MOD_USE_COUNT ( GET_USE_COUNT (&__this_module))
 #endif	/* MODULE */
 
-const char *lli_revision = "$Revision: 2.51.6.4 $";
+const char *lli_revision = "$Revision: 2.51.6.5 $";
 
 extern struct IsdnCard cards[];
 extern int nrcards;
-extern void HiSax_mod_dec_use_count(void);
-extern void HiSax_mod_inc_use_count(void);
+extern void HiSax_mod_dec_use_count(struct IsdnCardState *cs);
+extern void HiSax_mod_inc_use_count(struct IsdnCardState *cs);
 
 static int init_b_st(struct Channel *chanp, int incoming);
 static void release_b_st(struct Channel *chanp);
@@ -1584,7 +1584,7 @@
 			}
 			break;
 		case (ISDN_CMD_LOCK):
-			HiSax_mod_inc_use_count();
+			HiSax_mod_inc_use_count(csta);
 #ifdef MODULE
 			if (csta->channel[0].debug & 0x400)
 				HiSax_putstatus(csta, "   LOCK ", "modcnt %lx",
@@ -1592,7 +1592,7 @@
 #endif				/* MODULE */
 			break;
 		case (ISDN_CMD_UNLOCK):
-			HiSax_mod_dec_use_count();
+			HiSax_mod_dec_use_count(csta);
 #ifdef MODULE
 			if (csta->channel[0].debug & 0x400)
 				HiSax_putstatus(csta, " UNLOCK ", "modcnt %lx",
@@ -1624,11 +1624,11 @@
 					break;
 				case (3):
 					for (i = 0; i < *(unsigned int *) ic->parm.num; i++)
-						HiSax_mod_dec_use_count();
+						HiSax_mod_dec_use_count(NULL);
 					break;
 				case (4):
 					for (i = 0; i < *(unsigned int *) ic->parm.num; i++)
-						HiSax_mod_inc_use_count();
+						HiSax_mod_inc_use_count(NULL);
 					break;
 				case (5):	/* set card in leased mode */
 					num = *(unsigned int *) ic->parm.num;
@@ -1698,7 +1698,7 @@
 #ifdef MODULE
 				case (55):
 					MOD_USE_COUNT = 0;
-					HiSax_mod_inc_use_count();
+					HiSax_mod_inc_use_count(NULL);
 					break;
 #endif				/* MODULE */
 				case (11):
@@ -1810,6 +1810,7 @@
 		cli();
 		nskb = skb_clone(skb, GFP_ATOMIC);
 		if (nskb) {
+			nskb->truesize = nskb->len;
 			if (!ack)
 				nskb->pkt_type = PACKET_NOACK;
 			if (chanp->l2_active_protocol == ISDN_PROTO_L2_X75I)
diff -u --recursive --new-file v2.4.9/linux/drivers/isdn/hisax/config.c linux/drivers/isdn/hisax/config.c
--- v2.4.9/linux/drivers/isdn/hisax/config.c	Wed Jul 25 17:10:20 2001
+++ linux/drivers/isdn/hisax/config.c	Sun Sep  9 10:45:43 2001
@@ -1,4 +1,4 @@
-/* $Id: config.c,v 2.57.6.16 2001/07/13 09:01:00 kai Exp $
+/* $Id: config.c,v 2.57.6.18 2001/08/27 22:19:05 kai Exp $
  *
  * Author       Karsten Keil (keil@isdn4linux.de)
  *              based on the teles driver from Jan den Ouden
@@ -313,7 +313,8 @@
 #define DEFAULT_PROTO_NAME "UNKNOWN"
 #endif
 #ifndef DEFAULT_CARD
-#error "HiSax: No cards configured"
+#define DEFAULT_CARD 0
+#define DEFAULT_CFG {0,0,0,0}
 #endif
 
 int hisax_init_pcmcia(void *, int *, struct IsdnCard *);
@@ -423,16 +424,6 @@
 	certification_check(1);
 }
 
-void HiSax_mod_dec_use_count(void)
-{
-	MOD_DEC_USE_COUNT;
-}
-
-void HiSax_mod_inc_use_count(void)
-{
-	MOD_INC_USE_COUNT;
-}
-
 #ifndef MODULE
 #define MAX_ARG	(HISAX_MAX_CARDS*5)
 static int __init HiSax_setup(char *line)
@@ -840,8 +831,9 @@
 	if (csta->DC_Close != NULL) {
 		csta->DC_Close(csta);
 	}
-	csta->cardmsg(csta, CARD_RELEASE, NULL);
-	if (csta->dbusytimer.function != NULL)
+	if (csta->cardmsg)
+		csta->cardmsg(csta, CARD_RELEASE, NULL);
+	if (csta->dbusytimer.function != NULL) // FIXME?
 		del_timer(&csta->dbusytimer);
 	ll_unload(csta);
 }
@@ -1137,6 +1129,9 @@
 		ret = setup_netjet_u(card);
 		break;
 #endif
+	case ISDN_CTYPE_DYNAMIC:
+		ret = 2;
+		break;
 	default:
 		printk(KERN_WARNING
 		       "HiSax: Support for %s Card not selected\n",
@@ -1165,7 +1160,17 @@
 
 	init_bcstate(cs, 0);
 	init_bcstate(cs, 1);
-	ret = init_card(cs);
+
+	/* init_card only handles interrupts which are not */
+	/* used here for the loadable driver */
+	switch (card->typ) {
+	case ISDN_CTYPE_DYNAMIC:
+		ret = 0;
+		break;
+	default:
+		ret = init_card(cs);
+		break;
+	}
 	if (ret) {
 		closecard(cardnr);
 		ret = 0;
@@ -1343,6 +1348,8 @@
 #ifdef MODULE
 	if (!type[0]) {
 		/* We 'll register drivers later, but init basic functions */
+		for (i = 0; i < HISAX_MAX_CARDS; i++)
+			cards[i].typ = 0;
 		return 0;
 	}
 #ifdef CONFIG_HISAX_ELSA
@@ -1572,7 +1579,6 @@
 {
 #ifdef MODULE
 	int i;
-	int nzproto = 0;
 
 	nrcards = 0;
 	/* Initialize all structs, even though we only accept
@@ -1584,14 +1590,12 @@
 		cards[i].typ = type[i];
 		if (protocol[i]) {
 			cards[i].protocol = protocol[i];
-			nzproto++;
 		}
 	}
 	cards[0].para[0] = pcm_irq;
 	cards[0].para[1] = (int) pcm_iob;
 	cards[0].protocol = prot;
 	cards[0].typ = ISDN_CTYPE_HFC_SP_PCMCIA;
-	nzproto = 1;
 
 	if (!HiSax_id)
 		HiSax_id = HiSaxID;
@@ -1615,7 +1619,6 @@
 {
 #ifdef MODULE
 	int i;
-	int nzproto = 0;
 
 	nrcards = 0;
 	/* Initialize all structs, even though we only accept
@@ -1627,14 +1630,12 @@
 		cards[i].typ = type[i];
 		if (protocol[i]) {
 			cards[i].protocol = protocol[i];
-			nzproto++;
 		}
 	}
 	cards[0].para[0] = pcm_irq;
 	cards[0].para[1] = (int) pcm_iob;
 	cards[0].protocol = prot;
 	cards[0].typ = ISDN_CTYPE_SEDLBAUER_PCMCIA;
-	nzproto = 1;
 
 	if (!HiSax_id)
 		HiSax_id = HiSaxID;
@@ -1658,7 +1659,6 @@
 {
 #ifdef MODULE
 	int i;
-	int nzproto = 0;
 
 	nrcards = 0;
 	/* Initialize all structs, even though we only accept
@@ -1670,14 +1670,12 @@
 		cards[i].typ = type[i];
 		if (protocol[i]) {
 			cards[i].protocol = protocol[i];
-			nzproto++;
 		}
 	}
 	cards[0].para[0] = pcm_irq;
 	cards[0].para[1] = (int) pcm_iob;
 	cards[0].protocol = prot;
 	cards[0].typ = ISDN_CTYPE_A1_PCMCIA;
-	nzproto = 1;
 
 	if (!HiSax_id)
 		HiSax_id = HiSaxID;
@@ -1715,11 +1713,362 @@
 	return ret;
 }
 
+#include "hisax_if.h"
+
+EXPORT_SYMBOL(hisax_register);
+EXPORT_SYMBOL(hisax_unregister);
+
+static void hisax_d_l1l2(struct hisax_if *ifc, int pr, void *arg);
+static void hisax_b_l1l2(struct hisax_if *ifc, int pr, void *arg);
+static void hisax_d_l2l1(struct PStack *st, int pr, void *arg);
+static void hisax_b_l2l1(struct PStack *st, int pr, void *arg);
+static int hisax_cardmsg(struct IsdnCardState *cs, int mt, void *arg);
+static int hisax_bc_setstack(struct PStack *st, struct BCState *bcs);
+static void hisax_bc_close(struct BCState *bcs);
+static void hisax_bh(struct IsdnCardState *cs);
+static void EChannel_proc_rcv(struct hisax_d_if *d_if);
+
+int hisax_register(struct hisax_d_if *hisax_d_if, struct hisax_b_if *b_if[],
+		   char *name, int protocol)
+{
+	int i, retval;
+	char id[20];
+	struct IsdnCardState *cs;
+
+	for (i = 0; i < HISAX_MAX_CARDS; i++) {
+		if (!cards[i].typ)
+			break;
+	}
+
+	if (i >= HISAX_MAX_CARDS)
+		return -EBUSY;
+
+	cards[i].typ = ISDN_CTYPE_DYNAMIC;
+	cards[i].protocol = protocol;
+	sprintf(id, "%s%d", name, i);
+	nrcards++;
+	retval = checkcard(i, id, 0);
+	if (retval == 0) { // yuck
+		cards[i].typ = 0;
+		nrcards--;
+		return retval;
+	}
+	cs = cards[i].cs;
+	hisax_d_if->cs = cs;
+	cs->hw.hisax_d_if = hisax_d_if;
+	cs->cardmsg = hisax_cardmsg;
+	cs->tqueue.routine = (void *) (void *) hisax_bh;
+	cs->channel[0].d_st->l2.l2l1 = hisax_d_l2l1;
+	for (i = 0; i < 2; i++) {
+		cs->bcs[i].BC_SetStack = hisax_bc_setstack;
+		cs->bcs[i].BC_Close = hisax_bc_close;
+
+		b_if[i]->ifc.l1l2 = hisax_b_l1l2;
+
+		hisax_d_if->b_if[i] = b_if[i];
+	}
+	hisax_d_if->ifc.l1l2 = hisax_d_l1l2;
+	skb_queue_head_init(&hisax_d_if->erq);
+	clear_bit(0, &hisax_d_if->ph_state);
+	
+	return 0;
+}
+
+void hisax_unregister(struct hisax_d_if *hisax_d_if)
+{
+	cards[hisax_d_if->cs->cardnr].typ = 0;
+	HiSax_closecard(hisax_d_if->cs->cardnr);
+	skb_queue_purge(&hisax_d_if->erq);
+}
+
+#include "isdnl1.h"
+
+static void hisax_sched_event(struct IsdnCardState *cs, int event)
+{
+	cs->event |= 1 << event;
+	queue_task(&cs->tqueue, &tq_immediate);
+	mark_bh(IMMEDIATE_BH);
+}
+
+static void hisax_bh(struct IsdnCardState *cs)
+{
+	struct PStack *st;
+	int pr;
+
+	if (test_and_clear_bit(D_RCVBUFREADY, &cs->event))
+		DChannel_proc_rcv(cs);
+	if (test_and_clear_bit(E_RCVBUFREADY, &cs->event))
+		EChannel_proc_rcv(cs->hw.hisax_d_if);
+	if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) {
+		if (test_bit(0, &cs->hw.hisax_d_if->ph_state))
+			pr = PH_ACTIVATE | INDICATION;
+		else
+			pr = PH_DEACTIVATE | INDICATION;
+		for (st = cs->stlist; st; st = st->next)
+			st->l1.l1l2(st, pr, NULL);
+		
+	}
+}
+
+static void hisax_b_sched_event(struct BCState *bcs, int event)
+{
+	bcs->event |= 1 << event;
+	queue_task(&bcs->tqueue, &tq_immediate);
+	mark_bh(IMMEDIATE_BH);
+}
+
+static inline void D_L2L1(struct hisax_d_if *d_if, int pr, void *arg)
+{
+	struct hisax_if *ifc = (struct hisax_if *) d_if;
+	ifc->l2l1(ifc, pr, arg);
+}
+
+static inline void B_L2L1(struct hisax_b_if *b_if, int pr, void *arg)
+{
+	struct hisax_if *ifc = (struct hisax_if *) b_if;
+	ifc->l2l1(ifc, pr, arg);
+}
+
+static void hisax_d_l1l2(struct hisax_if *ifc, int pr, void *arg)
+{
+	struct hisax_d_if *d_if = (struct hisax_d_if *) ifc;
+	struct IsdnCardState *cs = d_if->cs;
+	struct PStack *st;
+	struct sk_buff *skb;
+
+	switch (pr) {
+	case PH_ACTIVATE | INDICATION:
+		set_bit(0, &d_if->ph_state);
+		hisax_sched_event(cs, D_L1STATECHANGE);
+		break;
+	case PH_DEACTIVATE | INDICATION:
+		clear_bit(0, &d_if->ph_state);
+		hisax_sched_event(cs, D_L1STATECHANGE);
+		break;
+	case PH_DATA | INDICATION:
+		skb_queue_tail(&cs->rq, arg);
+		hisax_sched_event(cs, D_RCVBUFREADY);
+		break;
+	case PH_DATA | CONFIRM:
+		skb = skb_dequeue(&cs->sq);
+		if (skb) {
+			D_L2L1(d_if, PH_DATA | REQUEST, skb);
+			break;
+		}
+		clear_bit(FLG_L1_DBUSY, &cs->HW_Flags);
+		for (st = cs->stlist; st; st = st->next) {
+			if (test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags)) {
+				st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
+				break;
+			}
+		}
+		break;
+	case PH_DATA_E | INDICATION:
+		skb_queue_tail(&d_if->erq, arg);
+		hisax_sched_event(cs, E_RCVBUFREADY);
+		break;
+	default:
+		printk("pr %#x\n", pr);
+		break;
+	}
+}
+
+static void hisax_b_l1l2(struct hisax_if *ifc, int pr, void *arg)
+{
+	struct hisax_b_if *b_if = (struct hisax_b_if *) ifc;
+	struct BCState *bcs = b_if->bcs;
+	struct PStack *st = bcs->st;
+	struct sk_buff *skb;
+
+	// FIXME use isdnl1?
+	switch (pr) {
+	case PH_ACTIVATE | INDICATION:
+		st->l1.l1l2(st, pr, NULL);
+		break;
+	case PH_DEACTIVATE | INDICATION:
+		st->l1.l1l2(st, pr, NULL);
+		bcs->hw.b_if = NULL;
+		break;
+	case PH_DATA | INDICATION:
+		skb_queue_tail(&bcs->rqueue, arg);
+		hisax_b_sched_event(bcs, B_RCVBUFREADY);
+		break;
+	case PH_DATA | CONFIRM:
+		bcs->tx_cnt -= (int) arg;
+		if (bcs->st->lli.l1writewakeup)
+			bcs->st->lli.l1writewakeup(bcs->st, (int) arg);
+		skb = skb_dequeue(&bcs->squeue);
+		if (skb) {
+			B_L2L1(b_if, PH_DATA | REQUEST, skb);
+			break;
+		}
+		clear_bit(BC_FLG_BUSY, &bcs->Flag);
+		if (test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags)) {
+			st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
+		}
+		break;
+	default:
+		printk("hisax_b_l1l2 pr %#x\n", pr);
+		break;
+	}
+}
+
+static void hisax_d_l2l1(struct PStack *st, int pr, void *arg)
+{
+	struct IsdnCardState *cs = st->l1.hardware;
+	struct hisax_d_if *hisax_d_if = cs->hw.hisax_d_if;
+	struct sk_buff *skb = arg;
+
+	switch (pr) {
+	case PH_DATA | REQUEST:
+	case PH_PULL | INDICATION:
+		if (cs->debug & DEB_DLOG_HEX)
+			LogFrame(cs, skb->data, skb->len);
+		if (cs->debug & DEB_DLOG_VERBOSE)
+			dlogframe(cs, skb, 0);
+		Logl2Frame(cs, skb, "PH_DATA_REQ", 0);
+		// FIXME lock?
+		if (!test_and_set_bit(FLG_L1_DBUSY, &cs->HW_Flags))
+			D_L2L1(hisax_d_if, PH_DATA | REQUEST, skb);
+		else
+			skb_queue_tail(&cs->sq, skb);
+		break;
+	case PH_PULL | REQUEST:
+		if (!test_bit(FLG_L1_DBUSY, &cs->HW_Flags))
+			st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
+		else
+			set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+		break;
+	default:
+		D_L2L1(hisax_d_if, pr, arg);
+		break;
+	}
+}
+
+static int hisax_cardmsg(struct IsdnCardState *cs, int mt, void *arg)
+{
+	return 0;
+}
+
+static void hisax_b_l2l1(struct PStack *st, int pr, void *arg)
+{
+	struct BCState *bcs = st->l1.bcs;
+	struct hisax_b_if *b_if = bcs->hw.b_if;
+
+	switch (pr) {
+	case PH_ACTIVATE | REQUEST:
+		B_L2L1(b_if, pr, (void *) st->l1.mode);
+		break;
+	case PH_DATA | REQUEST:
+	case PH_PULL | INDICATION:
+		// FIXME lock?
+		if (!test_and_set_bit(BC_FLG_BUSY, &bcs->Flag)) {
+			B_L2L1(b_if, PH_DATA | REQUEST, arg);
+		} else {
+			skb_queue_tail(&bcs->squeue, arg);
+		}
+		break;
+	case PH_PULL | REQUEST:
+		if (!test_bit(BC_FLG_BUSY, &bcs->Flag))
+			st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
+		else
+			set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+		break;
+	default:
+		B_L2L1(b_if, pr, arg);
+		break;
+	}
+}
+
+static int hisax_bc_setstack(struct PStack *st, struct BCState *bcs)
+{
+	struct IsdnCardState *cs = st->l1.hardware;
+	struct hisax_d_if *hisax_d_if = cs->hw.hisax_d_if;
+
+	bcs->channel = st->l1.bc;
+
+	bcs->hw.b_if = hisax_d_if->b_if[st->l1.bc];
+	hisax_d_if->b_if[st->l1.bc]->bcs = bcs;
+
+	st->l1.bcs = bcs;
+	st->l2.l2l1 = hisax_b_l2l1;
+	setstack_manager(st);
+	bcs->st = st;
+	setstack_l1_B(st);
+	skb_queue_head_init(&bcs->rqueue);
+	skb_queue_head_init(&bcs->squeue);
+	return 0;
+}
+
+static void hisax_bc_close(struct BCState *bcs)
+{
+	struct hisax_b_if *b_if = bcs->hw.b_if;
+
+	if (b_if)
+		B_L2L1(b_if, PH_DEACTIVATE | REQUEST, NULL);
+}
+
+static void EChannel_proc_rcv(struct hisax_d_if *d_if)
+{
+	struct IsdnCardState *cs = d_if->cs;
+	u_char *ptr;
+	struct sk_buff *skb;
+
+	while ((skb = skb_dequeue(&d_if->erq)) != NULL) {
+		if (cs->debug & DEB_DLOG_HEX) {
+			ptr = cs->dlog;
+			if ((skb->len) < MAX_DLOG_SPACE / 3 - 10) {
+				*ptr++ = 'E';
+				*ptr++ = 'C';
+				*ptr++ = 'H';
+				*ptr++ = 'O';
+				*ptr++ = ':';
+				ptr += QuickHex(ptr, skb->data, skb->len);
+				ptr--;
+				*ptr++ = '\n';
+				*ptr = 0;
+				HiSax_putstatus(cs, NULL, cs->dlog);
+			} else
+				HiSax_putstatus(cs, "LogEcho: ",
+						"warning Frame too big (%d)",
+						skb->len);
+		}
+		dev_kfree_skb_any(skb);
+	}
+}
+
+void HiSax_mod_dec_use_count(struct IsdnCardState *cs)
+{
+	struct module *mod;
+
+	if (cs && cs->cardmsg == hisax_cardmsg) {
+		mod = cs->hw.hisax_d_if->owner;
+		if (mod)
+			__MOD_DEC_USE_COUNT(mod);
+	} else {
+		MOD_DEC_USE_COUNT;
+	}
+}
+
+void HiSax_mod_inc_use_count(struct IsdnCardState *cs)
+{
+	struct module *mod;
+
+	if (cs && cs->cardmsg == hisax_cardmsg) {
+		mod = cs->hw.hisax_d_if->owner;
+		if (mod)
+		// hope we do win the race...
+			try_inc_mod_count(mod);
+	} else {
+		MOD_INC_USE_COUNT;
+	}
+}
+
 #include <linux/pci.h>
 
 static struct pci_device_id hisax_pci_tbl[] __initdata = {
 #ifdef CONFIG_HISAX_FRITZPCI
-	{PCI_VENDOR_ID_AVM,      PCI_DEVICE_ID_AVM_A1,          PCI_ANY_ID, PCI_ANY_ID},
+	{PCI_VENDOR_ID_AVM,      PCI_DEVICE_ID_AVM_A1,           PCI_ANY_ID, PCI_ANY_ID},
 #endif
 #ifdef CONFIG_HISAX_DIEHLDIVA
 	{PCI_VENDOR_ID_EICON,    PCI_DEVICE_ID_EICON_DIVA20,     PCI_ANY_ID, PCI_ANY_ID},
diff -u --recursive --new-file v2.4.9/linux/drivers/isdn/hisax/elsa_ser.c linux/drivers/isdn/hisax/elsa_ser.c
--- v2.4.9/linux/drivers/isdn/hisax/elsa_ser.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/hisax/elsa_ser.c	Sun Sep  9 10:45:43 2001
@@ -1,4 +1,4 @@
-/* $Id: elsa_ser.c,v 2.10.6.2 2001/06/09 15:14:17 kai Exp $
+/* $Id: elsa_ser.c,v 2.10.6.3 2001/08/17 12:34:26 kai Exp $
  *
  * stuff for the serial modem on ELSA cards
  *
@@ -14,10 +14,6 @@
 #define RS_ISR_PASS_LIMIT 256
 #define BASE_BAUD ( 1843200 / 16 )
 
-#ifndef MIN
-#define MIN(a,b)	((a) < (b) ? (a) : (b))
-#endif
-
 //#define SERIAL_DEBUG_OPEN 1
 //#define SERIAL_DEBUG_INTR 1
 //#define SERIAL_DEBUG_FLOW 1
@@ -257,7 +253,7 @@
 write_modem(struct BCState *bcs) {
 	int ret=0;
 	struct IsdnCardState *cs = bcs->cs;
-	int count, len, fp, buflen;
+	int count, len, fp;
 	long flags;
 	
 	if (!bcs->tx_skb)
@@ -266,12 +262,14 @@
 		return 0;
 	save_flags(flags);
 	cli();
-	buflen = MAX_MODEM_BUF - cs->hw.elsa.transcnt;
-	len = MIN(buflen, bcs->tx_skb->len);		
+	len = bcs->tx_skb->len;
+	if (len > MAX_MODEM_BUF - cs->hw.elsa.transcnt)
+		len = MAX_MODEM_BUF - cs->hw.elsa.transcnt;
 	fp = cs->hw.elsa.transcnt + cs->hw.elsa.transp;
 	fp &= (MAX_MODEM_BUF -1);
-	count = MIN(len, MAX_MODEM_BUF - fp);
-	if (count < len) {
+	count = len;
+	if (count > MAX_MODEM_BUF - fp) {
+		count = MAX_MODEM_BUF - fp;
 		memcpy(cs->hw.elsa.transbuf + fp, bcs->tx_skb->data, count);
 		skb_pull(bcs->tx_skb, count);
 		cs->hw.elsa.transcnt += count;
@@ -472,8 +470,9 @@
 	}
 	fp = cs->hw.elsa.transcnt + cs->hw.elsa.transp;
 	fp &= (MAX_MODEM_BUF -1);
-	count = MIN(len, MAX_MODEM_BUF - fp);
-	if (count < len) {
+	count = len;
+	if (count > MAX_MODEM_BUF - fp) {
+		count = MAX_MODEM_BUF - fp;
 		memcpy(cs->hw.elsa.transbuf + fp, msg, count);
 		cs->hw.elsa.transcnt += count;
 		msg += count;
diff -u --recursive --new-file v2.4.9/linux/drivers/isdn/hisax/fsm.c linux/drivers/isdn/hisax/fsm.c
--- v2.4.9/linux/drivers/isdn/hisax/fsm.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/hisax/fsm.c	Sun Sep  9 10:45:43 2001
@@ -1,4 +1,4 @@
-/* $Id: fsm.c,v 1.14.6.2 2001/05/26 15:19:57 kai Exp $
+/* $Id: fsm.c,v 1.14.6.3 2001/08/23 19:44:23 kai Exp $
  *
  * Author       Karsten Keil (keil@isdn4linux.de)
  *              based on the teles driver from Jan den Ouden
@@ -14,6 +14,14 @@
 #include "hisax.h"
 
 #define FSM_TIMER_DEBUG 0
+
+EXPORT_SYMBOL(FsmNew);
+EXPORT_SYMBOL(FsmFree);
+EXPORT_SYMBOL(FsmEvent);
+EXPORT_SYMBOL(FsmChangeState);
+EXPORT_SYMBOL(FsmInitTimer);
+EXPORT_SYMBOL(FsmDelTimer);
+EXPORT_SYMBOL(FsmRestartTimer);
 
 int __init
 FsmNew(struct Fsm *fsm, struct FsmNode *fnlist, int fncount)
diff -u --recursive --new-file v2.4.9/linux/drivers/isdn/hisax/fsm.h linux/drivers/isdn/hisax/fsm.h
--- v2.4.9/linux/drivers/isdn/hisax/fsm.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/isdn/hisax/fsm.h	Sun Sep  9 10:45:43 2001
@@ -0,0 +1,48 @@
+#ifndef __FSM_H__
+#define __FSM_H__
+
+#include <linux/timer.h>
+
+struct FsmInst;
+
+typedef void (* FSMFNPTR)(struct FsmInst *, int, void *);
+
+struct Fsm {
+	FSMFNPTR *jumpmatrix;
+	int state_count, event_count;
+	char **strEvent, **strState;
+};
+
+struct FsmInst {
+	struct Fsm *fsm;
+	int state;
+	int debug;
+	void *userdata;
+	int userint;
+	void (*printdebug) (struct FsmInst *, char *, ...);
+};
+
+struct FsmNode {
+	int state, event;
+	void (*routine) (struct FsmInst *, int, void *);
+};
+
+struct FsmTimer {
+	struct FsmInst *fi;
+	struct timer_list tl;
+	int event;
+	void *arg;
+};
+
+int FsmNew(struct Fsm *fsm, struct FsmNode *fnlist, int fncount);
+void FsmFree(struct Fsm *fsm);
+int FsmEvent(struct FsmInst *fi, int event, void *arg);
+void FsmChangeState(struct FsmInst *fi, int newstate);
+void FsmInitTimer(struct FsmInst *fi, struct FsmTimer *ft);
+int FsmAddTimer(struct FsmTimer *ft, int millisec, int event,
+		void *arg, int where);
+void FsmRestartTimer(struct FsmTimer *ft, int millisec, int event,
+		     void *arg, int where);
+void FsmDelTimer(struct FsmTimer *ft, int where);
+
+#endif
diff -u --recursive --new-file v2.4.9/linux/drivers/isdn/hisax/hisax.h linux/drivers/isdn/hisax/hisax.h
--- v2.4.9/linux/drivers/isdn/hisax/hisax.h	Wed Jul 25 17:10:20 2001
+++ linux/drivers/isdn/hisax/hisax.h	Sun Sep  9 10:45:43 2001
@@ -1,4 +1,4 @@
-/* $Id: hisax.h,v 2.52.6.7 2001/07/18 16:02:15 kai Exp $
+/* $Id: hisax.h,v 2.52.6.8 2001/08/23 19:44:23 kai Exp $
  *
  *   Basic declarations, defines and prototypes
  *
@@ -455,7 +455,6 @@
 	struct tq_struct tq_xmt;
 };
 
-
 #define BC_FLG_INIT	1
 #define BC_FLG_ACTIV	2
 #define BC_FLG_BUSY	3
@@ -512,6 +511,7 @@
 		struct tiger_hw tiger;
 		struct amd7930_hw  amd7930;
 		struct w6692B_hw w6692;
+		struct hisax_b_if *b_if;
 	} hw;
 };
 
@@ -897,6 +897,7 @@
 		struct bkm_hw ax;
 		struct gazel_hw gazel;
 		struct w6692_hw w6692;
+		struct hisax_d_if *hisax_d_if;
 	} hw;
 	int myid;
 	isdn_if iif;
@@ -991,7 +992,8 @@
 #define  ISDN_CTYPE_HFC_SX      37
 #define  ISDN_CTYPE_NETJET_U	38
 #define  ISDN_CTYPE_HFC_SP_PCMCIA      39
-#define  ISDN_CTYPE_COUNT	39
+#define  ISDN_CTYPE_DYNAMIC     40
+#define  ISDN_CTYPE_COUNT	40
 
 
 #ifdef ISDN_CHIP_ISAC
diff -u --recursive --new-file v2.4.9/linux/drivers/isdn/hisax/hisax_debug.h linux/drivers/isdn/hisax/hisax_debug.h
--- v2.4.9/linux/drivers/isdn/hisax/hisax_debug.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/isdn/hisax/hisax_debug.h	Sun Sep  9 10:45:43 2001
@@ -0,0 +1,80 @@
+/*
+ * Common debugging macros for use with the hisax driver
+ *
+ * Author       Frode Isaksen
+ * Copyright    2001 by Frode Isaksen      <fisaksen@bewan.com>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ */
+
+/* 
+ * How to use:
+ * 
+ * Before including this file, you need to
+ *   #define __debug_variable my_debug
+ * where my_debug is a variable in your code which
+ * determines the debug bitmask.
+ *
+ * If CONFIG_HISAX_DEBUG is not set, all macros evaluate to nothing
+ */
+
+#ifndef __HISAX_DEBUG_H__
+#define __HISAX_DEBUG_H__
+
+#ifdef CONFIG_HISAX_DEBUG
+
+#define DBG(level, format, arg...) do { \
+if (level & __debug_variable) \
+printk(KERN_DEBUG __FUNCTION__ ": " format "\n" , ## arg); \
+} while (0)
+
+#define DBG_PACKET(level,data,count) \
+  if (level & __debug_variable) dump_packet(__FUNCTION__,data,count)
+
+#define DBG_SKB(level,skb) \
+  if ((level & __debug_variable) && skb) dump_packet(__FUNCTION__,skb->data,skb->len)
+
+
+static void __attribute__((unused))
+dump_packet(const char *name,const u_char *data,int pkt_len)
+{
+#define DUMP_HDR_SIZE 20
+#define DUMP_TLR_SIZE 8
+	if (pkt_len) {
+		int i,len1,len2;
+
+		printk(KERN_DEBUG "%s: length=%d,data=",name,pkt_len);
+
+		if (pkt_len >  DUMP_HDR_SIZE+ DUMP_TLR_SIZE) {
+			len1 = DUMP_HDR_SIZE;
+			len2 = DUMP_TLR_SIZE;
+		} else {
+			len1 = pkt_len > DUMP_HDR_SIZE ? DUMP_HDR_SIZE : pkt_len;
+			len2 = 0;			
+		}
+		for (i = 0; i < len1; ++i) {
+		 	printk ("%.2x", data[i]);
+		}
+		if (len2) {
+		 	printk ("..");
+			for (i = pkt_len-DUMP_TLR_SIZE; i < pkt_len; ++i) {
+				printk ("%.2x", data[i]);
+			}
+		}
+		printk ("\n");
+	}
+#undef DUMP_HDR_SIZE
+#undef DUMP_TLR_SIZE
+}
+
+#else
+
+#define DBG(level, format, arg...) do {} while (0)
+#define DBG_PACKET(level,data,count) do {} while (0)
+#define DBG_SKB(level,skb) do {} while (0)
+
+#endif
+
+#endif
diff -u --recursive --new-file v2.4.9/linux/drivers/isdn/hisax/hisax_if.h linux/drivers/isdn/hisax/hisax_if.h
--- v2.4.9/linux/drivers/isdn/hisax/hisax_if.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/isdn/hisax/hisax_if.h	Sun Sep  9 10:45:43 2001
@@ -0,0 +1,54 @@
+#ifndef __HISAX_IF_H__
+#define __HISAX_IF_H__
+
+#include <linux/skbuff.h>
+
+#define REQUEST		0
+#define CONFIRM		1
+#define INDICATION	2
+#define RESPONSE	3
+
+#define PH_ACTIVATE	0x0100
+#define PH_DEACTIVATE	0x0110
+#define PH_DATA		0x0120
+#define PH_PULL		0x0130
+#define PH_DATA_E	0x0140
+
+#define L1_MODE_NULL	0
+#define L1_MODE_TRANS	1
+#define L1_MODE_HDLC	2
+#define L1_MODE_EXTRN	3
+#define L1_MODE_HDLC_56K 4
+#define L1_MODE_MODEM	7
+#define L1_MODE_V32	8
+#define L1_MODE_FAX	9
+
+struct hisax_if {
+	void *priv; // private to driver
+	void (*l1l2)(struct hisax_if *, int pr, void *arg);
+	void (*l2l1)(struct hisax_if *, int pr, void *arg);
+};
+
+struct hisax_b_if {
+	struct hisax_if ifc;
+
+	// private to hisax
+	struct BCState *bcs;
+};
+
+struct hisax_d_if {
+	struct hisax_if ifc;
+
+	// private to hisax
+	struct module *owner;
+	struct IsdnCardState *cs;
+	struct hisax_b_if *b_if[2];
+	struct sk_buff_head erq;
+	long ph_state;
+};
+
+int hisax_register(struct hisax_d_if *hisax_if, struct hisax_b_if *b_if[],
+		   char *name, int protocol);
+void hisax_unregister(struct hisax_d_if *hisax_if);
+
+#endif
diff -u --recursive --new-file v2.4.9/linux/drivers/isdn/hisax/isar.c linux/drivers/isdn/hisax/isar.c
--- v2.4.9/linux/drivers/isdn/hisax/isar.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/hisax/isar.c	Fri Sep  7 09:28:38 2001
@@ -1,4 +1,4 @@
-/* $Id: isar.c,v 1.17.6.3 2001/06/09 15:14:17 kai Exp $
+/* $Id: isar.c,v 1.17.6.4 2001/08/17 12:34:26 kai Exp $
  *
  * isar.c   ISAR (Siemens PSB 7110) specific routines
  *
@@ -18,8 +18,6 @@
 #define DBG_LOADFIRM	0
 #define DUMP_MBOXFRAME	2
 
-#define MIN(a,b) ((a<b)?a:b)
-
 #define DLE	0x10
 #define ETX	0x03
 
@@ -272,7 +270,9 @@
 			ret = 1;goto reterror;
 		}
 		while (left>0) {
-			noc = MIN(126, left);
+			noc = left;
+			if (noc > 126)
+				noc = 126;
 			nom = 2*noc;
 			mp  = msg;
 			*mp++ = sadr / 256;
diff -u --recursive --new-file v2.4.9/linux/drivers/isdn/hisax/isdnl1.c linux/drivers/isdn/hisax/isdnl1.c
--- v2.4.9/linux/drivers/isdn/hisax/isdnl1.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/hisax/isdnl1.c	Sun Sep  9 10:45:43 2001
@@ -1,4 +1,4 @@
-/* $Id: isdnl1.c,v 2.41.6.3 2001/05/26 15:19:57 kai Exp $
+/* $Id: isdnl1.c,v 2.41.6.4 2001/08/23 19:44:23 kai Exp $
  *
  * isdnl1.c     common low level stuff for Siemens Chipsetbased isdn cards
  *              based on the teles driver from Jan den Ouden
@@ -15,7 +15,7 @@
  *
  */
 
-const char *l1_revision = "$Revision: 2.41.6.3 $";
+const char *l1_revision = "$Revision: 2.41.6.4 $";
 
 #define __NO_VERSION__
 #include <linux/init.h>
@@ -895,7 +895,8 @@
 	setstack_manager(st);
 	st->l1.stlistp = &(cs->stlist);
 	st->l2.l2l1  = dch_l2l1;
-	cs->setstack_d(st, cs);
+	if (cs->setstack_d)
+		cs->setstack_d(st, cs);
 }
 
 void
diff -u --recursive --new-file v2.4.9/linux/drivers/isdn/hisax/isdnl1.h linux/drivers/isdn/hisax/isdnl1.h
--- v2.4.9/linux/drivers/isdn/hisax/isdnl1.h	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/isdnl1.h	Sun Sep  9 10:45:43 2001
@@ -1,4 +1,4 @@
-/* $Id: isdnl1.h,v 2.9.6.1 2001/02/16 16:43:27 kai Exp $
+/* $Id: isdnl1.h,v 2.9.6.2 2001/08/23 19:44:23 kai Exp $
  *
  * Layer 1 defines
  *
@@ -14,6 +14,7 @@
 #define D_RX_MON1	5
 #define D_TX_MON0	6
 #define D_TX_MON1	7
+#define E_RCVBUFREADY	8
 
 #define B_RCVBUFREADY 0
 #define B_XMTBUFREADY 1
diff -u --recursive --new-file v2.4.9/linux/drivers/isdn/hisax/st5481.h linux/drivers/isdn/hisax/st5481.h
--- v2.4.9/linux/drivers/isdn/hisax/st5481.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/isdn/hisax/st5481.h	Sun Sep  9 10:45:43 2001
@@ -0,0 +1,533 @@
+/*
+ * Driver for ST5481 USB ISDN modem
+ *
+ * Author       Frode Isaksen
+ * Copyright    2001 by Frode Isaksen      <fisaksen@bewan.com>
+ *              2001 by Kai Germaschewski  <kai.germaschewski@gmx.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ */
+
+#ifndef _ST5481_H_
+#define _ST5481_H_
+
+// USB IDs, the Product Id is in the range 0x4810-0x481F
+
+#define ST_VENDOR_ID 0x0483
+#define ST5481_PRODUCT_ID 0x4810
+#define ST5481_PRODUCT_ID_MASK 0xFFF0
+
+// ST5481 endpoints when using alternative setting 3 (2B+D).
+// To get the endpoint address, OR with 0x80 for IN endpoints.
+
+#define EP_CTRL   0x00U /* Control endpoint */
+#define EP_INT    0x01U /* Interrupt endpoint */
+#define EP_B1_OUT 0x02U /* B1 channel out */
+#define EP_B1_IN  0x03U /* B1 channel in */
+#define EP_B2_OUT 0x04U /* B2 channel out */
+#define EP_B2_IN  0x05U /* B2 channel in */
+#define EP_D_OUT  0x06U /* D channel out */
+#define EP_D_IN   0x07U /* D channel in */
+  
+// Number of isochronous packets. With 20 packets we get
+// 50 interrupts/sec for each endpoint.
+
+#define NUM_ISO_PACKETS_D      20
+#define NUM_ISO_PACKETS_B      20
+
+// Size of each isochronous packet.
+// In outgoing direction we need to match ISDN data rates:
+// D:  2 bytes / msec -> 16 kbit / s
+// B: 16 bytes / msec -> 64 kbit / s
+#define SIZE_ISO_PACKETS_D_IN  16
+#define SIZE_ISO_PACKETS_D_OUT 2
+#define SIZE_ISO_PACKETS_B_IN  32
+#define SIZE_ISO_PACKETS_B_OUT 8
+
+// If we overrun/underrun, we send one packet with +/- 2 bytes
+#define B_FLOW_ADJUST 2
+
+// Registers that are written using vendor specific device request
+// on endpoint 0. 
+
+#define LBA			0x02 /* S loopback */
+#define SET_DEFAULT		0x06 /* Soft reset */
+#define LBB			0x1D /* S maintenance loopback */
+#define STT			0x1e /* S force transmission signals */
+#define SDA_MIN			0x20 /* SDA-sin minimal value */
+#define SDA_MAX			0x21 /* SDA-sin maximal value */
+#define SDELAY_VALUE		0x22 /* Delay between Tx and Rx clock */
+#define IN_D_COUNTER		0x36 /* D receive channel fifo counter */
+#define OUT_D_COUNTER		0x37 /* D transmit channel fifo counter */
+#define IN_B1_COUNTER		0x38 /* B1 receive channel fifo counter */
+#define OUT_B1_COUNTER		0x39 /* B1 transmit channel fifo counter */
+#define IN_B2_COUNTER		0x3a /* B2 receive channel fifo counter */
+#define OUT_B2_COUNTER		0x3b /* B2 transmit channel fifo counter */
+#define FFCTRL_IN_D		0x3C /* D receive channel fifo threshold low */
+#define FFCTRH_IN_D		0x3D /* D receive channel fifo threshold high */
+#define FFCTRL_OUT_D		0x3E /* D transmit channel fifo threshold low */
+#define FFCTRH_OUT_D		0x3F /* D transmit channel fifo threshold high */
+#define FFCTRL_IN_B1		0x40 /* B1 receive channel fifo threshold low */
+#define FFCTRH_IN_B1		0x41 /* B1 receive channel fifo threshold high */
+#define FFCTRL_OUT_B1		0x42 /* B1 transmit channel fifo threshold low */
+#define FFCTRH_OUT_B1		0x43 /* B1 transmit channel fifo threshold high */
+#define FFCTRL_IN_B2		0x44 /* B2 receive channel fifo threshold low */
+#define FFCTRH_IN_B2		0x45 /* B2 receive channel fifo threshold high */
+#define FFCTRL_OUT_B2		0x46 /* B2 transmit channel fifo threshold low */
+#define FFCTRH_OUT_B2		0x47 /* B2 transmit channel fifo threshold high */
+#define MPMSK			0x4A /* Multi purpose interrupt MASK register */
+#define	FFMSK_D			0x4c /* D fifo interrupt MASK register */
+#define	FFMSK_B1		0x4e /* B1 fifo interrupt MASK register */
+#define	FFMSK_B2		0x50 /* B2 fifo interrupt MASK register */
+#define GPIO_DIR		0x52 /* GPIO pins direction registers */
+#define GPIO_OUT		0x53 /* GPIO pins output register */
+#define GPIO_IN			0x54 /* GPIO pins input register */ 
+#define TXCI			0x56 /* CI command to be transmitted */
+
+
+// Format of the interrupt packet received on endpoint 1:
+//
+// +--------+--------+--------+--------+--------+--------+
+// !MPINT   !FFINT_D !FFINT_B1!FFINT_B2!CCIST   !GPIO_INT!
+// +--------+--------+--------+--------+--------+--------+
+
+// Offsets in the interrupt packet
+
+#define MPINT			0
+#define FFINT_D			1
+#define FFINT_B1		2
+#define FFINT_B2		3
+#define CCIST			4
+#define GPIO_INT		5
+#define INT_PKT_SIZE            6
+
+// MPINT
+#define LSD_INT                 0x80 /* S line activity detected */
+#define RXCI_INT		0x40 /* Indicate primitive arrived */
+#define	DEN_INT			0x20 /* Signal enabling data out of D Tx fifo */
+#define DCOLL_INT		0x10 /* D channel collision */
+#define AMIVN_INT		0x04 /* AMI violation number reached 2 */
+#define INFOI_INT		0x04 /* INFOi changed */
+#define DRXON_INT               0x02 /* Reception channel active */
+#define GPCHG_INT               0x01 /* GPIO pin value changed */
+
+// FFINT_x
+#define IN_OVERRUN		0x80 /* In fifo overrun */
+#define OUT_UNDERRUN		0x40 /* Out fifo underrun */
+#define IN_UP			0x20 /* In fifo thresholdh up-crossed */
+#define IN_DOWN			0x10 /* In fifo thresholdl down-crossed */
+#define OUT_UP			0x08 /* Out fifo thresholdh up-crossed */
+#define OUT_DOWN		0x04 /* Out fifo thresholdl down-crossed */
+#define IN_COUNTER_ZEROED	0x02 /* In down-counter reached 0 */
+#define OUT_COUNTER_ZEROED	0x01 /* Out down-counter reached 0 */
+
+#define ANY_REC_INT	(IN_OVERRUN+IN_UP+IN_DOWN+IN_COUNTER_ZEROED)
+#define ANY_XMIT_INT	(OUT_UNDERRUN+OUT_UP+OUT_DOWN+OUT_COUNTER_ZEROED)
+
+
+// Level 1 commands that are sent using the TXCI device request
+#define ST5481_CMD_DR		 0x0 /* Deactivation Request */
+#define ST5481_CMD_RES		 0x1 /* state machine RESet */
+#define ST5481_CMD_TM1		 0x2 /* Test Mode 1 */
+#define ST5481_CMD_TM2		 0x3 /* Test Mode 2 */
+#define ST5481_CMD_PUP		 0x7 /* Power UP */
+#define ST5481_CMD_AR8		 0x8 /* Activation Request class 1 */
+#define ST5481_CMD_AR10		 0x9 /* Activation Request class 2 */
+#define ST5481_CMD_ARL		 0xA /* Activation Request Loopback */
+#define ST5481_CMD_PDN		 0xF /* Power DoWn */
+
+// Turn on/off the LEDs using the GPIO device request.
+// To use the B LEDs, number_of_leds must be set to 4
+#define B1_LED		0x10U
+#define B2_LED		0x20U
+#define GREEN_LED	0x40U
+#define RED_LED	        0x80U
+
+// D channel out states
+enum {
+	ST_DOUT_NONE,
+
+	ST_DOUT_SHORT_INIT,
+	ST_DOUT_SHORT_WAIT_DEN,
+
+	ST_DOUT_LONG_INIT,
+	ST_DOUT_LONG_WAIT_DEN,
+	ST_DOUT_NORMAL,
+
+	ST_DOUT_WAIT_FOR_UNDERRUN,
+        ST_DOUT_WAIT_FOR_NOT_BUSY,
+	ST_DOUT_WAIT_FOR_STOP,
+	ST_DOUT_WAIT_FOR_RESET,
+};
+
+#define DOUT_STATE_COUNT (ST_DOUT_WAIT_FOR_RESET + 1)
+
+// D channel out events
+enum {
+	EV_DOUT_START_XMIT,
+	EV_DOUT_COMPLETE,
+	EV_DOUT_DEN,
+	EV_DOUT_RESETED,
+	EV_DOUT_STOPPED,
+	EV_DOUT_COLL,
+	EV_DOUT_UNDERRUN,
+};
+
+#define DOUT_EVENT_COUNT (EV_DOUT_UNDERRUN + 1)
+
+// ----------------------------------------------------------------------
+
+enum {
+	ST_L1_F3,
+	ST_L1_F4,
+	ST_L1_F6,
+	ST_L1_F7,
+	ST_L1_F8,
+};
+
+#define L1_STATE_COUNT (ST_L1_F8+1)
+
+// The first 16 entries match the Level 1 indications that 
+// are found at offset 4 (CCIST) in the interrupt packet
+
+enum {
+	EV_IND_DP,  // 0000 Deactivation Pending
+	EV_IND_1,   // 0001
+	EV_IND_2,   // 0010
+	EV_IND_3,   // 0011
+	EV_IND_RSY, // 0100 ReSYnchronizing
+	EV_IND_5,   // 0101
+	EV_IND_6,   // 0110
+	EV_IND_7,   // 0111
+	EV_IND_AP,  // 1000 Activation Pending
+	EV_IND_9,   // 1001
+	EV_IND_10,  // 1010
+	EV_IND_11,  // 1011
+	EV_IND_AI8, // 1100 Activation Indication class 8
+	EV_IND_AI10,// 1101 Activation Indication class 10
+	EV_IND_AIL, // 1110 Activation Indication Loopback
+	EV_IND_DI,  // 1111 Deactivation Indication
+	EV_PH_ACTIVATE_REQ,
+	EV_PH_DEACTIVATE_REQ,
+	EV_TIMER3,
+};
+
+#define L1_EVENT_COUNT (EV_TIMER3 + 1)
+
+#define ERR(format, arg...) \
+printk(KERN_ERR __FILE__ ": " __FUNCTION__ ": " format "\n" , ## arg)
+
+#define WARN(format, arg...) \
+printk(KERN_WARNING __FILE__ ": " __FUNCTION__ ": " format "\n" , ## arg)
+
+#define INFO(format, arg...) \
+printk(KERN_INFO __FILE__ ": " __FUNCTION__ ": " format "\n" , ## arg)
+
+#include "st5481_hdlc.h"
+#include "fsm.h"
+#include "hisax_if.h"
+#include <linux/skbuff.h>
+
+/* ======================================================================
+ * FIFO handling
+ */
+
+/* Generic FIFO structure */ 
+struct fifo {
+	u_char r,w,count,size;
+	spinlock_t lock;
+};
+
+/*
+ * Init an FIFO
+ */
+static inline void fifo_init(struct fifo *fifo, int size)
+{
+	fifo->r = fifo->w = fifo->count = 0;
+	fifo->size = size;
+	spin_lock_init(&fifo->lock);
+}
+
+/*
+ * Add an entry to the FIFO
+ */
+static inline int fifo_add(struct fifo *fifo)
+{
+	unsigned long flags;
+	int index;
+
+	if (!fifo) {
+		return -1;
+	}
+
+	spin_lock_irqsave(&fifo->lock, flags);
+	if (fifo->count == fifo->size) {
+		// FIFO full
+		index = -1;
+	} else {
+		// Return index where to get the next data to add to the FIFO
+		index = fifo->w++ & (fifo->size-1); 
+		fifo->count++;
+	}
+	spin_unlock_irqrestore(&fifo->lock, flags);
+	return index;
+}
+
+/*
+ * Remove an entry from the FIFO with the index returned.
+ */
+static inline int fifo_remove(struct fifo *fifo)
+{
+	unsigned long flags;
+	int index;
+
+	if (!fifo) {
+		return -1;
+	}
+
+	spin_lock_irqsave(&fifo->lock, flags);		
+	if (!fifo->count) {
+		// FIFO empty
+		index = -1;
+	} else {
+		// Return index where to get the next data from the FIFO
+		index = fifo->r++ & (fifo->size-1); 
+		fifo->count--;
+	}
+	spin_unlock_irqrestore(&fifo->lock, flags);
+
+	return index;
+}
+
+/* ======================================================================
+ * control pipe
+ */
+typedef void (*ctrl_complete_t)(void *);
+
+typedef struct ctrl_msg {
+	devrequest dr;
+	ctrl_complete_t complete;
+	void *context;
+} ctrl_msg; 
+
+/* FIFO of ctrl messages waiting to be sent */
+#define MAX_EP0_MSG 16
+struct ctrl_msg_fifo {
+	struct fifo f;
+	struct ctrl_msg data[MAX_EP0_MSG];
+};	
+
+#define MAX_DFRAME_LEN_L1	300
+#define HSCX_BUFMAX	4096
+
+struct st5481_ctrl {
+	struct ctrl_msg_fifo msg_fifo;
+	unsigned long busy;
+	struct urb *urb;
+};
+
+struct st5481_intr {
+  //	struct evt_fifo evt_fifo;
+	struct urb *urb;
+};
+
+struct st5481_d_out {
+	struct hdlc_vars hdlc_state;
+	struct urb *urb[2]; /* double buffering */
+	unsigned long busy;
+	struct sk_buff *tx_skb;
+	struct FsmInst fsm;
+};
+
+struct st5481_b_out {
+	struct hdlc_vars hdlc_state;
+	struct urb *urb[2]; /* double buffering */
+	u_char flow_event;
+	u_long busy;
+	struct sk_buff *tx_skb;
+};
+
+struct st5481_in {
+	struct hdlc_vars hdlc_state;
+	struct urb *urb[2]; /* double buffering */
+	int mode;
+	int bufsize;
+	unsigned int num_packets;
+	unsigned int packet_size;
+	unsigned char ep, counter;
+	unsigned char *rcvbuf;
+	struct st5481_adapter *adapter;
+	struct hisax_if *hisax_if;
+};
+
+int st5481_setup_in(struct st5481_in *in);
+void st5481_release_in(struct st5481_in *in);
+void st5481_in_mode(struct st5481_in *in, int mode);
+
+struct st5481_bcs {
+	struct hisax_b_if b_if;
+	struct st5481_adapter *adapter;
+	struct st5481_in b_in;
+	struct st5481_b_out b_out;
+	int channel;
+	int mode;
+};
+
+struct st5481_adapter {
+	struct list_head list;
+	int number_of_leds;
+	struct usb_device *usb_dev;
+	struct hisax_d_if hisax_d_if;
+
+	struct st5481_ctrl ctrl;
+	struct st5481_intr intr;
+	struct st5481_in d_in;
+	struct st5481_d_out d_out;
+
+	unsigned char leds;
+	unsigned int led_counter;
+
+	unsigned long event;
+
+	struct FsmInst l1m;
+	struct FsmTimer timer;
+
+	struct st5481_bcs bcs[2];
+};
+
+#define TIMER3_VALUE 7000
+
+/* ======================================================================
+ *
+ */
+
+/*
+ * Submit an URB with error reporting. This is a macro so
+ * the __FUNCTION__ returns the caller function name.
+ */
+#define SUBMIT_URB(urb) \
+({ \
+	int status; \
+	if ((status = usb_submit_urb(urb)) < 0) { \
+		WARN("usb_submit_urb failed,status=%d", status); \
+	} \
+        status; \
+})
+
+/*
+ * USB double buffering, return the URB index (0 or 1).
+ */
+static inline int get_buf_nr(struct urb *urbs[], struct urb *urb)
+{
+        return (urbs[0]==urb ? 0 : 1); 
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* B Channel */
+
+int  st5481_setup_b(struct st5481_bcs *bcs);
+void st5481_release_b(struct st5481_bcs *bcs);
+void st5481_d_l2l1(struct hisax_if *hisax_d_if, int pr, void *arg);
+
+/* D Channel */
+
+int  st5481_setup_d(struct st5481_adapter *adapter);
+void st5481_release_d(struct st5481_adapter *adapter);
+void st5481_b_l2l1(struct hisax_if *b_if, int pr, void *arg);
+int  st5481_d_init(void);
+void st5481_d_exit(void);
+
+/* USB */
+void st5481_ph_command(struct st5481_adapter *adapter, unsigned int command);
+int st5481_setup_isocpipes(struct urb* urb[2], struct usb_device *dev, 
+			   unsigned int pipe, int num_packets,
+			   int packet_size, int buf_size,
+			   usb_complete_t complete, void *context);
+void st5481_release_isocpipes(struct urb* urb[2]);
+
+int  st5481_isoc_flatten(struct urb *urb);
+void st5481_usb_pipe_reset(struct st5481_adapter *adapter,
+		    u_char pipe, ctrl_complete_t complete, void *context);
+void st5481_usb_ctrl_msg(struct st5481_adapter *adapter,
+		  u8 request, u8 requesttype, u16 value, u16 index,
+		  ctrl_complete_t complete, void *context);
+void st5481_usb_device_ctrl_msg(struct st5481_adapter *adapter,
+			 u8 request, u16 value,
+			 ctrl_complete_t complete, void *context);
+int  st5481_setup_usb(struct st5481_adapter *adapter);
+void st5481_release_usb(struct st5481_adapter *adapter);
+void st5481_start(struct st5481_adapter *adapter);
+void st5481_stop(struct st5481_adapter *adapter);
+
+// ----------------------------------------------------------------------
+// debugging macros
+
+#define __debug_variable st5481_debug
+#include "hisax_debug.h"
+
+#ifdef CONFIG_HISAX_DEBUG
+
+extern int st5481_debug;
+
+#define DBG_ISO_PACKET(level,urb) \
+  if (level & __debug_variable) dump_iso_packet(__FUNCTION__,urb)
+
+static void __attribute__((unused))
+dump_iso_packet(const char *name,urb_t *urb)
+{
+	int i,j;
+	int len,ofs;
+	u_char *data;
+
+	printk(KERN_DEBUG "%s: packets=%d,errors=%d\n",
+	       name,urb->number_of_packets,urb->error_count);
+	for (i = 0; i  < urb->number_of_packets; ++i) {
+		if (urb->pipe & USB_DIR_IN) {
+			len = urb->iso_frame_desc[i].actual_length;
+		} else {
+			len = urb->iso_frame_desc[i].length;
+		}
+		ofs = urb->iso_frame_desc[i].offset;
+		printk(KERN_DEBUG "len=%.2d,ofs=%.3d ",len,ofs);
+		if (len) {
+			data = urb->transfer_buffer+ofs;
+			for (j=0; j < len; j++) {
+				printk ("%.2x", data[j]);
+			}
+		}
+		printk("\n");
+	}
+}
+
+static inline const char *ST5481_CMD_string(int evt)
+{
+	static char s[16];
+
+	switch (evt) {
+	case ST5481_CMD_DR: return "DR";
+	case ST5481_CMD_RES: return "RES";
+	case ST5481_CMD_TM1: return "TM1";
+	case ST5481_CMD_TM2: return "TM2";
+	case ST5481_CMD_PUP: return "PUP";
+	case ST5481_CMD_AR8: return "AR8";
+	case ST5481_CMD_AR10: return "AR10";
+	case ST5481_CMD_ARL: return "ARL";
+	case ST5481_CMD_PDN: return "PDN";
+	};
+	
+	sprintf(s,"0x%x",evt);
+	return s;
+}	
+
+#else
+
+#define DBG_ISO_PACKET(level,urb) do {} while (0)
+
+#endif
+
+
+
+#endif 
diff -u --recursive --new-file v2.4.9/linux/drivers/isdn/hisax/st5481_b.c linux/drivers/isdn/hisax/st5481_b.c
--- v2.4.9/linux/drivers/isdn/hisax/st5481_b.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/isdn/hisax/st5481_b.c	Sun Sep  9 10:45:43 2001
@@ -0,0 +1,367 @@
+/*
+ * Driver for ST5481 USB ISDN modem
+ *
+ * Author       Frode Isaksen
+ * Copyright    2001 by Frode Isaksen      <fisaksen@bewan.com>
+ *              2001 by Kai Germaschewski  <kai.germaschewski@gmx.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/usb.h>
+#include <linux/slab.h>
+#include <linux/netdevice.h>
+#include "st5481.h"
+
+static inline void B_L1L2(struct st5481_bcs *bcs, int pr, void *arg)
+{
+	struct hisax_if *ifc = (struct hisax_if *) &bcs->b_if;
+
+	ifc->l1l2(ifc, pr, arg);
+}
+
+/*
+ * Encode and transmit next frame.
+ */
+static void usb_b_out(struct st5481_bcs *bcs,int buf_nr)
+{
+	struct st5481_b_out *b_out = &bcs->b_out;
+	struct st5481_adapter *adapter = bcs->adapter;
+	struct urb *urb;
+	unsigned int packet_size,offset;
+	int len,buf_size,bytes_sent;
+	int i;
+	struct sk_buff *skb;
+	
+	if (test_and_set_bit(buf_nr, &b_out->busy)) {
+		DBG(4,"ep %d urb %d busy",(bcs->channel+1)*2,buf_nr);
+		return;
+	}
+	urb = b_out->urb[buf_nr];
+
+	// Adjust isoc buffer size according to flow state
+	if(b_out->flow_event & (OUT_DOWN | OUT_UNDERRUN)) {
+		buf_size = NUM_ISO_PACKETS_B*SIZE_ISO_PACKETS_B_OUT + B_FLOW_ADJUST;
+		packet_size = SIZE_ISO_PACKETS_B_OUT + B_FLOW_ADJUST;
+		DBG(4,"B%d,adjust flow,add %d bytes",bcs->channel+1,B_FLOW_ADJUST);
+	} else if(b_out->flow_event & OUT_UP){
+		buf_size = NUM_ISO_PACKETS_B*SIZE_ISO_PACKETS_B_OUT - B_FLOW_ADJUST;
+		packet_size = SIZE_ISO_PACKETS_B_OUT - B_FLOW_ADJUST;
+		DBG(4,"B%d,adjust flow,remove %d bytes",bcs->channel+1,B_FLOW_ADJUST);
+	} else {
+		buf_size = NUM_ISO_PACKETS_B*SIZE_ISO_PACKETS_B_OUT;
+		packet_size = 8;
+	}
+	b_out->flow_event = 0;
+
+	len = 0;
+	while (len < buf_size) {
+		if ((skb = b_out->tx_skb)) {
+			DBG_SKB(0x100, skb);
+			DBG(4,"B%d,len=%d",bcs->channel+1,skb->len);
+			
+			if (bcs->mode == L1_MODE_TRANS) {	
+				bytes_sent = buf_size - len;
+				if (skb->len < bytes_sent)
+					bytes_sent = skb->len;
+
+				memcpy(urb->transfer_buffer+len, skb->data, bytes_sent);
+				
+				len += bytes_sent;
+			} else {
+				len += hdlc_encode(&b_out->hdlc_state, 
+						   skb->data, skb->len, &bytes_sent,
+						   urb->transfer_buffer+len, buf_size-len);
+			}
+
+			skb_pull(skb, bytes_sent);
+			
+			if (!skb->len) {
+				// Frame sent
+				b_out->tx_skb = NULL;
+				B_L1L2(bcs, PH_DATA | CONFIRM, (void *) skb->truesize);
+				dev_kfree_skb_any(skb);
+				
+/* 				if (!(bcs->tx_skb = skb_dequeue(&bcs->sq))) { */
+/* 					st5481B_sched_event(bcs, B_XMTBUFREADY); */
+/* 				} */
+			}
+		} else {
+			if (bcs->mode == L1_MODE_TRANS) {
+				memset(urb->transfer_buffer+len, 0xff, buf_size-len);
+				len = buf_size;
+			} else {
+				// Send flags
+				len += hdlc_encode(&b_out->hdlc_state, 
+						   NULL, 0, &bytes_sent,
+						   urb->transfer_buffer+len, buf_size-len);
+			}
+		}	
+	}
+
+	// Prepare the URB
+	for (i = 0, offset = 0; offset < len; i++) {
+		urb->iso_frame_desc[i].offset = offset;
+		urb->iso_frame_desc[i].length = packet_size;
+		offset += packet_size;
+		packet_size = SIZE_ISO_PACKETS_B_OUT;
+	}
+	urb->transfer_buffer_length = len;
+	urb->number_of_packets = i;
+	urb->dev = adapter->usb_dev;
+
+	DBG_ISO_PACKET(0x200,urb);
+
+	SUBMIT_URB(urb);
+}
+
+/*
+ * Start transfering (flags or data) on the B channel, since
+ * FIFO counters has been set to a non-zero value.
+ */
+static void st5481B_start_xfer(void *context)
+{
+	struct st5481_bcs *bcs = context;
+
+	DBG(4,"B%d",bcs->channel+1);
+
+	// Start transmitting (flags or data) on B channel
+
+	usb_b_out(bcs,0);
+	usb_b_out(bcs,1);
+}
+
+/*
+ * If the adapter has only 2 LEDs, the green
+ * LED will blink with a rate depending
+ * on the number of channels opened.
+ */
+static void led_blink(struct st5481_adapter *adapter)
+{
+	u_char leds = adapter->leds;
+
+	// 50 frames/sec for each channel
+	if (++adapter->led_counter % 50) {
+		return;
+	}
+
+	if (adapter->led_counter % 100) {
+		leds |= GREEN_LED;
+	} else {
+		leds &= ~GREEN_LED;
+	}
+	
+	st5481_usb_device_ctrl_msg(adapter, GPIO_OUT, leds, NULL, NULL);
+}
+
+static void usb_b_out_complete(struct urb *urb)
+{
+	struct st5481_bcs *bcs = urb->context;
+	struct st5481_b_out *b_out = &bcs->b_out;
+	struct st5481_adapter *adapter = bcs->adapter;
+	int buf_nr;
+	
+	buf_nr = get_buf_nr(b_out->urb, urb);
+	test_and_clear_bit(buf_nr, &b_out->busy);
+
+	if (urb->status < 0) {
+		if (urb->status != USB_ST_URB_KILLED) {
+			WARN("urb status %d",urb->status);
+			if (b_out->busy == 0) {
+				st5481_usb_pipe_reset(adapter, (bcs->channel+1)*2 | USB_DIR_OUT, NULL, NULL);
+			}
+		} else {
+			DBG(1,"urb killed"); 
+			return; // Give up
+		}
+	}
+
+	usb_b_out(bcs,buf_nr);
+
+	if (adapter->number_of_leds == 2)
+		led_blink(adapter);
+}
+
+/*
+ * Start or stop the transfer on the B channel.
+ */
+static void st5481B_mode(struct st5481_bcs *bcs, int mode)
+{
+	struct st5481_b_out *b_out = &bcs->b_out;
+	struct st5481_adapter *adapter = bcs->adapter;
+
+	DBG(4,"B%d,mode=%d", bcs->channel + 1, mode);
+
+	if (bcs->mode == mode)
+		return;
+
+	bcs->mode = mode;
+
+	// Cancel all USB transfers on this B channel
+	usb_unlink_urb(b_out->urb[0]);
+	usb_unlink_urb(b_out->urb[1]);
+	b_out->busy = 0;
+
+	st5481_in_mode(&bcs->b_in, mode);
+	if (bcs->mode != L1_MODE_NULL) {
+		// Open the B channel
+		if (bcs->mode != L1_MODE_TRANS) {
+			hdlc_out_init(&b_out->hdlc_state, 0, bcs->mode == L1_MODE_HDLC_56K);
+		}
+		st5481_usb_pipe_reset(adapter, (bcs->channel+1)*2, NULL, NULL);
+	
+		// Enable B channel interrupts
+		st5481_usb_device_ctrl_msg(adapter, FFMSK_B1+(bcs->channel*2), 
+				    OUT_UP+OUT_DOWN+OUT_UNDERRUN, NULL, NULL);
+
+		// Enable B channel FIFOs
+		st5481_usb_device_ctrl_msg(adapter, OUT_B1_COUNTER+(bcs->channel*2), 32, st5481B_start_xfer, bcs);
+		if (adapter->number_of_leds == 4) {
+			if (bcs->channel == 0) {
+				adapter->leds |= B1_LED;
+			} else {
+				adapter->leds |= B2_LED;
+			}
+		}
+	} else {
+		// Disble B channel interrupts
+		st5481_usb_device_ctrl_msg(adapter, FFMSK_B1+(bcs->channel*2), 0, NULL, NULL);
+
+		// Disable B channel FIFOs
+		st5481_usb_device_ctrl_msg(adapter, OUT_B1_COUNTER+(bcs->channel*2), 0, NULL, NULL);
+
+		if (adapter->number_of_leds == 4) {
+			if (bcs->channel == 0) {
+				adapter->leds &= ~B1_LED;
+			} else {
+				adapter->leds &= ~B2_LED;
+			}
+		} else {
+			st5481_usb_device_ctrl_msg(adapter, GPIO_OUT, adapter->leds, NULL, NULL);
+		}
+		if (b_out->tx_skb) {
+			dev_kfree_skb_any(b_out->tx_skb);
+			b_out->tx_skb = NULL;
+		}
+		
+	}
+}
+
+static int __devinit st5481_setup_b_out(struct st5481_bcs *bcs)
+{
+	struct usb_device *dev = bcs->adapter->usb_dev;
+	struct usb_interface_descriptor *altsetting;
+	struct usb_endpoint_descriptor *endpoint;
+  	struct st5481_b_out *b_out = &bcs->b_out;
+
+	DBG(4,"");
+
+	altsetting = &(dev->config->interface[0].altsetting[3]);
+
+	// Allocate URBs and buffers for the B channel out
+	endpoint = &altsetting->endpoint[EP_B1_OUT - 1 + bcs->channel * 2];
+
+	DBG(4,"endpoint address=%02x,packet size=%d",
+	    endpoint->bEndpointAddress,endpoint->wMaxPacketSize);
+
+	// Allocate memory for 8000bytes/sec + extra bytes if underrun
+	return st5481_setup_isocpipes(b_out->urb, dev, 
+				      usb_sndisocpipe(dev, endpoint->bEndpointAddress),
+				      NUM_ISO_PACKETS_B, SIZE_ISO_PACKETS_B_OUT,
+				      NUM_ISO_PACKETS_B * SIZE_ISO_PACKETS_B_OUT + B_FLOW_ADJUST,
+				      usb_b_out_complete, bcs);
+}
+
+static void __devexit st5481_release_b_out(struct st5481_bcs *bcs)
+{
+	struct st5481_b_out *b_out = &bcs->b_out;
+
+	DBG(4,"");
+
+	st5481_release_isocpipes(b_out->urb);
+}
+
+int __devinit st5481_setup_b(struct st5481_bcs *bcs)
+{
+	int retval;
+
+	DBG(4,"");
+
+	retval = st5481_setup_b_out(bcs);
+	if (retval)
+		goto err;
+	bcs->b_in.bufsize = HSCX_BUFMAX;
+	bcs->b_in.num_packets = NUM_ISO_PACKETS_B;
+	bcs->b_in.packet_size = SIZE_ISO_PACKETS_B_IN;
+	bcs->b_in.ep = (bcs->channel ? EP_B2_IN : EP_B1_IN) | USB_DIR_IN;
+	bcs->b_in.counter = bcs->channel ? IN_B2_COUNTER : IN_B1_COUNTER;
+	bcs->b_in.adapter = bcs->adapter;
+	bcs->b_in.hisax_if = &bcs->b_if.ifc;
+	retval = st5481_setup_in(&bcs->b_in);
+	if (retval)
+		goto err_b_out;
+
+
+	return 0;
+
+ err_b_out:
+	st5481_release_b_out(bcs);
+ err:
+	return retval;
+}
+
+/*
+ * Release buffers and URBs for the B channels
+ */
+void __devexit st5481_release_b(struct st5481_bcs *bcs)
+{
+	DBG(4,"");
+
+	st5481_release_in(&bcs->b_in);
+	st5481_release_b_out(bcs);
+}
+
+/*
+ * st5481_b_l2l1 is the entry point for upper layer routines that want to
+ * transmit on the B channel.  PH_DATA | REQUEST is a normal packet that
+ * we either start transmitting (if idle) or queue (if busy).
+ * PH_PULL | REQUEST can be called to request a callback message
+ * (PH_PULL | CONFIRM)
+ * once the link is idle.  After a "pull" callback, the upper layer
+ * routines can use PH_PULL | INDICATION to send data.
+ */
+void st5481_b_l2l1(struct hisax_if *ifc, int pr, void *arg)
+{
+	struct st5481_bcs *bcs = ifc->priv;
+	struct sk_buff *skb = arg;
+	int mode;
+
+	DBG(4, "");
+
+	switch (pr) {
+	case PH_DATA | REQUEST:
+		if (bcs->b_out.tx_skb)
+			BUG();
+		
+		bcs->b_out.tx_skb = skb;
+		break;
+	case PH_ACTIVATE | REQUEST:
+		mode = (int) arg;
+		DBG(4,"B%d,PH_ACTIVATE_REQUEST %d", bcs->channel + 1, mode);
+		st5481B_mode(bcs, mode);
+		B_L1L2(bcs, PH_ACTIVATE | INDICATION, NULL);
+		break;
+	case PH_DEACTIVATE | REQUEST:
+		DBG(4,"B%d,PH_DEACTIVATE_REQUEST", bcs->channel + 1);
+		st5481B_mode(bcs, L1_MODE_NULL);
+		B_L1L2(bcs, PH_DEACTIVATE | INDICATION, NULL);
+		break;
+	default:
+		WARN("pr %#x\n", pr);
+	}
+}
diff -u --recursive --new-file v2.4.9/linux/drivers/isdn/hisax/st5481_d.c linux/drivers/isdn/hisax/st5481_d.c
--- v2.4.9/linux/drivers/isdn/hisax/st5481_d.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/isdn/hisax/st5481_d.c	Sun Sep  9 10:45:43 2001
@@ -0,0 +1,774 @@
+/*
+ * Driver for ST5481 USB ISDN modem
+ *
+ * Author       Frode Isaksen
+ * Copyright    2001 by Frode Isaksen      <fisaksen@bewan.com>
+ *              2001 by Kai Germaschewski  <kai.germaschewski@gmx.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/usb.h>
+#include <linux/slab.h>
+#include <linux/netdevice.h>
+#include "st5481.h"
+
+static void ph_connect(struct st5481_adapter *adapter);
+static void ph_disconnect(struct st5481_adapter *adapter);
+
+static struct Fsm l1fsm;
+
+static char *strL1State[] =
+{
+	"ST_L1_F3",
+	"ST_L1_F4",
+	"ST_L1_F6",
+	"ST_L1_F7",
+	"ST_L1_F8",
+};
+
+static char *strL1Event[] =
+{
+	"EV_IND_DP",  
+	"EV_IND_1",   
+	"EV_IND_2",   
+	"EV_IND_3",   
+	"EV_IND_RSY", 
+	"EV_IND_5",   
+	"EV_IND_6",   
+	"EV_IND_7",   
+	"EV_IND_AP",  
+	"EV_IND_9",   
+	"EV_IND_10",  
+	"EV_IND_11",  
+	"EV_IND_AI8",
+	"EV_IND_AI10",
+	"EV_IND_AIL",
+	"EV_IND_DI",  
+	"EV_PH_ACTIVATE_REQ",
+	"EV_PH_DEACTIVATE_REQ",
+	"EV_TIMER3",
+};
+
+static inline void D_L1L2(struct st5481_adapter *adapter, int pr, void *arg)
+{
+	struct hisax_if *ifc = (struct hisax_if *) &adapter->hisax_d_if;
+
+	ifc->l1l2(ifc, pr, arg);
+}
+
+static void
+l1_go_f3(struct FsmInst *fi, int event, void *arg)
+{
+	struct st5481_adapter *adapter = fi->userdata;
+
+	if (fi->state == ST_L1_F7)
+		ph_disconnect(adapter);
+	
+	FsmChangeState(fi, ST_L1_F3);
+	D_L1L2(adapter, PH_DEACTIVATE | INDICATION, NULL);
+}
+
+static void
+l1_go_f6(struct FsmInst *fi, int event, void *arg)
+{
+	struct st5481_adapter *adapter = fi->userdata;
+
+	if (fi->state == ST_L1_F7)
+		ph_disconnect(adapter);
+
+	FsmChangeState(fi, ST_L1_F6);
+}
+
+static void
+l1_go_f7(struct FsmInst *fi, int event, void *arg)
+{
+	struct st5481_adapter *adapter = fi->userdata;
+
+	FsmDelTimer(&adapter->timer, 0);
+	ph_connect(adapter);
+	FsmChangeState(fi, ST_L1_F7);
+	D_L1L2(adapter, PH_ACTIVATE | INDICATION, NULL);
+}
+
+static void
+l1_go_f8(struct FsmInst *fi, int event, void *arg)
+{
+	struct st5481_adapter *adapter = fi->userdata;
+
+	if (fi->state == ST_L1_F7)
+		ph_disconnect(adapter);
+
+	FsmChangeState(fi, ST_L1_F8);
+}
+
+static void
+l1_timer3(struct FsmInst *fi, int event, void *arg)
+{
+	struct st5481_adapter *adapter = fi->userdata;
+
+	st5481_ph_command(adapter, ST5481_CMD_DR);
+	FsmChangeState(fi, ST_L1_F3);
+	D_L1L2(adapter, PH_DEACTIVATE | INDICATION, NULL);
+}
+
+static void
+l1_ignore(struct FsmInst *fi, int event, void *arg)
+{
+}
+
+static void
+l1_activate(struct FsmInst *fi, int event, void *arg)
+{
+	struct st5481_adapter *adapter = fi->userdata;
+
+	st5481_ph_command(adapter, ST5481_CMD_DR);
+	st5481_ph_command(adapter, ST5481_CMD_PUP);
+	FsmRestartTimer(&adapter->timer, TIMER3_VALUE, EV_TIMER3, NULL, 2);
+	st5481_ph_command(adapter, ST5481_CMD_AR8);
+	FsmChangeState(fi, ST_L1_F4);
+}
+
+static struct FsmNode L1FnList[] __initdata =
+{
+	{ST_L1_F3, EV_IND_DP,            l1_ignore},
+	{ST_L1_F3, EV_IND_AP,            l1_go_f6},
+	{ST_L1_F3, EV_IND_AI8,           l1_go_f7},
+	{ST_L1_F3, EV_IND_AI10,          l1_go_f7},
+	{ST_L1_F3, EV_PH_ACTIVATE_REQ,   l1_activate},
+
+	{ST_L1_F4, EV_TIMER3,            l1_timer3},
+	{ST_L1_F4, EV_IND_DP,            l1_go_f3},
+	{ST_L1_F4, EV_IND_AP,            l1_go_f6},
+	{ST_L1_F4, EV_IND_AI8,           l1_go_f7},
+	{ST_L1_F4, EV_IND_AI10,          l1_go_f7},
+
+	{ST_L1_F6, EV_TIMER3,            l1_timer3},
+	{ST_L1_F6, EV_IND_DP,            l1_go_f3},
+	{ST_L1_F6, EV_IND_AP,            l1_ignore},
+	{ST_L1_F6, EV_IND_AI8,           l1_go_f7},
+	{ST_L1_F6, EV_IND_AI10,          l1_go_f7},
+	{ST_L1_F7, EV_IND_RSY,           l1_go_f8},
+
+	{ST_L1_F7, EV_IND_DP,            l1_go_f3},
+	{ST_L1_F7, EV_IND_AP,            l1_go_f6},
+	{ST_L1_F7, EV_IND_AI8,           l1_ignore},
+	{ST_L1_F7, EV_IND_AI10,          l1_ignore},
+	{ST_L1_F7, EV_IND_RSY,           l1_go_f8},
+
+	{ST_L1_F8, EV_TIMER3,            l1_timer3},
+	{ST_L1_F8, EV_IND_DP,            l1_go_f3},
+	{ST_L1_F8, EV_IND_AP,            l1_go_f6},
+	{ST_L1_F8, EV_IND_AI8,           l1_go_f8},
+	{ST_L1_F8, EV_IND_AI10,          l1_go_f8},
+	{ST_L1_F8, EV_IND_RSY,           l1_ignore},
+};
+
+static void l1m_debug(struct FsmInst *fi, char *fmt, ...)
+{
+	va_list args;
+	char buf[256];
+	
+	va_start(args, fmt);
+	vsprintf(buf, fmt, args);
+	printk("buf %s\n", buf);
+	DBG(8, "%s", buf);
+	va_end(args);
+}
+
+/* ======================================================================
+ * D-Channel out
+ */
+
+/*
+  D OUT state machine:
+  ====================
+
+  Transmit short frame (< 16 bytes of encoded data):
+
+  L1 FRAME    D_OUT_STATE           USB                  D CHANNEL
+  --------    -----------           ---                  ---------
+ 
+              FIXME
+
+ -> [xx..xx]  SHORT_INIT            -> [7Exx..xxC1C27EFF]
+              SHORT_WAIT_DEN        <> OUT_D_COUNTER=16 
+                                                 
+              END_OF_SHORT          <- DEN_EVENT         -> 7Exx
+                                                          xxxx 
+                                                          xxxx
+							  xxxx 
+							  xxxx
+							  xxxx
+							  C1C1 
+							  7EFF 
+              WAIT_FOR_RESET_IDLE   <- D_UNDERRUN        <- (8ms)                        
+              IDLE                  <> Reset pipe
+
+              
+
+  Transmit long frame (>= 16 bytes of encoded data):
+
+  L1 FRAME    D_OUT_STATE           USB                  D CHANNEL
+  --------    -----------           ---                  ---------
+
+ -> [xx...xx] IDLE
+              WAIT_FOR_STOP         <> OUT_D_COUNTER=0
+              WAIT_FOR_RESET        <> Reset pipe
+	      STOP
+	      INIT_LONG_FRAME       -> [7Exx..xx]
+              WAIT_DEN              <> OUT_D_COUNTER=16 
+              OUT_NORMAL            <- DEN_EVENT       -> 7Exx
+              END_OF_FRAME_BUSY     -> [xxxx]             xxxx 
+              END_OF_FRAME_NOT_BUSY -> [xxxx]             xxxx
+				    -> [xxxx]		  xxxx 
+				    -> [C1C2]		  xxxx
+				    -> [7EFF]		  xxxx
+							  xxxx 
+							  xxxx 
+                                                          ....
+							  xxxx
+							  C1C2
+							  7EFF
+	                 	    <- D_UNDERRUN      <- (> 8ms)                        
+              WAIT_FOR_STOP         <> OUT_D_COUNTER=0
+              WAIT_FOR_RESET        <> Reset pipe
+	      STOP
+
+*/          
+
+static struct Fsm dout_fsm;
+
+static char *strDoutState[] =
+{
+	"ST_DOUT_NONE",
+
+	"ST_DOUT_SHORT_INIT",
+	"ST_DOUT_SHORT_WAIT_DEN",
+
+	"ST_DOUT_LONG_INIT",
+	"ST_DOUT_LONG_WAIT_DEN",
+	"ST_DOUT_NORMAL",
+
+	"ST_DOUT_WAIT_FOR_UNDERRUN",
+        "ST_DOUT_WAIT_FOR_NOT_BUSY",
+	"ST_DOUT_WAIT_FOR_STOP",
+	"ST_DOUT_WAIT_FOR_RESET",
+};
+
+static char *strDoutEvent[] =
+{
+	"EV_DOUT_START_XMIT",
+	"EV_DOUT_COMPLETE",
+	"EV_DOUT_DEN",
+	"EV_DOUT_RESETED",
+	"EV_DOUT_STOPPED",
+	"EV_DOUT_COLL",
+	"EV_DOUT_UNDERRUN",
+};
+
+static void dout_debug(struct FsmInst *fi, char *fmt, ...)
+{
+	va_list args;
+	char buf[256];
+	
+	va_start(args, fmt);
+	vsprintf(buf, fmt, args);
+	DBG(0x2, "%s", buf);
+	va_end(args);
+}
+
+static void dout_stop_event(void *context)
+{
+	struct st5481_adapter *adapter = context;
+
+	FsmEvent(&adapter->d_out.fsm, EV_DOUT_STOPPED, NULL);
+}
+
+/*
+ * Start the transfer of a D channel frame.
+ */
+static void usb_d_out(struct st5481_adapter *adapter, int buf_nr)
+{
+	struct st5481_d_out *d_out = &adapter->d_out;
+	struct urb *urb;
+	unsigned int num_packets, packet_offset;
+	int len, buf_size, bytes_sent;
+	struct sk_buff *skb;
+	iso_packet_descriptor_t *desc;
+
+	if (d_out->fsm.state != ST_DOUT_NORMAL)
+		return;
+
+	if (test_and_set_bit(buf_nr, &d_out->busy)) {
+		DBG(2, "ep %d urb %d busy %#lx", EP_D_OUT, buf_nr, d_out->busy);
+		return;
+	}
+	urb = d_out->urb[buf_nr];
+
+	skb = d_out->tx_skb;
+
+	buf_size = NUM_ISO_PACKETS_D * SIZE_ISO_PACKETS_D_OUT;
+	
+	if (skb) {
+		len = hdlc_encode(&d_out->hdlc_state, 
+				  skb->data, skb->len, &bytes_sent,
+				  urb->transfer_buffer, buf_size);
+		skb_pull(skb,bytes_sent);
+	} else {
+		// Send flags or idle
+		len = hdlc_encode(&d_out->hdlc_state, 
+				  NULL, 0, &bytes_sent,
+				  urb->transfer_buffer, buf_size);
+	}
+	
+	if (len < buf_size) {
+		FsmChangeState(&d_out->fsm, ST_DOUT_WAIT_FOR_UNDERRUN);
+	}
+	if (skb && !skb->len) {
+		d_out->tx_skb = NULL;
+		D_L1L2(adapter, PH_DATA | CONFIRM, NULL);
+		dev_kfree_skb_any(skb);
+	}
+
+	// Prepare the URB
+	urb->transfer_buffer_length = len;
+	num_packets = 0;
+	packet_offset = 0;
+	while (packet_offset < len) {
+		desc = &urb->iso_frame_desc[num_packets];
+		desc->offset = packet_offset;
+		desc->length = SIZE_ISO_PACKETS_D_OUT;
+		if (len - packet_offset < desc->length)
+			desc->length = len - packet_offset;
+		num_packets++;
+		packet_offset += desc->length;
+	}
+	urb->number_of_packets = num_packets;
+
+	// Prepare the URB
+	urb->dev = adapter->usb_dev;
+	// Need to transmit the next buffer 2ms after the DEN_EVENT
+	urb->transfer_flags = 0;
+	urb->start_frame = usb_get_current_frame_number(adapter->usb_dev)+2;
+
+	DBG_ISO_PACKET(0x20,urb);
+
+	if (usb_submit_urb(urb) < 0) {
+		// There is another URB queued up
+		urb->transfer_flags = USB_ISO_ASAP;
+		SUBMIT_URB(urb);
+	}	
+}
+
+static void fifo_reseted(void *context)
+{
+	struct st5481_adapter *adapter = context;
+
+	FsmEvent(&adapter->d_out.fsm, EV_DOUT_RESETED, NULL);
+}
+
+static void usb_d_out_complete(struct urb *urb)
+{
+	struct st5481_adapter *adapter = urb->context;
+	struct st5481_d_out *d_out = &adapter->d_out;
+	int buf_nr;
+	
+	DBG(2, "");
+
+	buf_nr = get_buf_nr(d_out->urb, urb);
+	test_and_clear_bit(buf_nr, &d_out->busy);
+
+	if (urb->status < 0) {
+		if (urb->status != USB_ST_URB_KILLED) {
+			WARN("urb status %d",urb->status);
+			if (d_out->busy == 0) {
+				st5481_usb_pipe_reset(adapter, EP_D_OUT | USB_DIR_OUT, fifo_reseted, adapter);
+			}
+			return;
+		} else {
+			DBG(1,"urb killed"); 
+			return; // Give up
+		}
+	}
+
+	FsmEvent(&adapter->d_out.fsm, EV_DOUT_COMPLETE, (void *) buf_nr);
+}
+
+/* ====================================================================== */
+
+static void dout_start_xmit(struct FsmInst *fsm, int event, void *arg)
+{
+	// FIXME unify?
+	struct st5481_adapter *adapter = fsm->userdata;
+	struct st5481_d_out *d_out = &adapter->d_out;
+	struct urb *urb;
+	int len, bytes_sent;
+	struct sk_buff *skb;
+	int buf_nr = 0;
+
+	skb = d_out->tx_skb;
+
+	DBG(2,"len=%d",skb->len);
+
+	hdlc_out_init(&d_out->hdlc_state, 1, 0);
+
+	if (test_and_set_bit(buf_nr, &d_out->busy)) {
+		WARN("ep %d urb %d busy %#lx", EP_D_OUT, buf_nr, d_out->busy);
+		return;
+	}
+	urb = d_out->urb[buf_nr];
+
+	DBG_SKB(0x10, skb);
+	len = hdlc_encode(&d_out->hdlc_state, 
+			  skb->data, skb->len, &bytes_sent,
+			  urb->transfer_buffer, 16);
+	skb_pull(skb, bytes_sent);
+
+	if(len < 16)
+		FsmChangeState(&d_out->fsm, ST_DOUT_SHORT_INIT);
+	else
+		FsmChangeState(&d_out->fsm, ST_DOUT_LONG_INIT);
+
+	if (skb->len == 0) {
+		d_out->tx_skb = NULL;
+		D_L1L2(adapter, PH_DATA | CONFIRM, NULL);
+		dev_kfree_skb_any(skb);
+	}
+
+// Prepare the URB
+	urb->transfer_buffer_length = len;
+
+	urb->iso_frame_desc[0].offset = 0;
+	urb->iso_frame_desc[0].length = len;
+	urb->number_of_packets = 1;
+
+	// Prepare the URB
+	urb->dev = adapter->usb_dev;
+	urb->transfer_flags = USB_ISO_ASAP;
+
+	DBG_ISO_PACKET(0x20,urb);
+	SUBMIT_URB(urb);
+}
+
+static void dout_short_fifo(struct FsmInst *fsm, int event, void *arg)
+{
+	struct st5481_adapter *adapter = fsm->userdata;
+	struct st5481_d_out *d_out = &adapter->d_out;
+
+	FsmChangeState(&d_out->fsm, ST_DOUT_SHORT_WAIT_DEN);
+	st5481_usb_device_ctrl_msg(adapter, OUT_D_COUNTER, 16, NULL, NULL);
+}
+
+static void dout_end_short_frame(struct FsmInst *fsm, int event, void *arg)
+{
+	struct st5481_adapter *adapter = fsm->userdata;
+	struct st5481_d_out *d_out = &adapter->d_out;
+
+	FsmChangeState(&d_out->fsm, ST_DOUT_WAIT_FOR_UNDERRUN);
+}
+
+static void dout_long_enable_fifo(struct FsmInst *fsm, int event, void *arg)
+{
+	struct st5481_adapter *adapter = fsm->userdata;
+	struct st5481_d_out *d_out = &adapter->d_out;
+    
+	st5481_usb_device_ctrl_msg(adapter, OUT_D_COUNTER, 16, NULL, NULL);
+	FsmChangeState(&d_out->fsm, ST_DOUT_LONG_WAIT_DEN);
+}
+
+static void dout_long_den(struct FsmInst *fsm, int event, void *arg)
+{
+	struct st5481_adapter *adapter = fsm->userdata;
+	struct st5481_d_out *d_out = &adapter->d_out;
+
+	FsmChangeState(&d_out->fsm, ST_DOUT_NORMAL);
+	usb_d_out(adapter, 0);
+	usb_d_out(adapter, 1);
+}
+
+static void dout_reset(struct FsmInst *fsm, int event, void *arg)
+{
+	struct st5481_adapter *adapter = fsm->userdata;
+	struct st5481_d_out *d_out = &adapter->d_out;
+
+	FsmChangeState(&d_out->fsm, ST_DOUT_WAIT_FOR_RESET);
+	st5481_usb_pipe_reset(adapter, EP_D_OUT | USB_DIR_OUT, fifo_reseted, adapter);
+}
+
+static void dout_stop(struct FsmInst *fsm, int event, void *arg)
+{
+	struct st5481_adapter *adapter = fsm->userdata;
+	struct st5481_d_out *d_out = &adapter->d_out;
+
+	FsmChangeState(&d_out->fsm, ST_DOUT_WAIT_FOR_STOP);
+	st5481_usb_device_ctrl_msg(adapter, OUT_D_COUNTER, 0, dout_stop_event, adapter);
+}
+
+static void dout_underrun(struct FsmInst *fsm, int event, void *arg)
+{
+	struct st5481_adapter *adapter = fsm->userdata;
+	struct st5481_d_out *d_out = &adapter->d_out;
+
+	if (test_bit(0, &d_out->busy) || test_bit(1, &d_out->busy)) {
+		FsmChangeState(&d_out->fsm, ST_DOUT_WAIT_FOR_NOT_BUSY);
+	}  else {
+		dout_stop(fsm, event, arg);
+	}
+}
+
+static void dout_check_busy(struct FsmInst *fsm, int event, void *arg)
+{
+	struct st5481_adapter *adapter = fsm->userdata;
+	struct st5481_d_out *d_out = &adapter->d_out;
+
+	if (!test_bit(0, &d_out->busy) && !test_bit(1, &d_out->busy))
+		dout_stop(fsm, event, arg);
+}
+
+static void dout_reseted(struct FsmInst *fsm, int event, void *arg)
+{
+	struct st5481_adapter *adapter = fsm->userdata;
+	struct st5481_d_out *d_out = &adapter->d_out;
+
+	FsmChangeState(&d_out->fsm, ST_DOUT_NONE);
+	// FIXME locking
+	if (d_out->tx_skb)
+		FsmEvent(&d_out->fsm, EV_DOUT_START_XMIT, NULL);
+}
+
+static void dout_complete(struct FsmInst *fsm, int event, void *arg)
+{
+	struct st5481_adapter *adapter = fsm->userdata;
+	int buf_nr = (int) arg;
+
+	usb_d_out(adapter, buf_nr);
+}
+
+static void dout_ignore(struct FsmInst *fsm, int event, void *arg)
+{
+}
+
+static struct FsmNode DoutFnList[] __initdata =
+{
+	{ST_DOUT_NONE,                   EV_DOUT_START_XMIT,   dout_start_xmit},
+
+	{ST_DOUT_SHORT_INIT,             EV_DOUT_COMPLETE,     dout_short_fifo},
+
+	{ST_DOUT_SHORT_WAIT_DEN,         EV_DOUT_DEN,          dout_end_short_frame},
+	{ST_DOUT_SHORT_WAIT_DEN,         EV_DOUT_UNDERRUN,     dout_underrun},
+
+	{ST_DOUT_LONG_INIT,              EV_DOUT_COMPLETE,     dout_long_enable_fifo},
+
+	{ST_DOUT_LONG_WAIT_DEN,          EV_DOUT_DEN,          dout_long_den},
+	{ST_DOUT_LONG_WAIT_DEN,          EV_DOUT_UNDERRUN,     dout_underrun},
+
+	{ST_DOUT_NORMAL,                 EV_DOUT_UNDERRUN,     dout_underrun},
+	{ST_DOUT_NORMAL,                 EV_DOUT_COMPLETE,     dout_complete},
+
+	{ST_DOUT_WAIT_FOR_UNDERRUN,      EV_DOUT_UNDERRUN,     dout_underrun},
+	{ST_DOUT_WAIT_FOR_UNDERRUN,      EV_DOUT_COMPLETE,     dout_ignore},
+
+	{ST_DOUT_WAIT_FOR_NOT_BUSY,      EV_DOUT_COMPLETE,     dout_check_busy},
+
+	{ST_DOUT_WAIT_FOR_STOP,          EV_DOUT_STOPPED,      dout_reset},
+
+	{ST_DOUT_WAIT_FOR_RESET,         EV_DOUT_RESETED,      dout_reseted},
+};
+
+void st5481_d_l2l1(struct hisax_if *hisax_d_if, int pr, void *arg)
+{
+	struct st5481_adapter *adapter = hisax_d_if->priv;
+	struct sk_buff *skb = arg;
+
+	switch (pr) {
+	case PH_ACTIVATE | REQUEST:
+		FsmEvent(&adapter->l1m, EV_PH_ACTIVATE_REQ, NULL);
+		break;
+	case PH_DEACTIVATE | REQUEST:
+		FsmEvent(&adapter->l1m, EV_PH_DEACTIVATE_REQ, NULL);
+		break;
+	case PH_DATA | REQUEST:
+		DBG(2, "PH_DATA REQUEST len %d", skb->len);
+		if (adapter->d_out.tx_skb)
+			BUG();
+
+		adapter->d_out.tx_skb = skb;
+		FsmEvent(&adapter->d_out.fsm, EV_DOUT_START_XMIT, NULL);
+		break;
+	default:
+		WARN("pr %#x\n", pr);
+		break;
+	}
+}
+
+/* ======================================================================
+ */
+
+/*
+ * Start receiving on the D channel since entered state F7.
+ */
+static void ph_connect(struct st5481_adapter *adapter)
+{
+	struct st5481_d_out *d_out = &adapter->d_out;
+	struct st5481_in *d_in = &adapter->d_in;
+
+	DBG(8,"");
+		
+	FsmChangeState(&d_out->fsm, ST_DOUT_NONE);
+
+	//	st5481_usb_device_ctrl_msg(adapter, FFMSK_D, OUT_UNDERRUN, NULL, NULL);
+	st5481_usb_device_ctrl_msg(adapter, FFMSK_D, 0xfc, NULL, NULL);
+	st5481_in_mode(d_in, L1_MODE_HDLC);
+
+#if LOOPBACK
+	// Turn loopback on (data sent on B and D looped back)
+	st5481_usb_device_ctrl_msg(cs, LBB, 0x04, NULL, NULL);
+#endif
+
+	st5481_usb_pipe_reset(adapter, EP_D_OUT | USB_DIR_OUT, NULL, NULL);
+
+	// Turn on the green LED to tell that we are in state F7
+	adapter->leds |= GREEN_LED;
+	st5481_usb_device_ctrl_msg(adapter, GPIO_OUT, adapter->leds, NULL, NULL);
+}
+
+/*
+ * Stop receiving on the D channel since not in state F7.
+ */
+static void ph_disconnect(struct st5481_adapter *adapter)
+{
+	DBG(8,"");
+
+	st5481_in_mode(&adapter->d_in, L1_MODE_NULL);
+
+	// Turn off the green LED to tell that we left state F7
+	adapter->leds &= ~GREEN_LED;
+	st5481_usb_device_ctrl_msg(adapter, GPIO_OUT, adapter->leds, NULL, NULL);
+}
+
+static int __devinit st5481_setup_d_out(struct st5481_adapter *adapter)
+{
+	struct usb_device *dev = adapter->usb_dev;
+	struct usb_interface_descriptor *altsetting;
+	struct usb_endpoint_descriptor *endpoint;
+	struct st5481_d_out *d_out = &adapter->d_out;
+
+	DBG(2,"");
+
+	altsetting = &(dev->config->interface[0].altsetting[3]);
+
+	// Allocate URBs and buffers for the D channel out
+	endpoint = &altsetting->endpoint[EP_D_OUT-1];
+
+	DBG(2,"endpoint address=%02x,packet size=%d",
+	    endpoint->bEndpointAddress,endpoint->wMaxPacketSize);
+
+	return st5481_setup_isocpipes(d_out->urb, dev, 
+				      usb_sndisocpipe(dev, endpoint->bEndpointAddress),
+				      NUM_ISO_PACKETS_D, SIZE_ISO_PACKETS_D_OUT,
+				      NUM_ISO_PACKETS_D * SIZE_ISO_PACKETS_D_OUT,
+				      usb_d_out_complete, adapter);
+}
+
+static void __devexit st5481_release_d_out(struct st5481_adapter *adapter)
+{
+	struct st5481_d_out *d_out = &adapter->d_out;
+
+	DBG(2,"");
+
+	st5481_release_isocpipes(d_out->urb);
+}
+
+int __devinit st5481_setup_d(struct st5481_adapter *adapter)
+{
+	int retval;
+
+	DBG(2,"");
+
+	retval = st5481_setup_d_out(adapter);
+	if (retval)
+		goto err;
+	adapter->d_in.bufsize = MAX_DFRAME_LEN_L1;
+	adapter->d_in.num_packets = NUM_ISO_PACKETS_D;
+	adapter->d_in.packet_size = SIZE_ISO_PACKETS_D_IN;
+	adapter->d_in.ep = EP_D_IN | USB_DIR_IN;
+	adapter->d_in.counter = IN_D_COUNTER;
+	adapter->d_in.adapter = adapter;
+	adapter->d_in.hisax_if = &adapter->hisax_d_if.ifc;
+	retval = st5481_setup_in(&adapter->d_in);
+	if (retval)
+		goto err_d_out;
+
+	adapter->l1m.fsm = &l1fsm;
+	adapter->l1m.state = ST_L1_F3;
+	adapter->l1m.debug = 1;
+	adapter->l1m.userdata = adapter;
+	adapter->l1m.printdebug = l1m_debug;
+	FsmInitTimer(&adapter->l1m, &adapter->timer);
+
+	adapter->d_out.fsm.fsm = &dout_fsm;
+	adapter->d_out.fsm.state = ST_DOUT_NONE;
+	adapter->d_out.fsm.debug = 1;
+	adapter->d_out.fsm.userdata = adapter;
+	adapter->d_out.fsm.printdebug = dout_debug;
+
+	return 0;
+
+ err_d_out:
+	st5481_release_d_out(adapter);
+ err:
+	return retval;
+}
+
+void __devexit st5481_release_d(struct st5481_adapter *adapter)
+{
+	DBG(2,"");
+
+	st5481_release_in(&adapter->d_in);
+	st5481_release_d_out(adapter);
+}
+
+/* ======================================================================
+ * init / exit
+ */
+
+int __init st5481_d_init(void)
+{
+	int retval;
+
+	l1fsm.state_count = L1_STATE_COUNT;
+	l1fsm.event_count = L1_EVENT_COUNT;
+	l1fsm.strEvent = strL1Event;
+	l1fsm.strState = strL1State;
+	retval = FsmNew(&l1fsm, L1FnList, ARRAY_SIZE(L1FnList));
+	if (retval)
+		goto err;
+
+	dout_fsm.state_count = DOUT_STATE_COUNT;
+	dout_fsm.event_count = DOUT_EVENT_COUNT;
+	dout_fsm.strEvent = strDoutEvent;
+	dout_fsm.strState = strDoutState;
+	retval = FsmNew(&dout_fsm, DoutFnList, ARRAY_SIZE(DoutFnList));
+	if (retval)
+		goto err_l1;
+
+	return 0;
+
+ err_l1:
+	FsmFree(&l1fsm);
+ err:
+	return retval;
+}
+
+// can't be __exit
+void st5481_d_exit(void)
+{
+	FsmFree(&l1fsm);
+	FsmFree(&dout_fsm);
+}
diff -u --recursive --new-file v2.4.9/linux/drivers/isdn/hisax/st5481_hdlc.c linux/drivers/isdn/hisax/st5481_hdlc.c
--- v2.4.9/linux/drivers/isdn/hisax/st5481_hdlc.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/isdn/hisax/st5481_hdlc.c	Sun Sep  9 10:45:43 2001
@@ -0,0 +1,620 @@
+/*
+ * Driver for ST5481 USB ISDN modem
+ *
+ * Author       Frode Isaksen
+ * Copyright    2001 by Frode Isaksen      <fisaksen@bewan.com>
+ *              2001 by Kai Germaschewski  <kai.germaschewski@gmx.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ */
+
+#include "st5481_hdlc.h"
+
+static const unsigned short int crc16_tab[] = {
+	0x0000,0x1189,0x2312,0x329b,0x4624,0x57ad,0x6536,0x74bf,
+	0x8c48,0x9dc1,0xaf5a,0xbed3,0xca6c,0xdbe5,0xe97e,0xf8f7,
+	0x1081,0x0108,0x3393,0x221a,0x56a5,0x472c,0x75b7,0x643e,
+	0x9cc9,0x8d40,0xbfdb,0xae52,0xdaed,0xcb64,0xf9ff,0xe876,
+	0x2102,0x308b,0x0210,0x1399,0x6726,0x76af,0x4434,0x55bd,
+	0xad4a,0xbcc3,0x8e58,0x9fd1,0xeb6e,0xfae7,0xc87c,0xd9f5,
+	0x3183,0x200a,0x1291,0x0318,0x77a7,0x662e,0x54b5,0x453c,
+	0xbdcb,0xac42,0x9ed9,0x8f50,0xfbef,0xea66,0xd8fd,0xc974,
+	0x4204,0x538d,0x6116,0x709f,0x0420,0x15a9,0x2732,0x36bb,
+	0xce4c,0xdfc5,0xed5e,0xfcd7,0x8868,0x99e1,0xab7a,0xbaf3,
+	0x5285,0x430c,0x7197,0x601e,0x14a1,0x0528,0x37b3,0x263a,
+	0xdecd,0xcf44,0xfddf,0xec56,0x98e9,0x8960,0xbbfb,0xaa72,
+	0x6306,0x728f,0x4014,0x519d,0x2522,0x34ab,0x0630,0x17b9,
+	0xef4e,0xfec7,0xcc5c,0xddd5,0xa96a,0xb8e3,0x8a78,0x9bf1,
+	0x7387,0x620e,0x5095,0x411c,0x35a3,0x242a,0x16b1,0x0738,
+	0xffcf,0xee46,0xdcdd,0xcd54,0xb9eb,0xa862,0x9af9,0x8b70,
+	0x8408,0x9581,0xa71a,0xb693,0xc22c,0xd3a5,0xe13e,0xf0b7,
+	0x0840,0x19c9,0x2b52,0x3adb,0x4e64,0x5fed,0x6d76,0x7cff,
+	0x9489,0x8500,0xb79b,0xa612,0xd2ad,0xc324,0xf1bf,0xe036,
+	0x18c1,0x0948,0x3bd3,0x2a5a,0x5ee5,0x4f6c,0x7df7,0x6c7e,
+	0xa50a,0xb483,0x8618,0x9791,0xe32e,0xf2a7,0xc03c,0xd1b5,
+	0x2942,0x38cb,0x0a50,0x1bd9,0x6f66,0x7eef,0x4c74,0x5dfd,
+	0xb58b,0xa402,0x9699,0x8710,0xf3af,0xe226,0xd0bd,0xc134,
+	0x39c3,0x284a,0x1ad1,0x0b58,0x7fe7,0x6e6e,0x5cf5,0x4d7c,
+	0xc60c,0xd785,0xe51e,0xf497,0x8028,0x91a1,0xa33a,0xb2b3,
+	0x4a44,0x5bcd,0x6956,0x78df,0x0c60,0x1de9,0x2f72,0x3efb,
+	0xd68d,0xc704,0xf59f,0xe416,0x90a9,0x8120,0xb3bb,0xa232,
+	0x5ac5,0x4b4c,0x79d7,0x685e,0x1ce1,0x0d68,0x3ff3,0x2e7a,
+	0xe70e,0xf687,0xc41c,0xd595,0xa12a,0xb0a3,0x8238,0x93b1,
+	0x6b46,0x7acf,0x4854,0x59dd,0x2d62,0x3ceb,0x0e70,0x1ff9,
+	0xf78f,0xe606,0xd49d,0xc514,0xb1ab,0xa022,0x92b9,0x8330,
+	0x7bc7,0x6a4e,0x58d5,0x495c,0x3de3,0x2c6a,0x1ef1,0x0f78
+};
+
+
+
+enum {
+	HDLC_FAST_IDLE,HDLC_GET_FLAG_B0,HDLC_GETFLAG_B1A6,HDLC_GETFLAG_B7,
+	HDLC_GET_DATA,HDLC_FAST_FLAG
+};
+
+enum {
+	HDLC_SEND_DATA,HDLC_SEND_CRC1,HDLC_SEND_FAST_FLAG,
+	HDLC_SEND_FIRST_FLAG,HDLC_SEND_CRC2,HDLC_SEND_CLOSING_FLAG,
+	HDLC_SEND_IDLE1,HDLC_SEND_FAST_IDLE,HDLC_SENDFLAG_B0,
+	HDLC_SENDFLAG_B1A6,HDLC_SENDFLAG_B7,STOPPED
+};
+
+void 
+hdlc_rcv_init(struct hdlc_vars *hdlc, int do_adapt56)
+{
+   	hdlc->bit_shift = 0;
+	hdlc->hdlc_bits1 = 0;
+	hdlc->data_bits = 0;
+	hdlc->ffbit_shift = 0;
+	hdlc->data_received = 0;
+	hdlc->state = HDLC_GET_DATA;
+	hdlc->do_adapt56 = do_adapt56;
+	hdlc->dchannel = 0;
+	hdlc->crc = 0;
+	hdlc->cbin = 0;
+	hdlc->shift_reg = 0;
+	hdlc->ffvalue = 0;
+	hdlc->dstpos = 0;
+}
+
+void 
+hdlc_out_init(struct hdlc_vars *hdlc, int is_d_channel, int do_adapt56)
+{
+   	hdlc->bit_shift = 0;
+	hdlc->hdlc_bits1 = 0;
+	hdlc->data_bits = 0;
+	hdlc->ffbit_shift = 0;
+	hdlc->data_received = 0;
+	hdlc->do_closing = 0;
+	hdlc->ffvalue = 0;
+	if (is_d_channel) {
+		hdlc->dchannel = 1;
+		hdlc->state = HDLC_SEND_FIRST_FLAG;
+	} else {
+		hdlc->dchannel = 0;
+		hdlc->state = HDLC_SEND_FAST_FLAG;
+		hdlc->ffvalue = 0x7e;
+	} 
+	hdlc->cbin = 0x7e;
+	hdlc->bit_shift = 0;
+	if(do_adapt56){
+		hdlc->do_adapt56 = 1;		
+		hdlc->data_bits = 0;
+		hdlc->state = HDLC_SENDFLAG_B0;
+	} else {
+		hdlc->do_adapt56 = 0;		
+		hdlc->data_bits = 8;
+	}
+	hdlc->shift_reg = 0;
+}
+
+/*
+  hdlc_decode - decodes HDLC frames from a transparent bit stream.
+
+  The source buffer is scanned for valid HDLC frames looking for
+  flags (01111110) to indicate the start of a frame. If the start of
+  the frame is found, the bit stuffing is removed (0 after 5 1's).
+  When a new flag is found, the complete frame has been received
+  and the CRC is checked.
+  If a valid frame is found, the function returns the frame length 
+  excluding the CRC with the bit HDLC_END_OF_FRAME set.
+  If the beginning of a valid frame is found, the function returns
+  the length. 
+  If a framing error is found (too many 1s and not a flag) the function 
+  returns the length with the bit HDLC_FRAMING_ERROR set.
+  If a CRC error is found the function returns the length with the
+  bit HDLC_CRC_ERROR set.
+  If the frame length exceeds the destination buffer size, the function
+  returns the length with the bit HDLC_LENGTH_ERROR set.
+
+  src - source buffer
+  slen - source buffer length
+  count - number of bytes removed (decoded) from the source buffer
+  dst _ destination buffer
+  dsize - destination buffer size
+  returns - number of decoded bytes in the destination buffer and status
+  flag.
+ */
+int hdlc_decode(struct hdlc_vars *hdlc, const unsigned char *src,
+		int slen, int *count, unsigned char *dst, int dsize)
+{
+	int status=0;
+
+	static const unsigned char fast_flag[]={
+		0x00,0x00,0x00,0x20,0x30,0x38,0x3c,0x3e,0x3f
+	};
+
+	static const unsigned char fast_flag_value[]={
+		0x00,0x7e,0xfc,0xf9,0xf3,0xe7,0xcf,0x9f,0x3f
+	};
+
+	static const unsigned char fast_abort[]={
+		0x00,0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff
+	};
+
+	*count = slen;
+
+	while(slen > 0){
+		if(hdlc->bit_shift==0){
+			hdlc->cbin = *src++;
+			slen--;
+			hdlc->bit_shift = 8;
+			if(hdlc->do_adapt56){
+				hdlc->bit_shift --;
+			}
+		}
+
+		switch(hdlc->state){
+		case STOPPED:
+			return 0;
+		case HDLC_FAST_IDLE:
+			if(hdlc->cbin == 0xff){
+				hdlc->bit_shift = 0;
+				break;
+			}
+			hdlc->state = HDLC_GET_FLAG_B0;
+			hdlc->hdlc_bits1 = 0;
+			hdlc->bit_shift = 8;
+			break;
+		case HDLC_GET_FLAG_B0:
+			if(!(hdlc->cbin & 0x80)) {
+				hdlc->state = HDLC_GETFLAG_B1A6;
+				hdlc->hdlc_bits1 = 0;
+			} else {
+				if(!hdlc->do_adapt56){
+					if(++hdlc->hdlc_bits1 >=8 ) if(hdlc->bit_shift==1)
+						hdlc->state = HDLC_FAST_IDLE;
+				}
+			}
+			hdlc->cbin<<=1;
+			hdlc->bit_shift --;
+			break;
+		case HDLC_GETFLAG_B1A6:
+			if(hdlc->cbin & 0x80){
+				hdlc->hdlc_bits1++;
+				if(hdlc->hdlc_bits1==6){
+					hdlc->state = HDLC_GETFLAG_B7;
+				}
+			} else {
+				hdlc->hdlc_bits1 = 0;
+			}
+			hdlc->cbin<<=1;
+			hdlc->bit_shift --;
+			break;
+		case HDLC_GETFLAG_B7:
+			if(hdlc->cbin & 0x80) {
+				hdlc->state = HDLC_GET_FLAG_B0;
+			} else {
+				hdlc->state = HDLC_GET_DATA;
+				hdlc->crc = 0xffff;
+				hdlc->shift_reg = 0;
+				hdlc->hdlc_bits1 = 0;
+				hdlc->data_bits = 0;
+				hdlc->data_received = 0;
+			}
+			hdlc->cbin<<=1;
+			hdlc->bit_shift --;
+			break;
+		case HDLC_GET_DATA:
+			if(hdlc->cbin & 0x80){
+				hdlc->hdlc_bits1++;
+				switch(hdlc->hdlc_bits1){
+				case 6:
+					break;
+				case 7:
+					if(hdlc->data_received) {
+						// bad frame
+						status = -HDLC_FRAMING_ERROR;
+					}
+					if(!hdlc->do_adapt56){
+						if(hdlc->cbin==fast_abort[hdlc->bit_shift+1]){
+							hdlc->state = HDLC_FAST_IDLE;
+							hdlc->bit_shift=1;
+							break;
+						}
+					} else {
+						hdlc->state = HDLC_GET_FLAG_B0;
+					}
+					break;
+				default:
+					hdlc->shift_reg>>=1;
+					hdlc->shift_reg |= 0x80;
+					hdlc->data_bits++;
+					break;
+				}
+			} else {
+				switch(hdlc->hdlc_bits1){
+				case 5:
+					break;
+				case 6:
+					if(hdlc->data_received){
+						if (hdlc->dstpos < 2) {
+							status = -HDLC_FRAMING_ERROR;
+						} else if (hdlc->crc != 0xf0b8){
+							// crc error
+							status = -HDLC_CRC_ERROR;
+						} else {
+							// remove CRC
+							hdlc->dstpos -= 2;
+							// good frame
+							status = hdlc->dstpos;
+						}
+					}
+					hdlc->crc = 0xffff;
+					hdlc->shift_reg = 0;
+					hdlc->data_bits = 0;
+					if(!hdlc->do_adapt56){
+						if(hdlc->cbin==fast_flag[hdlc->bit_shift]){
+							hdlc->ffvalue = fast_flag_value[hdlc->bit_shift];
+							hdlc->state = HDLC_FAST_FLAG;
+							hdlc->ffbit_shift = hdlc->bit_shift;
+							hdlc->bit_shift = 1;
+						} else {
+							hdlc->state = HDLC_GET_DATA;
+							hdlc->data_received = 0;
+						}
+					} else {
+						hdlc->state = HDLC_GET_DATA;
+						hdlc->data_received = 0;
+					}
+					break;
+				default:
+					hdlc->shift_reg>>=1;
+					hdlc->data_bits++;
+					break;
+				}
+				hdlc->hdlc_bits1 = 0;
+			}
+			if (status) {
+				hdlc->dstpos = 0;
+				*count -= slen;
+				hdlc->cbin <<= 1;
+				hdlc->bit_shift--;
+				return status;
+			}
+			if(hdlc->data_bits==8){
+				unsigned cval;
+				
+				hdlc->data_bits = 0;
+				hdlc->data_received = 1;
+				cval = (hdlc->crc^hdlc->shift_reg) & 0xff;
+				hdlc->crc = (hdlc->crc>>8)^crc16_tab[cval];
+				// good byte received
+				if (dsize--) {
+					dst[hdlc->dstpos++] = hdlc->shift_reg;
+				} else {
+					// frame too long
+					status = -HDLC_LENGTH_ERROR;
+					hdlc->dstpos = 0;
+				}
+			}
+			hdlc->cbin <<= 1;
+			hdlc->bit_shift--;
+			break;
+		case HDLC_FAST_FLAG:
+			if(hdlc->cbin==hdlc->ffvalue){
+				hdlc->bit_shift = 0;
+				break;
+			} else {
+				if(hdlc->cbin == 0xff){
+					hdlc->state = HDLC_FAST_IDLE;
+					hdlc->bit_shift=0;
+				} else if(hdlc->ffbit_shift==8){
+					hdlc->state = HDLC_GETFLAG_B7;
+					break;
+				} else {
+					hdlc->shift_reg = fast_abort[hdlc->ffbit_shift-1];
+					hdlc->hdlc_bits1 = hdlc->ffbit_shift-2;
+					if(hdlc->hdlc_bits1<0)hdlc->hdlc_bits1 = 0;
+					hdlc->data_bits = hdlc->ffbit_shift-1;
+					hdlc->state = HDLC_GET_DATA;
+					hdlc->data_received = 0;
+				}
+			}
+			break;
+		default:
+			break;
+		}
+	}
+	*count -= slen;
+	return 0;
+}
+
+/*
+  hdlc_encode - encodes HDLC frames to a transparent bit stream.
+
+  The bit stream starts with a beginning flag (01111110). After
+  that each byte is added to the bit stream with bit stuffing added
+  (0 after 5 1's).
+  When the last byte has been removed from the source buffer, the
+  CRC (2 bytes is added) and the frame terminates with the ending flag.
+  For the dchannel, the idle character (all 1's) is also added at the end.
+  If this function is called with empty source buffer (slen=0), flags or
+  idle character will be generated.
+ 
+  src - source buffer
+  slen - source buffer length
+  count - number of bytes removed (encoded) from source buffer
+  dst _ destination buffer
+  dsize - destination buffer size
+  returns - number of encoded bytes in the destination buffer
+*/
+int hdlc_encode(struct hdlc_vars *hdlc, const unsigned char *src, 
+		unsigned short slen, int *count,
+		unsigned char *dst, int dsize)
+{
+	static const unsigned char xfast_flag_value[] = {
+		0x7e,0x3f,0x9f,0xcf,0xe7,0xf3,0xf9,0xfc,0x7e
+	};
+
+	int len = 0;
+
+	*count = slen;
+
+	while (dsize > 0) {
+		if(hdlc->bit_shift==0){	
+			if(slen && !hdlc->do_closing){
+				hdlc->shift_reg = *src++;
+				slen--;
+				if (slen == 0) 
+					hdlc->do_closing = 1;  /* closing sequence, CRC + flag(s) */
+				hdlc->bit_shift = 8;
+			} else {
+				if(hdlc->state == HDLC_SEND_DATA){
+					if(hdlc->data_received){
+						hdlc->state = HDLC_SEND_CRC1;
+						hdlc->crc ^= 0xffff;
+						hdlc->bit_shift = 8;
+						hdlc->shift_reg = hdlc->crc & 0xff;
+					} else if(!hdlc->do_adapt56){
+						hdlc->state = HDLC_SEND_FAST_FLAG;
+					} else {
+						hdlc->state = HDLC_SENDFLAG_B0;
+					}
+				}
+			  
+			}
+		}
+
+		switch(hdlc->state){
+		case STOPPED:
+			while (dsize--)
+				*dst++ = 0xff;
+		  
+			return dsize;
+		case HDLC_SEND_FAST_FLAG:
+			hdlc->do_closing = 0;
+			if(slen == 0){
+				*dst++ = hdlc->ffvalue;
+				len++;
+				dsize--;
+				break;
+			}
+			if(hdlc->bit_shift==8){
+				hdlc->cbin = hdlc->ffvalue>>(8-hdlc->data_bits);
+				hdlc->state = HDLC_SEND_DATA;
+				hdlc->crc = 0xffff;
+				hdlc->hdlc_bits1 = 0;
+				hdlc->data_received = 1;
+			}
+			break;
+		case HDLC_SENDFLAG_B0:
+			hdlc->do_closing = 0;
+			hdlc->cbin <<= 1;
+			hdlc->data_bits++;
+			hdlc->hdlc_bits1 = 0;
+			hdlc->state = HDLC_SENDFLAG_B1A6;
+			break;
+		case HDLC_SENDFLAG_B1A6:
+			hdlc->cbin <<= 1;
+			hdlc->data_bits++;
+			hdlc->cbin++;
+			if(++hdlc->hdlc_bits1 == 6)
+				hdlc->state = HDLC_SENDFLAG_B7;
+			break;
+		case HDLC_SENDFLAG_B7:
+			hdlc->cbin <<= 1;
+			hdlc->data_bits++;
+			if(slen == 0){
+				hdlc->state = HDLC_SENDFLAG_B0;
+				break;
+			}
+			if(hdlc->bit_shift==8){
+				hdlc->state = HDLC_SEND_DATA;
+				hdlc->crc = 0xffff;
+				hdlc->hdlc_bits1 = 0;
+				hdlc->data_received = 1;
+			}
+			break;
+		case HDLC_SEND_FIRST_FLAG:
+			hdlc->data_received = 1;
+			if(hdlc->data_bits==8){
+				hdlc->state = HDLC_SEND_DATA;
+				hdlc->crc = 0xffff;
+				hdlc->hdlc_bits1 = 0;
+				break;
+			}
+			hdlc->cbin <<= 1;
+			hdlc->data_bits++;
+			if(hdlc->shift_reg & 0x01)
+				hdlc->cbin++;
+			hdlc->shift_reg >>= 1;
+			hdlc->bit_shift--;
+			if(hdlc->bit_shift==0){
+				hdlc->state = HDLC_SEND_DATA;
+				hdlc->crc = 0xffff;
+				hdlc->hdlc_bits1 = 0;
+			}
+			break;
+		case HDLC_SEND_DATA:
+			hdlc->cbin <<= 1;
+			hdlc->data_bits++;
+			if(hdlc->hdlc_bits1 == 5){
+				hdlc->hdlc_bits1 = 0;
+				break;
+			}
+			if(hdlc->bit_shift==8){
+				unsigned cval;
+
+				cval = (hdlc->crc^hdlc->shift_reg) & 0xff;
+				hdlc->crc = (hdlc->crc>>8)^crc16_tab[cval];
+			}
+			if(hdlc->shift_reg & 0x01){
+				hdlc->hdlc_bits1++;
+				hdlc->cbin++;
+				hdlc->shift_reg >>= 1;
+				hdlc->bit_shift--;
+			} else {
+				hdlc->hdlc_bits1 = 0;
+				hdlc->shift_reg >>= 1;
+				hdlc->bit_shift--;
+			}
+			break;
+		case HDLC_SEND_CRC1:
+			hdlc->cbin <<= 1;
+			hdlc->data_bits++;
+			if(hdlc->hdlc_bits1 == 5){
+				hdlc->hdlc_bits1 = 0;
+				break;
+			}
+			if(hdlc->shift_reg & 0x01){
+				hdlc->hdlc_bits1++;
+				hdlc->cbin++;
+				hdlc->shift_reg >>= 1;
+				hdlc->bit_shift--;
+			} else {
+				hdlc->hdlc_bits1 = 0;
+				hdlc->shift_reg >>= 1;
+				hdlc->bit_shift--;
+			}
+			if(hdlc->bit_shift==0){
+				hdlc->shift_reg = (hdlc->crc >> 8);
+				hdlc->state = HDLC_SEND_CRC2;
+				hdlc->bit_shift = 8;
+			}
+			break;
+		case HDLC_SEND_CRC2:
+			hdlc->cbin <<= 1;
+			hdlc->data_bits++;
+			if(hdlc->hdlc_bits1 == 5){
+				hdlc->hdlc_bits1 = 0;
+				break;
+			}
+			if(hdlc->shift_reg & 0x01){
+				hdlc->hdlc_bits1++;
+				hdlc->cbin++;
+				hdlc->shift_reg >>= 1;
+				hdlc->bit_shift--;
+			} else {
+				hdlc->hdlc_bits1 = 0;
+				hdlc->shift_reg >>= 1;
+				hdlc->bit_shift--;
+			}
+			if(hdlc->bit_shift==0){
+				hdlc->shift_reg = 0x7e;
+				hdlc->state = HDLC_SEND_CLOSING_FLAG;
+				hdlc->bit_shift = 8;
+			}
+			break;
+		case HDLC_SEND_CLOSING_FLAG:
+			hdlc->cbin <<= 1;
+			hdlc->data_bits++;
+			if(hdlc->hdlc_bits1 == 5){
+				hdlc->hdlc_bits1 = 0;
+				break;
+			}
+			if(hdlc->shift_reg & 0x01){
+				hdlc->cbin++;
+			}
+			hdlc->shift_reg >>= 1;
+			hdlc->bit_shift--;
+			if(hdlc->bit_shift==0){
+				hdlc->ffvalue = xfast_flag_value[hdlc->data_bits];
+				if(hdlc->dchannel){
+					hdlc->ffvalue = 0x7e;
+					hdlc->state = HDLC_SEND_IDLE1;
+					hdlc->bit_shift = 8-hdlc->data_bits;
+					if(hdlc->bit_shift==0)
+						hdlc->state = HDLC_SEND_FAST_IDLE;
+				} else {
+					if(!hdlc->do_adapt56){
+						hdlc->state = HDLC_SEND_FAST_FLAG;
+						hdlc->data_received = 0;
+					} else {
+						hdlc->state = HDLC_SENDFLAG_B0;
+						hdlc->data_received = 0;
+					}
+					// Finished with this frame, send flags
+					if (dsize > 1) dsize = 1; 
+				}
+			}
+			break;
+		case HDLC_SEND_IDLE1:
+			hdlc->do_closing = 0;
+			hdlc->cbin <<= 1;
+			hdlc->cbin++;
+			hdlc->data_bits++;
+			hdlc->bit_shift--;
+			if(hdlc->bit_shift==0){
+				hdlc->state = HDLC_SEND_FAST_IDLE;
+				hdlc->bit_shift = 0;
+			}
+			break;
+		case HDLC_SEND_FAST_IDLE:
+			hdlc->do_closing = 0;
+			hdlc->cbin = 0xff;
+			hdlc->data_bits = 8;
+			if(hdlc->bit_shift == 8){
+				hdlc->cbin = 0x7e;
+				hdlc->state = HDLC_SEND_FIRST_FLAG;
+			} else {
+				*dst++ = hdlc->cbin;
+				hdlc->bit_shift = hdlc->data_bits = 0;
+				len++;
+				dsize = 0;
+			}
+			break;
+		default:
+			break;
+		}
+		if(hdlc->do_adapt56){
+			if(hdlc->data_bits==7){
+				hdlc->cbin <<= 1;
+				hdlc->cbin++;
+				hdlc->data_bits++;
+			}
+		}
+		if(hdlc->data_bits==8){
+			*dst++ = hdlc->cbin;
+			hdlc->data_bits = 0;
+			len++;
+			dsize--;
+		}
+	}
+	*count -= slen;
+
+	return len;
+}
+
diff -u --recursive --new-file v2.4.9/linux/drivers/isdn/hisax/st5481_hdlc.h linux/drivers/isdn/hisax/st5481_hdlc.h
--- v2.4.9/linux/drivers/isdn/hisax/st5481_hdlc.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/isdn/hisax/st5481_hdlc.h	Sun Sep  9 10:45:43 2001
@@ -0,0 +1,62 @@
+/*
+ * Driver for ST5481 USB ISDN modem
+ *
+ * Author       Frode Isaksen
+ * Copyright    2001 by Frode Isaksen      <fisaksen@bewan.com>
+ *              2001 by Kai Germaschewski  <kai.germaschewski@gmx.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ */
+
+#ifndef __ST5481_HDLC_H__
+#define __ST5481_HDLC_H__
+
+struct hdlc_vars {
+  	int bit_shift; 
+	int hdlc_bits1;
+	int data_bits;
+	int ffbit_shift; // encoding only
+	int state;
+	int dstpos;
+
+	int data_received:1; // set if transferring data
+	int dchannel:1; // set if D channel (send idle instead of flags)
+	int do_adapt56:1; // set if 56K adaptation
+        int do_closing:1; // set if in closing phase (need to send CRC + flag
+
+	unsigned short crc;
+
+	unsigned char cbin; 
+	unsigned char shift_reg;
+	unsigned char ffvalue;
+	
+};
+
+
+/*
+  The return value from hdlc_decode is
+  the frame length, 0 if no complete frame was decoded,
+  or a negative error number
+*/
+
+#define HDLC_FRAMING_ERROR     1
+#define HDLC_CRC_ERROR         2
+#define HDLC_LENGTH_ERROR      3
+
+void 
+hdlc_rcv_init(struct hdlc_vars *hdlc, int do_adapt56);
+
+int
+hdlc_decode(struct hdlc_vars *hdlc, const unsigned char *src, int slen,int *count, 
+	    unsigned char *dst, int dsize);
+
+void 
+hdlc_out_init(struct hdlc_vars *hdlc,int is_d_channel,int do_adapt56);
+
+int 
+hdlc_encode(struct hdlc_vars *hdlc,const unsigned char *src,unsigned short slen,int *count,
+	    unsigned char *dst,int dsize);
+
+#endif
diff -u --recursive --new-file v2.4.9/linux/drivers/isdn/hisax/st5481_init.c linux/drivers/isdn/hisax/st5481_init.c
--- v2.4.9/linux/drivers/isdn/hisax/st5481_init.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/isdn/hisax/st5481_init.c	Sun Sep  9 10:45:43 2001
@@ -0,0 +1,215 @@
+/*
+ * Driver for ST5481 USB ISDN modem
+ *
+ * Author       Frode Isaksen
+ * Copyright    2001 by Frode Isaksen      <fisaksen@bewan.com>
+ *              2001 by Kai Germaschewski  <kai.germaschewski@gmx.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ */
+
+/* 
+ * TODO:
+ *
+ * b layer1 delay?
+ * hdlc as module
+ * hotplug / unregister issues
+ * mod_inc/dec_use_count
+ * unify parts of d/b channel usb handling
+ * file header
+ * avoid copy to isoc buffer?
+ * improve usb delay?
+ * merge l1 state machines?
+ * clean up debug
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/usb.h>
+#include <linux/slab.h>
+#include "st5481.h"
+
+MODULE_AUTHOR("Frode Isaksen <fisaksen@bewan.com>");
+MODULE_DESCRIPTION("ST5481 USB ISDN modem driver");
+
+static int protocol = 2;       /* EURO-ISDN Default */
+MODULE_PARM(protocol, "i");
+
+static int number_of_leds = 2;       /* 2 LEDs on the adpater default */
+MODULE_PARM(number_of_leds, "i");
+
+#ifdef CONFIG_HISAX_DEBUG
+static int debug = 0x1;
+MODULE_PARM(debug, "i");
+int st5481_debug;
+#endif
+
+static LIST_HEAD(adapter_list);
+
+/* ======================================================================
+ * registration/deregistration with the USB layer
+ */
+
+/*
+ * This function will be called when the adapter is plugged
+ * into the USB bus.
+ */
+static void * __devinit probe_st5481(struct usb_device *dev,
+				     unsigned int ifnum,
+				     const struct usb_device_id *id)
+{
+	struct st5481_adapter *adapter;
+	struct hisax_b_if *b_if[2];
+	int retval, i;
+
+	printk(KERN_INFO "st541: found adapter VendorId %04x, ProductId %04x, LEDs %d\n",
+	     dev->descriptor.idVendor, dev->descriptor.idProduct,
+	     number_of_leds);
+
+	adapter = kmalloc(sizeof(struct st5481_adapter), GFP_KERNEL);
+	if (!adapter)
+		return NULL;
+
+	memset(adapter, 0, sizeof(struct st5481_adapter));
+
+	adapter->number_of_leds = number_of_leds;
+	adapter->usb_dev = dev;
+
+	SET_MODULE_OWNER(&adapter->hisax_d_if);
+	adapter->hisax_d_if.ifc.priv = adapter;
+	adapter->hisax_d_if.ifc.l2l1 = st5481_d_l2l1;
+
+	for (i = 0; i < 2; i++) {
+		adapter->bcs[i].adapter = adapter;
+		adapter->bcs[i].channel = i;
+		adapter->bcs[i].b_if.ifc.priv = &adapter->bcs[i];
+		adapter->bcs[i].b_if.ifc.l2l1 = st5481_b_l2l1;
+	}
+	list_add(&adapter->list, &adapter_list);
+
+	retval = st5481_setup_usb(adapter);
+	if (retval < 0)
+		goto err;
+
+	retval = st5481_setup_d(adapter);
+	if (retval < 0)
+		goto err_usb;
+
+	retval = st5481_setup_b(&adapter->bcs[0]);
+	if (retval < 0)
+		goto err_d;
+
+	retval = st5481_setup_b(&adapter->bcs[1]);
+	if (retval < 0)
+		goto err_b;
+
+	for (i = 0; i < 2; i++)
+		b_if[i] = &adapter->bcs[i].b_if;
+
+	hisax_register(&adapter->hisax_d_if, b_if, "st5481_usb", protocol);
+	st5481_start(adapter);
+
+	return adapter;
+
+ err_b:
+	st5481_release_b(&adapter->bcs[0]);
+ err_d:
+	st5481_release_d(adapter);
+ err_usb:
+	st5481_release_usb(adapter);
+ err:
+	return NULL;
+}
+
+/*
+ * This function will be called when the adapter is removed
+ * from the USB bus.
+ */
+static void __devexit disconnect_st5481(struct usb_device *dev, void *arg)
+{
+	struct st5481_adapter *adapter = arg;
+
+	DBG(1,"");
+
+	list_del(&adapter->list);
+
+	st5481_stop(adapter);
+	st5481_release_b(&adapter->bcs[1]);
+	st5481_release_b(&adapter->bcs[0]);
+	st5481_release_d(adapter);
+	// we would actually better wait for completion of outstanding urbs
+	mdelay(2);
+	st5481_release_usb(adapter);
+
+	hisax_unregister(&adapter->hisax_d_if);
+
+	kfree(adapter);
+}
+
+/*
+ * The last 4 bits in the Product Id is set with 4 pins on the chip.
+ */
+static struct usb_device_id st5481_ids[] = {
+	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x0) },
+	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x1) },
+	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x2) },
+	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x3) },
+	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x4) },
+	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x5) },
+	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x6) },
+	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x7) },
+	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x8) },
+	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x9) },
+	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0xA) },
+	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0xB) },
+	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0xC) },
+	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0xD) },
+	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0xE) },
+	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0xF) },
+	{ }
+};
+MODULE_DEVICE_TABLE (usb, st5481_ids);
+
+static struct usb_driver st5481_usb_driver = {
+	name: "st5481_usb",
+	probe: probe_st5481,
+	disconnect: disconnect_st5481,
+	id_table: st5481_ids,
+};
+
+static int __init st5481_usb_init(void)
+{
+	int retval;
+
+#ifdef CONFIG_HISAX_DEBUG
+	st5481_debug = debug;
+#endif
+
+	printk(KERN_INFO "hiax_st5481: ST5481 USB ISDN driver v0.1.0\n");
+
+	retval = st5481_d_init();
+	if (retval < 0)
+		goto out;
+
+	retval = usb_register(&st5481_usb_driver);
+	if (retval < 0)
+		goto out_d_exit;
+
+	return 0;
+
+ out_d_exit:
+	st5481_d_exit();
+ out:
+	return retval;
+}
+
+static void __exit st5481_usb_exit(void)
+{
+	usb_deregister(&st5481_usb_driver);
+}
+
+module_init(st5481_usb_init);
+module_exit(st5481_usb_exit);
diff -u --recursive --new-file v2.4.9/linux/drivers/isdn/hisax/st5481_usb.c linux/drivers/isdn/hisax/st5481_usb.c
--- v2.4.9/linux/drivers/isdn/hisax/st5481_usb.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/isdn/hisax/st5481_usb.c	Sun Sep  9 10:45:43 2001
@@ -0,0 +1,639 @@
+/*
+ * Driver for ST5481 USB ISDN modem
+ *
+ * Author       Frode Isaksen
+ * Copyright    2001 by Frode Isaksen      <fisaksen@bewan.com>
+ *              2001 by Kai Germaschewski  <kai.germaschewski@gmx.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/usb.h>
+#include <linux/slab.h>
+#include "st5481.h"
+
+/* ======================================================================
+ * control pipe
+ */
+
+/*
+ * Send the next endpoint 0 request stored in the FIFO.
+ * Called either by the completion or by usb_ctrl_msg.
+ */
+static void usb_next_ctrl_msg(struct urb *urb,
+			      struct st5481_adapter *adapter)
+{
+	struct st5481_ctrl *ctrl = &adapter->ctrl;
+	int r_index;
+
+	if (test_and_set_bit(0, &ctrl->busy)) {
+		return;
+	}
+
+	if ((r_index = fifo_remove(&ctrl->msg_fifo.f)) < 0) {
+		test_and_clear_bit(0,&ctrl->busy);
+		return;
+	} 
+	urb->setup_packet = 
+		(unsigned char *)&ctrl->msg_fifo.data[r_index];
+	
+	DBG(1,"request=0x%02x,value=0x%04x,index=%x",
+	    ((struct ctrl_msg *)urb->setup_packet)->dr.request,
+	    ((struct ctrl_msg *)urb->setup_packet)->dr.value,
+	    ((struct ctrl_msg *)urb->setup_packet)->dr.index);
+
+	// Prepare the URB
+	urb->dev = adapter->usb_dev;
+
+	SUBMIT_URB(urb);
+}
+
+/*
+ * Asynchronous endpoint 0 request (async version of usb_control_msg).
+ * The request will be queued up in a FIFO if the endpoint is busy.
+ */
+void usb_ctrl_msg(struct st5481_adapter *adapter,
+		  u8 request, u8 requesttype, u16 value, u16 index,
+		  ctrl_complete_t complete, void *context)
+{
+	struct st5481_ctrl *ctrl = &adapter->ctrl;
+	int w_index;
+	struct ctrl_msg *ctrl_msg;
+	
+	if ((w_index = fifo_add(&ctrl->msg_fifo.f)) < 0) {
+		WARN("control msg FIFO full");
+		return;
+	}
+	ctrl_msg = &ctrl->msg_fifo.data[w_index]; 
+   
+	ctrl_msg->dr.requesttype = requesttype;
+	ctrl_msg->dr.request = request;
+	ctrl_msg->dr.value = cpu_to_le16p(&value);
+	ctrl_msg->dr.index = cpu_to_le16p(&index);
+	ctrl_msg->dr.length = 0;
+	ctrl_msg->complete = complete;
+	ctrl_msg->context = context;
+
+	usb_next_ctrl_msg(ctrl->urb, adapter);
+}
+
+/*
+ * Asynchronous endpoint 0 device request.
+ */
+void st5481_usb_device_ctrl_msg(struct st5481_adapter *adapter,
+			 u8 request, u16 value,
+			 ctrl_complete_t complete, void *context)
+{
+	usb_ctrl_msg(adapter, request, 
+		     USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 
+		     value, 0, complete, context);
+}
+
+/*
+ * Asynchronous pipe reset (async version of usb_clear_halt).
+ */
+void st5481_usb_pipe_reset(struct st5481_adapter *adapter,
+		    u_char pipe,
+		    ctrl_complete_t complete, void *context)
+{
+	DBG(1,"pipe=%02x",pipe);
+
+	usb_ctrl_msg(adapter,
+		     USB_REQ_CLEAR_FEATURE, USB_DIR_OUT | USB_RECIP_ENDPOINT,
+		     0, pipe, complete, context);
+}
+
+
+/*
+  Physical level functions
+*/
+
+void st5481_ph_command(struct st5481_adapter *adapter, unsigned int command)
+{
+	DBG(8,"command=%s", ST5481_CMD_string(command));
+
+	st5481_usb_device_ctrl_msg(adapter, TXCI, command, NULL, NULL);
+}
+
+/*
+ * The request on endpoint 0 has completed.
+ * Call the user provided completion routine and try
+ * to send the next request.
+ */
+static void usb_ctrl_complete(struct urb *urb)
+{
+	struct st5481_adapter *adapter = urb->context;
+	struct st5481_ctrl *ctrl = &adapter->ctrl;
+	struct ctrl_msg *ctrl_msg;
+	
+	if (urb->status < 0) {
+		if (urb->status != USB_ST_URB_KILLED) {
+			WARN("urb status %d",urb->status);
+		} else {
+			DBG(1,"urb killed");
+			return; // Give up
+		}
+	}
+
+	ctrl_msg = (struct ctrl_msg *)urb->setup_packet;
+	
+	if (ctrl_msg->dr.request == USB_REQ_CLEAR_FEATURE) {
+	        /* Special case handling for pipe reset */
+		le16_to_cpus(&ctrl_msg->dr.index);
+		usb_endpoint_running(adapter->usb_dev,
+				     ctrl_msg->dr.index & ~USB_DIR_IN, 
+				     (ctrl_msg->dr.index & USB_DIR_IN) == 0);
+
+		/* toggle is reset on clear */
+		usb_settoggle(adapter->usb_dev, 
+			      ctrl_msg->dr.index & ~USB_DIR_IN, 
+			      (ctrl_msg->dr.index & USB_DIR_IN) == 0,
+			      0);
+
+
+	}
+	
+	if (ctrl_msg->complete)
+		ctrl_msg->complete(ctrl_msg->context);
+
+	clear_bit(0, &ctrl->busy);
+	
+	// Try to send next control message
+	usb_next_ctrl_msg(urb, adapter);
+	return;
+}
+
+/* ======================================================================
+ * interrupt pipe
+ */
+
+/*
+ * The interrupt endpoint will be called when any
+ * of the 6 registers changes state (depending on masks).
+ * Decode the register values and schedule a private event.
+ * Called at interrupt.
+ */
+static void usb_int_complete(struct urb *urb)
+{
+	u_char *data = urb->transfer_buffer;
+	u_char irqbyte;
+	struct st5481_adapter *adapter = urb->context;
+	int j;
+
+	if (urb->status < 0) {
+		if (urb->status != USB_ST_URB_KILLED) {
+			WARN("urb status %d",urb->status);
+			urb->actual_length = 0;
+		} else {
+			DBG(1,"urb killed");
+			return; // Give up
+		}
+	}
+	
+	DBG_PACKET(1, data, INT_PKT_SIZE);
+		
+	if (urb->actual_length == 0) {
+		return;
+	}
+
+	irqbyte = data[MPINT];
+	if (irqbyte & DEN_INT)
+		FsmEvent(&adapter->d_out.fsm, EV_DOUT_DEN, NULL);
+
+	if (irqbyte & DCOLL_INT)
+		FsmEvent(&adapter->d_out.fsm, EV_DOUT_COLL, NULL);
+
+	irqbyte = data[FFINT_D];
+	if (irqbyte & OUT_UNDERRUN)
+		FsmEvent(&adapter->d_out.fsm, EV_DOUT_UNDERRUN, NULL);
+
+	if (irqbyte & OUT_DOWN)
+;//		printk("OUT_DOWN\n");
+
+	irqbyte = data[MPINT];
+	if (irqbyte & RXCI_INT)
+		FsmEvent(&adapter->l1m, data[CCIST] & 0x0f, NULL);
+
+	for (j = 0; j < 2; j++)
+		adapter->bcs[j].b_out.flow_event |= data[FFINT_B1 + j];
+
+	urb->actual_length = 0;
+}
+
+/* ======================================================================
+ * initialization
+ */
+
+int __devinit st5481_setup_usb(struct st5481_adapter *adapter)
+{
+	struct usb_device *dev = adapter->usb_dev;
+	struct st5481_ctrl *ctrl = &adapter->ctrl;
+	struct st5481_intr *intr = &adapter->intr;
+	struct usb_interface_descriptor *altsetting;
+	struct usb_endpoint_descriptor *endpoint;
+	int status;
+	urb_t *urb;
+	u_char *buf;
+	
+	DBG(1,"");
+	
+	if ((status = usb_set_configuration (dev,dev->config[0].bConfigurationValue)) < 0) {
+		WARN("set_configuration failed,status=%d",status);
+		return status;
+	}
+
+	
+	altsetting = &(dev->config->interface[0].altsetting[3]);	
+
+	// Check if the config is sane
+	if ( altsetting->bNumEndpoints != 7 ) {
+		WARN("expecting 7 got %d endpoints!", altsetting->bNumEndpoints);
+		return -EINVAL;
+	}
+
+	// The descriptor is wrong for some early samples of the ST5481 chip
+	altsetting->endpoint[3].wMaxPacketSize = 32;
+	altsetting->endpoint[4].wMaxPacketSize = 32;
+
+	// Use alternative setting 3 on interface 0 to have 2B+D
+	if ((status = usb_set_interface (dev, 0, 3)) < 0) {
+		WARN("usb_set_interface failed,status=%d",status);
+		return status;
+	}
+
+	// Allocate URB for control endpoint
+	urb = usb_alloc_urb(0);
+	if (!urb) {
+		return -ENOMEM;
+	}
+	ctrl->urb = urb;
+	
+	// Fill the control URB
+	FILL_CONTROL_URB (urb, dev, 
+			  usb_sndctrlpipe(dev, 0),
+			  NULL, NULL, 0, usb_ctrl_complete, adapter);
+
+		
+	fifo_init(&ctrl->msg_fifo.f, ARRAY_SIZE(ctrl->msg_fifo.data));
+
+	// Allocate URBs and buffers for interrupt endpoint
+	urb = usb_alloc_urb(0);
+	if (!urb) { 
+		return -ENOMEM;
+	}
+	intr->urb = urb;
+	
+	buf = kmalloc(INT_PKT_SIZE, GFP_KERNEL);
+	if (!buf) {
+		return -ENOMEM;
+	}
+
+	endpoint = &altsetting->endpoint[EP_INT-1];
+				
+	// Fill the interrupt URB
+	FILL_INT_URB(urb, dev,
+		     usb_rcvintpipe(dev, endpoint->bEndpointAddress),
+		     buf, INT_PKT_SIZE,
+		     usb_int_complete, adapter,
+		     endpoint->bInterval);
+		
+	return 0;
+}
+
+/*
+ * Release buffers and URBs for the interrupt and control
+ * endpoint.
+ */
+void __devexit st5481_release_usb(struct st5481_adapter *adapter)
+{
+	struct st5481_intr *intr = &adapter->intr;
+	struct st5481_ctrl *ctrl = &adapter->ctrl;
+
+	DBG(1,"");
+
+	// Stop and free Control and Interrupt URBs
+	usb_unlink_urb(ctrl->urb);
+	if (ctrl->urb->transfer_buffer)
+		kfree(ctrl->urb->transfer_buffer);
+	usb_free_urb(ctrl->urb);
+
+	usb_unlink_urb(intr->urb);
+	if (intr->urb->transfer_buffer)
+		kfree(intr->urb->transfer_buffer);
+	usb_free_urb(intr->urb);
+}
+
+/*
+ *  Initialize the adapter.
+ */
+void __devinit st5481_start(struct st5481_adapter *adapter)
+{
+	static const u8 init_cmd_table[]={
+		SET_DEFAULT,0,
+		STT,0,
+		SDA_MIN,0x0d,
+		SDA_MAX,0x29,
+		SDELAY_VALUE,0x14,
+		GPIO_DIR,0x01,		
+		GPIO_OUT,RED_LED,
+//		FFCTRL_OUT_D,4,
+//		FFCTRH_OUT_D,12,
+		FFCTRL_OUT_B1,6,
+		FFCTRH_OUT_B1,20,
+		FFCTRL_OUT_B2,6,
+		FFCTRH_OUT_B2,20,
+		MPMSK,RXCI_INT+DEN_INT+DCOLL_INT,
+		0
+	};	
+	struct st5481_intr *intr = &adapter->intr;
+	int i = 0;
+	u8 request,value;
+
+	DBG(8,"");
+
+	adapter->leds = RED_LED; 
+
+	// Start receiving on the interrupt endpoint
+	SUBMIT_URB(intr->urb); 
+
+	while ((request = init_cmd_table[i++])) {
+		value = init_cmd_table[i++];
+		st5481_usb_device_ctrl_msg(adapter, request, value, NULL, NULL);
+	}
+	st5481_ph_command(adapter, ST5481_CMD_PUP);
+}
+
+/*
+ * Reset the adapter to default values.
+ */
+void __devexit st5481_stop(struct st5481_adapter *adapter)
+{
+	DBG(8,"");
+
+	st5481_usb_device_ctrl_msg(adapter, SET_DEFAULT, 0, NULL, NULL);
+}
+
+/* ======================================================================
+ * isochronous USB  helpers
+ */
+
+static void __devinit
+fill_isoc_urb(struct urb *urb, struct usb_device *dev,
+	      unsigned int pipe, void *buf, int num_packets, 
+	      int packet_size, usb_complete_t complete,
+	      void *context) 
+{
+	int k;
+
+	spin_lock_init(&urb->lock);
+	urb->dev=dev;
+	urb->pipe=pipe;
+	urb->transfer_buffer=buf;
+	urb->number_of_packets = num_packets;
+	urb->transfer_buffer_length=num_packets*packet_size;
+	urb->actual_length = 0;
+	urb->complete=complete;
+	urb->context=context;
+	urb->transfer_flags=USB_ISO_ASAP;
+	for (k = 0; k < num_packets; k++) {
+		urb->iso_frame_desc[k].offset = packet_size * k;
+		urb->iso_frame_desc[k].length = packet_size;
+		urb->iso_frame_desc[k].actual_length = 0;
+	}
+}
+
+int __devinit
+st5481_setup_isocpipes(struct urb* urb[2], struct usb_device *dev, 
+			   unsigned int pipe, int num_packets,
+			   int packet_size, int buf_size,
+			   usb_complete_t complete, void *context)
+{
+	int j, retval;
+	unsigned char *buf;
+
+	for (j = 0; j < 2; j++) {
+		retval = -ENOMEM;
+		urb[j] = usb_alloc_urb(num_packets);
+		if (!urb[j])
+			goto err;
+
+		// Allocate memory for 2000bytes/sec (16Kb/s)
+		buf = kmalloc(buf_size, GFP_KERNEL);
+		if (!buf)
+			goto err;
+			
+		// Fill the isochronous URB
+		fill_isoc_urb(urb[j], dev, pipe, buf, 
+				     num_packets, packet_size, complete,
+				     context);
+	}
+	return 0;
+
+ err:
+	for (j = 0; j < 2; j++) {
+		if (urb[j]) {
+			if (urb[j]->transfer_buffer)
+				kfree(urb[j]->transfer_buffer);
+			usb_free_urb(urb[j]);
+		}
+	}
+	return retval;
+}
+
+void __devexit st5481_release_isocpipes(struct urb* urb[2])
+{
+	int j;
+
+	for (j = 0; j < 2; j++) {
+		usb_unlink_urb(urb[j]);
+		if (urb[j]->transfer_buffer)
+			kfree(urb[j]->transfer_buffer);			
+		usb_free_urb(urb[j]);
+	}
+}
+
+/*
+ * Decode frames received on the B/D channel.
+ * Note that this function will be called continously
+ * with 64Kbit/s / 16Kbit/s of data and hence it will be 
+ * called 50 times per second with 20 ISOC descriptors. 
+ * Called at interrupt.
+ */
+static void usb_in_complete(struct urb *urb)
+{
+	struct st5481_in *in = urb->context;
+	unsigned char *ptr;
+	struct sk_buff *skb;
+	int len, count, status;
+
+	if (urb->status < 0) {
+		if (urb->status != USB_ST_URB_KILLED) {
+			WARN("urb status %d",urb->status);
+		} else {
+			DBG(1,"urb killed");
+			return; // Give up
+		}
+	}
+
+	DBG_ISO_PACKET(0x80,urb);
+
+	len = st5481_isoc_flatten(urb);
+	ptr = urb->transfer_buffer;
+	while (len > 0) {
+		if (in->mode == L1_MODE_TRANS) {
+			memcpy(in->rcvbuf, ptr, len);
+			status = len;
+			len = 0;
+		} else {
+			status = hdlc_decode(&in->hdlc_state, ptr, len, &count,
+					     in->rcvbuf, in->bufsize);
+			ptr += count;
+			len -= count;
+		}
+		
+		if (status > 0) {
+			// Good frame received
+			DBG(4,"count=%d",status);
+			DBG_PACKET(0x400, in->rcvbuf, status);
+			if (!(skb = dev_alloc_skb(status))) {
+				WARN("receive out of memory\n");
+				break;
+			}
+			memcpy(skb_put(skb, status), in->rcvbuf, status);
+			in->hisax_if->l1l2(in->hisax_if, PH_DATA | INDICATION, skb);
+		} else if (status == -HDLC_CRC_ERROR) {
+			INFO("CRC error");
+		} else if (status == -HDLC_FRAMING_ERROR) {
+			INFO("framing error");
+		} else if (status == -HDLC_LENGTH_ERROR) {
+			INFO("length error");
+		}
+	}
+
+	// Prepare URB for next transfer
+	urb->dev = in->adapter->usb_dev;
+	urb->actual_length = 0;
+
+	SUBMIT_URB(urb);
+}
+
+int __devinit st5481_setup_in(struct st5481_in *in)
+{
+	struct usb_device *dev = in->adapter->usb_dev;
+	int retval;
+
+	DBG(4,"");
+
+	in->rcvbuf = kmalloc(in->bufsize, GFP_KERNEL);
+	retval = -ENOMEM;
+	if (!in->rcvbuf)
+		goto err;
+
+	retval = st5481_setup_isocpipes(in->urb, dev, 
+					usb_rcvisocpipe(dev, in->ep),
+					in->num_packets,  in->packet_size,
+					in->num_packets * in->packet_size,
+					usb_in_complete, in);
+	if (retval)
+		goto err_free;
+	return 0;
+
+ err_free:
+	kfree(in->rcvbuf);
+ err:
+	return retval;
+}
+
+void __devexit st5481_release_in(struct st5481_in *in)
+{
+	DBG(2,"");
+
+	st5481_release_isocpipes(in->urb);
+}
+
+/*
+ * Make the transfer_buffer contiguous by
+ * copying from the iso descriptors if necessary. 
+ */
+int st5481_isoc_flatten(struct urb *urb)
+{
+	piso_packet_descriptor_t pipd,pend;
+	unsigned char *src,*dst;
+	unsigned int len;
+	
+	if (urb->status < 0) {
+		return urb->status;
+	}
+	for (pipd = &urb->iso_frame_desc[0],
+		     pend = &urb->iso_frame_desc[urb->number_of_packets],
+		     dst = urb->transfer_buffer; 
+	     pipd < pend; 
+	     pipd++) {
+		
+		if (pipd->status < 0) {
+			return (pipd->status);
+		}
+	
+		len = pipd->actual_length;
+		pipd->actual_length = 0;
+		src = urb->transfer_buffer+pipd->offset;
+
+		if (src != dst) {
+			// Need to copy since isoc buffers not full
+			while (len--) {
+				*dst++ = *src++;
+			}			
+		} else {
+			// No need to copy, just update destination buffer
+			dst += len;
+		}
+	}
+	// Return size of flattened buffer
+	return (dst - (unsigned char *)urb->transfer_buffer);
+}
+
+static void st5481_start_rcv(void *context)
+{
+	struct st5481_in *in = context;
+	struct st5481_adapter *adapter = in->adapter;
+
+	DBG(4,"");
+
+	in->urb[0]->dev = adapter->usb_dev;
+	SUBMIT_URB(in->urb[0]);
+
+	in->urb[1]->dev = adapter->usb_dev;
+	SUBMIT_URB(in->urb[1]);
+}
+
+void st5481_in_mode(struct st5481_in *in, int mode)
+{
+	if (in->mode == mode)
+		return;
+
+	in->mode = mode;
+
+	usb_unlink_urb(in->urb[0]);
+	usb_unlink_urb(in->urb[1]);
+
+	if (in->mode != L1_MODE_NULL) {
+		if (in->mode != L1_MODE_TRANS)
+			hdlc_rcv_init(&in->hdlc_state,
+				      in->mode == L1_MODE_HDLC_56K);
+		
+		st5481_usb_pipe_reset(in->adapter, in->ep, NULL, NULL);
+		st5481_usb_device_ctrl_msg(in->adapter, in->counter,
+					   in->packet_size,
+					   NULL, NULL);
+		st5481_start_rcv(in);
+	} else {
+		st5481_usb_device_ctrl_msg(in->adapter, in->counter,
+					   0, NULL, NULL);
+	}
+}
+
diff -u --recursive --new-file v2.4.9/linux/drivers/isdn/icn/icn.c linux/drivers/isdn/icn/icn.c
--- v2.4.9/linux/drivers/isdn/icn/icn.c	Mon Aug 27 12:41:42 2001
+++ linux/drivers/isdn/icn/icn.c	Fri Sep  7 09:28:38 2001
@@ -1,4 +1,4 @@
-/* $Id: icn.c,v 1.65.6.6 2001/07/13 09:20:12 kai Exp $
+/* $Id: icn.c,v 1.65.6.7 2001/08/17 12:34:27 kai Exp $
 
  * ISDN low-level module for the ICN active ISDN-Card.
  *
@@ -34,7 +34,7 @@
 #undef MAP_DEBUG
 
 static char
-*revision = "$Revision: 1.65.6.6 $";
+*revision = "$Revision: 1.65.6.7 $";
 
 static int icn_addcard(int, char *, char *);
 
@@ -930,7 +930,9 @@
 	restore_flags(flags);
 	while (left) {
 		if (sbfree) {   /* If there is a free buffer...  */
-			cnt = MIN(256, left);
+			cnt = left;
+			if (cnt > 256)
+				cnt = 256;
 			if (copy_from_user(codebuf, p, cnt)) {
 				icn_maprelease_channel(card, 0);
 				return -EFAULT;
@@ -1029,7 +1031,6 @@
 icn_writecmd(const u_char * buf, int len, int user, icn_card * card)
 {
 	int mch = card->secondhalf ? 2 : 0;
-	int avail;
 	int pp;
 	int i;
 	int count;
@@ -1046,8 +1047,9 @@
 	ocount = 1;
 	xcount = loop = 0;
 	while (len) {
-		avail = cmd_free;
-		count = MIN(avail, len);
+		count = cmd_free;
+		if (count > len)
+			count = len;
 		if (user)
 			copy_from_user(msg, buf, count);
 		else
diff -u --recursive --new-file v2.4.9/linux/drivers/isdn/icn/icn.h linux/drivers/isdn/icn/icn.h
--- v2.4.9/linux/drivers/isdn/icn/icn.h	Thu Apr 19 22:30:23 2001
+++ linux/drivers/isdn/icn/icn.h	Fri Sep  7 09:28:38 2001
@@ -1,4 +1,4 @@
-/* $Id: icn.h,v 1.30.6.3 2001/04/20 02:42:01 keil Exp $
+/* $Id: icn.h,v 1.30.6.4 2001/08/17 12:34:27 kai Exp $
 
  * ISDN lowlevel-module for the ICN active ISDN-Card.
  *
@@ -284,9 +284,6 @@
 		   readb(&msg_i)-readb(&msg_o))
 
 #define CID (card->interface.id)
-
-#define MIN(a,b) ((a<b)?a:b)
-#define MAX(a,b) ((a>b)?a:b)
 
 #endif                          /* defined(__KERNEL__) || defined(__DEBUGVAR__) */
 #endif                          /* icn_h */
diff -u --recursive --new-file v2.4.9/linux/drivers/isdn/isdn_audio.c linux/drivers/isdn/isdn_audio.c
--- v2.4.9/linux/drivers/isdn/isdn_audio.c	Sun Aug  6 12:43:42 2000
+++ linux/drivers/isdn/isdn_audio.c	Fri Sep  7 09:28:38 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_audio.c,v 1.21 2000/06/20 18:01:55 keil Exp $
+/* $Id: isdn_audio.c,v 1.21.6.1 2001/08/17 12:34:25 kai Exp $
 
  * Linux ISDN subsystem, audio conversion and compression (linklevel).
  *
@@ -28,7 +28,7 @@
 #include "isdn_audio.h"
 #include "isdn_common.h"
 
-char *isdn_audio_revision = "$Revision: 1.21 $";
+char *isdn_audio_revision = "$Revision: 1.21.6.1 $";
 
 /*
  * Misc. lookup-tables.
@@ -607,7 +607,9 @@
 	int c;
 
 	while (len) {
-		c = MIN(len, (DTMF_NPOINTS - s->idx));
+		c = DTMF_NPOINTS - s->idx;
+		if (c > len)
+			c = len;
 		if (c <= 0)
 			break;
 		for (i = 0; i < c; i++) {
diff -u --recursive --new-file v2.4.9/linux/drivers/isdn/isdn_common.c linux/drivers/isdn/isdn_common.c
--- v2.4.9/linux/drivers/isdn/isdn_common.c	Mon Aug 27 12:41:42 2001
+++ linux/drivers/isdn/isdn_common.c	Sun Sep  9 10:45:43 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_common.c,v 1.114.6.13 2001/08/13 07:46:15 kai Exp $
+/* $Id: isdn_common.c,v 1.114.6.14 2001/08/17 12:34:25 kai Exp $
 
  * Linux ISDN subsystem, common used functions (linklevel).
  *
@@ -51,7 +51,7 @@
 
 isdn_dev *dev;
 
-static char *isdn_revision = "$Revision: 1.114.6.13 $";
+static char *isdn_revision = "$Revision: 1.114.6.14 $";
 
 extern char *isdn_net_revision;
 extern char *isdn_tty_revision;
@@ -792,7 +792,6 @@
 int
 isdn_readbchan(int di, int channel, u_char * buf, u_char * fp, int len, wait_queue_head_t *sleep)
 {
-	int left;
 	int count;
 	int count_pull;
 	int count_put;
@@ -808,10 +807,11 @@
 		else
 			return 0;
 	}
-	left = MIN(len, dev->drv[di]->rcvcount[channel]);
+	if (len > dev->drv[di]->rcvcount[channel])
+		len = dev->drv[di]->rcvcount[channel];
 	cp = buf;
 	count = 0;
-	while (left) {
+	while (len) {
 		if (!(skb = skb_peek(&dev->drv[di]->rpqueue[channel])))
 			break;
 #ifdef CONFIG_ISDN_AUDIO
@@ -824,8 +824,8 @@
 
 			dflag = 0;
 			count_pull = count_put = 0;
-			while ((count_pull < skb->len) && (left > 0)) {
-				left--;
+			while ((count_pull < skb->len) && (len > 0)) {
+				len--;
 				if (dev->drv[di]->DLEflag & DLEmask) {
 					*cp++ = DLE;
 					dev->drv[di]->DLEflag &= ~DLEmask;
@@ -846,14 +846,14 @@
 #endif
 			/* No DLE's in buff, so simply copy it */
 			dflag = 1;
-			if ((count_pull = skb->len) > left) {
-				count_pull = left;
+			if ((count_pull = skb->len) > len) {
+				count_pull = len;
 				dflag = 0;
 			}
 			count_put = count_pull;
 			memcpy(cp, skb->data, count_put);
 			cp += count_put;
-			left -= count_put;
+			len -= count_put;
 #ifdef CONFIG_ISDN_AUDIO
 		}
 #endif
@@ -1048,12 +1048,15 @@
 			}
 			interruptible_sleep_on(&(dev->drv[drvidx]->st_waitq));
 		}
-		if (dev->drv[drvidx]->interface->readstat)
+		if (dev->drv[drvidx]->interface->readstat) {
+			if (count > dev->drv[drvidx]->stavail)
+				count = dev->drv[drvidx]->stavail;
 			len = dev->drv[drvidx]->interface->
-			    readstat(buf, MIN(count, dev->drv[drvidx]->stavail),
-				     1, drvidx, isdn_minor2chan(minor));
-		else
+				readstat(buf, count, 1, drvidx,
+					 isdn_minor2chan(minor));
+		} else {
 			len = 0;
+		}
 		save_flags(flags);
 		cli();
 		if (len)
diff -u --recursive --new-file v2.4.9/linux/drivers/isdn/isdn_net.c linux/drivers/isdn/isdn_net.c
--- v2.4.9/linux/drivers/isdn/isdn_net.c	Sun Aug 12 13:27:59 2001
+++ linux/drivers/isdn/isdn_net.c	Sun Sep  9 10:45:43 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_net.c,v 1.140.6.7 2001/07/27 11:15:53 kai Exp $
+/* $Id: isdn_net.c,v 1.140.6.8 2001/08/14 14:04:21 kai Exp $
 
  * Linux ISDN subsystem, network interfaces and related functions (linklevel).
  *
@@ -190,7 +190,7 @@
 static void isdn_net_ciscohdlck_connected(isdn_net_local *lp);
 static void isdn_net_ciscohdlck_disconnected(isdn_net_local *lp);
 
-char *isdn_net_revision = "$Revision: 1.140.6.7 $";
+char *isdn_net_revision = "$Revision: 1.140.6.8 $";
 
  /*
   * Code for raw-networking over ISDN
@@ -1754,6 +1754,11 @@
 		break;
 	case CISCO_TYPE_SLARP:
 		isdn_net_ciscohdlck_slarp_in(lp, skb);
+		goto out_free;
+	case CISCO_TYPE_CDP:
+		if (lp->cisco_debserint)
+			printk(KERN_DEBUG "%s: Received CDP packet. use "
+				"\"no cdp enable\" on cisco.\n", lp->name);
 		goto out_free;
 	default:
 		printk(KERN_WARNING "%s: Unknown Cisco type 0x%04x\n",
diff -u --recursive --new-file v2.4.9/linux/drivers/isdn/isdn_net.h linux/drivers/isdn/isdn_net.h
--- v2.4.9/linux/drivers/isdn/isdn_net.h	Sat May 19 17:54:14 2001
+++ linux/drivers/isdn/isdn_net.h	Sun Sep  9 10:45:43 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_net.h,v 1.19.6.1 2001/04/20 02:41:58 keil Exp $
+/* $Id: isdn_net.h,v 1.19.6.2 2001/08/14 14:04:21 kai Exp $
 
  * header for Linux ISDN subsystem, network related functions (linklevel).
  *
@@ -36,6 +36,7 @@
 #define CISCO_ADDR_UNICAST    0x0f
 #define CISCO_ADDR_BROADCAST  0x8f
 #define CISCO_CTRL            0x00
+#define CISCO_TYPE_CDP        0x2000
 #define CISCO_TYPE_INET       0x0800
 #define CISCO_TYPE_SLARP      0x8035
 #define CISCO_SLARP_REPLY     0
diff -u --recursive --new-file v2.4.9/linux/drivers/isdn/isdn_tty.c linux/drivers/isdn/isdn_tty.c
--- v2.4.9/linux/drivers/isdn/isdn_tty.c	Sun Aug 12 13:27:59 2001
+++ linux/drivers/isdn/isdn_tty.c	Sun Sep  9 10:45:43 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_tty.c,v 1.94.6.4 2001/07/27 11:15:53 kai Exp $
+/* $Id: isdn_tty.c,v 1.94.6.7 2001/08/27 22:19:04 kai Exp $
 
  * Linux ISDN subsystem, tty functions and AT-command emulator (linklevel).
  *
@@ -66,7 +66,7 @@
 static int si2bit[8] =
 {4, 1, 4, 4, 4, 4, 4, 4};
 
-char *isdn_tty_revision = "$Revision: 1.94.6.4 $";
+char *isdn_tty_revision = "$Revision: 1.94.6.7 $";
 
 
 /* isdn_tty_try_read() is called from within isdn_tty_rcv_skb()
@@ -727,9 +727,19 @@
 isdn_tty_modem_hup(modem_info * info, int local)
 {
 	isdn_ctrl cmd;
+	int di, ch;
 
 	if (!info)
 		return;
+
+	di = info->isdn_driver;
+	ch = info->isdn_channel;
+	if (di < 0 || ch < 0)
+		return;
+
+	info->isdn_driver = -1;
+	info->isdn_channel = -1;
+
 #ifdef ISDN_DEBUG_MODEM_HUP
 	printk(KERN_DEBUG "Mhup ttyI%d\n", info->line);
 #endif
@@ -770,19 +780,18 @@
 		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) {
-		if (local) {
-			cmd.driver = info->isdn_driver;
-			cmd.command = ISDN_CMD_HANGUP;
-			cmd.arg = info->isdn_channel;
-			isdn_command(&cmd);
-		}
-		isdn_all_eaz(info->isdn_driver, info->isdn_channel);
-		info->emu.mdmreg[REG_RINGCNT] = 0;
-		isdn_free_channel(info->isdn_driver, info->isdn_channel, 0);
+
+	if (local) {
+		cmd.driver = di;
+		cmd.command = ISDN_CMD_HANGUP;
+		cmd.arg = ch;
+		isdn_command(&cmd);
 	}
-	info->isdn_driver = -1;
-	info->isdn_channel = -1;
+
+	isdn_all_eaz(di, ch);
+	info->emu.mdmreg[REG_RINGCNT] = 0;
+	isdn_free_channel(di, ch, 0);
+
 	if (info->drv_index >= 0) {
 		dev->m_idx[info->drv_index] = -1;
 		info->drv_index = -1;
@@ -1187,9 +1196,11 @@
 	/* See isdn_tty_senddown() */
 	atomic_inc(&info->xmit_lock);
 	while (1) {
-		c = MIN(count, info->xmit_size - info->xmit_count);
-		if (info->isdn_driver >= 0)
-			c = MIN(c, dev->drv[info->isdn_driver]->maxbufsize);
+		c = count;
+		if (c > info->xmit_size - info->xmit_count)
+			c = info->xmit_size - info->xmit_count;
+		if (info->isdn_driver >= 0 && c > dev->drv[info->isdn_driver]->maxbufsize)
+			c = dev->drv[info->isdn_driver]->maxbufsize;
 		if (c <= 0)
 			break;
 		if ((info->online > 1)
@@ -2709,6 +2720,10 @@
 			    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);
+				    if (m->mdmreg[REG_CDN] & BIT_CDN) {
+					    isdn_tty_at_cout("\r\nCALLED NUMBER: ", info);
+					    isdn_tty_at_cout(info->emu.cpn, info);
+				    }
 			    }
 			}
 			isdn_tty_at_cout("\r\n", info);
@@ -2734,6 +2749,10 @@
 						isdn_tty_at_cout("\r\n", info);
 						isdn_tty_at_cout("CALLER NUMBER: ", info);
 						isdn_tty_at_cout(dev->num[info->drv_index], info);
+						if (m->mdmreg[REG_CDN] & BIT_CDN) {
+							isdn_tty_at_cout("\r\nCALLED NUMBER: ", info);
+							isdn_tty_at_cout(info->emu.cpn, info);
+						}
 					}
 					break;
 				case RESULT_NO_CARRIER:
diff -u --recursive --new-file v2.4.9/linux/drivers/isdn/isdn_tty.h linux/drivers/isdn/isdn_tty.h
--- v2.4.9/linux/drivers/isdn/isdn_tty.h	Mon Dec 11 13:21:44 2000
+++ linux/drivers/isdn/isdn_tty.h	Sun Sep  9 10:45:43 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_tty.h,v 1.22 2000/06/21 09:54:29 keil Exp $
+/* $Id: isdn_tty.h,v 1.22.6.1 2001/08/14 14:12:18 kai Exp $
 
  * header for Linux ISDN subsystem, tty related functions (linklevel).
  *
@@ -85,7 +85,10 @@
 
 #define REG_CPN      23
 #define BIT_CPN       1
+#define REG_CPNFCON  23
 #define BIT_CPNFCON   2
+#define REG_CDN      23
+#define BIT_CDN       4
 
 /* defines for result codes */
 #define RESULT_OK		0
diff -u --recursive --new-file v2.4.9/linux/drivers/isdn/isdn_ttyfax.c linux/drivers/isdn/isdn_ttyfax.c
--- v2.4.9/linux/drivers/isdn/isdn_ttyfax.c	Sun Aug  6 12:43:42 2000
+++ linux/drivers/isdn/isdn_ttyfax.c	Sun Sep  9 10:45:43 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_ttyfax.c,v 1.7 2000/05/11 22:29:21 kai Exp $
+/* $Id: isdn_ttyfax.c,v 1.7.6.1 2001/08/14 14:12:18 kai Exp $
 
  * Linux ISDN subsystem, tty_fax AT-command emulator (linklevel).
  *
@@ -33,7 +33,7 @@
 #include "isdn_ttyfax.h"
 
 
-static char *isdn_tty_fax_revision = "$Revision: 1.7 $";
+static char *isdn_tty_fax_revision = "$Revision: 1.7.6.1 $";
 
 #define PARSE_ERROR1 { isdn_tty_fax_modem_result(1, info); return 1; }
 
@@ -86,7 +86,7 @@
 			break;
 		case 2:	/* +FCON */
 			/* Append CPN, if enabled */
-			if ((m->mdmreg[REG_CPN] & BIT_CPNFCON) &&
+			if ((m->mdmreg[REG_CPNFCON] & BIT_CPNFCON) &&
 				(!(dev->usage[info->isdn_channel] & ISDN_USAGE_OUTGOING))) {
 				sprintf(rs, "/%s", m->cpn);
 				isdn_tty_at_cout(rs, info);
diff -u --recursive --new-file v2.4.9/linux/drivers/isdn/isdnloop/isdnloop.c linux/drivers/isdn/isdnloop/isdnloop.c
--- v2.4.9/linux/drivers/isdn/isdnloop/isdnloop.c	Mon Aug 27 12:41:42 2001
+++ linux/drivers/isdn/isdnloop/isdnloop.c	Sun Sep  9 10:45:43 2001
@@ -1,4 +1,4 @@
-/* $Id: isdnloop.c,v 1.11.6.4 2001/07/13 09:20:12 kai Exp $
+/* $Id: isdnloop.c,v 1.11.6.5 2001/08/17 12:34:27 kai Exp $
 
  * ISDN low-level module implementing a dummy loop driver.
  *
@@ -26,7 +26,7 @@
 #include "isdnloop.h"
 
 static char
-*revision = "$Revision: 1.11.6.4 $";
+*revision = "$Revision: 1.11.6.5 $";
 
 static int isdnloop_addcard(char *);
 
@@ -985,10 +985,12 @@
 	isdn_ctrl cmd;
 
 	while (len) {
-		int count = MIN(255, len);
+		int count = len;
 		u_char *p;
 		u_char msg[0x100];
 
+		if (count > 255)
+			count = 255;
 		if (user)
 			copy_from_user(msg, buf, count);
 		else
diff -u --recursive --new-file v2.4.9/linux/drivers/isdn/isdnloop/isdnloop.h linux/drivers/isdn/isdnloop/isdnloop.h
--- v2.4.9/linux/drivers/isdn/isdnloop/isdnloop.h	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/isdnloop/isdnloop.h	Sun Sep  9 10:45:43 2001
@@ -1,4 +1,4 @@
-/* $Id: isdnloop.h,v 1.5.6.1 2001/02/10 14:41:23 kai Exp $
+/* $Id: isdnloop.h,v 1.5.6.2 2001/08/17 12:34:27 kai Exp $
 
  * Loopback lowlevel module for testing of linklevel.
  *
@@ -128,8 +128,6 @@
 /* Utility-Macros */
 
 #define CID (card->interface.id)
-#define MIN(a,b) ((a<b)?a:b)
-#define MAX(a,b) ((a>b)?a:b)
 
 #endif                          /* defined(__KERNEL__) || defined(__DEBUGVAR__) */
 #endif                          /* isdnloop_h */
diff -u --recursive --new-file v2.4.9/linux/drivers/isdn/pcbit/layer2.c linux/drivers/isdn/pcbit/layer2.c
--- v2.4.9/linux/drivers/isdn/pcbit/layer2.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/pcbit/layer2.c	Fri Sep  7 09:28:38 2001
@@ -176,7 +176,6 @@
 	struct frame_buf *frame = NULL;
 	unsigned char unacked;
 	int flen;               /* fragment frame length including all headers */
-	int totlen;             /* non-fragmented frame length */
 	int free;
 	int count,
 	 cp_len;
@@ -213,11 +212,12 @@
 			ulong 	msg;
 
 			if (frame->skb)
-				totlen = FRAME_HDR_LEN + PREHDR_LEN + frame->skb->len;
+				flen = FRAME_HDR_LEN + PREHDR_LEN + frame->skb->len;
 			else
-				totlen = FRAME_HDR_LEN + PREHDR_LEN;
+				flen = FRAME_HDR_LEN + PREHDR_LEN;
 
-			flen = MIN(totlen, free);
+			if (flen > free)
+				flen = free;
 
 			msg = frame->msg;
 
@@ -259,9 +259,10 @@
 		} else {
 			/* Type 1 frame */
 
-			totlen = 2 + (frame->skb->len - frame->copied);
+			flen = 2 + (frame->skb->len - frame->copied);
 
-			flen = MIN(totlen, free);
+			if (flen > free)
+				flen = free;
 
 			/* TT */
 			tt = ((ushort) (flen - 2)) | 0x8000U;	/* Type 1 */
@@ -271,8 +272,9 @@
 		}
 
 		if (frame->skb) {
-			cp_len = MIN(frame->skb->len - frame->copied,
-				     flen - count);
+			cp_len = frame->skb->len - frame->copied;
+			if (cp_len > flen - count)
+				cp_len = flen - count;
 
 			memcpy_topcbit(dev, frame->skb->data + frame->copied,
 				       cp_len);
diff -u --recursive --new-file v2.4.9/linux/drivers/isdn/pcbit/layer2.h linux/drivers/isdn/pcbit/layer2.h
--- v2.4.9/linux/drivers/isdn/pcbit/layer2.h	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/pcbit/layer2.h	Fri Sep  7 09:28:38 2001
@@ -121,8 +121,6 @@
         struct frame_buf * next;
 };
 
-#define MIN(a,b) ((a<b)?a:b)
-
 extern int pcbit_l2_write(struct pcbit_dev * dev, ulong msg, ushort refnum, 
                           struct sk_buff *skb, unsigned short hdr_len);
 
diff -u --recursive --new-file v2.4.9/linux/drivers/macintosh/Makefile linux/drivers/macintosh/Makefile
--- v2.4.9/linux/drivers/macintosh/Makefile	Sun Feb  4 10:21:25 2001
+++ linux/drivers/macintosh/Makefile	Wed Aug 29 20:49:36 2001
@@ -15,7 +15,7 @@
 
 # Objects that export symbols.
 
-export-objs	:= adb.o rtc.o mac_hid.o
+export-objs	:= adb.o rtc.o mac_hid.o via-pmu.o
 
 # Object file lists.
 
diff -u --recursive --new-file v2.4.9/linux/drivers/macintosh/macserial.c linux/drivers/macintosh/macserial.c
--- v2.4.9/linux/drivers/macintosh/macserial.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/macintosh/macserial.c	Sat Sep  8 12:38:42 2001
@@ -32,7 +32,7 @@
 #endif
 #include <linux/slab.h>
 
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <asm/io.h>
 #include <asm/pgtable.h>
 #include <asm/irq.h>
@@ -185,9 +185,9 @@
 		      dev_t device, const char *routine)
 {
 #ifdef SERIAL_PARANOIA_CHECK
-	static const char *badmagic =
+	static const char badmagic[] = KERN_WARNING
 		"Warning: bad magic number for serial struct (%d, %d) in %s\n";
-	static const char *badinfo =
+	static const char badinfo[] = KERN_WARNING
 		"Warning: null mac_serial for (%d, %d) in %s\n";
 
 	if (!info) {
@@ -418,7 +418,8 @@
 		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
 			static int flip_buf_ovf;
 			if (++flip_buf_ovf <= 1)
-				printk("FB. overflow: %d\n", flip_buf_ovf);
+				printk(KERN_WARNING "FB. overflow: %d\n",
+						    flip_buf_ovf);
 			break;
 		}
 		tty->flip.count++;
@@ -513,7 +514,7 @@
 		if ((status & CTS) == 0) {
 			if (info->tx_stopped) {
 #ifdef SERIAL_DEBUG_FLOW
-				printk("CTS up\n");
+				printk(KERN_DEBUG "CTS up\n");
 #endif
 				info->tx_stopped = 0;
 				if (!info->tx_active)
@@ -521,7 +522,7 @@
 			}
 		} else {
 #ifdef SERIAL_DEBUG_FLOW
-			printk("CTS down\n");
+			printk(KERN_DEBUG "CTS down\n");
 #endif
 			info->tx_stopped = 1;
 		}
@@ -568,7 +569,8 @@
 	int shift;
 
 	if (!(info->flags & ZILOG_INITIALIZED)) {
-		printk("rs_interrupt: irq %d, port not initialized\n", irq);
+		printk(KERN_WARNING "rs_interrupt: irq %d, port not "
+				    "initialized\n", irq);
 		disable_irq(irq);
 		return;
 	}
@@ -589,7 +591,7 @@
 	for (;;) {
 		zs_intreg = read_zsreg(info->zs_chan_a, 3) >> shift;
 #ifdef SERIAL_DEBUG_INTR
-		printk("rs_interrupt: irq %d, zs_intreg 0x%x\n",
+		printk(KERN_DEBUG "rs_interrupt: irq %d, zs_intreg 0x%x\n",
 		       irq, (int)zs_intreg);
 #endif
 
@@ -662,7 +664,7 @@
 	struct mac_serial *info = (struct mac_serial *)tty->driver_data;
 
 #ifdef SERIAL_DEBUG_STOP
-	printk("rs_stop %ld....\n",
+	printk(KERN_DEBUG "rs_stop %ld....\n",
 	       tty->ldisc.chars_in_buffer(tty));
 #endif
 
@@ -686,7 +688,7 @@
 	unsigned long flags;
 
 #ifdef SERIAL_DEBUG_STOP
-	printk("rs_start %ld....\n", 
+	printk(KERN_DEBUG "rs_start %ld....\n", 
 	       tty->ldisc.chars_in_buffer(tty));
 #endif
 
@@ -1214,13 +1216,8 @@
 		else
 			feature_set(info->dev_node, FEATURE_Serial_IO_B);
 		delay = 10;
-		if (info->is_cobalt_modem){
-			mdelay(300);
-			feature_set(info->dev_node, FEATURE_Modem_power);
-	   		mdelay(5);
-			feature_clear(info->dev_node, FEATURE_Modem_power);
-	   		mdelay(10);
-			feature_set(info->dev_node, FEATURE_Modem_power);
+		if (info->is_cobalt_modem) {
+			feature_set_modem_power(info->dev_node, 1);
 			delay = 2500;	/* wait for 2.5s before using */
 		}
 #ifdef CONFIG_PMAC_PBOOK
@@ -1228,11 +1225,13 @@
 			pmu_enable_irled(1);
 #endif /* CONFIG_PMAC_PBOOK */
 	} else {
+		/* TODO: Make that depend on a timer, don't power down
+		 * immediately
+		 */
 		PWRDBG("ttyS%02d: shutting down hardware\n", info->line);
 		if (info->is_cobalt_modem) {
 			PWRDBG("ttyS%02d: shutting down modem\n", info->line);
-			feature_clear(info->dev_node, FEATURE_Modem_power);
-			mdelay(10);
+			feature_set_modem_power(info->dev_node, 0);
 		}
 #ifdef CONFIG_PMAC_PBOOK
 		if (info->is_irda)
@@ -1648,7 +1647,7 @@
 	struct mac_serial *info = (struct mac_serial *)tty->driver_data;
 	unsigned long flags;
 #ifdef SERIAL_DEBUG_THROTTLE
-	printk("throttle %ld....\n",tty->ldisc.chars_in_buffer(tty));
+	printk(KERN_DEBUG "throttle %ld....\n",tty->ldisc.chars_in_buffer(tty));
 #endif
 
 	if (serial_paranoia_check(info, tty->device, "rs_throttle"))
@@ -1701,7 +1700,8 @@
 	struct mac_serial *info = (struct mac_serial *)tty->driver_data;
 	unsigned long flags;
 #ifdef SERIAL_DEBUG_THROTTLE
-	printk("unthrottle %s: %d....\n",tty->ldisc.chars_in_buffer(tty));
+	printk(KERN_DEBUG "unthrottle %s: %d....\n",
+			tty->ldisc.chars_in_buffer(tty));
 #endif
 
 	if (serial_paranoia_check(info, tty->device, "rs_unthrottle"))
@@ -1855,13 +1855,11 @@
 static int set_modem_info(struct mac_serial *info, unsigned int cmd,
 			  unsigned int *value)
 {
-	int error;
 	unsigned int arg, bits;
 	unsigned long flags;
 
-	error = get_user(arg, value);
-	if (error)
-		return error;
+	if (get_user(arg, value))
+		return -EFAULT;
 	bits = (arg & TIOCM_RTS? RTS: 0) + (arg & TIOCM_DTR? DTR: 0);
 	save_flags(flags); cli();
 	switch (cmd) {
@@ -2000,13 +1998,13 @@
 		 * one, we've got real problems, since it means the
 		 * serial port won't be shutdown.
 		 */
-		printk("rs_close: bad serial port count; tty->count is 1, "
-		       "info->count is %d\n", info->count);
+		printk(KERN_ERR "rs_close: bad serial port count; tty->count "
+				"is 1, info->count is %d\n", info->count);
 		info->count = 1;
 	}
 	if (--info->count < 0) {
-		printk("rs_close: bad serial port count for ttys%d: %d\n",
-		       info->line, info->count);
+		printk(KERN_ERR "rs_close: bad serial port count for "
+				"ttys%d: %d\n", info->line, info->count);
 		info->count = 0;
 	}
 	if (info->count) {
@@ -2104,14 +2102,16 @@
 	 * interval should also be less than the timeout.
 	 */
 	if (info->timeout <= HZ/50) {
-		printk("macserial: invalid info->timeout=%d\n", info->timeout);
+		printk(KERN_INFO "macserial: invalid info->timeout=%d\n",
+				    info->timeout);
 		info->timeout = HZ/50+1;
 	}
 
 	char_time = (info->timeout - HZ/50) / info->xmit_fifo_size;
 	char_time = char_time / 5;
 	if (char_time > HZ) {
-		printk("macserial: char_time %ld >HZ !!!\n", char_time);
+		printk(KERN_WARNING "macserial: char_time %ld >HZ !!!\n",
+				    char_time);
 		char_time = 1;
 	} else if (char_time == 0)
 		char_time = 1;
@@ -2374,7 +2374,7 @@
 
 static void show_serial_version(void)
 {
-	printk("PowerMac Z8530 serial driver version 2.0\n");
+	printk(KERN_INFO "PowerMac Z8530 serial driver version 2.0\n");
 }
 
 /*
@@ -2461,8 +2461,8 @@
 		nchan = 0;
 		chip = n;
 		if (n >= NUM_CHANNELS) {
-			printk("Sorry, can't use %s: no more channels\n",
-			       dev->full_name);
+			printk(KERN_WARNING "Sorry, can't use %s: no more "
+					    "channels\n", dev->full_name);
 			continue;
 		}
 		chan_a_index = 0;
@@ -2631,7 +2631,8 @@
 
 		/* If console serial line, then enable interrupts. */
 		if (zs_soft[channel].is_cons) {
-			printk("macserial: console line, enabling interrupt %d\n", zs_soft[channel].irq);
+			printk(KERN_INFO "macserial: console line, enabling "
+					"interrupt %d\n", zs_soft[channel].irq);
 			panic("macserial: console not supported yet !");
 			write_zsreg(zs_soft[channel].zs_channel, R1,
 				    (EXT_INT_ENAB | INT_ALL_Rx | TxINT_ENAB));
@@ -2669,7 +2670,7 @@
 		init_waitqueue_head(&info->open_wait);
 		init_waitqueue_head(&info->close_wait);
 		info->timeout = HZ;
-		printk("tty%02d at 0x%08x (irq = %d)", info->line, 
+		printk(KERN_INFO "tty%02d at 0x%08x (irq = %d)", info->line, 
 			info->port, info->irq);
 		printk(" is a Z8530 ESCC");
 		connector = get_property(info->dev_node, "AAPL,connector", &lenp);
diff -u --recursive --new-file v2.4.9/linux/drivers/macintosh/mediabay.c linux/drivers/macintosh/mediabay.c
--- v2.4.9/linux/drivers/macintosh/mediabay.c	Sun Sep 17 09:48:05 2000
+++ linux/drivers/macintosh/mediabay.c	Sat Sep  8 12:38:42 2001
@@ -27,7 +27,7 @@
 #include <asm/io.h>
 #include <asm/feature.h>
 #include <asm/mediabay.h>
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <linux/adb.h>
 #include <linux/pmu.h>
 
diff -u --recursive --new-file v2.4.9/linux/drivers/macintosh/nvram.c linux/drivers/macintosh/nvram.c
--- v2.4.9/linux/drivers/macintosh/nvram.c	Sun Sep 17 09:48:05 2000
+++ linux/drivers/macintosh/nvram.c	Fri Sep  7 09:28:38 2001
@@ -18,7 +18,7 @@
 
 #define NVRAM_SIZE	8192
 
-static long long nvram_llseek(struct file *file, loff_t offset, int origin)
+static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
 {
 	switch (origin) {
 	case 1:
diff -u --recursive --new-file v2.4.9/linux/drivers/macintosh/rtc.c linux/drivers/macintosh/rtc.c
--- v2.4.9/linux/drivers/macintosh/rtc.c	Mon Aug 27 12:41:42 2001
+++ linux/drivers/macintosh/rtc.c	Sat Sep  8 12:38:42 2001
@@ -49,11 +49,7 @@
 {
 	unsigned long nowtime;
 
-	printk(KERN_INFO "rtc.c:set_rtc_time: %04d-%02d-%02d %02d:%02d:%02d.\n", t->tm_year+1900, t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
-
 	nowtime = mktime(t->tm_year+1900, t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
-
-	printk(KERN_INFO "rtc.c:set_rtc_time: set rtc time to %ld seconds.\n", nowtime);
 
 	(ppc_md.set_rtc_time)(nowtime);
 }
diff -u --recursive --new-file v2.4.9/linux/drivers/macintosh/via-pmu.c linux/drivers/macintosh/via-pmu.c
--- v2.4.9/linux/drivers/macintosh/via-pmu.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/macintosh/via-pmu.c	Sat Sep  8 12:38:42 2001
@@ -32,24 +32,30 @@
 #include <linux/pmu.h>
 #include <linux/cuda.h>
 #include <linux/smp_lock.h>
+#include <linux/module.h>
 #include <linux/spinlock.h>
+#include <linux/pm.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
 #include <asm/prom.h>
 #include <asm/machdep.h>
 #include <asm/io.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <asm/irq.h>
 #include <asm/hardirq.h>
 #include <asm/feature.h>
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
+#include <asm/cputable.h>
 #ifdef CONFIG_PMAC_BACKLIGHT
 #include <asm/backlight.h>
 #endif
 
 /* Some compile options */
 #undef SUSPEND_USES_PMU
+#define DEBUG_SLEEP
 
 /* Misc minor number allocated for /dev/pmu */
 #define PMU_MINOR	154
@@ -102,13 +108,11 @@
 static struct adb_request *current_req;
 static struct adb_request *last_req;
 static struct adb_request *req_awaiting_reply;
-static unsigned char interrupt_data[256]; /* Made bigger: I've been told that might happen */
+static unsigned char interrupt_data[32];
 static unsigned char *reply_ptr;
 static int data_index;
 static int data_len;
 static volatile int adb_int_pending;
-static int pmu_adb_flags;
-static int adb_dev_map = 0;
 static struct adb_request bright_req_1, bright_req_2, bright_req_3;
 static struct device_node *vias;
 static int pmu_kind = PMU_UNKNOWN;
@@ -118,11 +122,20 @@
 static int gpio_irq = -1;
 static volatile int pmu_suspended = 0;
 static spinlock_t pmu_lock;
+static u8 pmu_intr_mask;
+static int pmu_version;
+static int drop_interrupts;
+#ifdef CONFIG_PMAC_PBOOK
+static int sleep_in_progress;
+#endif /* CONFIG_PMAC_PBOOK */
 
 int asleep;
 struct notifier_block *sleep_notifier_list;
 
 #ifdef CONFIG_ADB
+static int adb_dev_map = 0;
+static int pmu_adb_flags;
+
 static int pmu_probe(void);
 static int pmu_init(void);
 static int pmu_send_request(struct adb_request *req, int sync);
@@ -163,8 +176,25 @@
 #endif /* CONFIG_ADB */
 
 extern void low_sleep_handler(void);
-extern void sleep_save_intrs(int);
-extern void sleep_restore_intrs(void);
+extern void pmac_sleep_save_intrs(int);
+extern void pmac_sleep_restore_intrs(void);
+extern void openpic_sleep_save_intrs(void);
+extern void openpic_sleep_restore_intrs(void);
+extern void enable_kernel_altivec(void);
+extern void enable_kernel_fp(void);
+
+#ifdef DEBUG_SLEEP
+int pmu_polled_request(struct adb_request *req);
+int pmu_wink(struct adb_request *req);
+#endif
+
+#if defined(CONFIG_PMAC_PBOOK) && defined(CONFIG_PM)
+static int generic_notify_sleep(struct pmu_sleep_notifier *self, int when);
+static struct pmu_sleep_notifier generic_sleep_notifier = {
+	generic_notify_sleep,
+	SLEEP_LEVEL_MISC,
+};
+#endif /* defined(CONFIG_PMAC_PBOOK) && defined(CONFIG_PM) */
 
 /*
  * This table indicates for each PMU opcode:
@@ -246,6 +276,11 @@
 
 	pmu_has_adb = 1;
 
+	pmu_intr_mask =	PMU_INT_PCEJECT |
+			PMU_INT_SNDBRT |
+			PMU_INT_ADB |
+			PMU_INT_TICK;
+	
 	if (vias->parent->name && ((strcmp(vias->parent->name, "ohare") == 0)
 	    || device_is_compatible(vias->parent, "ohare")))
 		pmu_kind = PMU_OHARE_BASED;
@@ -258,7 +293,12 @@
 
 		pmu_kind = PMU_KEYLARGO_BASED;
 		pmu_has_adb = (find_type_devices("adb") != NULL);
-
+		pmu_intr_mask =	PMU_INT_PCEJECT |
+				PMU_INT_SNDBRT |
+				PMU_INT_ADB |
+				PMU_INT_TICK |
+				PMU_INT_ENVIRONMENT;
+		
 		gpiop = find_devices("gpio");
 		if (gpiop && gpiop->n_addrs) {
 			gpio_reg = ioremap(gpiop->addrs->address, 0x10);
@@ -281,11 +321,16 @@
 		return 0;
 	}
 
-	printk(KERN_INFO "PMU driver initialized for %s\n",
-	       pbook_type[pmu_kind]);
+	printk(KERN_INFO "PMU driver %d initialized for %s, firmware: %02x\n",
+	       PMU_DRIVER_VERSION, pbook_type[pmu_kind], pmu_version);
 	       
 	sys_ctrler = SYS_CTRLER_PMU;
 	
+#if defined(CONFIG_PMAC_PBOOK) && defined(CONFIG_PM)
+	pmu_register_sleep_notifier(&generic_sleep_notifier);
+	pm_active = 1;
+#endif	
+
 	return 1;
 }
 
@@ -367,7 +412,7 @@
 	out_8(&via[B], via[B] | TREQ);			/* negate TREQ */
 	out_8(&via[DIRB], (via[DIRB] | TREQ) & ~TACK);	/* TACK in, TREQ out */
 
-	pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, 0xfc);
+	pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, pmu_intr_mask);
 	timeout =  100000;
 	while (!req.complete) {
 		if (--timeout < 0) {
@@ -392,13 +437,20 @@
 		udelay(10);
 	}
 
-	/* Tell PMU we are ready. Which PMU support this ? */
+	/* Tell PMU we are ready.  */
 	if (pmu_kind == PMU_KEYLARGO_BASED) {
 		pmu_request(&req, NULL, 2, PMU_SYSTEM_READY, 2);
 		while (!req.complete)
 			pmu_poll();
 	}
-		
+
+	/* Read PMU version */
+	pmu_request(&req, NULL, 1, PMU_GET_VERSION);
+	while (!req.complete)
+		pmu_poll();
+	if (req.reply_len > 1)
+		pmu_version = req.reply[1];
+
 	return 1;
 }
 
@@ -529,7 +581,7 @@
 	req.done = NULL;
 	req.data[0] = PMU_ADB_CMD;
 	req.data[1] = 0;
-	req.data[2] = ADB_BUSRESET; /* 3 ??? */
+	req.data[2] = ADB_BUSRESET;
 	req.data[3] = 0;
 	req.data[4] = 0;
 	req.reply_len = 0;
@@ -759,7 +811,7 @@
 	}
 	adb_int_pending = 1;
 #ifdef SUSPEND_USES_PMU
-	pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, 0xfc);
+	pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, pmu_intr_mask);
 	spin_unlock_irqrestore(&pmu_lock, flags);
 	while(!req.complete)
 		pmu_poll();
@@ -789,16 +841,11 @@
 			       "intr=%x pmu_state=%d\n", intr, pmu_state);
 			break;
 		}
+		out_8(&via[IFR], intr);
 		if (intr & SR_INT)
 			pmu_sr_intr(regs);
-		else if (intr & CB1_INT) {
+		else if (intr & CB1_INT)
 			adb_int_pending = 1;
-			out_8(&via[IFR], CB1_INT);
-		}
-		intr &= ~(SR_INT | CB1_INT);
-		if (intr != 0) {
-			out_8(&via[IFR], intr);
-		}
 	}
 	/* This is not necessary except if synchronous ADB requests are done
 	 * with interrupts off, which should not happen. Since I'm not sure
@@ -846,23 +893,17 @@
 		out_8(&via[IFR], SR_INT);
 		return;
 	}
-	/* This one seems to appear with PMU99. According to OF methods,
-	 * the protocol didn't change...
-	 */
-	if (via[B] & TACK) {
-		while ((in_8(&via[B]) & TACK) != 0)
+	/* The ack may not yet be low when we get the interrupt */
+	while ((in_8(&via[B]) & TACK) != 0)
 			;
-	}
-
-	/* reset TREQ and wait for TACK to go high */
-	out_8(&via[B], in_8(&via[B]) | TREQ);
-	wait_for_ack();
 
 	/* if reading grab the byte, and reset the interrupt */
 	if (pmu_state == reading || pmu_state == reading_intr)
 		bite = in_8(&via[SR]);
 
-	out_8(&via[IFR], SR_INT);
+	/* reset TREQ and wait for TACK to go high */
+	out_8(&via[B], in_8(&via[B]) | TREQ);
+	wait_for_ack();
 
 	switch (pmu_state) {
 	case sending:
@@ -909,9 +950,8 @@
 		if (data_len == -1) {
 			data_len = bite;
 			if (bite > 32)
-				printk(KERN_ERR "PMU: bad reply len %d\n",
-				       bite);
-		} else {
+				printk(KERN_ERR "PMU: bad reply len %d\n", bite);
+		} else if (data_index < 32) {
 			reply_ptr[data_index++] = bite;
 		}
 		if (data_index < data_len) {
@@ -954,11 +994,14 @@
 pmu_handle_data(unsigned char *data, int len, struct pt_regs *regs)
 {
 	asleep = 0;
-	if (len < 1) {
-//		xmon_printk("empty ADB\n");
+	if (drop_interrupts || len < 1) {
 		adb_int_pending = 0;
 		return;
 	}
+	/* Note: for some reason, we get an interrupt with len=1,
+	 * data[0]==0 after each normal ADB interrupt, at least
+	 * on the Pismo. Still investigating...  --BenH
+	 */
 	if (data[0] & PMU_INT_ADB) {
 		if ((data[0] & PMU_INT_ADB_AUTO) == 0) {
 			struct adb_request *req = req_awaiting_reply;
@@ -1085,10 +1128,14 @@
 
 	cli();
 
-	pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, PMU_INT_ADB |
-					PMU_INT_TICK );
-	while(!req.complete)
-		pmu_poll();
+	drop_interrupts = 1;
+	
+	if (pmu_kind != PMU_KEYLARGO_BASED) {
+		pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, PMU_INT_ADB |
+						PMU_INT_TICK );
+		while(!req.complete)
+			pmu_poll();
+	}
 
 	pmu_request(&req, NULL, 1, PMU_RESET);
 	while(!req.complete || (pmu_state != idle))
@@ -1104,10 +1151,14 @@
 
 	cli();
 
-	pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, PMU_INT_ADB |
-					PMU_INT_TICK );
-	while(!req.complete)
-		pmu_poll();
+	drop_interrupts = 1;
+
+	if (pmu_kind != PMU_KEYLARGO_BASED) {
+		pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, PMU_INT_ADB |
+						PMU_INT_TICK );
+		while(!req.complete)
+			pmu_poll();
+	}
 
 	pmu_request(&req, NULL, 5, PMU_SHUTDOWN,
 		    'M', 'A', 'T', 'T');
@@ -1127,6 +1178,22 @@
 
 static LIST_HEAD(sleep_notifiers);
 
+#ifdef CONFIG_PM
+static int
+generic_notify_sleep(struct pmu_sleep_notifier *self, int when)
+{
+	switch (when) {
+		case PBOOK_SLEEP_NOW:
+			if (pm_send_all(PM_SUSPEND, (void *)3))
+				return PBOOK_SLEEP_REJECT;
+			break;
+		case PBOOK_WAKE:
+			(void) pm_send_all(PM_RESUME, (void *)0);
+	}
+	return PBOOK_SLEEP_OK;
+}
+#endif /* CONFIG_PM */
+
 int
 pmu_register_sleep_notifier(struct pmu_sleep_notifier *n)
 {
@@ -1268,23 +1335,42 @@
 	}
 }
 
-#if 0
+#ifdef DEBUG_SLEEP
 /* N.B. This doesn't work on the 3400 */
-void pmu_blink(int n)
+void
+pmu_blink(int n)
 {
 	struct adb_request req;
 
+	memset(&req, 0, sizeof(req));
+
 	for (; n > 0; --n) {
-		pmu_request(&req, NULL, 4, 0xee, 4, 0, 1);
-		while (!req.complete) pmu_poll();
-		udelay(50000);
-		pmu_request(&req, NULL, 4, 0xee, 4, 0, 0);
-		while (!req.complete) pmu_poll();
-		udelay(50000);
+		req.nbytes = 4;
+		req.done = NULL;
+		req.data[0] = 0xee;
+		req.data[1] = 4;
+		req.data[2] = 0;
+		req.data[3] = 1;
+		req.reply[0] = ADB_RET_OK;
+		req.reply_len = 1;
+		req.reply_expected = 0;
+		pmu_polled_request(&req);
+		mdelay(50);
+		req.nbytes = 4;
+		req.done = NULL;
+		req.data[0] = 0xee;
+		req.data[1] = 4;
+		req.data[2] = 0;
+		req.data[3] = 0;
+		req.reply[0] = ADB_RET_OK;
+		req.reply_len = 1;
+		req.reply_expected = 0;
+		pmu_polled_request(&req);
+		mdelay(50);
 	}
-	udelay(150000);
+	mdelay(50);
 }
-#endif
+#endif /* DEBUG_SLEEP */
 
 /*
  * Put the powerbook to sleep.
@@ -1317,7 +1403,6 @@
 	out_8(&via[IER], IER_SET | SR_INT | CB1_INT);
 }
 
-#define FEATURE_CTRL(base)	((unsigned int *)(base + 0x38))
 #define	GRACKLE_PM	(1<<7)
 #define GRACKLE_DOZE	(1<<5)
 #define	GRACKLE_NAP	(1<<4)
@@ -1363,7 +1448,8 @@
 		mb();
 
 	/* Wait for completion of async backlight requests */
-	while (!bright_req_1.complete || !bright_req_2.complete || !bright_req_3.complete)
+	while (!bright_req_1.complete || !bright_req_2.complete ||
+		!bright_req_3.complete)
 		pmu_poll();
 	
 	/* Turn off various things. Darwin does some retry tests here... */
@@ -1375,8 +1461,8 @@
 	while (!req.complete)
 		pmu_poll();
 
-	/* Disable all interrupts except pmu */
-	sleep_save_intrs(vias->intrs[0].line);
+	/* Disable all interrupts */
+	pmac_sleep_save_intrs(-1);
 
 	/* Make sure the PMU is idle */
 	while (pmu_state != idle)
@@ -1393,6 +1479,9 @@
 	if (current->thread.regs && (current->thread.regs->msr & MSR_FP) != 0)
 		giveup_fpu(current);
 
+	/* We can now disable MSR_EE */
+	cli();
+
 	/* For 750, save backside cache setting and disable it */
 	save_l2cr = _get_L2CR();	/* (returns 0 if not 750) */
 	if (save_l2cr)
@@ -1431,7 +1520,7 @@
  		_set_L2CR(save_l2cr);
 	
 	/* Restore userland MMU context */
-	set_context(current->mm->context);
+	set_context(current->active_mm->context, current->active_mm->pgd);
 
 	/* Re-enable DEC interrupts and kick DEC */
 	asm volatile("mtdec %0" : : "r" (0x7fffffff));
@@ -1464,26 +1553,29 @@
 	}
 
 	/* reenable interrupt controller */
-	sleep_restore_intrs();
+	pmac_sleep_restore_intrs();
 
 	/* Leave some time for HW to settle down */
 	mdelay(100);
 
 	/* Notify drivers */
-	mdelay(10);
 	broadcast_wake();
 
 	return 0;
 }
 
-/* Not finished yet */
 int __openfirmware powerbook_sleep_Core99(void)
 {
-	int ret;
 	unsigned long save_l2cr;
 	unsigned long wait;
 	struct adb_request req;
-
+	int ret, timeout;
+	
+	if (!feature_can_sleep()) {
+		printk(KERN_ERR "Sleep mode not supported on this machine\n");
+		return -ENOSYS;
+	}
+	
 	/* Notify device drivers */
 	ret = broadcast_sleep(PBOOK_SLEEP_REQUEST, PBOOK_SLEEP_REJECT);
 	if (ret != PBOOK_SLEEP_OK) {
@@ -1507,89 +1599,157 @@
 	}
 
 	/* Give the disks a little time to actually finish writing */
-	for (wait = jiffies + (HZ/4); time_before(jiffies, wait); )
+	for (wait = jiffies + HZ; time_before(jiffies, wait); )
 		mb();
 
+	/* Wait for completion of async backlight requests */
+	while (!bright_req_1.complete || !bright_req_2.complete ||
+		!bright_req_3.complete)
+		pmu_poll();
+
 	/* Tell PMU what events will wake us up */
 	pmu_request(&req, NULL, 4, PMU_POWER_EVENTS, PMU_PWR_CLR_WAKEUP_EVENTS,
 		0xff, 0xff);
 	while (!req.complete)
 		pmu_poll();
+
 	pmu_request(&req, NULL, 4, PMU_POWER_EVENTS, PMU_PWR_SET_WAKEUP_EVENTS,
 		0, PMU_PWR_WAKEUP_KEY | PMU_PWR_WAKEUP_LID_OPEN);
 	while (!req.complete)
 		pmu_poll();
 		
-	/* Disable all interrupts except pmu */
-	sleep_save_intrs(vias->intrs[0].line);
+	/* Save & disable all interrupts */
+	openpic_sleep_save_intrs();
+
+	/* Make sure the PMU is idle */
+	while (pmu_state != idle)
+		pmu_poll();
 
 	/* Make sure the decrementer won't interrupt us */
 	asm volatile("mtdec %0" : : "r" (0x7fffffff));
+	/* Make sure any pending DEC interrupt occuring while we did
+	 * the above didn't re-enable the DEC */
+	mb();
+	asm volatile("mtdec %0" : : "r" (0x7fffffff));
 
-	/* Save the state of PCI config space for some slots */
-	pbook_pci_save();
+	/* Giveup the FPU & vec */
+	enable_kernel_fp();
 
-	feature_prepare_for_sleep();
+#ifdef CONFIG_ALTIVEC
+	if (cur_cpu_spec[0]->cpu_features & CPU_FTR_ALTIVEC)
+		enable_kernel_altivec();
+#endif /* CONFIG_ALTIVEC */
+
+	/* We can now disable MSR_EE */
+	cli();
 
 	/* For 750, save backside cache setting and disable it */
 	save_l2cr = _get_L2CR();	/* (returns 0 if not 750) */
 	if (save_l2cr)
-		_set_L2CR(0);
+		_set_L2CR(save_l2cr & 0x7fffffff);
 
-	if (current->thread.regs && (current->thread.regs->msr & MSR_FP) != 0)
-		giveup_fpu(current);
+	/* Save the state of PCI config space for some slots */
+	//pbook_pci_save();
 
 	/* Ask the PMU to put us to sleep */
 	pmu_request(&req, NULL, 5, PMU_SLEEP, 'M', 'A', 'T', 'T');
-	while (!req.complete)
-		mb();
-
-	cli();
-	while (pmu_state != idle)
+	while (!req.complete && pmu_state != idle)
 		pmu_poll();
 
-	/* Call low-level ASM sleep handler */
-	low_sleep_handler();
+	out_8(&via[B], in_8(&via[B]) | TREQ);
+	wait_for_ack();
 
-	/* Make sure the PMU is idle */
-	while (pmu_state != idle)
-		pmu_poll();
+	/* The VIA is supposed not to be restored correctly*/
+	save_via_state();
 
-	sti();
+	/* Shut down various ASICs. There's a chance that we can no longer
+	 * talk to the PMU after this, so I moved it to _after_ sending the
+	 * sleep command to it. Still need to be checked.
+	 */
+	feature_prepare_for_sleep();
 
+	/* Call low-level ASM sleep handler */
+	low_sleep_handler();
+
+	/* Restore Apple core ASICs state */
 	feature_wake_up();
-	pbook_pci_restore();
 
-	set_context(current->mm->context);
+	/* Restore VIA */
+	restore_via_state();
+
+	/* Restore PCI config space. This should be overridable by PCI device
+	 * drivers as some of them may need special restore code. That's yet
+	 * another issue that should be handled by the common code properly,
+	 * maybe one day ?
+	 */
+	/* Don't restore PCI for now, it crashes. Maybe unnecessary on pbook */
+	//pbook_pci_restore();
 
+	pmu_blink(2);
+		
 	/* Restore L2 cache */
 	if (save_l2cr)
- 		_set_L2CR(save_l2cr | 0x200000); /* set invalidate bit */
+ 		_set_L2CR(save_l2cr);
+	
+	/* Restore userland MMU context */
+	set_context(current->active_mm->context, current->active_mm->pgd);
 
-	/* reenable interrupts */
-	sleep_restore_intrs();
+	/* Re-enable DEC interrupts and kick DEC */
+	asm volatile("mtdec %0" : : "r" (0x7fffffff));
+	sti();
+	asm volatile("mtdec %0" : : "r" (0x10000000));
 
 	/* Tell PMU we are ready */
 	pmu_request(&req, NULL, 2, PMU_SYSTEM_READY, 2);
 	while (!req.complete)
 		pmu_poll();
+	pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, 0xfc);
+	while (!req.complete)
+		pmu_poll();
 		
+	/* ack all pending interrupts */
+	timeout = 100000;
+	interrupt_data[0] = 1;
+	while (interrupt_data[0] || pmu_state != idle) {
+		if (--timeout < 0)
+			break;
+		if (pmu_state == idle)
+			adb_int_pending = 1;
+		via_pmu_interrupt(0, 0, 0);
+		udelay(10);
+	}
+
+	/* reenable interrupt controller */
+	openpic_sleep_restore_intrs();
+
+	/* Leave some time for HW to settle down */
+	mdelay(100);
+
 	/* Notify drivers */
-	mdelay(10);
 	broadcast_wake();
 
 	return 0;
 }
 
-#define PB3400_MEM_CTRL		((unsigned int *)0xf8000070)
+#define PB3400_MEM_CTRL		0xf8000000
+#define PB3400_MEM_CTRL_SLEEP	0x70
 
 int __openfirmware powerbook_sleep_3400(void)
 {
 	int ret, i, x;
-	unsigned long msr;
 	unsigned int hid0;
 	unsigned long p, wait;
 	struct adb_request sleep_req;
+	char *mem_ctrl;
+	unsigned int *mem_ctrl_sleep;
+
+	/* first map in the memory controller registers */
+	mem_ctrl = ioremap(PB3400_MEM_CTRL, 0x100);
+	if (mem_ctrl == NULL) {
+		printk("powerbook_sleep_3400: ioremap failed\n");
+		return -ENOMEM;
+	}
+	mem_ctrl_sleep = (unsigned int *) (mem_ctrl + PB3400_MEM_CTRL_SLEEP);
 
 	/* Notify device drivers */
 	ret = broadcast_sleep(PBOOK_SLEEP_REQUEST, PBOOK_SLEEP_REJECT);
@@ -1617,11 +1777,20 @@
 	for (wait = jiffies + (HZ/4); time_before(jiffies, wait); )
 		mb();
 
+	/* Wait for completion of async backlight requests */
+	while (!bright_req_1.complete || !bright_req_2.complete ||
+		!bright_req_3.complete)
+		pmu_poll();
+
 	/* Disable all interrupts except pmu */
-	sleep_save_intrs(vias->intrs[0].line);
+	pmac_sleep_save_intrs(vias->intrs[0].line);
 
 	/* Make sure the decrementer won't interrupt us */
 	asm volatile("mtdec %0" : : "r" (0x7fffffff));
+	/* Make sure any pending DEC interrupt occuring while we did
+	 * the above didn't re-enable the DEC */
+	mb();
+	asm volatile("mtdec %0" : : "r" (0x7fffffff));
 
 	/* Save the state of PCI config space for some slots */
 	pbook_pci_save();
@@ -1629,9 +1798,9 @@
 	/* Set the memory controller to keep the memory refreshed
 	   while we're asleep */
 	for (i = 0x403f; i >= 0x4000; --i) {
-		out_be32(PB3400_MEM_CTRL, i);
+		out_be32(mem_ctrl_sleep, i);
 		do {
-			x = (in_be32(PB3400_MEM_CTRL) >> 16) & 0x3ff;
+			x = (in_be32(mem_ctrl_sleep) >> 16) & 0x3ff;
 		} while (x == 0);
 		if (x >= 0x100)
 			break;
@@ -1651,32 +1820,36 @@
 	asm volatile("mfspr %0,1008" : "=r" (hid0) :);
 	hid0 = (hid0 & ~(HID0_NAP | HID0_DOZE)) | HID0_SLEEP;
 	asm volatile("mtspr 1008,%0" : : "r" (hid0));
-	save_flags(msr);
-	msr |= MSR_POW | MSR_EE;
-	restore_flags(msr);
+	_nmask_and_or_msr(0, MSR_POW | MSR_EE);
 	udelay(10);
 
 	/* OK, we're awake again, start restoring things */
-	out_be32(PB3400_MEM_CTRL, 0x3f);
+	out_be32(mem_ctrl_sleep, 0x3f);
 	pbook_pci_restore();
 
 	/* wait for the PMU interrupt sequence to complete */
 	while (asleep)
 		mb();
 
+	/* Re-enable DEC interrupts and kick DEC */
+	asm volatile("mtdec %0" : : "r" (0x7fffffff));
+	sti();
+	asm volatile("mtdec %0" : : "r" (0x10000000));
+
 	/* reenable interrupts */
-	sleep_restore_intrs();
+	pmac_sleep_restore_intrs();
 
 	/* Notify drivers */
 	broadcast_wake();
 
+	iounmap(mem_ctrl);
 	return 0;
 }
 
 /*
  * Support for /dev/pmu device
  */
-#define RB_SIZE		10
+#define RB_SIZE		0x10
 struct pmu_private {
 	struct list_head list;
 	int	rb_get;
@@ -1830,6 +2003,11 @@
 
 	switch (cmd) {
 	case PMU_IOC_SLEEP:
+		if (!capable(CAP_SYS_ADMIN))
+			return -EACCES;
+		if (sleep_in_progress)
+			return -EBUSY;
+		sleep_in_progress = 1;
 		switch (pmu_kind) {
 		case PMU_OHARE_BASED:
 			error = powerbook_sleep_3400();
@@ -1838,20 +2016,24 @@
 		case PMU_PADDINGTON_BASED:
 			error = powerbook_sleep_G3();
 			break;
-#if 0 /* Not ready yet */
 		case PMU_KEYLARGO_BASED:
 			error = powerbook_sleep_Core99();
 			break;
-#endif			
 		default:
 			error = -ENOSYS;
 		}
+		sleep_in_progress = 0;
 		return error;
+	case PMU_IOC_CAN_SLEEP:
+		return put_user(feature_can_sleep(), (__u32 *)arg);
+
 #ifdef CONFIG_PMAC_BACKLIGHT
 	/* Backlight should have its own device or go via
 	 * the fbdev
 	 */
 	case PMU_IOC_GET_BACKLIGHT:
+		if (sleep_in_progress)
+			return -EBUSY;
 		error = get_backlight_level();
 		if (error < 0)
 			return error;
@@ -1859,6 +2041,8 @@
 	case PMU_IOC_SET_BACKLIGHT:
 	{
 		__u32 value;
+		if (sleep_in_progress)
+			return -EBUSY;
 		error = get_user(value, (__u32 *)arg);
 		if (!error)
 			error = set_backlight_level(value);
@@ -1893,7 +2077,7 @@
 }
 #endif /* CONFIG_PMAC_PBOOK */
 
-#if 0
+#ifdef DEBUG_SLEEP
 static inline void polled_handshake(volatile unsigned char *via)
 {
 	via[B] &= ~TREQ; eieio();
@@ -1939,6 +2123,8 @@
 	while (pmu_state != idle)
 		pmu_poll();
 
+	while ((via[B] & TACK) == 0)
+		;
 	polled_send_byte(v, c);
 	if (l < 0) {
 		l = req->nbytes - 1;
@@ -1959,4 +2145,15 @@
 	restore_flags(flags);
 	return 0;
 }
-#endif /* 0 */
+#endif /* DEBUG_SLEEP */
+
+EXPORT_SYMBOL(pmu_request);
+EXPORT_SYMBOL(pmu_poll);
+EXPORT_SYMBOL(pmu_suspend);
+EXPORT_SYMBOL(pmu_resume);
+#ifdef CONFIG_PMAC_PBOOK
+EXPORT_SYMBOL(pmu_register_sleep_notifier);
+EXPORT_SYMBOL(pmu_unregister_sleep_notifier);
+EXPORT_SYMBOL(pmu_enable_irled);
+#endif /* CONFIG_PMAC_PBOOK */
+
diff -u --recursive --new-file v2.4.9/linux/drivers/md/lvm.c linux/drivers/md/lvm.c
--- v2.4.9/linux/drivers/md/lvm.c	Wed Jul 25 17:10:20 2001
+++ linux/drivers/md/lvm.c	Sun Sep  9 16:27:47 2001
@@ -376,17 +376,13 @@
 {0,};
 static struct gendisk lvm_gendisk =
 {
-	MAJOR_NR,		/* major # */
-	LVM_NAME,		/* name of major */
-	0,			/* number of times minor is shifted
-				   to get real minor */
-	1,			/* maximum partitions per device */
-	lvm_hd_struct,		/* partition table */
-	lvm_size,		/* device size in blocks, copied
-				   to block_size[] */
-	MAX_LV,			/* number or real devices */
-	NULL,			/* internal */
-	NULL,			/* pointer to next gendisk struct (internal) */
+	major:		MAJOR_NR,
+	major_name:	LVM_NAME,
+	minor_shift:	0,
+	max_p:		1,
+	part:		lvm_hd_struct,
+	sizes:		lvm_size,
+	nr_real:	MAX_LV,
 };
 
 /*
@@ -394,8 +390,6 @@
  */
 int lvm_init(void)
 {
-	struct gendisk *gendisk_ptr = NULL;
-
 	if (register_chrdev(LVM_CHAR_MAJOR, lvm_name, &lvm_chr_fops) < 0) {
 		printk(KERN_ERR "%s -- register_chrdev failed\n", lvm_name);
 		return -EIO;
@@ -423,19 +417,7 @@
 	lvm_init_vars();
 	lvm_geninit(&lvm_gendisk);
 
-	/* insert our gendisk at the corresponding major */
-	if (gendisk_head != NULL) {
-		gendisk_ptr = gendisk_head;
-		while (gendisk_ptr->next != NULL &&
-		       gendisk_ptr->major > lvm_gendisk.major) {
-			gendisk_ptr = gendisk_ptr->next;
-		}
-		lvm_gendisk.next = gendisk_ptr->next;
-		gendisk_ptr->next = &lvm_gendisk;
-	} else {
-		gendisk_head = &lvm_gendisk;
-		lvm_gendisk.next = NULL;
-	}
+	add_gendisk(&lvm_gendisk);
 
 #ifdef LVM_HD_NAME
 	/* reference from drivers/block/genhd.c */
@@ -469,8 +451,6 @@
  */
 static void lvm_cleanup(void)
 {
-	struct gendisk *gendisk_ptr = NULL, *gendisk_ptr_prev = NULL;
-
 	devfs_unregister (lvm_devfs_handle);
 
 	if (unregister_chrdev(LVM_CHAR_MAJOR, lvm_name) < 0) {
@@ -481,16 +461,7 @@
 	}
 
 
-	gendisk_ptr = gendisk_ptr_prev = gendisk_head;
-	while (gendisk_ptr != NULL) {
-		if (gendisk_ptr == &lvm_gendisk)
-			break;
-		gendisk_ptr_prev = gendisk_ptr;
-		gendisk_ptr = gendisk_ptr->next;
-	}
-	/* delete our gendisk from chain */
-	if (gendisk_ptr == &lvm_gendisk)
-		gendisk_ptr_prev->next = gendisk_ptr->next;
+	del_gendisk(&lvm_gendisk);
 
 	blk_size[MAJOR_NR] = NULL;
 	blksize_size[MAJOR_NR] = NULL;
@@ -1059,7 +1030,6 @@
 	       lvm_name, minor, VG_BLK(minor), LV_BLK(minor));
 #endif
 
-	sync_dev(inode->i_rdev);
 	if (lv_ptr->lv_open == 1) vg_ptr->lv_open--;
 	lv_ptr->lv_open--;
 
diff -u --recursive --new-file v2.4.9/linux/drivers/md/md.c linux/drivers/md/md.c
--- v2.4.9/linux/drivers/md/md.c	Mon Aug 27 12:41:42 2001
+++ linux/drivers/md/md.c	Sat Sep  8 12:02:32 2001
@@ -222,18 +222,6 @@
 	return mddev;
 }
 
-struct gendisk * find_gendisk (kdev_t dev)
-{
-	struct gendisk *tmp = gendisk_head;
-
-	while (tmp != NULL) {
-		if (tmp->major == MAJOR(dev))
-			return (tmp);
-		tmp = tmp->next;
-	}
-	return (NULL);
-}
-
 mdk_rdev_t * find_rdev_nr(mddev_t *mddev, int nr)
 {
 	mdk_rdev_t * rdev;
@@ -281,7 +269,7 @@
 	/*
 	 * ok, add this new device name to the list
 	 */
-	hd = find_gendisk (dev);
+	hd = get_gendisk (dev);
 	dname->name = NULL;
 	if (hd)
 		dname->name = disk_name (hd, MINOR(dev), dname->namebuf);
@@ -569,7 +557,7 @@
 static kdev_t dev_unit(kdev_t dev)
 {
 	unsigned int mask;
-	struct gendisk *hd = find_gendisk(dev);
+	struct gendisk *hd = get_gendisk(dev);
 
 	if (!hd)
 		return 0;
@@ -921,17 +909,19 @@
 	dev = rdev->dev;
 	sb_offset = calc_dev_sboffset(dev, rdev->mddev, 1);
 	if (rdev->sb_offset != sb_offset) {
-		printk("%s's sb offset has changed from %ld to %ld, skipping\n", partition_name(dev), rdev->sb_offset, sb_offset);
+		printk("%s's sb offset has changed from %ld to %ld, skipping\n",
+		       partition_name(dev), rdev->sb_offset, sb_offset);
 		goto skip;
 	}
 	/*
 	 * If the disk went offline meanwhile and it's just a spare, then
-	 * it's size has changed to zero silently, and the MD code does
+	 * its size has changed to zero silently, and the MD code does
 	 * not yet know that it's faulty.
 	 */
 	size = calc_dev_size(dev, rdev->mddev, 1);
 	if (size != rdev->size) {
-		printk("%s's size has changed from %ld to %ld since import, skipping\n", partition_name(dev), rdev->size, size);
+		printk("%s's size has changed from %ld to %ld since import, skipping\n",
+		       partition_name(dev), rdev->size, size);
 		goto skip;
 	}
 
@@ -2488,27 +2478,14 @@
 						(long *) arg);
 			goto done;
 
-		case BLKFLSBUF:
-			fsync_dev(dev);
-			invalidate_buffers(dev);
-			goto done;
-
+		case BLKRAGET:
 		case BLKRASET:
-			if (arg > 0xff) {
-				err = -EINVAL;
-				goto abort;
-			}
-			read_ahead[MAJOR(dev)] = arg;
-			goto done;
+		case BLKFLSBUF:
+		case BLKBSZGET:
+		case BLKBSZSET:
+			err = blk_ioctl (dev, cmd, arg);
+			goto abort;
 
-		case BLKRAGET:
-			if (!arg) {
-				err = -EINVAL;
-				goto abort;
-			}
-			err = md_put_user (read_ahead[
-				MAJOR(dev)], (long *) arg);
-			goto done;
 		default:;
 	}
 
@@ -2780,7 +2757,6 @@
 int md_thread(void * arg)
 {
 	mdk_thread_t *thread = arg;
-	struct completion *event;
 
 	md_lock_kernel();
 
@@ -2921,7 +2897,7 @@
 		return 0;
 	}
 	rrdev = find_rdev(mddev, rdev);
-	if (rrdev->faulty)
+	if (!rrdev || rrdev->faulty)
 		return 0;
 	if (mddev->pers->error_handler == NULL
 	    || mddev->pers->error_handler(mddev,rdev) <= 0) {
@@ -3224,7 +3200,7 @@
 		if (mddev2 == mddev)
 			continue;
 		if (mddev2->curr_resync && match_mddev_units(mddev,mddev2)) {
-			printk(KERN_INFO "md: serializing resync, md%d shares one or more physical units with md%d!\n", mdidx(mddev), mdidx(mddev2));
+			printk(KERN_INFO "md: delaying resync of md%d until md%d has finished resync (they share one or more physical units)\n", mdidx(mddev), mdidx(mddev2));
 			serialize = 1;
 			break;
 		}
@@ -3286,9 +3262,12 @@
 
 		if (last_check + window > j)
 			continue;
+
+		last_check = j;
 		
-		run_task_queue(&tq_disk); //??
+		run_task_queue(&tq_disk);
 
+	repeat:
 		if (jiffies >= mark[last_mark] + SYNC_MARK_STEP ) {
 			/* step marks */
 			int next = (last_mark+1) % SYNC_MARKS;
@@ -3320,7 +3299,6 @@
 		 * about not overloading the IO subsystem. (things like an
 		 * e2fsck being done on the RAID array should execute fast)
 		 */
-repeat:
 		if (md_need_resched(current))
 			schedule();
 
@@ -3333,8 +3311,7 @@
 					!is_mddev_idle(mddev)) {
 				current->state = TASK_INTERRUPTIBLE;
 				md_schedule_timeout(HZ/4);
-				if (!md_signal_pending(current))
-					goto repeat;
+				goto repeat;
 			}
 		} else
 			current->nice = -20;
@@ -3526,9 +3503,8 @@
 	
 
 	read_ahead[MAJOR_NR] = INT_MAX;
-	md_gendisk.next = gendisk_head;
 
-	gendisk_head = &md_gendisk;
+	add_gendisk(&md_gendisk);
 
 	md_recovery_thread = md_register_thread(md_do_recovery, NULL, name);
 	if (!md_recovery_thread)
@@ -3759,7 +3735,7 @@
 			ainfo.md_minor =minor;
 			ainfo.not_persistent = 1;
 
-			ainfo.state = MD_SB_CLEAN;
+			ainfo.state = (1 << MD_SB_CLEAN);
 			ainfo.active_disks = 0;
 			ainfo.working_disks = 0;
 			ainfo.failed_disks = 0;
@@ -3854,8 +3830,6 @@
 
 void cleanup_module (void)
 {
-	struct gendisk **gendisk_ptr;
-
 	md_unregister_thread(md_recovery_thread);
 	devfs_unregister(devfs_handle);
 
@@ -3865,15 +3839,9 @@
 #ifdef CONFIG_PROC_FS
 	remove_proc_entry("mdstat", NULL);
 #endif
-	
-	gendisk_ptr = &gendisk_head;
-	while (*gendisk_ptr) {
-		if (*gendisk_ptr == &md_gendisk) {
-			*gendisk_ptr = md_gendisk.next;
-			break;
-		}
-		gendisk_ptr = & (*gendisk_ptr)->next;
-	}
+
+	del_gendisk(&md_gendisk);
+
 	blk_dev[MAJOR_NR].queue = NULL;
 	blksize_size[MAJOR_NR] = NULL;
 	blk_size[MAJOR_NR] = NULL;
diff -u --recursive --new-file v2.4.9/linux/drivers/md/raid1.c linux/drivers/md/raid1.c
--- v2.4.9/linux/drivers/md/raid1.c	Mon Aug 27 12:41:42 2001
+++ linux/drivers/md/raid1.c	Wed Aug 29 20:47:41 2001
@@ -162,7 +162,7 @@
 			conf->freer1 = r1_bh->next_r1;
 			conf->freer1_cnt--;
 			r1_bh->next_r1 = NULL;
-			r1_bh->state = 0;
+			r1_bh->state = (1 << R1BH_PreAlloc);
 			r1_bh->bh_req.b_state = 0;
 		}
 		md_spin_unlock_irq(&conf->device_lock);
diff -u --recursive --new-file v2.4.9/linux/drivers/md/raid5.c linux/drivers/md/raid5.c
--- v2.4.9/linux/drivers/md/raid5.c	Wed Jul 25 17:10:20 2001
+++ linux/drivers/md/raid5.c	Fri Sep  7 10:48:39 2001
@@ -485,7 +485,7 @@
 	int i;
 
 	PRINTK("raid5_error called\n");
-	conf->resync_parity = 0;
+
 	for (i = 0, disk = conf->disks; i < conf->raid_disks; i++, disk++) {
 		if (disk->dev == dev && disk->operational) {
 			disk->operational = 0;
@@ -516,7 +516,7 @@
 				"raid5: Disk failure on spare %s\n",
 				partition_name (dev));
 			if (!conf->spare->operational) {
-				MD_BUG();
+				/* probably a SET_DISK_FAULTY ioctl */
 				return -EIO;
 			}
 			disk->operational = 0;
@@ -529,6 +529,9 @@
 			sb->working_disks--;
 			sb->failed_disks++;
 
+			mddev->sb_dirty = 1;
+			md_wakeup_thread(conf->thread);
+
 			return 0;
 		}
 	}
@@ -898,11 +901,11 @@
 				spin_unlock_irq(&conf->device_lock);
 			}
 		}
-		if (syncing) {
-			md_done_sync(conf->mddev, (sh->size>>9) - sh->sync_redone,0);
-			clear_bit(STRIPE_SYNCING, &sh->state);
-			syncing = 0;
-		}			
+	}
+	if (failed > 1 && syncing) {
+		md_done_sync(conf->mddev, (sh->size>>9) - sh->sync_redone,0);
+		clear_bit(STRIPE_SYNCING, &sh->state);
+		syncing = 0;
 	}
 
 	/* might be able to return some write requests if the parity block
@@ -1076,6 +1079,7 @@
 			}
 		}
 		if (!test_bit(STRIPE_INSYNC, &sh->state)) {
+			struct disk_info *spare;
 			if (failed==0)
 				failed_num = sh->pd_idx;
 			/* should be able to compute the missing block and write it to spare */
@@ -1094,8 +1098,8 @@
 			set_bit(STRIPE_INSYNC, &sh->state);
 			if (conf->disks[failed_num].operational)
 				md_sync_acct(conf->disks[failed_num].dev, bh->b_size>>9);
-			else if (conf->spare)
-				md_sync_acct(conf->spare->dev, bh->b_size>>9);
+			else if ((spare=conf->spare))
+				md_sync_acct(spare->dev, bh->b_size>>9);
 
 		}
 	}
@@ -1120,6 +1124,7 @@
 	for (i=disks; i-- ;) 
 		if (action[i]) {
 			struct buffer_head *bh = sh->bh_cache[i];
+			struct disk_info *spare = conf->spare;
 			int skip = 0;
 			if (action[i] == READ+1)
 				bh->b_end_io = raid5_end_read_request;
@@ -1127,8 +1132,8 @@
 				bh->b_end_io = raid5_end_write_request;
 			if (conf->disks[i].operational)
 				bh->b_dev = conf->disks[i].dev;
-			else if (conf->spare && action[i] == WRITE+1)
-				bh->b_dev = conf->spare->dev;
+			else if (spare && action[i] == WRITE+1)
+				bh->b_dev = spare->dev;
 			else skip=1;
 			if (!skip) {
 				PRINTK("for %ld schedule op %d on disc %d\n", sh->sector, action[i]-1, i);
diff -u --recursive --new-file v2.4.9/linux/drivers/media/video/videodev.c linux/drivers/media/video/videodev.c
--- v2.4.9/linux/drivers/media/video/videodev.c	Mon Aug 27 12:41:42 2001
+++ linux/drivers/media/video/videodev.c	Tue Aug 28 07:00:58 2001
@@ -164,7 +164,6 @@
 	
 	if(vfl->owner)
 		__MOD_INC_USE_COUNT(vfl->owner);
-	unlock_kernel();
 	
 	if(vfl->open)
 	{
@@ -175,9 +174,11 @@
 			if(vfl->owner)
 				__MOD_DEC_USE_COUNT(vfl->owner);
 			
+			unlock_kernel();
 			return err;
 		}
 	}
+	unlock_kernel();
 	return 0;
 error_out:
 	unlock_kernel();
diff -u --recursive --new-file v2.4.9/linux/drivers/media/video/vino.h linux/drivers/media/video/vino.h
--- v2.4.9/linux/drivers/media/video/vino.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/media/video/vino.h	Fri Sep  7 09:28:38 2001
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 1999 Ulf Carlsson (ulfc@bun.falkenberg.se)
+ * Copyright (C) 2001 Ralf Baechle (ralf@gnu.org)
+ */
+
+#define VINO_BASE		0x00080000	/* In EISA address space */
+
+#define VINO_REVID		0x0000
+#define VINO_CTRL		0x0008
+#define VINO_INTSTAT		0x0010	/* Interrupt status */
+#define VINO_I2C_CTRL		0x0018
+#define VINO_I2C_DATA		0x0020
+#define VINO_A_ALPHA		0x0028	/* Channel A ... */
+#define VINO_A_CLIPS		0x0030	/* Clipping start */
+#define VINO_A_CLIPE		0x0038	/* Clipping end */
+#define VINO_A_FRAMERT		0x0040	/* Framerate */
+#define VINO_A_FLDCNT		0x0048	/* Field counter */
+#define VINO_A_LNSZ		0x0050
+#define VINO_A_LNCNT		0x0058
+#define VINO_A_PGIX		0x0060	/* Page index */
+#define VINO_A_DESC_PTR		0x0068	/* Ptr to next four descriptors */
+#define VINO_A_DESC_TLB_PTR	0x0070	/* Ptr to start of descriptor table */
+#define VINO_A_DESC_DATA0	0x0078	/* Descriptor data 0 */
+#define VINO_A_DESC_DATA1	0x0080	/* ... */
+#define VINO_A_DESC_DATA2	0x0088
+#define VINO_A_DESC_DATA3	0x0090
+#define VINO_A_FIFO_THRESHOLD	0x0098	/* FIFO threshold */
+#define VINO_A_FIFO_RP		0x00a0
+#define VINO_A_FIFO_WP		0x00a8
+#define VINO_B_ALPHA		0x00b0	/* Channel B ... */
+#define VINO_B_CLIPS		0x00b8
+#define VINO_B_CLIPE		0x00c0
+#define VINO_B_FRAMERT		0x00c8
+#define VINO_B_FLDCNT		0x00d0
+#define VINO_B_LNSZ		0x00d8
+#define VINO_B_LNCNT		0x00e0
+#define VINO_B_PGIX		0x00e8
+#define VINO_B_DESC_PTR		0x00f0
+#define VINO_B_DESC_TLB_PTR	0x00f8
+#define VINO_B_DESC_DATA0	0x0100
+#define VINO_B_DESC_DATA1	0x0108
+#define VINO_B_DESC_DATA2	0x0110
+#define VINO_B_DESC_DATA3	0x0118
+#define VINO_B_FIFO_THRESHOLD	0x0120
+#define VINO_B_FIFO_RP		0x0128
+#define VINO_B_FIFO_WP		0x0130
+
+/* Bits in the VINO_REVID register */
+
+#define VINO_REVID_REV_MASK		0x000f	/* bits 0:3 */
+#define VINO_REVID_ID_MASK		0x00f0	/* bits 4:7 */
+
+/* Bits in the VINO_CTRL register */
+
+#define VINO_CTRL_LITTLE_ENDIAN		(1<<0)
+#define VINO_CTRL_A_FIELD_TRANS_INT	(1<<1)	/* Field transferred int */
+#define VINO_CTRL_A_FIFO_OF_INT		(1<<2)	/* FIFO overflow int */
+#define VINO_CTRL_A_END_DESC_TBL_INT	(1<<3)	/* End of desc table int */
+#define VINO_CTRL_B_FIELD_TRANS_INT	(1<<4)	/* Field transferred int */
+#define VINO_CTRL_B_FIFO_OF_INT		(1<<5)	/* FIFO overflow int */
+#define VINO_CTRL_B_END_DESC_TLB_INT	(1<<6)	/* End of desc table int */
+#define VINO_CTRL_A_DMA_ENBL		(1<<7)
+#define VINO_CTRL_A_INTERLEAVE_ENBL	(1<<8)
+#define VINO_CTRL_A_SYNC_ENBL		(1<<9)
+#define VINO_CTRL_A_SELECT		(1<<10)	/* 1=D1 0=Philips */
+#define VINO_CTRL_A_RGB			(1<<11)	/* 1=RGB 0=YUV */
+#define VINO_CTRL_A_LUMA_ONLY		(1<<12)
+#define VINO_CTRL_A_DEC_ENBL		(1<<13)	/* Decimation */
+#define VINO_CTRL_A_DEC_SCALE_MASK	0x1c000	/* bits 14:17 */
+#define VINO_CTRL_A_DEC_HOR_ONLY	(1<<17)	/* Horizontal only */
+#define VINO_CTRL_A_DITHER		(1<<18)	/* 24 -> 8 bit dither */
+#define VINO_CTRL_B_DMA_ENBL		(1<<19)
+#define VINO_CTRL_B_INTERLEAVE_ENBL	(1<<20)
+#define VINO_CTRL_B_SYNC_ENBL		(1<<21)
+#define VINO_CTRL_B_SELECT		(1<<22)	/* 1=D1 0=Philips */
+#define VINO_CTRL_B_RGB			(1<<22)	/* 1=RGB 0=YUV */
+#define VINO_CTRL_B_LUMA_ONLY		(1<<23)
+#define VINO_CTRL_B_DEC_ENBL		(1<<24)	/* Decimation */
+#define VINO_CTRL_B_DEC_SCALE_MASK	0x1c000000	/* bits 25:28 */
+#define VINO_CTRL_B_DEC_HOR_ONLY	(1<<29)	/* Decimation horizontal only */
+#define VINO_CTRL_B_DITHER		(1<<30)	/* ChanB 24 -> 8 bit dither */
+
+/* Bits in the Interrupt and Status register */
+
+#define VINO_INTSTAT_A_FIELD_TRANS	(1<<0)	/* Field transferred int */
+#define VINO_INTSTAT_A_FIFO_OF		(1<<1)	/* FIFO overflow int */
+#define VINO_INTSTAT_A_END_DESC_TBL	(1<<2)	/* End of desc table int */
+#define VINO_INTSTAT_B_FIELD_TRANS	(1<<3)	/* Field transferred int */
+#define VINO_INTSTAT_B_FIFO_OF		(1<<4)	/* FIFO overflow int */
+#define VINO_INTSTAT_B_END_DESC_TBL	(1<<5)	/* End of desc table int */
+
+/* Bits in the Clipping Start register */
+
+#define VINO_CLIPS_START		0x3ff		/* bits 0:9 */
+#define VINO_CLIPS_ODD_MASK		0x7fc00		/* bits 10:18 */
+#define VINO_CLIPS_EVEN_MASK		0xff80000	/* bits 19:27 */
+
+/* Bits in the Clipping End register */
+
+#define VINO_CLIPE_END			0x3ff		/* bits 0:9 */
+#define VINO_CLIPE_ODD_MASK		0x7fc00		/* bits 10:18 */
+#define VINO_CLIPE_EVEN_MASK		0xff80000	/* bits 19:27 */
+
+/* Bits in the Frame Rate register */
+
+#define VINO_FRAMERT_PAL		(1<<0)	/* 0=NTSC 1=PAL */
+#define VINO_FRAMERT_RT_MASK		0x1ffe		/* bits 1:12 */
+
+/* Bits in the VINO_I2C_CTRL */
+
+#define VINO_CTRL_I2C_IDLE		(1<<0)	/* write: 0=force idle
+						 * read: 0=idle 1=not idle */
+#define VINO_CTRL_I2C_DIR		(1<<1)	/* 0=read 1=write */
+#define VINO_CTRL_I2C_MORE_BYTES	(1<<2)	/* 0=last byte 1=more bytes */
+#define VINO_CTRL_I2C_TRANS_BUSY	(1<<4)	/* 0=trans done 1=trans busy */
+#define VINO_CTRL_I2C_ACK		(1<<5)	/* 0=ack received 1=ack not */
+#define VINO_CTRL_I2C_BUS_ERROR		(1<<7)	/* 0=no bus err 1=bus err */
diff -u --recursive --new-file v2.4.9/linux/drivers/media/video/zr36067.c linux/drivers/media/video/zr36067.c
--- v2.4.9/linux/drivers/media/video/zr36067.c	Sun Aug 12 13:27:59 2001
+++ linux/drivers/media/video/zr36067.c	Sun Sep  9 10:45:43 2001
@@ -3734,7 +3734,6 @@
 			zr->window.chromakey = 0;
 			zr->window.flags = 0;	// RJ: Is this intended for interlace on/off ?
 			zr->window.clips = NULL;
-			zr->window.clipcount = vw.clipcount;
 
 			/*
 			 * If an overlay is running, we have to switch it off
@@ -3775,7 +3774,8 @@
 				write_overlay_mask(zr, vcp, vw.clipcount);
 				vfree(vcp);
 			}
-
+			zr->window.clipcount = vw.clipcount;
+	
 			if (on)
 				zr36057_overlay(zr, 1);
 			zr->window_set = 1;
diff -u --recursive --new-file v2.4.9/linux/drivers/media/video/zr36120.c linux/drivers/media/video/zr36120.c
--- v2.4.9/linux/drivers/media/video/zr36120.c	Wed Jul 25 17:10:20 2001
+++ linux/drivers/media/video/zr36120.c	Sun Sep  9 10:45:43 2001
@@ -1056,7 +1056,7 @@
 		DEBUG(printk(CARD_DEBUG "VIDIOCSCHAN(%d,%d)\n",CARD,v.channel,v.norm));
 
 		/* too many inputs? no decoder -> no channels */
-		if (!ztv->have_decoder || v.channel >= ztv->card->video_inputs)
+		if (!ztv->have_decoder || v.channel >= ztv->card->video_inputs || v.channel < 0)
 			return -EINVAL;
 
 		if (v.norm != VIDEO_MODE_PAL &&
diff -u --recursive --new-file v2.4.9/linux/drivers/message/fusion/Makefile linux/drivers/message/fusion/Makefile
--- v2.4.9/linux/drivers/message/fusion/Makefile	Wed Jul 25 17:10:20 2001
+++ linux/drivers/message/fusion/Makefile	Fri Sep  7 09:28:38 2001
@@ -27,18 +27,22 @@
 #EXTRA_CFLAGS += -DDEBUG
 #EXTRA_CFLAGS += -DMPT_DEBUG
 #EXTRA_CFLAGS += -DMPT_DEBUG_MSG_FRAME
-#EXTRA_CFLAGS += -DMPT_DEBUG_SPINLOCK
+#
 # driver/module specifics...
+#
 #  For mptbase:
 #CFLAGS_mptbase.o += -DMPT_DEBUG_HANDSHAKE
 #CFLAGS_mptbase.o += -DMPT_DEBUG_IRQ
+#
 #  For {mptscsih, mptctl}:
 #CFLAGS_mptscsih.o += -DMPT_SCSI_USE_NEW_EH
-#CFLAGS_mptscsih.o += -DMPT_SCSI_CACHE_AUTOSENSE
+#CFLAGS_mptscsih.o += -DMPT_DEBUG_SCANDV
 #CFLAGS_mptscsih.o += -DMPT_DEBUG_SG
 #CFLAGS_mptctl.o += -DMPT_DEBUG_SG
+#
 #  For mptlan:
 #CFLAGS_mptlan.o += -DMPT_LAN_IO_DEBUG
+#
 #  For isense:
 
 #  EXP...
diff -u --recursive --new-file v2.4.9/linux/drivers/message/fusion/isense.c linux/drivers/message/fusion/isense.c
--- v2.4.9/linux/drivers/message/fusion/isense.c	Wed Jul 25 17:10:20 2001
+++ linux/drivers/message/fusion/isense.c	Fri Sep  7 09:28:38 2001
@@ -10,7 +10,7 @@
  *  (yes I wrote some of the orig. code back in 1991!)
  *  (mailto:Steve.Ralston@lsil.com)
  *
- *  $Id: isense.c,v 1.28 2001/01/14 23:11:09 sralston Exp $
+ *  $Id: isense.c,v 1.28.14.1 2001/08/24 20:07:04 sralston Exp $
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -61,7 +61,7 @@
 #endif
 
 #define MODULEAUTHOR "Steven J. Ralston"
-#define COPYRIGHT "Copyright (c) 2000 " MODULEAUTHOR
+#define COPYRIGHT "Copyright (c) 2001 " MODULEAUTHOR
 #include "mptbase.h"
 
 #include "isense.h"
diff -u --recursive --new-file v2.4.9/linux/drivers/message/fusion/lsi/fc_log.h linux/drivers/message/fusion/lsi/fc_log.h
--- v2.4.9/linux/drivers/message/fusion/lsi/fc_log.h	Wed Jul 25 17:10:20 2001
+++ linux/drivers/message/fusion/lsi/fc_log.h	Fri Sep  7 09:28:38 2001
@@ -7,7 +7,7 @@
  *                  in the IOCLogInfo field of a MPI Default Reply Message.
  *
  *  CREATION DATE:  6/02/2000
- *  ID:             $Id: fc_log.h,v 4.2 2001/03/01 18:28:59 fibre Exp $
+ *  ID:             $Id: fc_log.h,v 4.5 2001/06/07 19:18:00 sschremm Exp $
  */
 
 
@@ -38,11 +38,16 @@
 {
     MPI_IOCLOGINFO_FC_INIT_BASE                     = 0x20000000,
     MPI_IOCLOGINFO_FC_INIT_ERROR_OUT_OF_ORDER_FRAME = 0x20000001, /* received an out of order frame - unsupported */
-    MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_START_OF_FRAME = 0x20000002, /* bad start of frame primative */
-    MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_END_OF_FRAME   = 0x20000003, /* bad end of frame primative */
-    MPI_IOCLOGINFO_FC_INIT_ERROR_OVER_RUN           = 0x20000004, /* Receiver hardware detected overrun */
+    MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_START_OF_FRAME = 0x20000002, /* Bad Rx Frame, bad start of frame primative */
+    MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_END_OF_FRAME   = 0x20000003, /* Bad Rx Frame, bad end of frame primative */
+    MPI_IOCLOGINFO_FC_INIT_ERROR_OVER_RUN           = 0x20000004, /* Bad Rx Frame, overrun */
     MPI_IOCLOGINFO_FC_INIT_ERROR_RX_OTHER           = 0x20000005, /* Other errors caught by IOC which require retries */
     MPI_IOCLOGINFO_FC_INIT_ERROR_SUBPROC_DEAD       = 0x20000006, /* Main processor could not initialize sub-processor */
+    MPI_IOCLOGINFO_FC_INIT_ERROR_RX_OVERRUN         = 0x20000007, /* Scatter Gather overrun  */
+    MPI_IOCLOGINFO_FC_INIT_ERROR_RX_BAD_STATUS      = 0x20000008, /* Receiver detected context mismatch via invalid header */
+    MPI_IOCLOGINFO_FC_INIT_ERROR_RX_UNEXPECTED_FRAME= 0x20000009, /* CtxMgr detected unsupported frame type  */
+    MPI_IOCLOGINFO_FC_INIT_ERROR_LINK_FAILURE       = 0x2000000A, /* Link failure occurred  */
+    MPI_IOCLOGINFO_FC_INIT_ERROR_TX_TIMEOUT         = 0x2000000B, /* Transmitter timeout error */
 
     MPI_IOCLOGINFO_FC_TARGET_BASE                   = 0x21000000,
     MPI_IOCLOGINFO_FC_TARGET_NO_PDISC               = 0x21000001, /* not sent because we are waiting for a PDISC from the initiator */
@@ -72,10 +77,11 @@
     MPI_IOCLOGINFO_FC_LINK_LOOP_INIT_TIMEOUT        = 0x24000001, /* Loop initialization timed out */
     MPI_IOCLOGINFO_FC_LINK_ALREADY_INITIALIZED      = 0x24000002, /* Another system controller already initialized the loop */
     MPI_IOCLOGINFO_FC_LINK_LINK_NOT_ESTABLISHED     = 0x24000003, /* Not synchronized to signal or still negotiating (possible cable problem) */
+    MPI_IOCLOGINFO_FC_LINK_CRC_ERROR                = 0x24000004, /* CRC check detected error on received frame */
 
     MPI_IOCLOGINFO_FC_CTX_BASE                      = 0x25000000,
 
-    MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET     = 0x26000000, /* The lower 24 bits give the byte offset of the field in the request message that is invalid. */
+    MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET     = 0x26000000, /* The lower 24 bits give the byte offset of the field in the request message that is invalid */
     MPI_IOCLOGINFO_FC_INVALID_FIELD_MAX_OFFSET      = 0x26ffffff,
 
     MPI_IOCLOGINFO_FC_STATE_CHANGE                  = 0x27000000  /* The lower 24 bits give additional information concerning state change */
diff -u --recursive --new-file v2.4.9/linux/drivers/message/fusion/lsi/mpi.h linux/drivers/message/fusion/lsi/mpi.h
--- v2.4.9/linux/drivers/message/fusion/lsi/mpi.h	Wed Jul 25 17:10:20 2001
+++ linux/drivers/message/fusion/lsi/mpi.h	Fri Sep  7 09:28:38 2001
@@ -6,7 +6,7 @@
  *          Title:  MPI Message independent structures and definitions
  *  Creation Date:  July 27, 2000
  *
- *    MPI Version:  01.01.06
+ *    MPI Version:  01.01.07
  *
  *  Version History
  *  ---------------
@@ -37,6 +37,8 @@
  *                      Obsoleted MPI_IOCSTATUS_TARGET_FC_ defines.
  *  02-27-01  01.01.06  Removed MPI_HOST_INDEX_REGISTER define.
  *                      Added function codes for RAID.
+ *  04-09-01  01.01.07  Added alternate define for MPI_DOORBELL_ACTIVE,
+ *                      MPI_DOORBELL_USED, to better match the spec.
  *  --------------------------------------------------------------------------
  */
 
@@ -90,7 +92,8 @@
 
 /* S y s t e m    D o o r b e l l */
 #define MPI_DOORBELL_OFFSET                 (0x00000000)
-#define MPI_DOORBELL_ACTIVE                 (0x08000000)
+#define MPI_DOORBELL_ACTIVE                 (0x08000000) /* DoorbellUsed */
+#define MPI_DOORBELL_USED                   (MPI_DOORBELL_ACTIVE)
 #define MPI_DOORBELL_ACTIVE_SHIFT           (27)
 #define MPI_DOORBELL_WHO_INIT_MASK          (0x07000000)
 #define MPI_DOORBELL_WHO_INIT_SHIFT         (24)
@@ -634,9 +637,9 @@
 /****************************************************************************/
 
 #define MPI_IOCLOGINFO_TYPE_MASK                (0xF0000000)
-#define MPI_IOCLOGINFO_TYPE_NONE                (0x00)
-#define MPI_IOCLOGINFO_TYPE_SCSI                (0x01)
-#define MPI_IOCLOGINFO_TYPE_FC                  (0x02)
+#define MPI_IOCLOGINFO_TYPE_NONE                (0x0)
+#define MPI_IOCLOGINFO_TYPE_SCSI                (0x1)
+#define MPI_IOCLOGINFO_TYPE_FC                  (0x2)
 #define MPI_IOCLOGINFO_LOG_DATA_MASK            (0x0FFFFFFF)
 
 
diff -u --recursive --new-file v2.4.9/linux/drivers/message/fusion/lsi/mpi_cnfg.h linux/drivers/message/fusion/lsi/mpi_cnfg.h
--- v2.4.9/linux/drivers/message/fusion/lsi/mpi_cnfg.h	Wed Jul 25 17:10:20 2001
+++ linux/drivers/message/fusion/lsi/mpi_cnfg.h	Fri Sep  7 09:28:38 2001
@@ -6,7 +6,7 @@
  *          Title:  MPI Config message, structures, and Pages
  *  Creation Date:  July 27, 2000
  *
- *    MPI Version:  01.01.09
+ *    MPI Version:  01.01.11
  *
  *  Version History
  *  ---------------
@@ -60,6 +60,18 @@
  *                      MPI_CONFIG_PAGETYPE_RAID_VOLUME.
  *                      Added definitions and structures for IOC Page 2 and
  *                      RAID Volume Page 2.
+ *  03-27-01  01.01.10  Added CONFIG_PAGE_FC_PORT_8 and CONFIG_PAGE_FC_PORT_9.
+ *                      CONFIG_PAGE_FC_PORT_3 now supports persistent by DID.
+ *                      Added VendorId and ProductRevLevel fields to
+ *                      RAIDVOL2_IM_PHYS_ID struct.
+ *                      Modified values for MPI_FCPORTPAGE0_FLAGS_ATTACH_
+ *                      defines to make them compatible to MPI version 1.0.
+ *                      Added structure offset comments.
+ *  04-09-01  01.01.11  Added some new defines for the PageAddress field and
+ *                      removed some obsolete ones.
+ *                      Added IO Unit Page 3.
+ *                      Modified defines for Scsi Port Page 2.
+ *                      Modified RAID Volume Pages.
  *  --------------------------------------------------------------------------
  */
 
@@ -75,10 +87,10 @@
 
 typedef struct _CONFIG_PAGE_HEADER
 {
-    U8                      PageVersion;
-    U8                      PageLength;
-    U8                      PageNumber;
-    U8                      PageType;
+    U8                      PageVersion;                /* 00h */
+    U8                      PageLength;                 /* 01h */
+    U8                      PageNumber;                 /* 02h */
+    U8                      PageType;                   /* 03h */
 } fCONFIG_PAGE_HEADER, MPI_POINTER PTR_CONFIG_PAGE_HEADER,
   ConfigPageHeader_t, MPI_POINTER pConfigPageHeader_t;
 
@@ -120,17 +132,19 @@
  ****************************************************************************/
 #define MPI_SCSI_PORT_PGAD_PORT_MASK                (0x000000FF)
 
+#define MPI_SCSI_DEVICE_FORM_MASK                   (0xF0000000)
+#define MPI_SCSI_DEVICE_FORM_TARGETID               (0x00000000)
+#define MPI_SCSI_DEVICE_FORM_RAID_PHYS_DEV_NUM      (0x10000000)
 #define MPI_SCSI_DEVICE_TARGET_ID_MASK              (0x000000FF)
 #define MPI_SCSI_DEVICE_TARGET_ID_SHIFT             (0)
 #define MPI_SCSI_DEVICE_BUS_MASK                    (0x0000FF00)
 #define MPI_SCSI_DEVICE_BUS_SHIFT                   (8)
-
-#define MPI_SCSI_LUN_TARGET_ID_MASK                 (0x000000FF)
-#define MPI_SCSI_LUN_TARGET_ID_SHIFT                (0)
-#define MPI_SCSI_LUN_BUS_MASK                       (0x0000FF00)
-#define MPI_SCSI_LUN_BUS_SHIFT                      (8)
-#define MPI_SCSI_LUN_LUN_MASK                       (0x00FF0000)
-#define MPI_SCSI_LUN_LUN_SHIFT                      (16)
+#define MPI_SCSI_DEVICE_VOLUME_TARG_ID_MASK         (0x000000FF)
+#define MPI_SCSI_DEVICE_VOLUME_TARG_ID_SHIFT        (0)
+#define MPI_SCSI_DEVICE_VOLUME_BUS_MASK             (0x0000FF00)
+#define MPI_SCSI_DEVICE_VOLUME_BUS_SHIFT            (8)
+#define MPI_SCSI_DEVICE_PHYS_DISK_NUM_MASK          (0x00FF0000)
+#define MPI_SCSI_DEVICE_PHYS_DISK_NUM_SHIFT         (16)
 
 #define MPI_FC_PORT_PGAD_PORT_MASK                  (0xF0000000)
 #define MPI_FC_PORT_PGAD_PORT_SHIFT                 (28)
@@ -159,17 +173,17 @@
 /****************************************************************************/
 typedef struct _MSG_CONFIG
 {
-    U8                      Action;
-    U8                      Reserved;
-    U8                      ChainOffset;
-    U8                      Function;
-    U8                      Reserved1[3];
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U8                      Reserved2[8];
-   fCONFIG_PAGE_HEADER      Header;
-    U32                     PageAddress;
-    SGE_IO_UNION            PageBufferSGE;
+    U8                      Action;                     /* 00h */
+    U8                      Reserved;                   /* 01h */
+    U8                      ChainOffset;                /* 02h */
+    U8                      Function;                   /* 03h */
+    U8                      Reserved1[3];               /* 04h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U8                      Reserved2[8];               /* 0Ch */
+   fCONFIG_PAGE_HEADER      Header;                     /* 14h */
+    U32                     PageAddress;                /* 18h */
+    SGE_IO_UNION            PageBufferSGE;              /* 1Ch */
 } MSG_CONFIG, MPI_POINTER PTR_MSG_CONFIG,
   Config_t, MPI_POINTER pConfig_t;
 
@@ -178,12 +192,9 @@
 /*  Action field values                                                     */
 /****************************************************************************/
 #define MPI_CONFIG_ACTION_PAGE_HEADER               (0x00)
-/*#define MPI_CONFIG_ACTION_PAGE_READ                 (0x01) *//* obsolete */
 #define MPI_CONFIG_ACTION_PAGE_READ_CURRENT         (0x01)
-/*#define MPI_CONFIG_ACTION_PAGE_WRITE                (0x02) *//* obsolete */
 #define MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT        (0x02)
 #define MPI_CONFIG_ACTION_PAGE_DEFAULT              (0x03)
-/*#define MPI_CONFIG_ACTION_PAGE_WRITE_COMMIT         (0x04) */ /* obsolete */
 #define MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM          (0x04)
 #define MPI_CONFIG_ACTION_PAGE_READ_DEFAULT         (0x05)
 #define MPI_CONFIG_ACTION_PAGE_READ_NVRAM           (0x06)
@@ -192,17 +203,17 @@
 /* Config Reply Message */
 typedef struct _MSG_CONFIG_REPLY
 {
-    U8                      Action;
-    U8                      Reserved;
-    U8                      MsgLength;
-    U8                      Function;
-    U8                      Reserved1[3];
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U8                      Reserved2[2];
-    U16                     IOCStatus;
-    U32                     IOCLogInfo;
-   fCONFIG_PAGE_HEADER      Header;
+    U8                      Action;                     /* 00h */
+    U8                      Reserved;                   /* 01h */
+    U8                      MsgLength;                  /* 02h */
+    U8                      Function;                   /* 03h */
+    U8                      Reserved1[3];               /* 04h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U8                      Reserved2[2];               /* 0Ch */
+    U16                     IOCStatus;                  /* 0Eh */
+    U32                     IOCLogInfo;                 /* 10h */
+   fCONFIG_PAGE_HEADER      Header;                     /* 14h */
 } MSG_CONFIG_REPLY, MPI_POINTER PTR_MSG_CONFIG_REPLY,
   ConfigReply_t, MPI_POINTER pConfigReply_t;
 
@@ -226,12 +237,12 @@
 
 typedef struct _CONFIG_PAGE_MANUFACTURING_0
 {
-   fCONFIG_PAGE_HEADER      Header;
-    U8                      ChipName[16];
-    U8                      ChipRevision[8];
-    U8                      BoardName[16];
-    U8                      BoardAssembly[16];
-    U8                      BoardTracerNumber[16];
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U8                      ChipName[16];               /* 04h */
+    U8                      ChipRevision[8];            /* 14h */
+    U8                      BoardName[16];              /* 1Ch */
+    U8                      BoardAssembly[16];          /* 2Ch */
+    U8                      BoardTracerNumber[16];      /* 3Ch */
 
 } fCONFIG_PAGE_MANUFACTURING_0, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_0,
   ManufacturingPage0_t, MPI_POINTER pManufacturingPage0_t;
@@ -241,8 +252,8 @@
 
 typedef struct _CONFIG_PAGE_MANUFACTURING_1
 {
-   fCONFIG_PAGE_HEADER      Header;
-    U8                      VPD[256];
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U8                      VPD[256];                   /* 04h */
 } fCONFIG_PAGE_MANUFACTURING_1, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_1,
   ManufacturingPage1_t, MPI_POINTER pManufacturingPage1_t;
 
@@ -251,18 +262,18 @@
 
 typedef struct _MPI_CHIP_REVISION_ID
 {
-    U16 DeviceID;
-    U8  PCIRevisionID;
-    U8  Reserved;
+    U16 DeviceID;                                       /* 00h */
+    U8  PCIRevisionID;                                  /* 02h */
+    U8  Reserved;                                       /* 03h */
 } MPI_CHIP_REVISION_ID, MPI_POINTER PTR_MPI_CHIP_REVISION_ID,
   MpiChipRevisionId_t, MPI_POINTER pMpiChipRevisionId_t;
 
 
 typedef struct _CONFIG_PAGE_MANUFACTURING_2
 {
-   fCONFIG_PAGE_HEADER                  Header;
-    MPI_CHIP_REVISION_ID                ChipId;
-    U32                                 HwSettings[1];
+   fCONFIG_PAGE_HEADER                  Header;         /* 00h */
+    MPI_CHIP_REVISION_ID                ChipId;         /* 04h */
+    U32                                 HwSettings[1];  /* 08h */
 } fCONFIG_PAGE_MANUFACTURING_2, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_2,
   ManufacturingPage2_t, MPI_POINTER pManufacturingPage2_t;
 
@@ -271,9 +282,9 @@
 
 typedef struct _CONFIG_PAGE_MANUFACTURING_3
 {
-   fCONFIG_PAGE_HEADER                  Header;
-    MPI_CHIP_REVISION_ID                ChipId;
-    U32                                 Info[1];
+   fCONFIG_PAGE_HEADER                  Header;         /* 00h */
+    MPI_CHIP_REVISION_ID                ChipId;         /* 04h */
+    U32                                 Info[1];        /* 08h */
 } fCONFIG_PAGE_MANUFACTURING_3, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_3,
   ManufacturingPage3_t, MPI_POINTER pManufacturingPage3_t;
 
@@ -286,8 +297,8 @@
 
 typedef struct _CONFIG_PAGE_IO_UNIT_0
 {
-   fCONFIG_PAGE_HEADER      Header;
-    U64                     UniqueValue;
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U64                     UniqueValue;                /* 04h */
 } fCONFIG_PAGE_IO_UNIT_0, MPI_POINTER PTR_CONFIG_PAGE_IO_UNIT_0,
   IOUnitPage0_t, MPI_POINTER pIOUnitPage0_t;
 
@@ -296,8 +307,8 @@
 
 typedef struct _CONFIG_PAGE_IO_UNIT_1
 {
-   fCONFIG_PAGE_HEADER      Header;
-    U32                     Flags;
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U32                     Flags;                      /* 04h */
 } fCONFIG_PAGE_IO_UNIT_1, MPI_POINTER PTR_CONFIG_PAGE_IO_UNIT_1,
   IOUnitPage1_t, MPI_POINTER pIOUnitPage1_t;
 
@@ -313,9 +324,9 @@
 
 typedef struct _MPI_ADAPTER_INFO
 {
-    U8      PciBusNumber;
-    U8      PciDeviceAndFunctionNumber;
-    U16     AdapterFlags;
+    U8      PciBusNumber;                               /* 00h */
+    U8      PciDeviceAndFunctionNumber;                 /* 01h */
+    U16     AdapterFlags;                               /* 02h */
 } MPI_ADAPTER_INFO, MPI_POINTER PTR_MPI_ADAPTER_INFO,
   MpiAdapterInfo_t, MPI_POINTER pMpiAdapterInfo_t;
 
@@ -324,10 +335,10 @@
 
 typedef struct _CONFIG_PAGE_IO_UNIT_2
 {
-   fCONFIG_PAGE_HEADER      Header;
-    U32                     Flags;
-    U32                     BiosVersion;
-    MPI_ADAPTER_INFO        AdapterOrder[4];
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U32                     Flags;                      /* 04h */
+    U32                     BiosVersion;                /* 08h */
+    MPI_ADAPTER_INFO        AdapterOrder[4];            /* 0Ch */
 } fCONFIG_PAGE_IO_UNIT_2, MPI_POINTER PTR_CONFIG_PAGE_IO_UNIT_2,
   IOUnitPage2_t, MPI_POINTER pIOUnitPage2_t;
 
@@ -340,34 +351,53 @@
 #define MPI_IOUNITPAGE2_FLAGS_DONT_HOOK_INT_40          (0x00000010)
 
 
+typedef struct _CONFIG_PAGE_IO_UNIT_3
+{
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U32                     VolumeSettings;             /* 04h */
+    U8                      InfoOffset0;                /* 08h */
+    U8                      InfoSize0;                  /* 09h */
+    U8                      InfoOffset1;                /* 0Ah */
+    U8                      InfoSize1;                  /* 0Bh */
+    U8                      InquirySize;                /* 0Ch */
+    U8                      Reserved;                   /* 0Dh */
+    U16                     Reserved2;                  /* 0Eh */
+    U8                      InquiryData[56];            /* 10h */
+} fCONFIG_PAGE_IO_UNIT_3, MPI_POINTER PTR_CONFIG_PAGE_IO_UNIT_3,
+  IOUnitPage3_t, MPI_POINTER pIOUnitPage3_t;
+
+#define MPI_IOUNITPAGE3_PAGEVERSION                     (0x00)
+
+
 /****************************************************************************/
 /*  IOC Config Pages                                                        */
 /****************************************************************************/
 
 typedef struct _CONFIG_PAGE_IOC_0
 {
-   fCONFIG_PAGE_HEADER      Header;
-    U32                     TotalNVStore;
-    U32                     FreeNVStore;
-    U16                     VendorID;
-    U16                     DeviceID;
-    U8                      RevisionID;
-    U8                      Reserved[3];
-    U32                     ClassCode;
-    U16                     SubsystemVendorID;
-    U16                     SubsystemID;
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U32                     TotalNVStore;               /* 04h */
+    U32                     FreeNVStore;                /* 08h */
+    U16                     VendorID;                   /* 0Ch */
+    U16                     DeviceID;                   /* 0Eh */
+    U8                      RevisionID;                 /* 10h */
+    U8                      Reserved[3];                /* 11h */
+    U32                     ClassCode;                  /* 14h */
+    U16                     SubsystemVendorID;          /* 18h */
+    U16                     SubsystemID;                /* 1Ah */
 } fCONFIG_PAGE_IOC_0, MPI_POINTER PTR_CONFIG_PAGE_IOC_0,
   IOCPage0_t, MPI_POINTER pIOCPage0_t;
 
 #define MPI_IOCPAGE0_PAGEVERSION                        (0x01)
 
+
 typedef struct _CONFIG_PAGE_IOC_1
 {
-   fCONFIG_PAGE_HEADER      Header;
-    U32                     Flags;
-    U32                     CoalescingTimeout;
-    U8                      CoalescingDepth;
-    U8                      Reserved[3];
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U32                     Flags;                      /* 04h */
+    U32                     CoalescingTimeout;          /* 08h */
+    U8                      CoalescingDepth;            /* 0Ch */
+    U8                      Reserved[3];                /* 0Dh */
 } fCONFIG_PAGE_IOC_1, MPI_POINTER PTR_CONFIG_PAGE_IOC_1,
   IOCPage1_t, MPI_POINTER pIOCPage1_t;
 
@@ -375,26 +405,27 @@
 
 #define MPI_IOCPAGE1_REPLY_COALESCING                   (0x00000001)
 
+
 typedef struct _CONFIG_PAGE_IOC_2_RAID_VOL
 {
-    U8                      VolumeTargetID;
-    U8                      VolumeBus;
-    U16                     Reserved;
-    U8                      VolumeVersionMinor;
-    U8                      VolumeVersionMajor;
-    U8                      VolumeRaidType;
-    U8                      Reserved1;
+    U8                      VolumeTargetID;             /* 00h */
+    U8                      VolumeBus;                  /* 01h */
+    U16                     Reserved;                   /* 02h */
+    U8                      VolumeVersionMinor;         /* 04h */
+    U8                      VolumeVersionMajor;         /* 05h */
+    U8                      VolumeRaidType;             /* 06h */
+    U8                      Reserved1;                  /* 07h */
 } fCONFIG_PAGE_IOC_2_RAID_VOL, MPI_POINTER PTR_CONFIG_PAGE_IOC_2_RAID_VOL,
   ConfigPageIoc2RaidVol_t, MPI_POINTER pConfigPageIoc2RaidVol_t;
 
 typedef struct _CONFIG_PAGE_IOC_2
 {
-   fCONFIG_PAGE_HEADER          Header;
-    U32                         CapabilitiesFlags;
-    U8                          NumActiveVolumes;
-    U8                          MaxVolumes;
-    U16                         Reserved;
-   fCONFIG_PAGE_IOC_2_RAID_VOL  RaidVolume[1];
+   fCONFIG_PAGE_HEADER          Header;                 /* 00h */
+    U32                         CapabilitiesFlags;      /* 04h */
+    U8                          NumActiveVolumes;       /* 08h */
+    U8                          MaxVolumes;             /* 09h */
+    U16                         Reserved;               /* 0Ah */
+   fCONFIG_PAGE_IOC_2_RAID_VOL  RaidVolume[1];          /* 0Ch */
 } fCONFIG_PAGE_IOC_2, MPI_POINTER PTR_CONFIG_PAGE_IOC_2,
   IOCPage2_t, MPI_POINTER pIOCPage2_t;
 
@@ -423,9 +454,9 @@
 
 typedef struct _CONFIG_PAGE_SCSI_PORT_0
 {
-   fCONFIG_PAGE_HEADER      Header;
-    U32                     Capabilities;
-    U32                     PhysicalInterface;
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U32                     Capabilities;               /* 04h */
+    U32                     PhysicalInterface;          /* 08h */
 } fCONFIG_PAGE_SCSI_PORT_0, MPI_POINTER PTR_CONFIG_PAGE_SCSI_PORT_0,
   SCSIPortPage0_t, MPI_POINTER pSCSIPortPage0_t;
 
@@ -445,10 +476,11 @@
 #define MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE                 (0x02)
 #define MPI_SCSIPORTPAGE0_PHY_SIGNAL_LVD                (0x03)
 
+
 typedef struct _CONFIG_PAGE_SCSI_PORT_1
 {
-   fCONFIG_PAGE_HEADER      Header;
-    U32                     Configuration;
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U32                     Configuration;              /* 04h */
 } fCONFIG_PAGE_SCSI_PORT_1, MPI_POINTER PTR_CONFIG_PAGE_SCSI_PORT_1,
   SCSIPortPage1_t, MPI_POINTER pSCSIPortPage1_t;
 
@@ -457,20 +489,21 @@
 #define MPI_SCSIPORTPAGE1_CFG_PORT_SCSI_ID_MASK         (0x000000FF)
 #define MPI_SCSIPORTPAGE1_CFG_PORT_RESPONSE_ID_MASK     (0xFFFF0000)
 
+
 typedef struct _MPI_DEVICE_INFO
 {
-    U8      Timeout;
-    U8      SyncFactor;
-    U16     DeviceFlags;
+    U8      Timeout;                                    /* 00h */
+    U8      SyncFactor;                                 /* 01h */
+    U16     DeviceFlags;                                /* 02h */
 } MPI_DEVICE_INFO, MPI_POINTER PTR_MPI_DEVICE_INFO,
   MpiDeviceInfo_t, MPI_POINTER pMpiDeviceInfo_t;
 
 typedef struct _CONFIG_PAGE_SCSI_PORT_2
 {
-   fCONFIG_PAGE_HEADER  Header;
-    U32                 PortFlags;
-    U32                 PortSettings;
-    MPI_DEVICE_INFO     DeviceSettings[16];
+   fCONFIG_PAGE_HEADER  Header;                         /* 00h */
+    U32                 PortFlags;                      /* 04h */
+    U32                 PortSettings;                   /* 08h */
+    MPI_DEVICE_INFO     DeviceSettings[16];             /* 0Ch */
 } fCONFIG_PAGE_SCSI_PORT_2, MPI_POINTER PTR_CONFIG_PAGE_SCSI_PORT_2,
   SCSIPortPage2_t, MPI_POINTER pSCSIPortPage2_t;
 
@@ -492,15 +525,15 @@
 #define MPI_SCSIPORTPAGE2_PORT_SPINUP_DELAY_MASK            (0x00000F00)
 #define MPI_SCSIPORTPAGE2_PORT_MASK_NEGO_MASTER_SETTINGS    (0x00003000)
 #define MPI_SCSIPORTPAGE2_PORT_NEGO_MASTER_SETTINGS         (0x00000000)
-#define MPI_SCSIPORTPAGE2_PORT_NONE_MASTER_SETTINGS         (0x00000001)
-#define MPI_SCSIPORTPAGE2_PORT_ALL_MASTER_SETTINGS          (0x00000003)
+#define MPI_SCSIPORTPAGE2_PORT_NONE_MASTER_SETTINGS         (0x00001000)
+#define MPI_SCSIPORTPAGE2_PORT_ALL_MASTER_SETTINGS          (0x00003000)
 
-#define MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE          (0x00000001)
-#define MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE             (0x00000002)
-#define MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE            (0x00000004)
-#define MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE           (0x00000008)
-#define MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE               (0x00000010)
-#define MPI_SCSIPORTPAGE2_DEVICE_BOOT_CHOICE                (0x00000020)
+#define MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE          (0x0001)
+#define MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE             (0x0002)
+#define MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE            (0x0004)
+#define MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE           (0x0008)
+#define MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE               (0x0010)
+#define MPI_SCSIPORTPAGE2_DEVICE_BOOT_CHOICE                (0x0020)
 
 
 /****************************************************************************/
@@ -509,9 +542,9 @@
 
 typedef struct _CONFIG_PAGE_SCSI_DEVICE_0
 {
-   fCONFIG_PAGE_HEADER      Header;
-    U32                     NegotiatedParameters;
-    U32                     Information;
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U32                     NegotiatedParameters;       /* 04h */
+    U32                     Information;                /* 08h */
 } fCONFIG_PAGE_SCSI_DEVICE_0, MPI_POINTER PTR_CONFIG_PAGE_SCSI_DEVICE_0,
   SCSIDevicePage0_t, MPI_POINTER pSCSIDevicePage0_t;
 
@@ -528,16 +561,17 @@
 
 #define MPI_SCSIDEVPAGE0_INFO_PARAMS_NEGOTIATED         (0x00000001)
 
+
 typedef struct _CONFIG_PAGE_SCSI_DEVICE_1
 {
-   fCONFIG_PAGE_HEADER      Header;
-    U32                     RequestedParameters;
-    U32                     DomainValidation;
-    U32                     Configuration;
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U32                     RequestedParameters;        /* 04h */
+    U32                     Reserved;                   /* 08h */
+    U32                     Configuration;              /* 0Ch */
 } fCONFIG_PAGE_SCSI_DEVICE_1, MPI_POINTER PTR_CONFIG_PAGE_SCSI_DEVICE_1,
   SCSIDevicePage1_t, MPI_POINTER pSCSIDevicePage1_t;
 
-#define MPI_SCSIDEVPAGE1_PAGEVERSION                    (0x01)
+#define MPI_SCSIDEVPAGE1_PAGEVERSION                    (0x02)
 
 #define MPI_SCSIDEVPAGE1_RP_IU                          (0x00000001)
 #define MPI_SCSIDEVPAGE1_RP_DT                          (0x00000002)
@@ -553,29 +587,71 @@
 
 #define MPI_SCSIDEVPAGE1_CONF_PPR_ALLOWED               (0x00000001)
 
+
+typedef struct _CONFIG_PAGE_SCSI_DEVICE_2
+{
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U32                     DomainValidation;           /* 04h */
+    U32                     ParityPipeSelect;           /* 08h */
+    U32                     DataPipeSelect;             /* 0Ch */
+} fCONFIG_PAGE_SCSI_DEVICE_2, MPI_POINTER PTR_CONFIG_PAGE_SCSI_DEVICE_2,
+  SCSIDevicePage2_t, MPI_POINTER pSCSIDevicePage2_t;
+
+#define MPI_SCSIDEVPAGE2_PAGEVERSION                    (0x00)
+
+#define MPI_SCSIDEVPAGE2_DV_ISI_ENABLE                  (0x00000010)
+#define MPI_SCSIDEVPAGE2_DV_SECONDARY_DRIVER_ENABLE     (0x00000020)
+#define MPI_SCSIDEVPAGE2_DV_SLEW_RATE_CTRL              (0x00000380)
+#define MPI_SCSIDEVPAGE2_DV_PRIM_DRIVE_STR_CTRL         (0x00001C00)
+#define MPI_SCSIDEVPAGE2_DV_SECOND_DRIVE_STR_CTRL       (0x0000E000)
+#define MPI_SCSIDEVPAGE2_DV_XCLKH_ST                    (0x10000000)
+#define MPI_SCSIDEVPAGE2_DV_XCLKS_ST                    (0x20000000)
+#define MPI_SCSIDEVPAGE2_DV_XCLKH_DT                    (0x40000000)
+#define MPI_SCSIDEVPAGE2_DV_XCLKS_DT                    (0x80000000)
+
+#define MPI_SCSIDEVPAGE2_PPS_PPS_MASK                   (0x00000003)
+
+#define MPI_SCSIDEVPAGE2_DPS_BIT_0_PL_SELECT_MASK       (0x00000003)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_1_PL_SELECT_MASK       (0x0000000C)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_2_PL_SELECT_MASK       (0x00000030)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_3_PL_SELECT_MASK       (0x000000C0)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_4_PL_SELECT_MASK       (0x00000300)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_5_PL_SELECT_MASK       (0x00000C00)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_6_PL_SELECT_MASK       (0x00003000)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_7_PL_SELECT_MASK       (0x0000C000)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_8_PL_SELECT_MASK       (0x00030000)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_9_PL_SELECT_MASK       (0x000C0000)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_10_PL_SELECT_MASK      (0x00300000)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_11_PL_SELECT_MASK      (0x00C00000)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_12_PL_SELECT_MASK      (0x03000000)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_13_PL_SELECT_MASK      (0x0C000000)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_14_PL_SELECT_MASK      (0x30000000)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_15_PL_SELECT_MASK      (0xC0000000)
+
+
 /****************************************************************************/
 /*  FC Port Config Pages                                                    */
 /****************************************************************************/
 
 typedef struct _CONFIG_PAGE_FC_PORT_0
 {
-   fCONFIG_PAGE_HEADER      Header;
-    U32                     Flags;
-    U8                      MPIPortNumber;
-    U8                      LinkType;
-    U8                      PortState;
-    U8                      Reserved;
-    U32                     PortIdentifier;
-    U64                     WWNN;
-    U64                     WWPN;
-    U32                     SupportedServiceClass;
-    U32                     SupportedSpeeds;
-    U32                     CurrentSpeed;
-    U32                     MaxFrameSize;
-    U64                     FabricWWNN;
-    U64                     FabricWWPN;
-    U32                     DiscoveredPortsCount;
-    U32                     MaxInitiators;
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U32                     Flags;                      /* 04h */
+    U8                      MPIPortNumber;              /* 08h */
+    U8                      LinkType;                   /* 09h */
+    U8                      PortState;                  /* 0Ah */
+    U8                      Reserved;                   /* 0Bh */
+    U32                     PortIdentifier;             /* 0Ch */
+    U64                     WWNN;                       /* 10h */
+    U64                     WWPN;                       /* 18h */
+    U32                     SupportedServiceClass;      /* 20h */
+    U32                     SupportedSpeeds;            /* 24h */
+    U32                     CurrentSpeed;               /* 28h */
+    U32                     MaxFrameSize;               /* 2Ch */
+    U64                     FabricWWNN;                 /* 30h */
+    U64                     FabricWWPN;                 /* 38h */
+    U32                     DiscoveredPortsCount;       /* 40h */
+    U32                     MaxInitiators;              /* 44h */
 } fCONFIG_PAGE_FC_PORT_0, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_0,
   FCPortPage0_t, MPI_POINTER pFCPortPage0_t;
 
@@ -591,12 +667,12 @@
 #define MPI_FCPORTPAGE0_FLAGS_ALIAS_WWN_SUPPORTED       (0x00000020)
 #define MPI_FCPORTPAGE0_FLAGS_FABRIC_WWN_VALID          (0x00000030)
 
-#define MPI_FCPORTPAGE0_FLAGS_ATTACH_TYPE_MASK          (0x00000700)
-#define MPI_FCPORTPAGE0_FLAGS_ATTACH_POINT_TO_POINT     (0x00000000)
-#define MPI_FCPORTPAGE0_FLAGS_ATTACH_PRIVATE_LOOP       (0x00000100)
-#define MPI_FCPORTPAGE0_FLAGS_ATTACH_FABRIC_DIRECT      (0x00000200)
-#define MPI_FCPORTPAGE0_FLAGS_ATTACH_PUBLIC_LOOP        (0x00000300)
-#define MPI_FCPORTPAGE0_FLAGS_ATTACH_NO_INIT            (0x00000700)
+#define MPI_FCPORTPAGE0_FLAGS_ATTACH_TYPE_MASK          (0x00000F00)
+#define MPI_FCPORTPAGE0_FLAGS_ATTACH_NO_INIT            (0x00000000)
+#define MPI_FCPORTPAGE0_FLAGS_ATTACH_POINT_TO_POINT     (0x00000100)
+#define MPI_FCPORTPAGE0_FLAGS_ATTACH_PRIVATE_LOOP       (0x00000200)
+#define MPI_FCPORTPAGE0_FLAGS_ATTACH_FABRIC_DIRECT      (0x00000400)
+#define MPI_FCPORTPAGE0_FLAGS_ATTACH_PUBLIC_LOOP        (0x00000800)
 
 #define MPI_FCPORTPAGE0_LTYPE_RESERVED                  (0x00)
 #define MPI_FCPORTPAGE0_LTYPE_OTHER                     (0x01)
@@ -639,14 +715,14 @@
 
 typedef struct _CONFIG_PAGE_FC_PORT_1
 {
-   fCONFIG_PAGE_HEADER      Header;
-    U32                     Flags;
-    U64                     NoSEEPROMWWNN;
-    U64                     NoSEEPROMWWPN;
-    U8                      HardALPA;
-    U8                      LinkConfig;
-    U8                      TopologyConfig;
-    U8                      Reserved;
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U32                     Flags;                      /* 04h */
+    U64                     NoSEEPROMWWNN;              /* 08h */
+    U64                     NoSEEPROMWWPN;              /* 10h */
+    U8                      HardALPA;                   /* 18h */
+    U8                      LinkConfig;                 /* 19h */
+    U8                      TopologyConfig;             /* 1Ah */
+    U8                      Reserved;                   /* 1Bh */
 } fCONFIG_PAGE_FC_PORT_1, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_1,
   FCPortPage1_t, MPI_POINTER pFCPortPage1_t;
 
@@ -679,23 +755,36 @@
 
 typedef struct _CONFIG_PAGE_FC_PORT_2
 {
-   fCONFIG_PAGE_HEADER      Header;
-    U8                      NumberActive;
-    U8                      ALPA[126];
-    U8                      Reserved;
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U8                      NumberActive;               /* 04h */
+    U8                      ALPA[126];                  /* 05h */
+    U8                      Reserved;                   /* 83h */
 } fCONFIG_PAGE_FC_PORT_2, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_2,
   FCPortPage2_t, MPI_POINTER pFCPortPage2_t;
 
 #define MPI_FCPORTPAGE2_PAGEVERSION                     (0x00)
 
 
+typedef struct _WWN_FORMAT
+{
+    U64                     WWNN;                       /* 00h */
+    U64                     WWPN;                       /* 08h */
+} WWN_FORMAT, MPI_POINTER PTR_WWN_FORMAT,
+  WWNFormat, MPI_POINTER pWWNFormat;
+
+typedef union _FC_PORT_PERSISTENT_PHYSICAL_ID
+{
+    WWN_FORMAT              WWN;
+    U32                     Did;
+} FC_PORT_PERSISTENT_PHYSICAL_ID, MPI_POINTER PTR_FC_PORT_PERSISTENT_PHYSICAL_ID,
+  PersistentPhysicalId_t, MPI_POINTER pPersistentPhysicalId_t;
+
 typedef struct _FC_PORT_PERSISTENT
 {
-    U64                     WWNN;
-    U64                     WWPN;
-    U8                      TargetID;
-    U8                      Bus;
-    U16                     Flags;
+    FC_PORT_PERSISTENT_PHYSICAL_ID  PhysicalIdentifier; /* 00h */
+    U8                              TargetID;           /* 10h */
+    U8                              Bus;                /* 11h */
+    U16                             Flags;              /* 12h */
 } FC_PORT_PERSISTENT, MPI_POINTER PTR_FC_PORT_PERSISTENT,
   PersistentData_t, MPI_POINTER pPersistentData_t;
 
@@ -704,22 +793,23 @@
 #define MPI_PERSISTENT_FLAGS_SCAN_ID                    (0x0002)
 #define MPI_PERSISTENT_FLAGS_SCAN_LUNS                  (0x0004)
 #define MPI_PERSISTENT_FLAGS_BOOT_DEVICE                (0x0008)
+#define MPI_PERSISTENT_FLAGS_BY_DID                     (0x0080)
 
 typedef struct _CONFIG_PAGE_FC_PORT_3
 {
-   fCONFIG_PAGE_HEADER      Header;
-    FC_PORT_PERSISTENT      Entry[1];
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    FC_PORT_PERSISTENT      Entry[1];                   /* 04h */
 } fCONFIG_PAGE_FC_PORT_3, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_3,
   FCPortPage3_t, MPI_POINTER pFCPortPage3_t;
 
-#define MPI_FCPORTPAGE3_PAGEVERSION                     (0x00)
+#define MPI_FCPORTPAGE3_PAGEVERSION                     (0x01)
 
 
 typedef struct _CONFIG_PAGE_FC_PORT_4
 {
-   fCONFIG_PAGE_HEADER      Header;
-    U32                     PortFlags;
-    U32                     PortSettings;
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U32                     PortFlags;                  /* 04h */
+    U32                     PortSettings;               /* 08h */
 } fCONFIG_PAGE_FC_PORT_4, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_4,
   FCPortPage4_t, MPI_POINTER pFCPortPage4_t;
 
@@ -738,18 +828,18 @@
 
 typedef struct _CONFIG_PAGE_FC_PORT_5_ALIAS_INFO
 {
-    U8      Flags;
-    U8      AliasAlpa;
-    U16     Reserved;
-    U64     AliasWWNN;
-    U64     AliasWWPN;
+    U8      Flags;                                      /* 00h */
+    U8      AliasAlpa;                                  /* 01h */
+    U16     Reserved;                                   /* 02h */
+    U64     AliasWWNN;                                  /* 04h */
+    U64     AliasWWPN;                                  /* 0Ch */
 } fCONFIG_PAGE_FC_PORT_5_ALIAS_INFO, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_5_ALIAS_INFO,
   FcPortPage5AliasInfo_t, MPI_POINTER pFcPortPage5AliasInfo_t;
 
 typedef struct _CONFIG_PAGE_FC_PORT_5
 {
-   fCONFIG_PAGE_HEADER                  Header;
-   fCONFIG_PAGE_FC_PORT_5_ALIAS_INFO    AliasInfo[1];
+   fCONFIG_PAGE_HEADER                  Header;         /* 00h */
+   fCONFIG_PAGE_FC_PORT_5_ALIAS_INFO    AliasInfo[1];   /* 04h */
 } fCONFIG_PAGE_FC_PORT_5, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_5,
   FCPortPage5_t, MPI_POINTER pFCPortPage5_t;
 
@@ -761,24 +851,24 @@
 
 typedef struct _CONFIG_PAGE_FC_PORT_6
 {
-   fCONFIG_PAGE_HEADER      Header;
-    U32                     Reserved;
-    U64                     TimeSinceReset;
-    U64                     TxFrames;
-    U64                     RxFrames;
-    U64                     TxWords;
-    U64                     RxWords;
-    U64                     LipCount;
-    U64                     NosCount;
-    U64                     ErrorFrames;
-    U64                     DumpedFrames;
-    U64                     LinkFailureCount;
-    U64                     LossOfSyncCount;
-    U64                     LossOfSignalCount;
-    U64                     PrimativeSeqErrCount;
-    U64                     InvalidTxWordCount;
-    U64                     InvalidCrcCount;
-    U64                     FcpInitiatorIoCount;
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U32                     Reserved;                   /* 04h */
+    U64                     TimeSinceReset;             /* 08h */
+    U64                     TxFrames;                   /* 10h */
+    U64                     RxFrames;                   /* 18h */
+    U64                     TxWords;                    /* 20h */
+    U64                     RxWords;                    /* 28h */
+    U64                     LipCount;                   /* 30h */
+    U64                     NosCount;                   /* 38h */
+    U64                     ErrorFrames;                /* 40h */
+    U64                     DumpedFrames;               /* 48h */
+    U64                     LinkFailureCount;           /* 50h */
+    U64                     LossOfSyncCount;            /* 58h */
+    U64                     LossOfSignalCount;          /* 60h */
+    U64                     PrimativeSeqErrCount;       /* 68h */
+    U64                     InvalidTxWordCount;         /* 70h */
+    U64                     InvalidCrcCount;            /* 78h */
+    U64                     FcpInitiatorIoCount;        /* 80h */
 } fCONFIG_PAGE_FC_PORT_6, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_6,
   FCPortPage6_t, MPI_POINTER pFCPortPage6_t;
 
@@ -787,35 +877,65 @@
 
 typedef struct _CONFIG_PAGE_FC_PORT_7
 {
-   fCONFIG_PAGE_HEADER      Header;
-    U32                     Reserved;
-    U8                      PortSymbolicName[256];
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U32                     Reserved;                   /* 04h */
+    U8                      PortSymbolicName[256];      /* 08h */
 } fCONFIG_PAGE_FC_PORT_7, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_7,
   FCPortPage7_t, MPI_POINTER pFCPortPage7_t;
 
 #define MPI_FCPORTPAGE7_PAGEVERSION                     (0x00)
 
 
+typedef struct _CONFIG_PAGE_FC_PORT_8
+{
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U32                     BitVector[8];               /* 04h */
+} fCONFIG_PAGE_FC_PORT_8, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_8,
+  FCPortPage8_t, MPI_POINTER pFCPortPage8_t;
+
+#define MPI_FCPORTPAGE8_PAGEVERSION                     (0x00)
+
+
+typedef struct _CONFIG_PAGE_FC_PORT_9
+{
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U32                     Reserved;                   /* 04h */
+    U64                     GlobalWWPN;                 /* 08h */
+    U64                     GlobalWWNN;                 /* 10h */
+    U32                     UnitType;                   /* 18h */
+    U32                     PhysicalPortNumber;         /* 1Ch */
+    U32                     NumAttachedNodes;           /* 20h */
+    U16                     IPVersion;                  /* 24h */
+    U16                     UDPPortNumber;              /* 26h */
+    U8                      IPAddress[16];              /* 28h */
+    U16                     Reserved1;                  /* 38h */
+    U16                     TopologyDiscoveryFlags;     /* 3Ah */
+} fCONFIG_PAGE_FC_PORT_9, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_9,
+  FCPortPage9_t, MPI_POINTER pFCPortPage9_t;
+
+#define MPI_FCPORTPAGE9_PAGEVERSION                     (0x00)
+
+
 /****************************************************************************/
 /*  FC Device Config Pages                                                  */
 /****************************************************************************/
 
 typedef struct _CONFIG_PAGE_FC_DEVICE_0
 {
-   fCONFIG_PAGE_HEADER      Header;
-    U64                     WWNN;
-    U64                     WWPN;
-    U32                     PortIdentifier;
-    U8                      Protocol;
-    U8                      Flags;
-    U16                     BBCredit;
-    U16                     MaxRxFrameSize;
-    U8                      Reserved1;
-    U8                      PortNumber;
-    U8                      FcPhLowestVersion;
-    U8                      FcPhHighestVersion;
-    U8                      CurrentTargetID;
-    U8                      CurrentBus;
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U64                     WWNN;                       /* 04h */
+    U64                     WWPN;                       /* 0Ch */
+    U32                     PortIdentifier;             /* 14h */
+    U8                      Protocol;                   /* 18h */
+    U8                      Flags;                      /* 19h */
+    U16                     BBCredit;                   /* 1Ah */
+    U16                     MaxRxFrameSize;             /* 1Ch */
+    U8                      Reserved1;                  /* 1Eh */
+    U8                      PortNumber;                 /* 1Fh */
+    U8                      FcPhLowestVersion;          /* 20h */
+    U8                      FcPhHighestVersion;         /* 21h */
+    U8                      CurrentTargetID;            /* 22h */
+    U8                      CurrentBus;                 /* 23h */
 } fCONFIG_PAGE_FC_DEVICE_0, MPI_POINTER PTR_CONFIG_PAGE_FC_DEVICE_0,
   FCDevicePage0_t, MPI_POINTER pFCDevicePage0_t;
 
@@ -841,70 +961,75 @@
 /*  RAID Volume Config Pages                                                  */
 /****************************************************************************/
 
-typedef struct _RAIDVOL2_EM_PHYS_ID
+typedef struct _RAIDVOL2_IM_PHYS_ID
 {
-    U8                      TargetID;
-    U8                      Bus;
-    U8                      IocNumber;
-    U8                      PhysDiskNumber;
-    U8                      Reserved[8];
-    U8                      PhysicalDiskIdentifier[16];
-    U8                      ProductId[16];
-    U8                      InfoOffset0;
-    U8                      InfoSize0;
-    U8                      InfoOffset1;
-    U8                      InfoSize1;
-    U8                      Info[32];
-} RAIDVOL2_EM_PHYS_ID, MPI_POINTER PTR_RAIDVOL2_EM_PHYS_ID,
-  RaidVol2EmPhysicalID_t, MPI_POINTER pRaidVol2EmPhysicalID_t;
-
-typedef struct _RAIDVOL2_EM_DISK_INFO
-{
-    U32                     DiskStatus;
-    U32                     DeviceSettings;
-    U16                     ErrorCount;
-    U16                     Reserved;
-    U8                      ErrorCdbByte;
-    U8                      ErrorSenseKey;
-    U8                      ErrorASC;
-    U8                      ErrorASCQ;
-    U16                     SmartCount;
-    U8                      SmartASC;
-    U8                      SmartASCQ;
-} RAIDVOL2_EM_DISK_INFO, MPI_POINTER PTR_RAIDVOL2_EM_DISK_INFO,
-  RaidVol2EmDiskInfo_t, MPI_POINTER pRaidVol2EmDiskInfo_t;
-
-/* RAID Volume 2 EM Physical Disk DiskStatus flags */
-
-#define MPI_RAIDVOLPAGE2_PHYS_DISK_PRIMARY              (0x00000001)
-#define MPI_RAIDVOLPAGE2_PHYS_DISK_SECONDARY            (0x00000002)
-#define MPI_RAIDVOLPAGE2_PHYS_DISK_HOT_SPARE            (0x00000004)
-#define MPI_RAIDVOLPAGE2_PHYS_DISK_OUT_OF_SYNC          (0x00000008)
-#define MPI_RAIDVOLPAGE2_PHYS_DISK_OFFLINE              (0x00000010)
-#define MPI_RAIDVOLPAGE2_PHYS_DISK_NOT_RESPONDING       (0x00000020)
-
-typedef struct _RAIDVOL2_EM_PHYSICAL_DISK
-{
-    RAIDVOL2_EM_PHYS_ID     Id;
-    RAIDVOL2_EM_DISK_INFO   Info;
-} RAIDVOL2_EM_PHYSICAL_DISK, MPI_POINTER PTR_RAIDVOL2_EM_PHYSICAL_DISK,
-  RaidVol2EmPhysicalDisk_t, MPI_POINTER pRaidVol2EmPhysicalDisk_t;
+    U8                      TargetID;                   /* 00h */
+    U8                      Bus;                        /* 01h */
+    U8                      IocNumber;                  /* 02h */
+    U8                      PhysDiskNumber;             /* 03h */
+    U8                      Reserved[8];                /* 04h */
+    U8                      PhysicalDiskIdentifier[16]; /* 0Ch */
+    U8                      VendorId[8];                /* 1Ch */
+    U8                      ProductId[16];              /* 24h */
+    U8                      ProductRevLevel[4];         /* 34h */
+    U32                     Reserved1;                  /* 38h */
+    U8                      Info[32];                   /* 3Ch */
+} RAIDVOL2_IM_PHYS_ID, MPI_POINTER PTR_RAIDVOL2_IM_PHYS_ID,
+  RaidVol2ImPhysicalID_t, MPI_POINTER pRaidVol2ImPhysicalID_t;
+
+typedef struct _RAIDVOL2_IM_DISK_INFO
+{
+    U32                     DiskStatus;                 /* 00h */
+    U32                     DeviceSettings;             /* 04h */
+    U16                     ErrorCount;                 /* 08h */
+    U16                     Reserved;                   /* 0Ah */
+    U8                      ErrorCdbByte;               /* 0Ch */
+    U8                      ErrorSenseKey;              /* 0Dh */
+    U8                      ErrorASC;                   /* 0Eh */
+    U8                      ErrorASCQ;                  /* 0Fh */
+    U16                     SmartCount;                 /* 10h */
+    U8                      SmartASC;                   /* 12h */
+    U8                      SmartASCQ;                  /* 13h */
+} RAIDVOL2_IM_DISK_INFO, MPI_POINTER PTR_RAIDVOL2_IM_DISK_INFO,
+  RaidVol2ImDiskInfo_t, MPI_POINTER pRaidVol2ImDiskInfo_t;
+
+/* RAID Volume 2 IM Physical Disk DiskStatus flags */
+
+#define MPI_RVP2_PHYS_DISK_PRIMARY                      (0x00000001)
+#define MPI_RVP2_PHYS_DISK_SECONDARY                    (0x00000002)
+#define MPI_RVP2_PHYS_DISK_HOT_SPARE                    (0x00000004)
+#define MPI_RVP2_PHYS_DISK_OUT_OF_SYNC                  (0x00000008)
+#define MPI_RVP2_PHYS_DISK_STATUS_MASK                  (0x00000F00)
+#define MPI_RVP2_PHYS_DISK_STATUS_ONLINE                (0x00000000)
+#define MPI_RVP2_PHYS_DISK_STATUS_MISSING               (0x00000100)
+#define MPI_RVP2_PHYS_DISK_STATUS_NOT_COMPATIBLE        (0x00000200)
+#define MPI_RVP2_PHYS_DISK_STATUS_FAILED                (0x00000300)
+#define MPI_RVP2_PHYS_DISK_STATUS_INITIALIZING          (0x00000400)
+#define MPI_RVP2_PHYS_DISK_STATUS_OFFLINE_REQUESTED     (0x00000500)
+#define MPI_RVP2_PHYS_DISK_STATUS_OTHER_OFFLINE         (0x00000F00)
+
+
+typedef struct _RAIDVOL2_IM_PHYSICAL_DISK
+{
+    RAIDVOL2_IM_PHYS_ID     Id;                         /* 00h */
+    RAIDVOL2_IM_DISK_INFO   Info;                       /* 5Ch */
+} RAIDVOL2_IM_PHYSICAL_DISK, MPI_POINTER PTR_RAIDVOL2_IM_PHYSICAL_DISK,
+  RaidVol2ImPhysicalDisk_t, MPI_POINTER pRaidVol2ImPhysicalDisk_t;
 
 #define MPI_RAIDVOLPAGE2_MAX_DISKS                      (3)
 
 typedef struct _CONFIG_PAGE_RAID_VOL_2
 {
-   fCONFIG_PAGE_HEADER          Header;
-    U32                         VolumeStatus;
-    U32                         VolumeSettings;
-    U32                         Reserved;
-    U64                         MaxLba;
-    U32                         BlockSize;
-    U8                          InquirySize;
-    U8                          NumPhysicalDisks;
-    U16                         Reserved1;
-    U8                          InquiryData[56];
-    RAIDVOL2_EM_PHYSICAL_DISK   EMPhysicalDisk[MPI_RAIDVOLPAGE2_MAX_DISKS];
+   fCONFIG_PAGE_HEADER          Header;                 /* 00h */
+    U32                         VolumeStatus;           /* 04h */
+    U32                         VolumeSettings;         /* 08h */
+    U32                         Reserved;               /* 0Ch */
+    U64                         MaxLba;                 /* 10h */
+    U32                         BlockSize;              /* 18h */
+    U8                          Reserved1;              /* 1Ch */
+    U8                          NumPhysicalDisks;       /* 1Dh */
+    U16                         Reserved2;              /* 1Eh */
+    RAIDVOL2_IM_PHYSICAL_DISK   IMPhysicalDisk[MPI_RAIDVOLPAGE2_MAX_DISKS];
 } fCONFIG_PAGE_RAID_VOL_2, MPI_POINTER PTR_CONFIG_PAGE_RAID_VOL_2,
   RaidVolumePage2_t, MPI_POINTER pRaidVolumePage2_t;
 
@@ -922,6 +1047,7 @@
 #define MPI_RAIDVOLPAGE2_SETTING_WRITE_CACHING_ENABLE   (0x00000001)
 #define MPI_RAIDVOLPAGE2_SETTING_OFFLINE_ON_SMART       (0x00000002)
 #define MPI_RAIDVOLPAGE2_SETTING_AUTO_CONFIGURE         (0x00000004)
+#define MPI_RAIDVOLPAGE2_SETTING_USE_DEFAULTS           (0x80000000)
 
 
 /****************************************************************************/
@@ -930,10 +1056,10 @@
 
 typedef struct _CONFIG_PAGE_LAN_0
 {
-    ConfigPageHeader_t      Header;
-    U16                     TxRxModes;
-    U16                     Reserved;
-    U32                     PacketPrePad;
+    ConfigPageHeader_t      Header;                     /* 00h */
+    U16                     TxRxModes;                  /* 04h */
+    U16                     Reserved;                   /* 06h */
+    U32                     PacketPrePad;               /* 08h */
 } fCONFIG_PAGE_LAN_0, MPI_POINTER PTR_CONFIG_PAGE_LAN_0,
   LANPage0_t, MPI_POINTER pLANPage0_t;
 
@@ -945,20 +1071,20 @@
 
 typedef struct _CONFIG_PAGE_LAN_1
 {
-    ConfigPageHeader_t      Header;
-    U16                     Reserved;
-    U8                      CurrentDeviceState;
-    U8                      Reserved1;
-    U32                     MinPacketSize;
-    U32                     MaxPacketSize;
-    U32                     HardwareAddressLow;
-    U32                     HardwareAddressHigh;
-    U32                     MaxWireSpeedLow;
-    U32                     MaxWireSpeedHigh;
-    U32                     BucketsRemaining;
-    U32                     MaxReplySize;
-    U32                     NegWireSpeedHigh;
-    U32                     NegWireSpeedLow;
+    ConfigPageHeader_t      Header;                     /* 00h */
+    U16                     Reserved;                   /* 04h */
+    U8                      CurrentDeviceState;         /* 06h */
+    U8                      Reserved1;                  /* 07h */
+    U32                     MinPacketSize;              /* 08h */
+    U32                     MaxPacketSize;              /* 0Ch */
+    U32                     HardwareAddressLow;         /* 10h */
+    U32                     HardwareAddressHigh;        /* 14h */
+    U32                     MaxWireSpeedLow;            /* 18h */
+    U32                     MaxWireSpeedHigh;           /* 1Ch */
+    U32                     BucketsRemaining;           /* 20h */
+    U32                     MaxReplySize;               /* 24h */
+    U32                     NegWireSpeedHigh;           /* 28h */
+    U32                     NegWireSpeedLow;            /* 2Ch */
 } fCONFIG_PAGE_LAN_1, MPI_POINTER PTR_CONFIG_PAGE_LAN_1,
   LANPage1_t, MPI_POINTER pLANPage1_t;
 
diff -u --recursive --new-file v2.4.9/linux/drivers/message/fusion/lsi/mpi_fc.h linux/drivers/message/fusion/lsi/mpi_fc.h
--- v2.4.9/linux/drivers/message/fusion/lsi/mpi_fc.h	Wed Jul 25 17:10:20 2001
+++ linux/drivers/message/fusion/lsi/mpi_fc.h	Fri Sep  7 09:28:38 2001
@@ -6,7 +6,7 @@
  *          Title:  MPI Fibre Channel messages and structures
  *  Creation Date:  June 12, 2000
  *
- *    MPI Version:  01.01.05
+ *    MPI Version:  01.01.07
  *
  *  Version History
  *  ---------------
@@ -27,6 +27,11 @@
  *                      FC_ABORT_TYPE_EXLINKSEND_REQUEST for FcAbort request.
  *                      Added MPI_FC_PRIM_SEND_FLAGS_STOP_SEND.
  *  02-20-01  01.01.05  Started using MPI_POINTER.
+ *  03-27-01  01.01.06  Added Flags field to MSG_LINK_SERVICE_BUFFER_POST_REPLY
+ *                      and defined MPI_LS_BUF_POST_REPLY_FLAG_NO_RSP_NEEDED.
+ *                      Added MPI_FC_PRIM_SEND_FLAGS_RESET_LINK define.
+ *                      Added structure offset comments.
+ *  04-09-01  01.01.07  Added RspLength field to MSG_LINK_SERVICE_RSP_REQUEST.
  *  --------------------------------------------------------------------------
  */
 
@@ -136,7 +141,7 @@
 typedef struct _MSG_LINK_SERVICE_RSP_REQUEST
 {
     U8                      RspFlags;           /* 00h */
-    U8                      Reserved;           /* 01h */
+    U8                      RspLength;          /* 01h */
     U8                      ChainOffset;        /* 02h */
     U8                      Function;           /* 03h */
     U16                     Reserved1;          /* 04h */
@@ -224,14 +229,14 @@
 
 typedef struct _MSG_FC_ABORT_REQUEST
 {
-    U8                      AbortFlags;         /* 00h */
-    U8                      AbortType;          /* 01h */
-    U8                      ChainOffset;        /* 02h */
-    U8                      Function;           /* 03h */
-    U16                     Reserved1;          /* 04h */
-    U8                      Reserved2;          /* 06h */
-    U8                      MsgFlags;           /* 07h */
-    U32                     MsgContext;         /* 08h */
+    U8                      AbortFlags;                 /* 00h */
+    U8                      AbortType;                  /* 01h */
+    U8                      ChainOffset;                /* 02h */
+    U8                      Function;                   /* 03h */
+    U16                     Reserved1;                  /* 04h */
+    U8                      Reserved2;                  /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
     U32                     TransactionContextToAbort;  /* 0Ch */
 } MSG_FC_ABORT_REQUEST, MPI_POINTER PTR_MSG_FC_ABORT_REQUEST,
   FcAbortRequest_t, MPI_POINTER pFcAbortRequest_t;
@@ -323,6 +328,7 @@
   FcPrimitiveSendRequest_t, MPI_POINTER pFcPrimitiveSendRequest_t;
 
 #define MPI_FC_PRIM_SEND_FLAGS_PORT_MASK       (0x01)
+#define MPI_FC_PRIM_SEND_FLAGS_RESET_LINK      (0x04)
 #define MPI_FC_PRIM_SEND_FLAGS_STOP_SEND       (0x08)
 #define MPI_FC_PRIM_SEND_FLAGS_SEND_ONCE       (0x10)
 #define MPI_FC_PRIM_SEND_FLAGS_SEND_AROUND     (0x20)
diff -u --recursive --new-file v2.4.9/linux/drivers/message/fusion/lsi/mpi_history.txt linux/drivers/message/fusion/lsi/mpi_history.txt
--- v2.4.9/linux/drivers/message/fusion/lsi/mpi_history.txt	Wed Jul 25 17:10:20 2001
+++ linux/drivers/message/fusion/lsi/mpi_history.txt	Fri Sep  7 09:28:38 2001
@@ -6,22 +6,22 @@
  Copyright (c) 2000-2001 LSI Logic Corporation.
 
  ---------------------------------------
- Header Set Release Version:    01.01.08
- Header Set Release Date:       02-27-01
+ Header Set Release Version:    01.01.10
+ Header Set Release Date:       04-09-01
  ---------------------------------------
 
  Filename               Current version     Prior version
  ----------             ---------------     -------------
- mpi.h                  01.01.06            01.01.05
- mpi_ioc.h              01.01.05            01.01.04
- mpi_cnfg.h             01.01.09            01.01.08
- mpi_init.h             01.01.03            01.01.03
- mpi_targ.h             01.01.03            01.01.03
- mpi_fc.h               01.01.05            01.01.05
- mpi_lan.h              01.01.02            01.01.02
- mpi_raid.h             01.01.01            none
+ mpi.h                  01.01.07            01.01.06
+ mpi_ioc.h              01.01.07            01.01.06
+ mpi_cnfg.h             01.01.11            01.01.10
+ mpi_init.h             01.01.05            01.01.04
+ mpi_targ.h             01.01.04            01.01.04
+ mpi_fc.h               01.01.07            01.01.06
+ mpi_lan.h              01.01.03            01.01.03
+ mpi_raid.h             01.01.02            01.01.02
  mpi_type.h             01.01.02            01.01.02
- mpi_history.txt        01.01.08            01.01.07
+ mpi_history.txt        01.01.09            01.01.09
 
 
  *  Date      Version   Description
@@ -51,6 +51,8 @@
  *                      Obsoleted MPI_IOCSTATUS_TARGET_FC_ defines.
  *  02-27-01  01.01.06  Removed MPI_HOST_INDEX_REGISTER define.
  *                      Added function codes for RAID.
+ *  04-09-01  01.01.07  Added alternate define for MPI_DOORBELL_ACTIVE,
+ *                      MPI_DOORBELL_USED, to better match the spec.
  *  --------------------------------------------------------------------------
 
 mpi_ioc.h
@@ -76,6 +78,9 @@
  *  02-20-01  01.01.04  Started using MPI_POINTER.
  *  02-27-01  01.01.05  Added event for RAID status change and its event data.
  *                      Added IocNumber field to MSG_IOC_FACTS_REPLY.
+ *  03-27-01  01.01.06  Added defines for ProductId field of MPI_FW_HEADER.
+ *                      Added structure offset comments.
+ *  04-09-01  01.01.07  Added structure EVENT_DATA_EVENT_CHANGE.
  *  --------------------------------------------------------------------------
 
 mpi_cnfg.h
@@ -125,6 +130,18 @@
  *                      MPI_CONFIG_PAGETYPE_RAID_VOLUME.
  *                      Added definitions and structures for IOC Page 2 and
  *                      RAID Volume Page 2.
+ *  03-27-01  01.01.10  Added CONFIG_PAGE_FC_PORT_8 and CONFIG_PAGE_FC_PORT_9.
+ *                      CONFIG_PAGE_FC_PORT_3 now supports persistent by DID.
+ *                      Added VendorId and ProductRevLevel fields to
+ *                      RAIDVOL2_IM_PHYS_ID struct.
+ *                      Modified values for MPI_FCPORTPAGE0_FLAGS_ATTACH_
+ *                      defines to make them compatible to MPI version 1.0.
+ *                      Added structure offset comments.
+ *  04-09-01  01.01.11  Added some new defines for the PageAddress field and
+ *                      removed some obsolete ones.
+ *                      Added IO Unit Page 3.
+ *                      Modified defines for Scsi Port Page 2.
+ *                      Modified RAID Volume Pages.
  *  --------------------------------------------------------------------------
 
 mpi_init.h
@@ -135,6 +152,8 @@
  *  11-02-00  01.01.01  Original release for post 1.0 work
  *  12-04-00  01.01.02  Added MPI_SCSIIO_CONTROL_NO_DISCONNECT.
  *  02-20-01  01.01.03  Started using MPI_POINTER.
+ *  03-27-01  01.01.04  Added structure offset comments.
+ *  04-10-01  01.01.05  Added new MsgFlag for MSG_SCSI_TASK_MGMT.
  *  --------------------------------------------------------------------------
 
 mpi_targ.h
@@ -150,6 +169,7 @@
  *  02-20-01  01.01.03  Started using MPI_POINTER.
  *                      Added structures for MPI_TARGET_SCSI_SPI_CMD_BUFFER and
  *                      MPI_TARGET_FCP_CMD_BUFFER.
+ *  03-27-01  01.01.04  Added structure offset comments.
  *  --------------------------------------------------------------------------
 
 mpi_fc.h
@@ -167,6 +187,11 @@
  *                      FC_ABORT_TYPE_EXLINKSEND_REQUEST for FcAbort request.
  *                      Added MPI_FC_PRIM_SEND_FLAGS_STOP_SEND.
  *  02-20-01  01.01.05  Started using MPI_POINTER.
+ *  03-27-01  01.01.06  Added Flags field to MSG_LINK_SERVICE_BUFFER_POST_REPLY
+ *                      and defined MPI_LS_BUF_POST_REPLY_FLAG_NO_RSP_NEEDED.
+ *                      Added MPI_FC_PRIM_SEND_FLAGS_RESET_LINK define.
+ *                      Added structure offset comments.
+ *  04-09-01  01.01.07  Added RspLength field to MSG_LINK_SERVICE_RSP_REQUEST.
  *  --------------------------------------------------------------------------
 
 mpi_lan.h
@@ -183,10 +208,12 @@
  *                      to lan private header file
  *  11-02-00  01.01.01  Original release for post 1.0 work
  *  02-20-01  01.01.02  Started using MPI_POINTER.
+ *  03-27-01  01.01.03  Added structure offset comments.
  *  --------------------------------------------------------------------------
 
 mpi_raid.h
  *  02-27-01  01.01.01  Original release for this file.
+ *  03-27-01  01.01.02  Added structure offset comments.
  *  --------------------------------------------------------------------------
 
 mpi_type.h
@@ -198,17 +225,29 @@
 
 mpi_history.txt         Parts list history
 
-Filename    01.01.08   01.01.07   01.01.06   01.01.05   01.01.04
-----------  --------   --------   --------   --------   --------
-mpi.h       01.01.06   01.01.05   01.01.04   01.01.04   01.01.03
-mpi_ioc.h   01.01.05   01.01.04   01.01.03   01.01.03   01.01.03
-mpi_cnfg.h  01.01.09   01.01.08   01.01.07   01.01.06   01.01.05
-mpi_init.h  01.01.03   01.01.03   01.01.02   01.01.02   01.01.02
-mpi_targ.h  01.01.03   01.01.03   01.01.02   01.01.02   01.01.02
-mpi_fc.h    01.01.05   01.01.05   01.01.04   01.01.04   01.01.03
-mpi_lan.h   01.01.02   01.01.02   01.01.01   01.01.01   01.01.01
-mpi_raid.h  01.01.01
-mpi_type.h  01.01.02   01.01.02   01.01.01   01.01.01   01.01.01
+Filename    01.01.10
+----------  --------
+mpi.h       01.01.07
+mpi_ioc.h   01.01.07
+mpi_cnfg.h  01.01.11
+mpi_init.h  01.01.05
+mpi_targ.h  01.01.04
+mpi_fc.h    01.01.07
+mpi_lan.h   01.01.03
+mpi_raid.h  01.01.02
+mpi_type.h  01.01.02
+
+Filename    01.01.09   01.01.08   01.01.07   01.01.06   01.01.05   01.01.04
+----------  --------   --------   --------   --------   --------   --------
+mpi.h       01.01.06   01.01.06   01.01.05   01.01.04   01.01.04   01.01.03
+mpi_ioc.h   01.01.06   01.01.05   01.01.04   01.01.03   01.01.03   01.01.03
+mpi_cnfg.h  01.01.10   01.01.09   01.01.08   01.01.07   01.01.06   01.01.05
+mpi_init.h  01.01.04   01.01.03   01.01.03   01.01.02   01.01.02   01.01.02
+mpi_targ.h  01.01.04   01.01.03   01.01.03   01.01.02   01.01.02   01.01.02
+mpi_fc.h    01.01.06   01.01.05   01.01.05   01.01.04   01.01.04   01.01.03
+mpi_lan.h   01.01.03   01.01.02   01.01.02   01.01.01   01.01.01   01.01.01
+mpi_raid.h  01.01.02   01.01.01
+mpi_type.h  01.01.02   01.01.02   01.01.02   01.01.01   01.01.01   01.01.01
 
 Filename    01.01.03   01.01.02   01.01.01   01.00.07   01.00.06   01.00.05
 ----------  --------   --------   --------   --------   --------   --------
diff -u --recursive --new-file v2.4.9/linux/drivers/message/fusion/lsi/mpi_init.h linux/drivers/message/fusion/lsi/mpi_init.h
--- v2.4.9/linux/drivers/message/fusion/lsi/mpi_init.h	Wed Jul 25 17:10:20 2001
+++ linux/drivers/message/fusion/lsi/mpi_init.h	Fri Sep  7 09:28:38 2001
@@ -6,7 +6,7 @@
  *          Title:  MPI initiator mode messages and structures
  *  Creation Date:  June 8, 2000
  *
- *    MPI Version:  01.01.03
+ *    MPI Version:  01.01.05
  *
  *  Version History
  *  ---------------
@@ -20,6 +20,8 @@
  *  11-02-00  01.01.01  Original release for post 1.0 work.
  *  12-04-00  01.01.02  Added MPI_SCSIIO_CONTROL_NO_DISCONNECT.
  *  02-20-01  01.01.03  Started using MPI_POINTER.
+ *  03-27-01  01.01.04  Added structure offset comments.
+ *  04-10-01  01.01.05  Added new MsgFlag for MSG_SCSI_TASK_MGMT.
  *  --------------------------------------------------------------------------
  */
 
@@ -39,21 +41,21 @@
 
 typedef struct _MSG_SCSI_IO_REQUEST
 {
-    U8                      TargetID;
-    U8                      Bus;
-    U8                      ChainOffset;
-    U8                      Function;
-    U8                      CDBLength;
-    U8                      SenseBufferLength;
-    U8                      Reserved;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U8                      LUN[8];
-    U32                     Control;
-    U8                      CDB[16];
-    U32                     DataLength;
-    U32                     SenseBufferLowAddr;
-    SGE_IO_UNION            SGL;
+    U8                      TargetID;           /* 00h */
+    U8                      Bus;                /* 01h */
+    U8                      ChainOffset;        /* 02h */
+    U8                      Function;           /* 03h */
+    U8                      CDBLength;          /* 04h */
+    U8                      SenseBufferLength;  /* 05h */
+    U8                      Reserved;           /* 06h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
+    U8                      LUN[8];             /* 0Ch */
+    U32                     Control;            /* 14h */
+    U8                      CDB[16];            /* 18h */
+    U32                     DataLength;         /* 28h */
+    U32                     SenseBufferLowAddr; /* 2Ch */
+    SGE_IO_UNION            SGL;                /* 30h */
 } MSG_SCSI_IO_REQUEST, MPI_POINTER PTR_MSG_SCSI_IO_REQUEST,
   SCSIIORequest_t, MPI_POINTER pSCSIIORequest_t;
 
@@ -108,22 +110,22 @@
 /* SCSIIO reply structure */
 typedef struct _MSG_SCSI_IO_REPLY
 {
-    U8                      TargetID;
-    U8                      Bus;
-    U8                      MsgLength;
-    U8                      Function;
-    U8                      CDBLength;
-    U8                      SenseBufferLength;
-    U8                      Reserved;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U8                      SCSIStatus;
-    U8                      SCSIState;
-    U16                     IOCStatus;
-    U32                     IOCLogInfo;
-    U32                     TransferCount;
-    U32                     SenseCount;
-    U32                     ResponseInfo;
+    U8                      TargetID;           /* 00h */
+    U8                      Bus;                /* 01h */
+    U8                      MsgLength;          /* 02h */
+    U8                      Function;           /* 03h */
+    U8                      CDBLength;          /* 04h */
+    U8                      SenseBufferLength;  /* 05h */
+    U8                      Reserved;           /* 06h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
+    U8                      SCSIStatus;         /* 0Ch */
+    U8                      SCSIState;          /* 0Dh */
+    U16                     IOCStatus;          /* 0Eh */
+    U32                     IOCLogInfo;         /* 10h */
+    U32                     TransferCount;      /* 14h */
+    U32                     SenseCount;         /* 18h */
+    U32                     ResponseInfo;       /* 1Ch */
 } MSG_SCSI_IO_REPLY, MPI_POINTER PTR_MSG_SCSI_IO_REPLY,
   SCSIIOReply_t, MPI_POINTER pSCSIIOReply_t;
 
@@ -168,47 +170,49 @@
 
 typedef struct _MSG_SCSI_TASK_MGMT
 {
-    U8                      TargetID;
-    U8                      Bus;
-    U8                      ChainOffset;
-    U8                      Function;
-    U8                      Reserved;
-    U8                      TaskType;
-    U8                      Reserved1;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U8                      LUN[8];
-    U32                     Reserved2[7];
-    U32                     TaskMsgContext;
+    U8                      TargetID;           /* 00h */
+    U8                      Bus;                /* 01h */
+    U8                      ChainOffset;        /* 02h */
+    U8                      Function;           /* 03h */
+    U8                      Reserved;           /* 04h */
+    U8                      TaskType;           /* 05h */
+    U8                      Reserved1;          /* 06h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
+    U8                      LUN[8];             /* 0Ch */
+    U32                     Reserved2[7];       /* 14h */
+    U32                     TaskMsgContext;     /* 30h */
 } MSG_SCSI_TASK_MGMT, MPI_POINTER PTR_SCSI_TASK_MGMT,
   SCSITaskMgmt_t, MPI_POINTER pSCSITaskMgmt_t;
 
 /* TaskType values */
 
-#define MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK        (0x00000001)
-#define MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET     (0x00000002)
-#define MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET      (0x00000003)
-#define MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS         (0x00000004)
+#define MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK            (0x01)
+#define MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET         (0x02)
+#define MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET          (0x03)
+#define MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS             (0x04)
 
 /* MsgFlags bits */
-#define MPI_SCSITASKMGMT_MSGFLAGS_LIP_RESET_OPTION  (0x00000002)
+#define MPI_SCSITASKMGMT_MSGFLAGS_TARGET_RESET_OPTION   (0x00)
+#define MPI_SCSITASKMGMT_MSGFLAGS_LIP_RESET_OPTION      (0x02)
+#define MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION (0x04)
 
 /* SCSI Task Management Reply */
 typedef struct _MSG_SCSI_TASK_MGMT_REPLY
 {
-    U8                      TargetID;
-    U8                      Bus;
-    U8                      MsgLength;
-    U8                      Function;
-    U8                      Reserved;
-    U8                      TaskType;
-    U8                      Reserved1;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U8                      Reserved2[2];
-    U16                     IOCStatus;
-    U32                     IOCLogInfo;
-    U32                     TerminationCount;
+    U8                      TargetID;           /* 00h */
+    U8                      Bus;                /* 01h */
+    U8                      MsgLength;          /* 02h */
+    U8                      Function;           /* 03h */
+    U8                      Reserved;           /* 04h */
+    U8                      TaskType;           /* 05h */
+    U8                      Reserved1;          /* 06h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
+    U8                      Reserved2[2];       /* 0Ch */
+    U16                     IOCStatus;          /* 0Eh */
+    U32                     IOCLogInfo;         /* 10h */
+    U32                     TerminationCount;   /* 14h */
 } MSG_SCSI_TASK_MGMT_REPLY, MPI_POINTER PTR_MSG_SCSI_TASK_MGMT_REPLY,
   SCSITaskMgmtReply_t, MPI_POINTER pSCSITaskMgmtReply_t;
 
diff -u --recursive --new-file v2.4.9/linux/drivers/message/fusion/lsi/mpi_ioc.h linux/drivers/message/fusion/lsi/mpi_ioc.h
--- v2.4.9/linux/drivers/message/fusion/lsi/mpi_ioc.h	Wed Jul 25 17:10:20 2001
+++ linux/drivers/message/fusion/lsi/mpi_ioc.h	Fri Sep  7 09:28:38 2001
@@ -3,10 +3,10 @@
  *
  *
  *           Name:  MPI_IOC.H
- *          Title:  MPI IOC, Port, Event, FW Load, and ToolBox messages
+ *          Title:  MPI IOC, Port, Event, FW Download, and FW Upload messages
  *  Creation Date:  August 11, 2000
  *
- *    MPI Version:  01.01.05
+ *    MPI Version:  01.01.07
  *
  *  Version History
  *  ---------------
@@ -35,6 +35,9 @@
  *  02-20-01  01.01.04  Started using MPI_POINTER.
  *  02-27-01  01.01.05  Added event for RAID status change and its event data.
  *                      Added IocNumber field to MSG_IOC_FACTS_REPLY.
+ *  03-27-01  01.01.06  Added defines for ProductId field of MPI_FW_HEADER.
+ *                      Added structure offset comments.
+ *  04-09-01  01.01.07  Added structure EVENT_DATA_EVENT_CHANGE.
  *  --------------------------------------------------------------------------
  */
 
@@ -54,36 +57,36 @@
 
 typedef struct _MSG_IOC_INIT
 {
-    U8                      WhoInit;
-    U8                      Reserved;
-    U8                      ChainOffset;
-    U8                      Function;
-    U8                      Flags;
-    U8                      MaxDevices;
-    U8                      MaxBuses;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U16                     ReplyFrameSize;
-    U8                      Reserved1[2];
-    U32                     HostMfaHighAddr;
-    U32                     SenseBufferHighAddr;
+    U8                      WhoInit;                    /* 00h */
+    U8                      Reserved;                   /* 01h */
+    U8                      ChainOffset;                /* 02h */
+    U8                      Function;                   /* 03h */
+    U8                      Flags;                      /* 04h */
+    U8                      MaxDevices;                 /* 05h */
+    U8                      MaxBuses;                   /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U16                     ReplyFrameSize;             /* 0Ch */
+    U8                      Reserved1[2];               /* 0Eh */
+    U32                     HostMfaHighAddr;            /* 10h */
+    U32                     SenseBufferHighAddr;        /* 14h */
 } MSG_IOC_INIT, MPI_POINTER PTR_MSG_IOC_INIT,
   IOCInit_t, MPI_POINTER pIOCInit_t;
 
 typedef struct _MSG_IOC_INIT_REPLY
 {
-    U8                      WhoInit;
-    U8                      Reserved;
-    U8                      MsgLength;
-    U8                      Function;
-    U8                      Flags;
-    U8                      MaxDevices;
-    U8                      MaxBuses;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U16                     Reserved2;
-    U16                     IOCStatus;
-    U32                     IOCLogInfo;
+    U8                      WhoInit;                    /* 00h */
+    U8                      Reserved;                   /* 01h */
+    U8                      MsgLength;                  /* 02h */
+    U8                      Function;                   /* 03h */
+    U8                      Flags;                      /* 04h */
+    U8                      MaxDevices;                 /* 05h */
+    U8                      MaxBuses;                   /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U16                     Reserved2;                  /* 0Ch */
+    U16                     IOCStatus;                  /* 0Eh */
+    U32                     IOCLogInfo;                 /* 10h */
 } MSG_IOC_INIT_REPLY, MPI_POINTER PTR_MSG_IOC_INIT_REPLY,
   IOCInitReply_t, MPI_POINTER pIOCInitReply_t;
 
@@ -103,12 +106,12 @@
 
 typedef struct _MSG_IOC_FACTS
 {
-    U8                      Reserved[2];
-    U8                      ChainOffset;
-    U8                      Function;
-    U8                      Reserved1[3];
-    U8                      MsgFlags;
-    U32                     MsgContext;
+    U8                      Reserved[2];                /* 00h */
+    U8                      ChainOffset;                /* 01h */
+    U8                      Function;                   /* 02h */
+    U8                      Reserved1[3];               /* 03h */
+    U8                      MsgFlags;                   /* 04h */
+    U32                     MsgContext;                 /* 08h */
 } MSG_IOC_FACTS, MPI_POINTER PTR_IOC_FACTS,
   IOCFacts_t, MPI_POINTER pIOCFacts_t;
 
@@ -116,34 +119,34 @@
 
 typedef struct _MSG_IOC_FACTS_REPLY
 {
-    U16                     MsgVersion;
-    U8                      MsgLength;
-    U8                      Function;
-    U16                     Reserved;
-    U8                      IOCNumber;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U16                     Reserved2;
-    U16                     IOCStatus;
-    U32                     IOCLogInfo;
-    U8                      MaxChainDepth;
-    U8                      WhoInit;
-    U8                      BlockSize;
-    U8                      Flags;
-    U16                     ReplyQueueDepth;
-    U16                     RequestFrameSize;
-    U16                     FWVersion;
-    U16                     ProductID;
-    U32                     CurrentHostMfaHighAddr;
-    U16                     GlobalCredits;
-    U8                      NumberOfPorts;
-    U8                      EventState;
-    U32                     CurrentSenseBufferHighAddr;
-    U16                     CurReplyFrameSize;
-    U8                      MaxDevices;
-    U8                      MaxBuses;
-    U32                     FWImageSize;
-    U32                     DataImageSize;
+    U16                     MsgVersion;                 /* 00h */
+    U8                      MsgLength;                  /* 02h */
+    U8                      Function;                   /* 03h */
+    U16                     Reserved;                   /* 04h */
+    U8                      IOCNumber;                  /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U16                     Reserved2;                  /* 0Ch */
+    U16                     IOCStatus;                  /* 0Eh */
+    U32                     IOCLogInfo;                 /* 10h */
+    U8                      MaxChainDepth;              /* 14h */
+    U8                      WhoInit;                    /* 15h */
+    U8                      BlockSize;                  /* 16h */
+    U8                      Flags;                      /* 17h */
+    U16                     ReplyQueueDepth;            /* 18h */
+    U16                     RequestFrameSize;           /* 1Ah */
+    U16                     FWVersion;                  /* 1Ch */
+    U16                     ProductID;                  /* 1Eh */
+    U32                     CurrentHostMfaHighAddr;     /* 20h */
+    U16                     GlobalCredits;              /* 24h */
+    U8                      NumberOfPorts;              /* 26h */
+    U8                      EventState;                 /* 27h */
+    U32                     CurrentSenseBufferHighAddr; /* 28h */
+    U16                     CurReplyFrameSize;          /* 2Ch */
+    U8                      MaxDevices;                 /* 2Eh */
+    U8                      MaxBuses;                   /* 2Fh */
+    U32                     FWImageSize;                /* 30h */
+    U32                     DataImageSize;              /* 34h */
 } MSG_IOC_FACTS_REPLY, MPI_POINTER PTR_MSG_IOC_FACTS_REPLY,
   IOCFactsReply_t, MPI_POINTER pIOCFactsReply_t;
 
@@ -170,38 +173,38 @@
 
 typedef struct _MSG_PORT_FACTS
 {
-     U8                     Reserved[2];
-     U8                     ChainOffset;
-     U8                     Function;
-     U8                     Reserved1[2];
-     U8                     PortNumber;
-     U8                     MsgFlags;
-     U32                    MsgContext;
+     U8                     Reserved[2];                /* 00h */
+     U8                     ChainOffset;                /* 02h */
+     U8                     Function;                   /* 03h */
+     U8                     Reserved1[2];               /* 04h */
+     U8                     PortNumber;                 /* 06h */
+     U8                     MsgFlags;                   /* 07h */
+     U32                    MsgContext;                 /* 08h */
 } MSG_PORT_FACTS, MPI_POINTER PTR_MSG_PORT_FACTS,
   PortFacts_t, MPI_POINTER pPortFacts_t;
 
 typedef struct _MSG_PORT_FACTS_REPLY
 {
-     U16                    Reserved;
-     U8                     MsgLength;
-     U8                     Function;
-     U16                    Reserved1;
-     U8                     PortNumber;
-     U8                     MsgFlags;
-     U32                    MsgContext;
-     U16                    Reserved2;
-     U16                    IOCStatus;
-     U32                    IOCLogInfo;
-     U8                     Reserved3;
-     U8                     PortType;
-     U16                    MaxDevices;
-     U16                    PortSCSIID;
-     U16                    ProtocolFlags;
-     U16                    MaxPostedCmdBuffers;
-     U16                    MaxPersistentIDs;
-     U16                    MaxLanBuckets;
-     U16                    Reserved4;
-     U32                    Reserved5;
+     U16                    Reserved;                   /* 00h */
+     U8                     MsgLength;                  /* 02h */
+     U8                     Function;                   /* 03h */
+     U16                    Reserved1;                  /* 04h */
+     U8                     PortNumber;                 /* 06h */
+     U8                     MsgFlags;                   /* 07h */
+     U32                    MsgContext;                 /* 08h */
+     U16                    Reserved2;                  /* 0Ch */
+     U16                    IOCStatus;                  /* 0Eh */
+     U32                    IOCLogInfo;                 /* 10h */
+     U8                     Reserved3;                  /* 14h */
+     U8                     PortType;                   /* 15h */
+     U16                    MaxDevices;                 /* 16h */
+     U16                    PortSCSIID;                 /* 18h */
+     U16                    ProtocolFlags;              /* 1Ah */
+     U16                    MaxPostedCmdBuffers;        /* 1Ch */
+     U16                    MaxPersistentIDs;           /* 1Eh */
+     U16                    MaxLanBuckets;              /* 20h */
+     U16                    Reserved4;                  /* 22h */
+     U32                    Reserved5;                  /* 24h */
 } MSG_PORT_FACTS_REPLY, MPI_POINTER PTR_MSG_PORT_FACTS_REPLY,
   PortFactsReply_t, MPI_POINTER pPortFactsReply_t;
 
@@ -226,28 +229,28 @@
 
 typedef struct _MSG_PORT_ENABLE
 {
-    U8                      Reserved[2];
-    U8                      ChainOffset;
-    U8                      Function;
-    U8                      Reserved1[2];
-    U8                      PortNumber;
-    U8                      MsgFlags;
-    U32                     MsgContext;
+    U8                      Reserved[2];                /* 00h */
+    U8                      ChainOffset;                /* 02h */
+    U8                      Function;                   /* 03h */
+    U8                      Reserved1[2];               /* 04h */
+    U8                      PortNumber;                 /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
 } MSG_PORT_ENABLE, MPI_POINTER PTR_MSG_PORT_ENABLE,
   PortEnable_t, MPI_POINTER pPortEnable_t;
 
 typedef struct _MSG_PORT_ENABLE_REPLY
 {
-    U8                      Reserved[2];
-    U8                      MsgLength;
-    U8                      Function;
-    U8                      Reserved1[2];
-    U8                      PortNumber;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U16                     Reserved2;
-    U16                     IOCStatus;
-    U32                     IOCLogInfo;
+    U8                      Reserved[2];                /* 00h */
+    U8                      MsgLength;                  /* 02h */
+    U8                      Function;                   /* 03h */
+    U8                      Reserved1[2];               /* 04h */
+    U8                      PortNumber;                 /* 05h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U16                     Reserved2;                  /* 0Ch */
+    U16                     IOCStatus;                  /* 0Eh */
+    U32                     IOCLogInfo;                 /* 10h */
 } MSG_PORT_ENABLE_REPLY, MPI_POINTER PTR_MSG_PORT_ENABLE_REPLY,
   PortEnableReply_t, MPI_POINTER pPortEnableReply_t;
 
@@ -264,13 +267,13 @@
 
 typedef struct _MSG_EVENT_NOTIFY
 {
-    U8                      Switch;
-    U8                      Reserved;
-    U8                      ChainOffset;
-    U8                      Function;
-    U8                      Reserved1[3];
-    U8                      MsgFlags;
-    U32                     MsgContext;
+    U8                      Switch;                     /* 00h */
+    U8                      Reserved;                   /* 01h */
+    U8                      ChainOffset;                /* 02h */
+    U8                      Function;                   /* 03h */
+    U8                      Reserved1[3];               /* 04h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
 } MSG_EVENT_NOTIFY, MPI_POINTER PTR_MSG_EVENT_NOTIFY,
   EventNotification_t, MPI_POINTER pEventNotification_t;
 
@@ -278,19 +281,19 @@
 
 typedef struct _MSG_EVENT_NOTIFY_REPLY
 {
-     U16                    EventDataLength;
-     U8                     MsgLength;
-     U8                     Function;
-     U8                     Reserved1[2];
-     U8                     AckRequired;
-     U8                     MsgFlags;
-     U32                    MsgContext;
-     U8                     Reserved2[2];
-     U16                    IOCStatus;
-     U32                    IOCLogInfo;
-     U32                    Event;
-     U32                    EventContext;
-     U32                    Data[1];
+     U16                    EventDataLength;            /* 00h */
+     U8                     MsgLength;                  /* 02h */
+     U8                     Function;                   /* 03h */
+     U8                     Reserved1[2];               /* 04h */
+     U8                     AckRequired;                /* 06h */
+     U8                     MsgFlags;                   /* 07h */
+     U32                    MsgContext;                 /* 08h */
+     U8                     Reserved2[2];               /* 0Ch */
+     U16                    IOCStatus;                  /* 0Eh */
+     U32                    IOCLogInfo;                 /* 10h */
+     U32                    Event;                      /* 14h */
+     U32                    EventContext;               /* 18h */
+     U32                    Data[1];                    /* 1Ch */
 } MSG_EVENT_NOTIFY_REPLY, MPI_POINTER PTR_MSG_EVENT_NOTIFY_REPLY,
   EventNotificationReply_t, MPI_POINTER pEventNotificationReply_t;
 
@@ -298,28 +301,28 @@
 
 typedef struct _MSG_EVENT_ACK
 {
-    U8                      Reserved[2];
-    U8                      ChainOffset;
-    U8                      Function;
-    U8                      Reserved1[3];
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U32                     Event;
-    U32                     EventContext;
+    U8                      Reserved[2];                /* 00h */
+    U8                      ChainOffset;                /* 02h */
+    U8                      Function;                   /* 03h */
+    U8                      Reserved1[3];               /* 04h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U32                     Event;                      /* 0Ch */
+    U32                     EventContext;               /* 10h */
 } MSG_EVENT_ACK, MPI_POINTER PTR_MSG_EVENT_ACK,
   EventAck_t, MPI_POINTER pEventAck_t;
 
 typedef struct _MSG_EVENT_ACK_REPLY
 {
-    U8                      Reserved[2];
-    U8                      MsgLength;
-    U8                      Function;
-    U8                      Reserved1[3];
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U16                     Reserved2;
-    U16                     IOCStatus;
-    U32                     IOCLogInfo;
+    U8                      Reserved[2];                /* 00h */
+    U8                      MsgLength;                  /* 02h */
+    U8                      Function;                   /* 03h */
+    U8                      Reserved1[3];               /* 04h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U16                     Reserved2;                  /* 0Ch */
+    U16                     IOCStatus;                  /* 0Eh */
+    U32                     IOCLogInfo;                 /* 10h */
 } MSG_EVENT_ACK_REPLY, MPI_POINTER PTR_MSG_EVENT_ACK_REPLY,
   EventAckReply_t, MPI_POINTER pEventAckReply_t;
 
@@ -349,13 +352,23 @@
 #define MPI_EVENT_NOTIFICATION_ACK_NOT_REQUIRED (0x00)
 #define MPI_EVENT_NOTIFICATION_ACK_REQUIRED     (0x01)
 
-/* SCSI Event data for Port, Bus and Device forms) */
+/* EventChange Event data */
+
+typedef struct _EVENT_DATA_EVENT_CHANGE
+{
+    U8                      EventState;                 /* 00h */
+    U8                      Reserved;                   /* 01h */
+    U16                     Reserved1;                  /* 02h */
+} EVENT_DATA_EVENT_CHANGE, MPI_POINTER PTR_EVENT_DATA_EVENT_CHANGE,
+  EventDataEventChange_t, MPI_POINTER pEventDataEventChange_t;
+
+/* SCSI Event data for Port, Bus and Device forms */
 
 typedef struct _EVENT_DATA_SCSI
 {
-    U8                      TargetID;
-    U8                      BusPort;
-    U16                     Reserved;
+    U8                      TargetID;                   /* 00h */
+    U8                      BusPort;                    /* 01h */
+    U16                     Reserved;                   /* 02h */
 } EVENT_DATA_SCSI, MPI_POINTER PTR_EVENT_DATA_SCSI,
   EventDataScsi_t, MPI_POINTER pEventDataScsi_t;
 
@@ -363,12 +376,12 @@
 
 typedef struct _EVENT_DATA_LINK_STATUS
 {
-    U8                      State;
-    U8                      Reserved;
-    U16                     Reserved1;
-    U8                      Reserved2;
-    U8                      Port;
-    U16                     Reserved3;
+    U8                      State;                      /* 00h */
+    U8                      Reserved;                   /* 01h */
+    U16                     Reserved1;                  /* 02h */
+    U8                      Reserved2;                  /* 04h */
+    U8                      Port;                       /* 05h */
+    U16                     Reserved3;                  /* 06h */
 } EVENT_DATA_LINK_STATUS, MPI_POINTER PTR_EVENT_DATA_LINK_STATUS,
   EventDataLinkStatus_t, MPI_POINTER pEventDataLinkStatus_t;
 
@@ -379,13 +392,13 @@
 
 typedef struct _EVENT_DATA_LOOP_STATE
 {
-    U8                      Character4;
-    U8                      Character3;
-    U8                      Type;
-    U8                      Reserved;
-    U8                      Reserved1;
-    U8                      Port;
-    U16                     Reserved2;
+    U8                      Character4;                 /* 00h */
+    U8                      Character3;                 /* 01h */
+    U8                      Type;                       /* 02h */
+    U8                      Reserved;                   /* 03h */
+    U8                      Reserved1;                  /* 04h */
+    U8                      Port;                       /* 05h */
+    U16                     Reserved2;                  /* 06h */
 } EVENT_DATA_LOOP_STATE, MPI_POINTER PTR_EVENT_DATA_LOOP_STATE,
   EventDataLoopState_t, MPI_POINTER pEventDataLoopState_t;
 
@@ -397,10 +410,10 @@
 
 typedef struct _EVENT_DATA_LOGOUT
 {
-    U32                     NPortID;
-    U8                      Reserved;
-    U8                      Port;
-    U16                     Reserved1;
+    U32                     NPortID;                    /* 00h */
+    U8                      Reserved;                   /* 04h */
+    U8                      Port;                       /* 05h */
+    U16                     Reserved1;                  /* 06h */
 } EVENT_DATA_LOGOUT, MPI_POINTER PTR_EVENT_DATA_LOGOUT,
   EventDataLogout_t, MPI_POINTER pEventDataLogout_t;
 
@@ -408,13 +421,13 @@
 
 typedef struct _EVENT_DATA_RAID_STATUS_CHANGE
 {
-    U8                      VolumeTargetID;
-    U8                      VolumeBus;
-    U8                      ReasonCode;
-    U8                      PhysDiskNum;
-    U8                      ASC;
-    U8                      ASCQ;
-    U16                     Reserved;
+    U8                      VolumeTargetID;             /* 00h */
+    U8                      VolumeBus;                  /* 01h */
+    U8                      ReasonCode;                 /* 02h */
+    U8                      PhysDiskNum;                /* 03h */
+    U8                      ASC;                        /* 04h */
+    U8                      ASCQ;                       /* 05h */
+    U16                     Reserved;                   /* 06h */
 } EVENT_DATA_RAID_STATUS_CHANGE, MPI_POINTER PTR_EVENT_DATA_RAID_STATUS_CHANGE,
   MpiEventDataRaidStatusChange_t, MPI_POINTER pMpiEventDataRaidStatusChange_t;
 
@@ -441,14 +454,14 @@
 
 typedef struct _MSG_FW_DOWNLOAD
 {
-    U8                      ImageType;
-    U8                      Reserved;
-    U8                      ChainOffset;
-    U8                      Function;
-    U8                      Reserved1[3];
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    SGE_MPI_UNION           SGL;
+    U8                      ImageType;                  /* 00h */
+    U8                      Reserved;                   /* 01h */
+    U8                      ChainOffset;                /* 02h */
+    U8                      Function;                   /* 03h */
+    U8                      Reserved1[3];               /* 04h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    SGE_MPI_UNION           SGL;                        /* 0Ch */
 } MSG_FW_DOWNLOAD, MPI_POINTER PTR_MSG_FW_DOWNLOAD,
   FWDownload_t, MPI_POINTER pFWDownload_t;
 
@@ -459,29 +472,29 @@
 
 typedef struct _FWDownloadTCSGE
 {
-    U8                      Reserved;
-    U8                      ContextSize;
-    U8                      DetailsLength;
-    U8                      Flags;
-    U32                     Reserved1;
-    U32                     ImageOffset;
-    U32                     ImageSize;
+    U8                      Reserved;                   /* 00h */
+    U8                      ContextSize;                /* 01h */
+    U8                      DetailsLength;              /* 02h */
+    U8                      Flags;                      /* 03h */
+    U32                     Reserved1;                  /* 04h */
+    U32                     ImageOffset;                /* 08h */
+    U32                     ImageSize;                  /* 0Ch */
 } FW_DOWNLOAD_TCSGE, MPI_POINTER PTR_FW_DOWNLOAD_TCSGE,
   FWDownloadTCSGE_t, MPI_POINTER pFWDownloadTCSGE_t;
 
 /* Firmware Download reply */
 typedef struct _MSG_FW_DOWNLOAD_REPLY
 {
-    U8                      ImageType;
-    U8                      Reserved;
-    U8                      MsgLength;
-    U8                      Function;
-    U8                      Reserved1[3];
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U16                     Reserved2;
-    U16                     IOCStatus;
-    U32                     IOCLogInfo;
+    U8                      ImageType;                  /* 00h */
+    U8                      Reserved;                   /* 01h */
+    U8                      MsgLength;                  /* 02h */
+    U8                      Function;                   /* 03h */
+    U8                      Reserved1[3];               /* 04h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U16                     Reserved2;                  /* 0Ch */
+    U16                     IOCStatus;                  /* 0Eh */
+    U32                     IOCLogInfo;                 /* 10h */
 } MSG_FW_DOWNLOAD_REPLY, MPI_POINTER PTR_MSG_FW_DOWNLOAD_REPLY,
   FWDownloadReply_t, MPI_POINTER pFWDownloadReply_t;
 
@@ -492,14 +505,14 @@
 
 typedef struct _MSG_FW_UPLOAD
 {
-    U8                      ImageType;
-    U8                      Reserved;
-    U8                      ChainOffset;
-    U8                      Function;
-    U8                      Reserved1[3];
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    SGE_MPI_UNION           SGL;
+    U8                      ImageType;                  /* 00h */
+    U8                      Reserved;                   /* 01h */
+    U8                      ChainOffset;                /* 02h */
+    U8                      Function;                   /* 03h */
+    U8                      Reserved1[3];               /* 04h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    SGE_MPI_UNION           SGL;                        /* 0Ch */
 } MSG_FW_UPLOAD, MPI_POINTER PTR_MSG_FW_UPLOAD,
   FWUpload_t, MPI_POINTER pFWUpload_t;
 
@@ -510,74 +523,88 @@
 
 typedef struct _FWUploadTCSGE
 {
-    U8                      Reserved;
-    U8                      ContextSize;
-    U8                      DetailsLength;
-    U8                      Flags;
-    U32                     Reserved1;
-    U32                     ImageOffset;
-    U32                     ImageSize;
+    U8                      Reserved;                   /* 00h */
+    U8                      ContextSize;                /* 01h */
+    U8                      DetailsLength;              /* 02h */
+    U8                      Flags;                      /* 03h */
+    U32                     Reserved1;                  /* 04h */
+    U32                     ImageOffset;                /* 08h */
+    U32                     ImageSize;                  /* 0Ch */
 } FW_UPLOAD_TCSGE, MPI_POINTER PTR_FW_UPLOAD_TCSGE,
   FWUploadTCSGE_t, MPI_POINTER pFWUploadTCSGE_t;
 
 /* Firmware Upload reply */
 typedef struct _MSG_FW_UPLOAD_REPLY
 {
-    U8                      ImageType;
-    U8                      Reserved;
-    U8                      MsgLength;
-    U8                      Function;
-    U8                      Reserved1[3];
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U16                     Reserved2;
-    U16                     IOCStatus;
-    U32                     IOCLogInfo;
-    U32                     ActualImageSize;
+    U8                      ImageType;                  /* 00h */
+    U8                      Reserved;                   /* 01h */
+    U8                      MsgLength;                  /* 02h */
+    U8                      Function;                   /* 03h */
+    U8                      Reserved1[3];               /* 04h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U16                     Reserved2;                  /* 0Ch */
+    U16                     IOCStatus;                  /* 0Eh */
+    U32                     IOCLogInfo;                 /* 10h */
+    U32                     ActualImageSize;            /* 14h */
 } MSG_FW_UPLOAD_REPLY, MPI_POINTER PTR_MSG_FW_UPLOAD_REPLY,
   FWUploadReply_t, MPI_POINTER pFWUploadReply_t;
 
 
 typedef struct _MPI_FW_HEADER
 {
-    U32                     ArmBranchInstruction0;
-    U32                     Signature0;
-    U32                     Signature1;
-    U32                     Signature2;
-    U32                     ArmBranchInstruction1;
-    U32                     ArmBranchInstruction2;
-    U32                     Reserved;
-    U32                     Checksum;
-    U16                     VendorId;
-    U16                     ProductId;
-    U16                     FwVersion;
-    U16                     Reserved1;
-    U32                     SeqCodeVersion;
-    U32                     ImageSize;
-    U32                     Reserved2;
-    U32                     LoadStartAddress;
-    U32                     IopResetVectorValue;
-    U32                     IopResetRegAddr;
-    U32                     VersionNameWhat;
-    U8                      VersionName[32];
-    U32                     VendorNameWhat;
-    U8                      VendorName[32];
+    U32                     ArmBranchInstruction0;      /* 00h */
+    U32                     Signature0;                 /* 04h */
+    U32                     Signature1;                 /* 08h */
+    U32                     Signature2;                 /* 0Ch */
+    U32                     ArmBranchInstruction1;      /* 10h */
+    U32                     ArmBranchInstruction2;      /* 14h */
+    U32                     Reserved;                   /* 18h */
+    U32                     Checksum;                   /* 1Ch */
+    U16                     VendorId;                   /* 20h */
+    U16                     ProductId;                  /* 22h */
+    U16                     FwVersion;                  /* 24h */
+    U16                     Reserved1;                  /* 26h */
+    U32                     SeqCodeVersion;             /* 28h */
+    U32                     ImageSize;                  /* 2Ch */
+    U32                     Reserved2;                  /* 30h */
+    U32                     LoadStartAddress;           /* 34h */
+    U32                     IopResetVectorValue;        /* 38h */
+    U32                     IopResetRegAddr;            /* 3Ch */
+    U32                     VersionNameWhat;            /* 40h */
+    U8                      VersionName[32];            /* 44h */
+    U32                     VendorNameWhat;             /* 64h */
+    U8                      VendorName[32];             /* 68h */
 } MPI_FW_HEADER, MPI_POINTER PTR_MPI_FW_HEADER,
   MpiFwHeader_t, MPI_POINTER pMpiFwHeader_t;
 
-#define MPI_FW_HEADER_WHAT_SIGNATURE    (0x29232840)
+#define MPI_FW_HEADER_WHAT_SIGNATURE        (0x29232840)
+
+/* defines for using the ProductId field */
+#define MPI_FW_HEADER_PID_TYPE_MASK         (0xF000)
+#define MPI_FW_HEADER_PID_TYPE_SCSI         (0x0000)
+#define MPI_FW_HEADER_PID_TYPE_FC           (0x1000)
+
+#define MPI_FW_HEADER_PID_FW_VENDOR_MASK    (0x0F00)
+#define MPI_FW_HEADER_PID_FW_VENDOR_LSI     (0x0000)
+
+#define MPI_FW_HEADER_PID_FAMILY_MASK       (0x000F)
+#define MPI_FW_HEADER_PID_FAMILY_1030_SCSI  (0x0000)
+#define MPI_FW_HEADER_PID_FAMILY_909_FC     (0x0000)
+#define MPI_FW_HEADER_PID_FAMILY_919_FC     (0x0001)
+#define MPI_FW_HEADER_PID_FAMILY_919X_FC    (0x0002)
 
 
 typedef struct _MPI_DATA_HEADER
 {
-    U32                     Signature;
-    U16                     FunctionNumber;
-    U16                     Length;
-    U32                     Checksum;
-    U32                     LoadStartAddress;
+    U32                     Signature;                  /* 00h */
+    U16                     FunctionNumber;             /* 04h */
+    U16                     Length;                     /* 06h */
+    U32                     Checksum;                   /* 08h */
+    U32                     LoadStartAddress;           /* 0Ch */
 } MPI_DATA_HEADER, MPI_POINTER PTR_MPI_DATA_HEADER,
   MpiDataHeader_t, MPI_POINTER pMpiDataHeader_t;
 
-#define MPI_DATA_HEADER_SIGNATURE       (0x43504147)
+#define MPI_DATA_HEADER_SIGNATURE           (0x43504147)
 
 #endif
diff -u --recursive --new-file v2.4.9/linux/drivers/message/fusion/lsi/mpi_lan.h linux/drivers/message/fusion/lsi/mpi_lan.h
--- v2.4.9/linux/drivers/message/fusion/lsi/mpi_lan.h	Wed Jul 25 17:10:20 2001
+++ linux/drivers/message/fusion/lsi/mpi_lan.h	Fri Sep  7 09:28:38 2001
@@ -6,7 +6,7 @@
  *          Title:  MPI LAN messages and structures
  *  Creation Date:  June 30, 2000
  *
- *    MPI Version:  01.01.02
+ *    MPI Version:  01.01.03
  *
  *  Version History
  *  ---------------
@@ -26,6 +26,7 @@
  *                      to lan private header file
  *  11-02-00  01.01.01  Original release for post 1.0 work
  *  02-20-01  01.01.02  Started using MPI_POINTER.
+ *  03-27-01  01.01.03  Added structure offset comments.
  *  --------------------------------------------------------------------------
  */
 
@@ -43,32 +44,32 @@
 
 typedef struct _MSG_LAN_SEND_REQUEST
 {
-    U16                     Reserved;
-    U8                      ChainOffset;
-    U8                      Function;
-    U16                     Reserved2;
-    U8                      PortNumber;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    SGE_MPI_UNION           SG_List[1];
+    U16                     Reserved;           /* 00h */
+    U8                      ChainOffset;        /* 02h */
+    U8                      Function;           /* 03h */
+    U16                     Reserved2;          /* 04h */
+    U8                      PortNumber;         /* 06h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
+    SGE_MPI_UNION           SG_List[1];         /* 0Ch */
 } MSG_LAN_SEND_REQUEST, MPI_POINTER PTR_MSG_LAN_SEND_REQUEST,
   LANSendRequest_t, MPI_POINTER pLANSendRequest_t;
 
 
 typedef struct _MSG_LAN_SEND_REPLY
 {
-    U16                     Reserved;
-    U8                      MsgLength;
-    U8                      Function;
-    U8                      Reserved2;
-    U8                      NumberOfContexts;
-    U8                      PortNumber;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U16                     Reserved3;
-    U16                     IOCStatus;
-    U32                     IOCLogInfo;
-    U32                     BufferContext;
+    U16                     Reserved;           /* 00h */
+    U8                      MsgLength;          /* 02h */
+    U8                      Function;           /* 03h */
+    U8                      Reserved2;          /* 04h */
+    U8                      NumberOfContexts;   /* 05h */
+    U8                      PortNumber;         /* 06h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
+    U16                     Reserved3;          /* 0Ch */
+    U16                     IOCStatus;          /* 0Eh */
+    U32                     IOCLogInfo;         /* 10h */
+    U32                     BufferContext;      /* 14h */
 } MSG_LAN_SEND_REPLY, MPI_POINTER PTR_MSG_LAN_SEND_REPLY,
   LANSendReply_t, MPI_POINTER pLANSendReply_t;
 
@@ -77,36 +78,36 @@
 
 typedef struct _MSG_LAN_RECEIVE_POST_REQUEST
 {
-    U16                     Reserved;
-    U8                      ChainOffset;
-    U8                      Function;
-    U16                     Reserved2;
-    U8                      PortNumber;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U32                     BucketCount;
-    SGE_MPI_UNION           SG_List[1];
+    U16                     Reserved;           /* 00h */
+    U8                      ChainOffset;        /* 02h */
+    U8                      Function;           /* 03h */
+    U16                     Reserved2;          /* 04h */
+    U8                      PortNumber;         /* 06h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
+    U32                     BucketCount;        /* 0Ch */
+    SGE_MPI_UNION           SG_List[1];         /* 10h */
 } MSG_LAN_RECEIVE_POST_REQUEST, MPI_POINTER PTR_MSG_LAN_RECEIVE_POST_REQUEST,
   LANReceivePostRequest_t, MPI_POINTER pLANReceivePostRequest_t;
 
 
 typedef struct _MSG_LAN_RECEIVE_POST_REPLY
 {
-    U16                     Reserved;
-    U8                      MsgLength;
-    U8                      Function;
-    U8                      Reserved2;
-    U8                      NumberOfContexts;
-    U8                      PortNumber;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U16                     Reserved3;
-    U16                     IOCStatus;
-    U32                     IOCLogInfo;
-    U32                     BucketsRemaining;
-    U32                     PacketOffset;
-    U32                     PacketLength;
-    U32                     BucketContext[1];
+    U16                     Reserved;           /* 00h */
+    U8                      MsgLength;          /* 02h */
+    U8                      Function;           /* 03h */
+    U8                      Reserved2;          /* 04h */
+    U8                      NumberOfContexts;   /* 05h */
+    U8                      PortNumber;         /* 06h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
+    U16                     Reserved3;          /* 0Ch */
+    U16                     IOCStatus;          /* 0Eh */
+    U32                     IOCLogInfo;         /* 10h */
+    U32                     BucketsRemaining;   /* 14h */
+    U32                     PacketOffset;       /* 18h */
+    U32                     PacketLength;       /* 1Ch */
+    U32                     BucketContext[1];   /* 20h */
 } MSG_LAN_RECEIVE_POST_REPLY, MPI_POINTER PTR_MSG_LAN_RECEIVE_POST_REPLY,
   LANReceivePostReply_t, MPI_POINTER pLANReceivePostReply_t;
 
@@ -115,29 +116,29 @@
 
 typedef struct _MSG_LAN_RESET_REQUEST
 {
-    U16                     Reserved;
-    U8                      ChainOffset;
-    U8                      Function;
-    U16                     Reserved2;
-    U8                      PortNumber;
-    U8                      MsgFlags;
-    U32                     MsgContext;
+    U16                     Reserved;           /* 00h */
+    U8                      ChainOffset;        /* 02h */
+    U8                      Function;           /* 03h */
+    U16                     Reserved2;          /* 04h */
+    U8                      PortNumber;         /* 05h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
 } MSG_LAN_RESET_REQUEST, MPI_POINTER PTR_MSG_LAN_RESET_REQUEST,
   LANResetRequest_t, MPI_POINTER pLANResetRequest_t;
 
 
 typedef struct _MSG_LAN_RESET_REPLY
 {
-    U16                     Reserved;
-    U8                      MsgLength;
-    U8                      Function;
-    U16                     Reserved2;
-    U8                      PortNumber;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U16                     Reserved3;
-    U16                     IOCStatus;
-    U32                     IOCLogInfo;
+    U16                     Reserved;           /* 00h */
+    U8                      MsgLength;          /* 02h */
+    U8                      Function;           /* 03h */
+    U16                     Reserved2;          /* 04h */
+    U8                      PortNumber;         /* 06h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
+    U16                     Reserved3;          /* 0Ch */
+    U16                     IOCStatus;          /* 0Eh */
+    U32                     IOCLogInfo;         /* 10h */
 } MSG_LAN_RESET_REPLY, MPI_POINTER PTR_MSG_LAN_RESET_REPLY,
   LANResetReply_t, MPI_POINTER pLANResetReply_t;
 
@@ -199,6 +200,12 @@
 #define MPI_LAN_DEVICE_STATE_RESET                     (0x00)
 #define MPI_LAN_DEVICE_STATE_OPERATIONAL               (0x01)
 
+
+/****************************************************************************/
+/* LAN Loopback defines                                                     */
+/****************************************************************************/
+
+#define MPI_LAN_TX_MODES_ENABLE_LOOPBACK_SUPPRESSION   (0x01)
 
 #endif
 
diff -u --recursive --new-file v2.4.9/linux/drivers/message/fusion/lsi/mpi_targ.h linux/drivers/message/fusion/lsi/mpi_targ.h
--- v2.4.9/linux/drivers/message/fusion/lsi/mpi_targ.h	Wed Jul 25 17:10:20 2001
+++ linux/drivers/message/fusion/lsi/mpi_targ.h	Fri Sep  7 09:28:38 2001
@@ -6,7 +6,7 @@
  *          Title:  MPI Target mode messages and structures
  *  Creation Date:  June 22, 2000
  *
- *    MPI Version:  01.01.03
+ *    MPI Version:  01.01.04
  *
  *  Version History
  *  ---------------
@@ -25,6 +25,7 @@
  *  02-20-01  01.01.03  Started using MPI_POINTER.
  *                      Added structures for MPI_TARGET_SCSI_SPI_CMD_BUFFER and
  *                      MPI_TARGET_FCP_CMD_BUFFER.
+ *  03-27-01  01.01.04  Added structure offset comments.
  *  --------------------------------------------------------------------------
  */
 
@@ -40,9 +41,9 @@
 
 typedef struct _CMD_BUFFER_DESCRIPTOR
 {
-    U16                     IoIndex;
-    U16                     Reserved;
-    union
+    U16                     IoIndex;                    /* 00h */
+    U16                     Reserved;                   /* 02h */
+    union                                               /* 04h */
     {
         U32                 PhysicalAddress32;
         U64                 PhysicalAddress64;
@@ -57,16 +58,16 @@
 
 typedef struct _MSG_TARGET_CMD_BUFFER_POST_REQUEST
 {
-    U8                      BufferPostFlags;
-    U8                      BufferCount;
-    U8                      ChainOffset;
-    U8                      Function;
-    U8                      BufferLength;
-    U8                      Reserved;
-    U8                      Reserved1;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    CMD_BUFFER_DESCRIPTOR   Buffer[1];
+    U8                      BufferPostFlags;            /* 00h */
+    U8                      BufferCount;                /* 01h */
+    U8                      ChainOffset;                /* 02h */
+    U8                      Function;                   /* 03h */
+    U8                      BufferLength;               /* 04h */
+    U8                      Reserved;                   /* 05h */
+    U8                      Reserved1;                  /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    CMD_BUFFER_DESCRIPTOR   Buffer[1];                  /* 0Ch */
 } MSG_TARGET_CMD_BUFFER_POST_REQUEST, MPI_POINTER PTR_MSG_TARGET_CMD_BUFFER_POST_REQUEST,
   TargetCmdBufferPostRequest_t, MPI_POINTER pTargetCmdBufferPostRequest_t;
 
@@ -81,36 +82,36 @@
 
 typedef struct _MSG_TARGET_CMD_BUFFER_POST_REPLY
 {
-    U8                      BufferPostFlags;
-    U8                      BufferCount;
-    U8                      MsgLength;
-    U8                      Function;
-    U8                      BufferLength;
-    U8                      Reserved;
-    U8                      Reserved1;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U16                     Reserved2;
-    U16                     IOCStatus;
-    U32                     IOCLogInfo;
+    U8                      BufferPostFlags;            /* 00h */
+    U8                      BufferCount;                /* 01h */
+    U8                      MsgLength;                  /* 02h */
+    U8                      Function;                   /* 03h */
+    U8                      BufferLength;               /* 04h */
+    U8                      Reserved;                   /* 05h */
+    U8                      Reserved1;                  /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U16                     Reserved2;                  /* 0Ch */
+    U16                     IOCStatus;                  /* 0Eh */
+    U32                     IOCLogInfo;                 /* 10h */
 } MSG_TARGET_CMD_BUFFER_POST_REPLY, MPI_POINTER PTR_MSG_TARGET_CMD_BUFFER_POST_REPLY,
   TargetCmdBufferPostReply_t, MPI_POINTER pTargetCmdBufferPostReply_t;
 
 
 typedef struct _MSG_PRIORITY_CMD_RECEIVED_REPLY
 {
-    U16                     Reserved;
-    U8                      MsgLength;
-    U8                      Function;
-    U16                     Reserved1;
-    U8                      Reserved2;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U8                      PriorityReason;
-    U8                      Reserved3;
-    U16                     IOCStatus;
-    U32                     IOCLogInfo;
-    U32                     ReplyWord;
+    U16                     Reserved;                   /* 00h */
+    U8                      MsgLength;                  /* 02h */
+    U8                      Function;                   /* 03h */
+    U16                     Reserved1;                  /* 04h */
+    U8                      Reserved2;                  /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U8                      PriorityReason;             /* 0Ch */
+    U8                      Reserved3;                  /* 0Dh */
+    U16                     IOCStatus;                  /* 0Eh */
+    U32                     IOCLogInfo;                 /* 10h */
+    U32                     ReplyWord;                  /* 14h */
 } MSG_PRIORITY_CMD_RECEIVED_REPLY, MPI_POINTER PTR_MSG_PRIORITY_CMD_RECEIVED_REPLY,
   PriorityCommandReceivedReply_t, MPI_POINTER pPriorityCommandReceivedReply_t;
 
@@ -121,17 +122,17 @@
 
 typedef struct _MSG_TARGET_CMD_BUFFER_POST_ERROR_REPLY
 {
-    U16                     Reserved;
-    U8                      MsgLength;
-    U8                      Function;
-    U16                     Reserved1;
-    U8                      Reserved2;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U16                     Reserved3;
-    U16                     IOCStatus;
-    U32                     IOCLogInfo;
-    U32                     ReplyWord;
+    U16                     Reserved;                   /* 00h */
+    U8                      MsgLength;                  /* 02h */
+    U8                      Function;                   /* 03h */
+    U16                     Reserved1;                  /* 04h */
+    U8                      Reserved2;                  /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U16                     Reserved3;                  /* 0Ch */
+    U16                     IOCStatus;                  /* 0Eh */
+    U32                     IOCLogInfo;                 /* 10h */
+    U32                     ReplyWord;                  /* 14h */
 } MSG_TARGET_CMD_BUFFER_POST_ERROR_REPLY,
   MPI_POINTER PTR_MSG_TARGET_CMD_BUFFER_POST_ERROR_REPLY,
   TargetCmdBufferPostErrorReply_t, MPI_POINTER pTargetCmdBufferPostErrorReply_t;
@@ -139,10 +140,10 @@
 
 typedef struct _MPI_TARGET_FCP_CMD_BUFFER
 {
-    U8      FcpLun[8];
-    U8      FcpCntl[4];
-    U8      FcpCdb[16];
-    U32     FcpDl;
+    U8      FcpLun[8];                                  /* 00h */
+    U8      FcpCntl[4];                                 /* 08h */
+    U8      FcpCdb[16];                                 /* 0Ch */
+    U32     FcpDl;                                      /* 1Ch */
 } MPI_TARGET_FCP_CMD_BUFFER, MPI_POINTER PTR_MPI_TARGET_FCP_CMD_BUFFER,
   MpiTargetFcpCmdBuffer, MPI_POINTER pMpiTargetFcpCmdBuffer;
 
@@ -150,17 +151,17 @@
 typedef struct _MPI_TARGET_SCSI_SPI_CMD_BUFFER
 {
     /* SPI L_Q information unit */
-    U8      L_QType;
-    U8      Reserved;
-    U16     Tag;
-    U8      LogicalUnitNumber[8];
-    U32     DataLength;
+    U8      L_QType;                                    /* 00h */
+    U8      Reserved;                                   /* 01h */
+    U16     Tag;                                        /* 02h */
+    U8      LogicalUnitNumber[8];                       /* 04h */
+    U32     DataLength;                                 /* 0Ch */
     /* SPI command information unit */
-    U8      ReservedFirstByteOfCommandIU;
-    U8      TaskAttribute;
-    U8      TaskManagementFlags;
-    U8      AdditionalCDBLength;
-    U8      CDB[16];
+    U8      ReservedFirstByteOfCommandIU;               /* 10h */
+    U8      TaskAttribute;                              /* 11h */
+    U8      TaskManagementFlags;                        /* 12h */
+    U8      AdditionalCDBLength;                        /* 13h */
+    U8      CDB[16];                                    /* 14h */
 } MPI_TARGET_SCSI_SPI_CMD_BUFFER,
   MPI_POINTER PTR_MPI_TARGET_SCSI_SPI_CMD_BUFFER,
   MpiTargetScsiSpiCmdBuffer, MPI_POINTER pMpiTargetScsiSpiCmdBuffer;
@@ -172,19 +173,19 @@
 
 typedef struct _MSG_TARGET_ASSIST_REQUEST
 {
-    U8                      StatusCode;
-    U8                      TargetAssistFlags;
-    U8                      ChainOffset;
-    U8                      Function;
-    U16                     QueueTag;
-    U8                      Reserved;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U32                     ReplyWord;
-    U8                      LUN[8];
-    U32                     RelativeOffset;
-    U32                     DataLength;
-    SGE_IO_UNION            SGL[1];
+    U8                      StatusCode;                 /* 00h */
+    U8                      TargetAssistFlags;          /* 01h */
+    U8                      ChainOffset;                /* 02h */
+    U8                      Function;                   /* 03h */
+    U16                     QueueTag;                   /* 04h */
+    U8                      Reserved;                   /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U32                     ReplyWord;                  /* 0Ch */
+    U8                      LUN[8];                     /* 10h */
+    U32                     RelativeOffset;             /* 18h */
+    U32                     DataLength;                 /* 1Ch */
+    SGE_IO_UNION            SGL[1];                     /* 20h */
 } MSG_TARGET_ASSIST_REQUEST, MPI_POINTER PTR_MSG_TARGET_ASSIST_REQUEST,
   TargetAssistRequest_t, MPI_POINTER pTargetAssistRequest_t;
 
@@ -196,18 +197,18 @@
 
 typedef struct _MSG_TARGET_ERROR_REPLY
 {
-    U16                     Reserved;
-    U8                      MsgLength;
-    U8                      Function;
-    U16                     Reserved1;
-    U8                      Reserved2;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U16                     Reserved3;
-    U16                     IOCStatus;
-    U32                     IOCLogInfo;
-    U32                     ReplyWord;
-    U32                     TransferCount;
+    U16                     Reserved;                   /* 00h */
+    U8                      MsgLength;                  /* 02h */
+    U8                      Function;                   /* 03h */
+    U16                     Reserved1;                  /* 04h */
+    U8                      Reserved2;                  /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U16                     Reserved3;                  /* 0Ch */
+    U16                     IOCStatus;                  /* 0Eh */
+    U32                     IOCLogInfo;                 /* 10h */
+    U32                     ReplyWord;                  /* 14h */
+    U32                     TransferCount;              /* 18h */
 } MSG_TARGET_ERROR_REPLY, MPI_POINTER PTR_MSG_TARGET_ERROR_REPLY,
   TargetErrorReply_t, MPI_POINTER pTargetErrorReply_t;
 
@@ -218,17 +219,17 @@
 
 typedef struct _MSG_TARGET_STATUS_SEND_REQUEST
 {
-    U8                      StatusCode;
-    U8                      StatusFlags;
-    U8                      ChainOffset;
-    U8                      Function;
-    U16                     QueueTag;
-    U8                      Reserved;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U32                     ReplyWord;
-    U8                      LUN[8];
-    SGE_SIMPLE_UNION        StatusDataSGE;
+    U8                      StatusCode;                 /* 00h */
+    U8                      StatusFlags;                /* 01h */
+    U8                      ChainOffset;                /* 02h */
+    U8                      Function;                   /* 03h */
+    U16                     QueueTag;                   /* 04h */
+    U8                      Reserved;                   /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U32                     ReplyWord;                  /* 0Ch */
+    U8                      LUN[8];                     /* 10h */
+    SGE_SIMPLE_UNION        StatusDataSGE;              /* 18h */
 } MSG_TARGET_STATUS_SEND_REQUEST, MPI_POINTER PTR_MSG_TARGET_STATUS_SEND_REQUEST,
   TargetStatusSendRequest_t, MPI_POINTER pTargetStatusSendRequest_t;
 
@@ -242,16 +243,16 @@
 
 typedef struct _MSG_TARGET_MODE_ABORT_REQUEST
 {
-    U8                      AbortType;
-    U8                      Reserved;
-    U8                      ChainOffset;
-    U8                      Function;
-    U16                     Reserved1;
-    U8                      Reserved2;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U32                     ReplyWord;
-    U32                     MsgContextToAbort;
+    U8                      AbortType;                  /* 00h */
+    U8                      Reserved;                   /* 01h */
+    U8                      ChainOffset;                /* 02h */
+    U8                      Function;                   /* 03h */
+    U16                     Reserved1;                  /* 04h */
+    U8                      Reserved2;                  /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U32                     ReplyWord;                  /* 0Ch */
+    U32                     MsgContextToAbort;          /* 10h */
 } MSG_TARGET_MODE_ABORT, MPI_POINTER PTR_MSG_TARGET_MODE_ABORT,
   TargetModeAbort_t, MPI_POINTER pTargetModeAbort_t;
 
@@ -264,17 +265,17 @@
 
 typedef struct _MSG_TARGET_MODE_ABORT_REPLY
 {
-    U16                     Reserved;
-    U8                      MsgLength;
-    U8                      Function;
-    U16                     Reserved1;
-    U8                      Reserved2;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U16                     Reserved3;
-    U16                     IOCStatus;
-    U32                     IOCLogInfo;
-    U32                     AbortCount;
+    U16                     Reserved;                   /* 00h */
+    U8                      MsgLength;                  /* 02h */
+    U8                      Function;                   /* 03h */
+    U16                     Reserved1;                  /* 04h */
+    U8                      Reserved2;                  /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U16                     Reserved3;                  /* 0Ch */
+    U16                     IOCStatus;                  /* 0Eh */
+    U32                     IOCLogInfo;                 /* 10h */
+    U32                     AbortCount;                 /* 14h */
 } MSG_TARGET_MODE_ABORT_REPLY, MPI_POINTER PTR_MSG_TARGET_MODE_ABORT_REPLY,
   TargetModeAbortReply_t, MPI_POINTER pTargetModeAbortReply_t;
 
diff -u --recursive --new-file v2.4.9/linux/drivers/message/fusion/mptbase.c linux/drivers/message/fusion/mptbase.c
--- v2.4.9/linux/drivers/message/fusion/mptbase.c	Wed Jul 25 17:10:20 2001
+++ linux/drivers/message/fusion/mptbase.c	Fri Sep  7 09:28:38 2001
@@ -42,7 +42,7 @@
  *  Originally By: Steven J. Ralston
  *  (mailto:Steve.Ralston@lsil.com)
  *
- *  $Id: mptbase.c,v 1.47 2001/03/22 10:32:23 sralston Exp $
+ *  $Id: mptbase.c,v 1.53.4.1 2001/08/24 20:07:05 sralston Exp $
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -130,6 +130,8 @@
 const char **mpt_ScsiOpcodesPtr = NULL;
 int mpt_ASCQ_TableSz = 0;
 
+#define WHOINIT_UNKNOWN		0xAA
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *  Private data...
@@ -143,6 +145,8 @@
 static int	 		 MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
 					/* Event handler lookup table */
 static MPT_EVHANDLER		 MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
+					/* Reset handler lookup table */
+static MPT_RESETHANDLER		 MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
 
 static int	FusionInitCalled = 0;
 static int	mpt_base_index = -1;
@@ -154,25 +158,27 @@
 static void	mpt_interrupt(int irq, void *bus_id, struct pt_regs *r);
 static int	mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
 
+static int 	mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason);
 static int 	mpt_adapter_install(struct pci_dev *pdev);
 static void	mpt_detect_929_bound_ports(MPT_ADAPTER *this, struct pci_dev *pdev);
-static void	mpt_adapter_disable(MPT_ADAPTER *ioc);
+static void	mpt_adapter_disable(MPT_ADAPTER *ioc, int freeup);
 static void	mpt_adapter_dispose(MPT_ADAPTER *ioc);
 
 static void	MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
+static int	MakeIocReady(MPT_ADAPTER *ioc, int force);
 static u32	GetIocState(MPT_ADAPTER *ioc, int cooked);
 static int	GetIocFacts(MPT_ADAPTER *ioc);
-static int	GetPortFacts(MPT_ADAPTER *ioc);
+static int	GetPortFacts(MPT_ADAPTER *ioc, int portnum);
 static int	SendIocInit(MPT_ADAPTER *ioc);
 static int	SendPortEnable(MPT_ADAPTER *ioc, int portnum);
-static int	mpt_fc9x9_reset(MPT_ADAPTER *ioc);
-static int	KickStart(MPT_ADAPTER *ioc);
+static int	mpt_fc9x9_reset(MPT_ADAPTER *ioc, int ignore);
+static int	KickStart(MPT_ADAPTER *ioc, int ignore);
 static int	SendIocReset(MPT_ADAPTER *ioc, u8 reset_type);
 static int	PrimeIocFifos(MPT_ADAPTER *ioc);
-static int	HandShakeReqAndReply(MPT_ADAPTER *ioc, int reqBytes, u32 *req, int replyBytes, u16 *u16reply);
-static int	WaitForDoorbellAck(MPT_ADAPTER *ioc);
-static int	WaitForDoorbellInt(MPT_ADAPTER *ioc);
-static int	WaitForDoorbellReply(MPT_ADAPTER *ioc);
+static int	HandShakeReqAndReply(MPT_ADAPTER *ioc, int reqBytes, u32 *req, int replyBytes, u16 *u16reply, int maxwait);
+static int	WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong);
+static int	WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong);
+static int	WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong);
 static int	GetLanConfigPages(MPT_ADAPTER *ioc);
 static int	SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch);
 static int	SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
@@ -192,6 +198,7 @@
 static struct proc_dir_entry	*procmpt_root_dir = NULL;
 
 int		fusion_init(void);
+static void	fusion_exit(void);
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /* 20000207 -sralston
@@ -586,6 +593,45 @@
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
+ *	mpt_reset_register - Register protocol-specific IOC reset handler.
+ *	@cb_idx: previously registered (via mpt_register) callback handle
+ *	@reset_func: reset function
+ *
+ *	This routine can be called by one or more protocol-specific drivers
+ *	if/when they choose to be notified of IOC resets.
+ *
+ *	Returns 0 for success.
+ */
+int
+mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func)
+{
+	if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
+		return -1;
+
+	MptResetHandlers[cb_idx] = reset_func;
+	return 0;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/**
+ *	mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
+ *	@cb_idx: previously registered callback handle
+ *
+ *	Each protocol-specific driver should call this routine
+ *	when it does not (or can no longer) handle IOC reset handling,
+ *	or when it's module is unloaded.
+ */
+void
+mpt_reset_deregister(int cb_idx)
+{
+	if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
+		return;
+
+	MptResetHandlers[cb_idx] = NULL;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/**
  *	mpt_get_msg_frame - Obtain a MPT request frame from the pool (of 1024)
  *	allocated per MPT adapter.
  *	@handle: Handle of registered MPT protocol driver
@@ -723,13 +769,29 @@
 
 	iocp = mpt_adapters[iocid];
 	if (iocp != NULL) {
-		u8 *req_as_bytes;
-		int i;
+		u8		*req_as_bytes;
+		u32		 ioc_raw_state;
+		int		 i;
+
+		/* YIKES!  We already know something is amiss.
+		 * Do upfront check on IOC state.
+		 */
+		ioc_raw_state = GetIocState(iocp, 0);
+		if ((ioc_raw_state & MPI_DOORBELL_ACTIVE) ||
+		    ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL)) {
+			printk(KERN_WARNING MYNAM ": %s: Bad IOC state (%08x) WARNING!\n",
+					iocp->name, ioc_raw_state);
+			if ((r = mpt_do_ioc_recovery(iocp, MPT_HOSTEVENT_IOC_RECOVER)) != 0) {
+				printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",
+						r, iocp->name);
+				return r;
+			}
+		}
 
 		/*
-		 *  Emulate what mpt_put_msg_frame() does /wrt to sanity
-		 *  setting cb_idx/req_idx.  But ONLY if this request
-		 *  is in proper (pre-alloc'd) request buffer range...
+		 * Emulate what mpt_put_msg_frame() does /wrt to sanity
+		 * setting cb_idx/req_idx.  But ONLY if this request
+		 * is in proper (pre-alloc'd) request buffer range...
 		 */
 		i = MFPTR_2_MPT_INDEX(iocp,(MPT_FRAME_HDR*)req);
 		if (reqBytes >= 12 && i >= 0 && i < iocp->req_depth) {
@@ -738,17 +800,15 @@
 			mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;
 		}
 
-		/*  Make sure there are no doorbells  */
+		/* Make sure there are no doorbells */
 		CHIPREG_WRITE32(&iocp->chip->IntStatus, 0);
 
 		CHIPREG_WRITE32(&iocp->chip->Doorbell,
 				((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
 				 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
 
-		/*  Wait for IOC doorbell int  */
-		if ((i = WaitForDoorbellInt(iocp)) < 0) {
-			/* FIXME! Recovery action(s)? */
-			/*i = unresponsive_ioc(i);*/
+		/* Wait for IOC doorbell int */
+		if ((i = WaitForDoorbellInt(iocp, 2)) < 0) {
 			return i;
 		}
 
@@ -757,10 +817,11 @@
 
 		CHIPREG_WRITE32(&iocp->chip->IntStatus, 0);
 
-		if ((r = WaitForDoorbellAck(iocp)) < 0)
+		if ((r = WaitForDoorbellAck(iocp, 1)) < 0) {
 			return -2;
+		}
 
-		/*  Send request via doorbell handshake  */
+		/* Send request via doorbell handshake */
 		req_as_bytes = (u8 *) req;
 		for (i = 0; i < reqBytes/4; i++) {
 			u32 word;
@@ -770,15 +831,19 @@
 				(req_as_bytes[(i*4) + 2] << 16) |
 				(req_as_bytes[(i*4) + 3] << 24));
 			CHIPREG_WRITE32(&iocp->chip->Doorbell, word);
-			if ((r = WaitForDoorbellAck(iocp)) < 0) {
+			if ((r = WaitForDoorbellAck(iocp, 1)) < 0) {
 				r = -3;
 				break;
 			}
 		}
 
-		/*  Make sure there are no doorbells  */
-		CHIPREG_WRITE32(&iocp->chip->IntStatus, 0);
+		if ((r = WaitForDoorbellInt(iocp, 2)) >= 0)
+			r = 0;
+		else
+			r = -4;
 
+		/* Make sure there are no doorbells */
+		CHIPREG_WRITE32(&iocp->chip->IntStatus, 0);
 	}
 
 	return r;
@@ -849,9 +914,8 @@
 
 		if ((pdev->device != MPI_MANUFACTPAGE_DEVICEID_FC909) &&
 		    (pdev->device != MPI_MANUFACTPAGE_DEVICEID_FC929) &&
-#if 0
-		    /* FIXME! FC919 */
 		    (pdev->device != MPI_MANUFACTPAGE_DEVICEID_FC919) &&
+#if 0
 		    /* FIXME! C103x family */
 		    (pdev->device != MPI_MANUFACTPAGE_DEVID_53C1030) &&
 		    (pdev->device != MPI_MANUFACTPAGE_DEVID_53C1030_ZC) &&
@@ -897,8 +961,10 @@
 	printk(KERN_INFO MYNAM ": %d MPT adapter%s found, %d installed.\n",
 		 found, (found==1) ? "" : "s", count);
 
-	if (count == 0)
+	if (!found || !count) {
+		fusion_exit();
 		return -ENODEV;
+	}
 
 #ifdef CONFIG_PROC_FS
 	if (procmpt_create() != 0)
@@ -962,12 +1028,9 @@
 	unsigned long	 port;
 	u32		 msize;
 	u32		 psize;
-	u32		 ioc_state;
 	int		 i;
 	int		 r = -ENODEV;
-	int 		 cntdn;
 	int		 len;
-	int		 statefault = 0;
 
 	ioc = kmalloc(sizeof(MPT_ADAPTER), GFP_KERNEL);
 	if (ioc == NULL) {
@@ -980,7 +1043,7 @@
 
 	ioc->pcidev = pdev;
 
-	/*  Find lookup slot.  GRRRR...  */
+	/* Find lookup slot. */
 	for (i=0; i < MPT_MAX_ADAPTERS; i++) {
 		if (mpt_adapters[i] == NULL) {
 			ioc->id = i;		/* Assign adapter unique id (lookup) */
@@ -997,11 +1060,11 @@
 	port = psize = 0;
 	for (i=0; i < DEVICE_COUNT_RESOURCE; i++) {
 		if (pdev->PCI_BASEADDR_FLAGS(i) & PCI_BASE_ADDRESS_SPACE_IO) {
-			/*  Get I/O space!  */
+			/* Get I/O space! */
 			port = pdev->PCI_BASEADDR_START(i);
 			psize = PCI_BASEADDR_SIZE(pdev,i);
 		} else {
-			/*  Get memmap  */
+			/* Get memmap */
 			mem_phys = pdev->PCI_BASEADDR_START(i);
 			msize = PCI_BASEADDR_SIZE(pdev,i);
 			break;
@@ -1021,7 +1084,7 @@
 
 	mem = NULL;
 	if (! PortIo) {
-		/*  Get logical ptr for PciMem0 space  */
+		/* Get logical ptr for PciMem0 space */
 		/*mem = ioremap(mem_phys, msize);*/
 		mem = ioremap(mem_phys, 0x100);
 		if (mem == NULL) {
@@ -1051,11 +1114,11 @@
 		ioc->chip_type = FC929;
 		ioc->prod_name = "LSIFC929";
 	}
-#if 0
 	else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919) {
-		ioc->chip_type = C1030;
+		ioc->chip_type = FC919;
 		ioc->prod_name = "LSIFC919";
 	}
+#if 0
 	else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_53C1030) {
 		ioc->chip_type = C1030;
 		ioc->prod_name = "LSI53C1030";
@@ -1070,10 +1133,10 @@
 	Q_INIT(&ioc->FreeQ, MPT_FRAME_HDR);
 	spin_lock_init(&ioc->FreeQlock);
 
-	/*  Disable all!  */
+	/* Disable all! */
 	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
-	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
 	ioc->active = 0;
+	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
 
 	ioc->pci_irq = -1;
 	if (pdev->irq) {
@@ -1094,7 +1157,7 @@
 		dprintk((KERN_INFO MYNAM ": %s installed at interrupt %d\n", ioc->name, pdev->irq));
 	}
 
-	/*  tack onto tail of our MPT adapter list  */
+	/* tack onto tail of our MPT adapter list */
 	Q_ADD_TAIL(&MptAdapters, ioc, MPT_ADAPTER);
 
 	/* Set lookup ptr. */
@@ -1106,115 +1169,168 @@
 	if (ioc->chip_type == FC929)
 		mpt_detect_929_bound_ports(ioc, pdev);
 
-	/*  Get current [raw] IOC state  */
-	ioc_state = GetIocState(ioc, 0);
-	dhsprintk((KERN_INFO MYNAM ": %s initial [raw] state=%08x\n", ioc->name, ioc_state));
+	if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP)) != 0) {
+		printk(KERN_WARNING MYNAM ": WARNING - %s did not initialize properly! (%d)\n",
+				ioc->name, r);
+	}
 
-	/*
-	 *  Check to see if IOC got left/stuck in doorbell handshake
-	 *  grip of death.  If so, hard reset the IOC.
-	 */
-	if (ioc_state & MPI_DOORBELL_ACTIVE) {
-		statefault = 1;
-		printk(KERN_WARNING MYNAM ": %s: Uh-oh, unexpected doorbell active!\n",
+	return r;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/**
+ *	mpt_do_ioc_recovery - Initialize or recover MPT adapter.
+ *	@ioc: Pointer to MPT adapter structure
+ *	@reason: Event word / reason
+ *
+ *	This routine performs all the steps necessary to bring the IOC
+ *	to a OPERATIONAL state.
+ *
+ *	This routine also pre-fetches the LAN MAC address of a Fibre Channel
+ *	MPT adapter.
+ *
+ *	Returns 0 for success.
+ */
+static int
+mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason)
+{
+	int	 hard_reset_done = 0;
+	int	 alt_ioc_ready = 0;
+	int	 hard;
+	int	 r;
+	int	 i;
+	int	 handlers;
+
+	printk(KERN_INFO MYNAM ": Initiating %s %s\n",
+			ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
+
+	/* Disable reply interrupts */
+	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
+	ioc->active = 0;
+	/* NOTE: Access to IOC's request FreeQ is now blocked! */
+
+// FIXME? Cleanup all IOC requests here! (or below?)
+// But watch out for event associated request?
+
+	hard = HardReset;
+	if (ioc->alt_ioc && (reason == MPT_HOSTEVENT_IOC_BRINGUP))
+		hard = 0;
+
+	if ((hard_reset_done = MakeIocReady(ioc, hard)) < 0) {
+		printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n",
 				ioc->name);
+		return -1;
 	}
 
-	/*
-	 *  Check to see if IOC is in FAULT state.
-	 *  If so, hard reset the IOC.
-	 */
-	if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
-		statefault = 2;
-		printk(KERN_WARNING MYNAM ": %s: Uh-oh, IOC is in FAULT state!!!\n",
-				ioc->name);
-		printk(KERN_WARNING "           FAULT code = %04xh\n",
-				ioc_state & MPI_DOORBELL_DATA_MASK);
+// NEW!
+#if 0						// Kiss-of-death!?!
+	if (ioc->alt_ioc) {
+// Grrr... Hold off any alt-IOC interrupts (and events) while
+// handshaking to <this> IOC, needed because?
+		/* Disable alt-IOC's reply interrupts for a bit ... */
+		alt_ioc_intmask = CHIPREG_READ32(&ioc->alt_ioc->chip->IntMask);
+		CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
+		ioc->alt_ioc->active = 0;
+		/* NOTE: Access to alt-IOC's request FreeQ is now blocked! */
 	}
+#endif
 
-	if (HardReset || statefault) {
-		if ((r = KickStart(ioc)) != 0) {
-			r = -ENODEV;
-			goto ioc_up_fail;
-		}
+	if (hard_reset_done && ioc->alt_ioc) {
+		if ((r = MakeIocReady(ioc->alt_ioc, 0)) == 0)
+			alt_ioc_ready = 1;
+		else
+			printk(KERN_WARNING MYNAM ": alt-%s: (%d) Not ready WARNING!\n",
+					ioc->alt_ioc->name, r);
+	}
+
+	if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
+		/* Get IOC facts! */
+		if ((r = GetIocFacts(ioc)) != 0)
+			return -2;
+		MptDisplayIocCapabilities(ioc);
 	}
 
 	/*
-	 *  Loop here waiting for IOC to come READY.
-	 */
-	i = 0;
-	cntdn = HZ * 10;
-	while ((ioc_state = GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
-		if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
-			/*
-			 *  BIOS or previous driver load left IOC in OP state.
-			 *  Reset messaging FIFOs.
-			 */
-			dprintk((KERN_WARNING MYNAM ": %s: Sending IOC msg unit reset!\n", ioc->name));
-			if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET)) != 0) {
-				printk(KERN_ERR MYNAM ": %s: ERROR - IOC msg unit reset failed!\n", ioc->name);
-				r = -ENODEV;
-				goto ioc_up_fail;
-			}
-		} else if (ioc_state == MPI_IOC_STATE_RESET) {
-			/*
-			 *  Something is wrong.  Try to get IOC back
-			 *  to a known state.
-			 */
-			dprintk((KERN_WARNING MYNAM ": %s: Sending IO unit reset!\n", ioc->name));
-			if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET)) != 0) {
-				printk(KERN_ERR MYNAM ": %s: ERROR - IO unit reset failed!\n", ioc->name);
-				r = -ENODEV;
-				goto ioc_up_fail;
+	 * Call each currently registered protocol IOC reset handler
+	 * with pre-reset indication.
+	 * NOTE: If we're doing _IOC_BRINGUP, there can be no
+	 * MptResetHandlers[] registered yet.
+	 */
+	if (hard_reset_done) {
+		r = handlers = 0;
+		for (i=MPT_MAX_PROTOCOL_DRIVERS-1; i; i--) {
+			if (MptResetHandlers[i]) {
+				dprintk((KERN_INFO MYNAM ": %s: Calling IOC pre_reset handler #%d\n",
+						ioc->name, i));
+				r += (*(MptResetHandlers[i]))(ioc, MPT_IOC_PRE_RESET);
+				handlers++;
+
+				if (alt_ioc_ready) {
+					dprintk((KERN_INFO MYNAM ": %s: Calling alt-IOC pre_reset handler #%d\n",
+							ioc->alt_ioc->name, i));
+					r += (*(MptResetHandlers[i]))(ioc->alt_ioc, MPT_IOC_PRE_RESET);
+					handlers++;
+				}
 			}
 		}
+		/* FIXME?  Examine results here? */
+	}
 
-		i++; cntdn--;
-		if (!cntdn) {
-			printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
-					ioc->name, (i+5)/HZ);
-			r = -ETIME;
-			goto ioc_up_fail;
-		}
+	// May need to check/upload firmware & data here!
 
-		current->state = TASK_INTERRUPTIBLE;
-		schedule_timeout(1);
+	if ((r = SendIocInit(ioc)) != 0)
+		return -3;
+// NEW!
+	if (alt_ioc_ready) {
+		if ((r = SendIocInit(ioc->alt_ioc)) != 0) {
+			alt_ioc_ready = 0;
+			printk(KERN_WARNING MYNAM ": alt-%s: (%d) init failure WARNING!\n",
+					ioc->alt_ioc->name, r);
+		}
 	}
 
-	if (statefault) {
-		printk(KERN_WARNING MYNAM ": %s: Whew!  Recovered from %s\n",
-				ioc->name, statefault==1 ? "stuck handshake" : "IOC FAULT");
+	/*
+	 * Call each currently registered protocol IOC reset handler
+	 * with post-reset indication.
+	 * NOTE: If we're doing _IOC_BRINGUP, there can be no
+	 * MptResetHandlers[] registered yet.
+	 */
+	if (hard_reset_done) {
+		r = handlers = 0;
+		for (i=MPT_MAX_PROTOCOL_DRIVERS-1; i; i--) {
+			if (MptResetHandlers[i]) {
+				dprintk((KERN_INFO MYNAM ": %s: Calling IOC post_reset handler #%d\n",
+						ioc->name, i));
+				r += (*(MptResetHandlers[i]))(ioc, MPT_IOC_POST_RESET);
+				handlers++;
+
+				if (alt_ioc_ready) {
+					dprintk((KERN_INFO MYNAM ": %s: Calling alt-IOC post_reset handler #%d\n",
+							ioc->alt_ioc->name, i));
+					r += (*(MptResetHandlers[i]))(ioc->alt_ioc, MPT_IOC_POST_RESET);
+					handlers++;
+				}
+			}
+		}
+		/* FIXME?  Examine results here? */
 	}
 
-	/*  Enable! (reply interrupt)  */
-	CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));
-	ioc->active = 1;
-
-	/*  Get IOC facts! (first time, ioc->facts0 and ioc->pfacts0)  */
-	if ((r = GetIocFacts(ioc)) != 0)
-		goto ioc_up_fail;
-
-	/* Does IocFacts.EventState need any looking at / attention here? */
-
-	if ((r = SendIocInit(ioc)) != 0)
-		goto ioc_up_fail;
-
 	/*
-	 *  Prime reply & request queues!
-	 *  (mucho alloc's)
+	 * Prime reply & request queues!
+	 * (mucho alloc's)
 	 */
 	if ((r = PrimeIocFifos(ioc)) != 0)
-		goto ioc_up_fail;
-
-	/*  Get IOC facts again! (2nd time, ioc->factsN and ioc->pfactsN)  */
-	if ((r = GetIocFacts(ioc)) != 0)
-		goto ioc_up_fail;
-
-	/* Does IocFacts.EventState need any looking at / attention here? */
+		return -4;
+// NEW!
+	if (alt_ioc_ready && ((r = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
+		printk(KERN_WARNING MYNAM ": alt-%s: (%d) FIFO mgmt alloc WARNING!\n",
+				ioc->alt_ioc->name, r);
+	}
 
-	MptDisplayIocCapabilities(ioc);
+// FIXME! Cleanup all IOC (and alt-IOC?) requests here!
 
-	if (ioc->pfacts0.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
+	if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
+	    (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
 		/*
 		 *  Pre-fetch the ports LAN MAC address!
 		 *  (LANPage1_t stuff)
@@ -1229,19 +1345,34 @@
 #endif
 	}
 
+	/* Enable! (reply interrupt) */
+	CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));
+	ioc->active = 1;
+
+// NEW!
+#if 0						// Kiss-of-death!?!
+	if (alt_ioc_ready && (r==0)) {
+		/* (re)Enable alt-IOC! (reply interrupt) */
+		dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
+				ioc->alt_ioc->name));
+		CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM));
+		ioc->alt_ioc->active = 1;
+	}
+#endif
+
 	/* NEW!  20010120 -sralston
 	 *  Enable MPT base driver management of EventNotification
 	 *  and EventAck handling.
 	 */
-	(void) SendEventNotification(ioc, 1);	/* 1=Enable EventNotification */
+	if (!ioc->facts.EventState)
+		(void) SendEventNotification(ioc, 1);	/* 1=Enable EventNotification */
+// NEW!
+// FIXME!?!
+//	if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState) {
+//		(void) SendEventNotification(ioc->alt_ioc, 1);	/* 1=Enable EventNotification */
+//	}
 
 	return 0;
-
-ioc_up_fail:
-	//Q_DEL_ITEM(ioc);
-	//mpt_adapter_dispose(ioc);
-	mpt_adapter_disable(ioc);
-	return r;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1297,20 +1428,25 @@
 /*
  *	mpt_adapter_disable - Disable misbehaving MPT adapter.
  *	@this: Pointer to MPT adapter structure
+ *	@free: Free up alloc'd reply, request, etc.
  */
 static void
-mpt_adapter_disable(MPT_ADAPTER *this)
+mpt_adapter_disable(MPT_ADAPTER *this, int freeup)
 {
 	if (this != NULL) {
 		int sz;
 
+		/* Disable the FW */
+		if (SendIocReset(this, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET) != 0)
+			(void) KickStart(this, 1);
+
 		/* Disable adapter interrupts! */
 		CHIPREG_WRITE32(&this->chip->IntMask, 0xFFFFFFFF);
+		this->active = 0;
 		/* Clear any lingering interrupt */
 		CHIPREG_WRITE32(&this->chip->IntStatus, 0);
-		this->active = 0;
 
-		if (this->reply_alloc != NULL) {
+		if (freeup && this->reply_alloc != NULL) {
 			sz = (this->reply_sz * this->reply_depth) + 128;
 			pci_free_consistent(this->pcidev, sz,
 					this->reply_alloc, this->reply_alloc_dma);
@@ -1319,7 +1455,7 @@
 			this->alloc_total -= sz;
 		}
 
-		if (this->req_alloc != NULL) {
+		if (freeup && this->req_alloc != NULL) {
 			sz = (this->req_sz * this->req_depth) + 128;
 			/*
 			 *  Rounding UP to nearest 4-kB boundary here...
@@ -1332,7 +1468,7 @@
 			this->alloc_total -= sz;
 		}
 
-		if (this->sense_buf_pool != NULL) {
+		if (freeup && this->sense_buf_pool != NULL) {
 			sz = (this->req_depth * 256);
 			pci_free_consistent(this->pcidev, sz,
 					this->sense_buf_pool, this->sense_buf_pool_dma);
@@ -1359,7 +1495,7 @@
 
 		sz_first = this->alloc_total;
 
-		mpt_adapter_disable(this);
+		mpt_adapter_disable(this, 1);
 
 		if (this->pci_irq != -1) {
 			free_irq(this->pci_irq, this);
@@ -1401,17 +1537,17 @@
 		printk("%s: ", ioc->prod_name+3);
 	printk("Capabilities={");
 
-	if (ioc->pfacts0.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
+	if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
 		printk("Initiator");
 		i++;
 	}
 
-	if (ioc->pfacts0.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
+	if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
 		printk("%sTarget", i ? "," : "");
 		i++;
 	}
 
-	if (ioc->pfacts0.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
+	if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
 		printk("%sLAN", i ? "," : "");
 		i++;
 	}
@@ -1420,7 +1556,7 @@
 	/*
 	 *  This would probably evoke more questions than it's worth
 	 */
-	if (ioc->pfacts0.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
+	if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
 		printk("%sLogBusAddr", i ? "," : "");
 		i++;
 	}
@@ -1431,6 +1567,113 @@
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
+ *	MakeIocReady - Get IOC to a READY state, using KickStart if needed.
+ *	@ioc: Pointer to MPT_ADAPTER structure
+ *	@kick: Force hard KickStart of IOC
+ *
+ *	Returns 0 for already-READY, 1 for hard reset success,
+ *	else negative for failure.
+ */
+static int
+MakeIocReady(MPT_ADAPTER *ioc, int force)
+{
+	u32	 ioc_state;
+	int	 statefault = 0;
+	int 	 cntdn;
+	int	 hard_reset_done = 0;
+	int	 r;
+	int	 i;
+
+	/* Get current [raw] IOC state  */
+	ioc_state = GetIocState(ioc, 0);
+	dhsprintk((KERN_INFO MYNAM "::MakeIocReady, %s [raw] state=%08x\n", ioc->name, ioc_state));
+
+	/*
+	 *	Check to see if IOC got left/stuck in doorbell handshake
+	 *	grip of death.  If so, hard reset the IOC.
+	 */
+	if (ioc_state & MPI_DOORBELL_ACTIVE) {
+		statefault = 1;
+		printk(KERN_WARNING MYNAM ": %s: Uh-oh, unexpected doorbell active!\n",
+				ioc->name);
+	}
+
+	/* Is it already READY? */
+	if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
+		return 0;
+
+	/*
+	 *	Check to see if IOC is in FAULT state.
+	 */
+	if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
+		statefault = 2;
+		printk(KERN_WARNING MYNAM ": %s: Uh-oh, IOC is in FAULT state!!!\n",
+				ioc->name);
+		printk(KERN_WARNING "           FAULT code = %04xh\n",
+				ioc_state & MPI_DOORBELL_DATA_MASK);
+	}
+
+	/*
+	 *	Hmmm...  Did it get left operational?
+	 */
+	if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
+		statefault = 3;
+		dprintk((KERN_WARNING MYNAM ": %s: Hmmm... IOC operational unexpected\n",
+				ioc->name));
+	}
+
+	hard_reset_done = KickStart(ioc, statefault||force);
+	if (hard_reset_done < 0)
+		return -1;
+
+	/*
+	 *  Loop here waiting for IOC to come READY.
+	 */
+	i = 0;
+	cntdn = HZ * 15;
+	while ((ioc_state = GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
+		if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
+			/*
+			 *  BIOS or previous driver load left IOC in OP state.
+			 *  Reset messaging FIFOs.
+			 */
+			if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET)) != 0) {
+				printk(KERN_ERR MYNAM ": %s: ERROR - IOC msg unit reset failed!\n", ioc->name);
+				return -2;
+			}
+		} else if (ioc_state == MPI_IOC_STATE_RESET) {
+			/*
+			 *  Something is wrong.  Try to get IOC back
+			 *  to a known state.
+			 */
+			if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET)) != 0) {
+				printk(KERN_ERR MYNAM ": %s: ERROR - IO unit reset failed!\n", ioc->name);
+				return -3;
+			}
+		}
+
+		i++; cntdn--;
+		if (!cntdn) {
+			printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
+					ioc->name, (i+5)/HZ);
+			return -ETIME;
+		}
+
+		current->state = TASK_INTERRUPTIBLE;
+		schedule_timeout(1);
+	}
+
+	if (statefault < 3) {
+		printk(KERN_WARNING MYNAM ": %s: Whew!  Recovered from %s\n",
+				ioc->name,
+				statefault==1 ? "stuck handshake" : "IOC FAULT");
+	}
+
+	return hard_reset_done;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
  *	GetIocState - Get the current state of a MPT adapter.
  *	@ioc: Pointer to MPT_ADAPTER structure
  *	@cooked: Request raw or cooked IOC state
@@ -1471,7 +1714,7 @@
 	int			 reply_sz;
 	u32			 status;
 
-	/*  IOC *must* NOT be in RESET state!  */
+	/* IOC *must* NOT be in RESET state! */
 	if (ioc->last_state == MPI_IOC_STATE_RESET) {
 		printk(KERN_ERR MYNAM ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
 				ioc->name,
@@ -1479,44 +1722,45 @@
 		return -44;
 	}
 
-	facts = &ioc->facts0;
-	/*  Nth (2,3,...) time thru? (been here, done that?)  */
-	if (ioc->facts0.Function == MPI_FUNCTION_IOC_FACTS) {
-		facts = &ioc->factsN;
-	}
+	facts = &ioc->facts;
 
-	/*  Destination (reply area)...  */
+	/* Destination (reply area)... */
 	reply_sz = sizeof(*facts);
 	memset(facts, 0, reply_sz);
 
-	/*  Request area (get_facts on the stack right now!)  */
+	/* Request area (get_facts on the stack right now!) */
 	req_sz = sizeof(get_facts);
 	memset(&get_facts, 0, req_sz);
 
 	get_facts.Function = MPI_FUNCTION_IOC_FACTS;
-	/*  Assert: All other get_facts fields are zero!  */
+	/* Assert: All other get_facts fields are zero! */
 
-	dprintk((KERN_INFO MYNAM ": %s: Sending IocFacts%s request\n",
-			ioc->name, facts == &ioc->facts0 ? "0" : "N" ));
+	dprintk((KERN_INFO MYNAM ": %s: Sending get IocFacts request\n", ioc->name));
 
 	/* No non-zero fields in the get_facts request are greater than
 	 * 1 byte in size, so we can just fire it off as is.
 	 */
 	r = HandShakeReqAndReply(ioc,
 			req_sz, (u32*)&get_facts,
-			reply_sz, (u16*)facts);
+			reply_sz, (u16*)facts, 3);
 	if (r != 0)
 		return r;
 
 	/*
-	 *  Now byte swap the necessary fields before any further
-	 *  inspection of reply contents.
+	 * Now byte swap (GRRR) the necessary fields before any further
+	 * inspection of reply contents.
 	 *
-	 *  But need to do some sanity checks on MsgLength (byte) field
-	 *  to make sure we don't zero IOC's req_sz!
+	 * But need to do some sanity checks on MsgLength (byte) field
+	 * to make sure we don't zero IOC's req_sz!
 	 */
 	/* Did we get a valid reply? */
 	if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
+		/*
+		 * If not been here, done that, save off first WhoInit value
+		 */
+		if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
+			ioc->FirstWhoInit = facts->WhoInit;
+
 		facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
 		facts->MsgContext = le32_to_cpu(facts->MsgContext);
 		facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
@@ -1537,9 +1781,9 @@
 				le16_to_cpu(facts->CurReplyFrameSize);
 
 		/*
-		 *  Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
-		 *  Older MPI-1.00.xx struct had 13 dwords, and enlarged
-		 *  to 14 in MPI-1.01.0x.
+		 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
+		 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
+		 * to 14 in MPI-1.01.0x.
 		 */
 		if (facts->MsgLength >= sizeof(IOCFactsReply_t)/sizeof(u32) && facts->MsgVersion > 0x0100) {
 			facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
@@ -1548,7 +1792,7 @@
 
 		if (facts->RequestFrameSize) {
 			/*
-			 *  Set values for this IOC's REQUEST queue size & depth...
+			 * Set values for this IOC's REQUEST queue size & depth...
 			 */
 			ioc->req_sz = MIN(MPT_REQ_SIZE, facts->RequestFrameSize * 4);
 
@@ -1582,8 +1826,8 @@
 		dprintk((KERN_INFO MYNAM ": %s: req_sz  =%3d, req_depth  =%4d\n",
 				ioc->name, ioc->req_sz, ioc->req_depth));
 
-		/*  Get port facts!  */
-		if ( (r = GetPortFacts(ioc)) != 0 )
+		/* Get port facts! */
+		if ( (r = GetPortFacts(ioc, 0)) != 0 )
 			return r;
 	} else {
 		printk(KERN_ERR MYNAM ": %s: ERROR - Invalid IOC facts reply!\n",
@@ -1598,11 +1842,12 @@
 /*
  *	GetPortFacts - Send PortFacts request to MPT adapter.
  *	@ioc: Pointer to MPT_ADAPTER structure
+ *	@portnum: Port number
  *
  *	Returns 0 for success, non-zero for failure.
  */
 static int
-GetPortFacts(MPT_ADAPTER *ioc)
+GetPortFacts(MPT_ADAPTER *ioc, int portnum)
 {
 	PortFacts_t		 get_pfacts;
 	PortFactsReply_t	*pfacts;
@@ -1610,7 +1855,7 @@
 	int			 req_sz;
 	int			 reply_sz;
 
-	/*  IOC *must* NOT be in RESET state!  */
+	/* IOC *must* NOT be in RESET state! */
 	if (ioc->last_state == MPI_IOC_STATE_RESET) {
 		printk(KERN_ERR MYNAM ": ERROR - Can't get PortFacts, %s NOT READY! (%08x)\n",
 				ioc->name,
@@ -1618,31 +1863,28 @@
 		return -4;
 	}
 
-	pfacts = &ioc->pfacts0;
-	/*  Nth (2,3,...) time thru? (been here, done that?)  */
-	if (ioc->pfacts0.Function == MPI_FUNCTION_PORT_FACTS) {
-		pfacts = &ioc->pfactsN;
-	}
+	pfacts = &ioc->pfacts[portnum];
 
-	/*  Destination (reply area)...  */
+	/* Destination (reply area)...  */
 	reply_sz = sizeof(*pfacts);
 	memset(pfacts, 0, reply_sz);
 
-	/*  Request area (get_pfacts on the stack right now!)  */
+	/* Request area (get_pfacts on the stack right now!) */
 	req_sz = sizeof(get_pfacts);
 	memset(&get_pfacts, 0, req_sz);
 
 	get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
-	/*  Assert: All other get_pfacts fields are zero!  */
+	get_pfacts.PortNumber = portnum;
+	/* Assert: All other get_pfacts fields are zero! */
 
-	dprintk((KERN_INFO MYNAM ": %s: Sending PortFacts%s request\n",
-			ioc->name, pfacts == &ioc->pfacts0 ? "0" : "N" ));
+	dprintk((KERN_INFO MYNAM ": %s: Sending get PortFacts(%d) request\n",
+			ioc->name, portnum));
 
 	/* No non-zero fields in the get_pfacts request are greater than
 	 * 1 byte in size, so we can just fire it off as is.
 	 */
 	i = HandShakeReqAndReply(ioc, req_sz, (u32*)&get_pfacts,
-				reply_sz, (u16*)pfacts);
+				reply_sz, (u16*)pfacts, 3);
 	if (i != 0)
 		return i;
 
@@ -1702,7 +1944,7 @@
 	dprintk((KERN_INFO MYNAM ": %s: Sending IOCInit (req @ %p)\n", ioc->name, &ioc_init));
 
 	r = HandShakeReqAndReply(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
-			sizeof(MPIDefaultReply_t), (u16*)&init_reply);
+			sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10);
 	if (r != 0)
 		return r;
 
@@ -1775,7 +2017,7 @@
 			ioc->name, portnum, &port_enable));
 
 	i = HandShakeReqAndReply(ioc, req_sz, (u32*)&port_enable,
-			reply_sz, (u16*)&reply_buf);
+			reply_sz, (u16*)&reply_buf, 65);
 	if (i != 0)
 		return i;
 
@@ -1790,24 +2032,28 @@
 /*
  *	KickStart - Perform hard reset of MPT adapter.
  *	@ioc: Pointer to MPT_ADAPTER structure
+ *	@force: Force hard reset
  *
  *	This routine places MPT adapter in diagnostic mode via the
  *	WriteSequence register, and then performs a hard reset of adapter
  *	via the Diagnostic register.
  *
- *	Returns 0 for success, non-zero for failure.
+ *	Returns 0 for soft reset success, 1 for hard reset success,
+ *	else a negative value for failure.
  */
 static int
-KickStart(MPT_ADAPTER *ioc)
+KickStart(MPT_ADAPTER *ioc, int force)
 {
-	int r;
+	int hard_reset_done = 0;
 	u32 ioc_state;
 	int cnt = 0;
 
 	dprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
 
-	if (ioc->chip_type == FC909) {
-		r = mpt_fc9x9_reset(ioc);
+	hard_reset_done = mpt_fc9x9_reset(ioc, force);
+#if 0
+	if (ioc->chip_type == FC909 || ioc->chip-type == FC919) {
+		hard_reset_done = mpt_fc9x9_reset(ioc, force);
 	} else if (ioc->chip_type == FC929) {
 		unsigned long delta;
 
@@ -1815,15 +2061,12 @@
 		dprintk((KERN_INFO MYNAM ": %s: 929 KickStart, last=%ld, delta = %ld\n",
 				ioc->name, ioc->last_kickstart, delta));
 		if ((ioc->sod_reset == 0) || (delta >= 10*HZ))
-			r = mpt_fc9x9_reset(ioc);
+			hard_reset_done = mpt_fc9x9_reset(ioc, ignore);
 		else {
 			dprintk((KERN_INFO MYNAM ": %s: Skipping KickStart (delta=%ld)!\n",
 					ioc->name, delta));
 			return 0;
 		}
-	/* TODO! Add FC919!
-	} else if (ioc->chip_type == FC919) {
-	 */
 	/* TODO! Add C1030!
 	} else if (ioc->chip_type == C1030) {
 	 */
@@ -1832,9 +2075,10 @@
 				ioc->name, ioc->chip_type);
 		return -5;
 	}
+#endif
 
-	if (r != 0)
-		return -r;
+	if (hard_reset_done < 0)
+		return hard_reset_done;
 
 	dprintk((KERN_INFO MYNAM ": %s: Diagnostic reset successful\n",
 			ioc->name));
@@ -1843,7 +2087,7 @@
 		if ((ioc_state = GetIocState(ioc, 1)) == MPI_IOC_STATE_READY) {
 			dprintk((KERN_INFO MYNAM ": %s: KickStart successful! (cnt=%d)\n",
 					ioc->name, cnt));
-			return 0;
+			return hard_reset_done;
 		}
 		/* udelay(10000) ? */
 		current->state = TASK_INTERRUPTIBLE;
@@ -1867,52 +2111,112 @@
  *	Returns 0 for success, non-zero for failure.
  */
 static int
-mpt_fc9x9_reset(MPT_ADAPTER *ioc)
+mpt_fc9x9_reset(MPT_ADAPTER *ioc, int ignore)
 {
-	u32 diagval;
+	u32 diag0val;
+	int hard_reset_done = 0;
 
 	/* Use "Diagnostic reset" method! (only thing available!) */
 
-	/*
-	 * Extra read to handle 909 B.0 chip problem with reset
-	 * logic not finishing the RAM access before hard reset hits.
-	 * (? comment taken from NT SYMMPI source)
-	 */
-	(void) CHIPREG_READ32(&ioc->chip->Fubar);
+	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+#ifdef MPT_DEBUG
+{
+	u32 diag1val = 0;
+	if (ioc->alt_ioc)
+		diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+	dprintk((KERN_INFO MYNAM ": %s: DBG1: diag0=%08x, diag1=%08x\n",
+			ioc->name, diag0val, diag1val));
+}
+#endif
+	if (diag0val & MPI_DIAG_DRWE) {
+		dprintk((KERN_INFO MYNAM ": %s: DiagWriteEn bit already set\n",
+				ioc->name));
+	} else {
+		/* Write magic sequence to WriteSequence register */
+		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
+		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
+		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
+		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
+		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
+		dprintk((KERN_INFO MYNAM ": %s: Wrote magic DiagWriteEn sequence [spot#1]\n",
+				ioc->name));
+	}
 
-	/*
-	 * Write magic sequence to WriteSequence register.
-	 * But, send 0x0F first to insure a reset to the beginning of the sequence.
-	 */
-	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_KEY_VALUE_MASK);
+	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+#ifdef MPT_DEBUG
+{
+	u32 diag1val = 0;
+	if (ioc->alt_ioc)
+		diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+	dprintk((KERN_INFO MYNAM ": %s: DbG2: diag0=%08x, diag1=%08x\n",
+			ioc->name, diag0val, diag1val));
+}
+#endif
+	if (!ignore && (diag0val & MPI_DIAG_RESET_HISTORY)) {
+		dprintk((KERN_INFO MYNAM ": %s: Skipping due to ResetHistory bit set!\n",
+				ioc->name));
+	} else {
+		/*
+		 * Now hit the reset bit in the Diagnostic register
+		 * (THE BIG HAMMER!)
+		 */
+		CHIPREG_WRITE32(&ioc->chip->Diagnostic, MPI_DIAG_RESET_ADAPTER);
+		hard_reset_done = 1;
+		dprintk((KERN_INFO MYNAM ": %s: Diagnostic reset performed\n",
+				ioc->name));
 
-	/* Now write magic sequence */
-	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
-	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
-	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
-	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
-	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
-	dprintk((KERN_INFO MYNAM ": %s: Wrote magic DiagWriteEn sequence\n",
-			ioc->name));
+		/* want udelay(100) */
+		current->state = TASK_INTERRUPTIBLE;
+		schedule_timeout(1);
 
-	/* Now hit the reset bit in the Diagnostic register */
-	CHIPREG_WRITE32(&ioc->chip->Diagnostic, MPI_DIAG_RESET_ADAPTER);
+		/* Write magic sequence to WriteSequence register */
+		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
+		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
+		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
+		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
+		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
+		dprintk((KERN_INFO MYNAM ": %s: Wrote magic DiagWriteEn sequence [spot#2]\n",
+				ioc->name));
+	}
 
-	udelay(100);
+	/* Clear RESET_HISTORY bit! */
+	CHIPREG_WRITE32(&ioc->chip->Diagnostic, 0x0);
 
-	if ((diagval = CHIPREG_READ32(&ioc->chip->Diagnostic)) &
-				(MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_DISABLE_ARM)) {
-		printk(KERN_ERR MYNAM ": %s: ERROR - Diagnostic reset FAILED!\n",
+	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+#ifdef MPT_DEBUG
+{
+	u32 diag1val = 0;
+	if (ioc->alt_ioc)
+		diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+	dprintk((KERN_INFO MYNAM ": %s: DbG3: diag0=%08x, diag1=%08x\n",
+			ioc->name, diag0val, diag1val));
+}
+#endif
+	if (diag0val & MPI_DIAG_RESET_HISTORY) {
+		printk(KERN_WARNING MYNAM ": %s: WARNING - ResetHistory bit failed to clear!\n",
 				ioc->name);
-		return -9;
 	}
 
-	/* TODO!
-	 * Cleanup all event stuff for this IOC;
-	 * re-issue EventNotification request if needed.
+	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+#ifdef MPT_DEBUG
+{
+	u32 diag1val = 0;
+	if (ioc->alt_ioc)
+		diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+	dprintk((KERN_INFO MYNAM ": %s: DbG4: diag0=%08x, diag1=%08x\n",
+			ioc->name, diag0val, diag1val));
+}
+#endif
+	if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
+		printk(KERN_ERR MYNAM ": %s: ERROR - Diagnostic reset FAILED! (%02xh)\n",
+				ioc->name, diag0val);
+		return -3;
+	}
+
+	/*
+	 * Reset flag that says we've enabled event notification
 	 */
-	if (ioc->factsN.Function)
-		ioc->factsN.EventState = 0;
+	ioc->facts.EventState = 0;
 
 	/* NEW!  20010220 -sralston
 	 * Try to avoid redundant resets of the 929.
@@ -1924,7 +2228,7 @@
 		ioc->alt_ioc->last_kickstart = ioc->last_kickstart;
 	}
 
-	return 0;
+	return hard_reset_done;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1943,18 +2247,18 @@
 {
 	int r;
 
-	printk(KERN_WARNING MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
-			ioc->name, reset_type);
+	dprintk((KERN_WARNING MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
+			ioc->name, reset_type));
 	CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
-	if ((r = WaitForDoorbellAck(ioc)) < 0)
+	if ((r = WaitForDoorbellAck(ioc, 2)) < 0)
 		return r;
 
 	/* TODO!
 	 *  Cleanup all event stuff for this IOC; re-issue EventNotification
 	 *  request if needed.
 	 */
-	if (ioc->factsN.Function)
-		ioc->factsN.EventState = 0;
+	if (ioc->facts.Function)
+		ioc->facts.EventState = 0;
 
 	return 0;
 }
@@ -2125,6 +2429,7 @@
  *	@req: Pointer to MPT request frame
  *	@replyBytes: Expected size of the reply in bytes
  *	@u16reply: Pointer to area where reply should be written
+ *	@maxwait: Max wait time for a reply (in seconds)
  *
  *	NOTES: It is the callers responsibility to byte-swap fields in the
  *	request which are greater than 1 byte in size.  It is also the
@@ -2134,7 +2439,7 @@
  *	Returns 0 for success, non-zero for failure.
  */
 static int
-HandShakeReqAndReply(MPT_ADAPTER *ioc, int reqBytes, u32 *req, int replyBytes, u16 *u16reply)
+HandShakeReqAndReply(MPT_ADAPTER *ioc, int reqBytes, u32 *req, int replyBytes, u16 *u16reply, int maxwait)
 {
 	MPIDefaultReply_t *mptReply;
 	int failcnt = 0;
@@ -2160,7 +2465,7 @@
 	/*
 	 * Wait for IOC's doorbell handshake int
 	 */
-	if ((t = WaitForDoorbellInt(ioc)) < 0)
+	if ((t = WaitForDoorbellInt(ioc, 2)) < 0)
 		failcnt++;
 
 	dhsprintk((KERN_INFO MYNAM ": %s: HandShake request start, WaitCnt=%d%s\n",
@@ -2172,7 +2477,7 @@
 	 * our handshake request.
 	 */
 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
-	if (!failcnt && (t = WaitForDoorbellAck(ioc)) < 0)
+	if (!failcnt && (t = WaitForDoorbellAck(ioc, 2)) < 0)
 		failcnt++;
 
 	if (!failcnt) {
@@ -2190,7 +2495,7 @@
 				    (req_as_bytes[(i*4) + 3] << 24));
 
 			CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
-			if ((t = WaitForDoorbellAck(ioc)) < 0)
+			if ((t = WaitForDoorbellAck(ioc, 2)) < 0)
 				failcnt++;
 		}
 
@@ -2203,7 +2508,7 @@
 		/*
 		 * Wait for completion of doorbell handshake reply from the IOC
 		 */
-		if (!failcnt && (t = WaitForDoorbellReply(ioc)) < 0)
+		if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait)) < 0)
 			failcnt++;
 
 		/*
@@ -2223,16 +2528,17 @@
  *	WaitForDoorbellAck - Wait for IOC to clear the IOP_DOORBELL_STATUS bit
  *	in it's IntStatus register.
  *	@ioc: Pointer to MPT_ADAPTER structure
+ *	@howlong: How long to wait (in seconds)
  *
- *	This routine waits (up to ~30 seconds max) for IOC doorbell
+ *	This routine waits (up to ~2 seconds max) for IOC doorbell
  *	handshake ACKnowledge.
  *
  *	Returns a negative value on failure, else wait loop count.
  */
 static int
-WaitForDoorbellAck(MPT_ADAPTER *ioc)
+WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong)
 {
-	int cntdn = HZ * 30;			/* ~30 seconds */
+	int cntdn = HZ * howlong;
 	int count = 0;
 	u32 intstat;
 
@@ -2261,15 +2567,16 @@
  *	WaitForDoorbellInt - Wait for IOC to set the HIS_DOORBELL_INTERRUPT bit
  *	in it's IntStatus register.
  *	@ioc: Pointer to MPT_ADAPTER structure
+ *	@howlong: How long to wait (in seconds)
  *
- *	This routine waits (up to ~30 seconds max) for IOC doorbell interrupt.
+ *	This routine waits (up to ~2 seconds max) for IOC doorbell interrupt.
  *
  *	Returns a negative value on failure, else wait loop count.
  */
 static int
-WaitForDoorbellInt(MPT_ADAPTER *ioc)
+WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong)
 {
-	int cntdn = HZ * 30;			/* ~30 seconds */
+	int cntdn = HZ * howlong;
 	int count = 0;
 	u32 intstat;
 
@@ -2297,6 +2604,7 @@
 /*
  *	WaitForDoorbellReply - Wait for and capture a IOC handshake reply.
  *	@ioc: Pointer to MPT_ADAPTER structure
+ *	@howlong: How long to wait (in seconds)
  *
  *	This routine polls the IOC for a handshake reply, 16 bits at a time.
  *	Reply is cached to IOC private area large enough to hold a maximum
@@ -2305,7 +2613,7 @@
  *	Returns a negative value on failure, else size of reply in WORDS.
  */
 static int
-WaitForDoorbellReply(MPT_ADAPTER *ioc)
+WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong)
 {
 	int u16cnt = 0;
 	int failcnt = 0;
@@ -2319,11 +2627,18 @@
 	/*
 	 * Get first two u16's so we can look at IOC's intended reply MsgLength
 	 */
-	for (u16cnt=0; !failcnt && u16cnt < 2; u16cnt++) {
-		if ((t = WaitForDoorbellInt(ioc)) < 0)
-			failcnt++;
-		hs_reply[u16cnt] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
+	u16cnt=0;
+	if ((t = WaitForDoorbellInt(ioc, howlong)) < 0) {
+		failcnt++;
+	} else {
+		hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
 		CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
+		if ((t = WaitForDoorbellInt(ioc, 2)) < 0)
+			failcnt++;
+		else {
+			hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
+			CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
+		}
 	}
 
 	dhsprintk((KERN_INFO MYNAM ": %s: First handshake reply word=%08x%s\n",
@@ -2335,7 +2650,7 @@
 	 * reply 16 bits at a time.
 	 */
 	for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
-		if ((t = WaitForDoorbellInt(ioc)) < 0)
+		if ((t = WaitForDoorbellInt(ioc, 2)) < 0)
 			failcnt++;
 		hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
 		/* don't overflow our IOC hs_reply[] buffer! */
@@ -2344,7 +2659,7 @@
 		CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
 	}
 
-	if (!failcnt && (t = WaitForDoorbellInt(ioc)) < 0)
+	if (!failcnt && (t = WaitForDoorbellInt(ioc, 2)) < 0)
 		failcnt++;
 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
 
@@ -2428,7 +2743,7 @@
 			ioc->name));
 
 	i = HandShakeReqAndReply(ioc, req_sz, (u32*)&config_req,
-				reply_sz, (u16*)&config_reply);
+				reply_sz, (u16*)&config_reply, 3);
 	pci_unmap_single(ioc->pcidev, page0_dma, data_sz, PCI_DMA_FROMDEVICE);
 	if (i != 0)
 		return i;
@@ -2472,7 +2787,7 @@
 			ioc->name));
 
 	i = HandShakeReqAndReply(ioc, req_sz, (u32*)&config_req,
-				reply_sz, (u16*)&config_reply);
+				reply_sz, (u16*)&config_reply, 3);
 	pci_unmap_single(ioc->pcidev, page1_dma, data_sz, PCI_DMA_FROMDEVICE);
 	if (i != 0)
 		return i;
@@ -2564,7 +2879,6 @@
 	return len;			\
 }
 
-
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *	procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
@@ -2653,6 +2967,9 @@
 {
 	MPT_ADAPTER *ioc;
 
+	if (!procmpt_root_dir)
+		return 0;
+
 	/*
 	 * 	BEWARE: If/when MPT_PROCFS_MPTBASEDIR changes from "mpt"
 	 * 	(single level) to multi level (e.g. "driver/message/fusion")
@@ -2685,6 +3002,7 @@
 
 	if (atomic_read((atomic_t *)&procmpt_root_dir->count) == 0) {
 		remove_proc_entry(MPT_PROCFS_MPTBASEDIR, 0);
+		procmpt_root_dir = NULL;
 		return 0;
 	}
 
@@ -2724,7 +3042,7 @@
 
 // Too verbose!
 //		mpt_print_ioc_facts(ioc, out, &more, 0);
-		mpt_print_ioc_summary(ioc, out, &more, 0);
+		mpt_print_ioc_summary(ioc, out, &more, 0, 1);
 
 		out += more;
 		if ((out-page) >= count) {
@@ -2784,15 +3102,15 @@
 static void
 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
 {
-	if ((ioc->facts0.FWVersion & 0xF000) == 0xE000)
+	if ((ioc->facts.FWVersion & 0xF000) == 0xE000)
 		sprintf(buf, " (Exp %02d%02d)",
-			(ioc->facts0.FWVersion & 0x0F00) >> 8,	/* Month */
-			ioc->facts0.FWVersion & 0x001F);	/* Day */
+			(ioc->facts.FWVersion & 0x0F00) >> 8,	/* Month */
+			ioc->facts.FWVersion & 0x001F);		/* Day */
 	else
 		buf[0] ='\0';
 
 	/* insider hack! */
-	if (ioc->facts0.FWVersion & 0x0080) {
+	if (ioc->facts.FWVersion & 0x0080) {
 		strcat(buf, " [MDBG]");
 	}
 }
@@ -2804,17 +3122,17 @@
  *	@buffer: Pointer to buffer where IOC summary info should be written
  *	@size: Pointer to number of bytes we wrote (set by this routine)
  *	@len: Offset at which to start writing in buffer
+ *	@showlan: Display LAN stuff?
  *
  * 	This routine writes (english readable) ASCII text, which represents
  * 	a summary of IOC information, to a buffer.
  */
 void
-mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len)
+mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
 {
 	char expVer[32];
 	int y;
 
-
 	mpt_get_fw_exp_ver(expVer, ioc);
 
 	/*
@@ -2824,17 +3142,20 @@
 			ioc->name,
 			ioc->prod_name,
 			MPT_FW_REV_MAGIC_ID_STRING,	/* "FwRev=" or somesuch */
-			ioc->facts0.FWVersion,
+			ioc->facts.FWVersion,
 			expVer,
-			ioc->facts0.NumberOfPorts,
+			ioc->facts.NumberOfPorts,
 			ioc->req_depth);
 
-	if (ioc->pfacts0.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
+	if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
 		u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
 		y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
 			a[5], a[4], a[3], a[2], a[1], a[0]);
 	}
 
+	if (ioc->pci_irq < 100)
+		y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
+
 	if (!ioc->active)
 		y += sprintf(buffer+len+y, " (disabled)");
 
@@ -2861,32 +3182,34 @@
 	char iocName[16];
 	int sz;
 	int y;
-
+	int p;
 
 	mpt_get_fw_exp_ver(expVer, ioc);
 
 	strcpy(iocName, ioc->name);
 	y = sprintf(buffer+len, "%s:\n", iocName);
 
-	y += sprintf(buffer+len+y, "  ProductID = 0x%04x\n", ioc->facts0.ProductID);
-	y += sprintf(buffer+len+y, "  PortNumber = %d (of %d)\n",
-		ioc->pfacts0.PortNumber+1,
-		ioc->facts0.NumberOfPorts);
-	if (ioc->pfacts0.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
-		u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
-		y += sprintf(buffer+len+y, "  LanAddr = 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
-			a[5], a[4], a[3], a[2], a[1], a[0]);
+	y += sprintf(buffer+len+y, "  ProductID = 0x%04x\n", ioc->facts.ProductID);
+	for (p=0; p < ioc->facts.NumberOfPorts; p++) {
+		y += sprintf(buffer+len+y, "  PortNumber = %d (of %d)\n",
+			p+1,
+			ioc->facts.NumberOfPorts);
+		if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
+			u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
+			y += sprintf(buffer+len+y, "  LanAddr = 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
+				a[5], a[4], a[3], a[2], a[1], a[0]);
+		}
 	}
-	y += sprintf(buffer+len+y, "  FWVersion = 0x%04x%s\n", ioc->facts0.FWVersion, expVer);
-	y += sprintf(buffer+len+y, "  MsgVersion = 0x%04x\n", ioc->facts0.MsgVersion);
-	y += sprintf(buffer+len+y, "  WhoInit = 0x%02x\n", ioc->facts0.WhoInit);
-	y += sprintf(buffer+len+y, "  EventState = 0x%02x\n", ioc->facts0.EventState);
+	y += sprintf(buffer+len+y, "  FWVersion = 0x%04x%s\n", ioc->facts.FWVersion, expVer);
+	y += sprintf(buffer+len+y, "  MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
+	y += sprintf(buffer+len+y, "  FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
+	y += sprintf(buffer+len+y, "  EventState = 0x%02x\n", ioc->facts.EventState);
 	y += sprintf(buffer+len+y, "  CurrentHostMfaHighAddr = 0x%08x\n",
-		 	ioc->facts0.CurrentHostMfaHighAddr);
+		 	ioc->facts.CurrentHostMfaHighAddr);
 	y += sprintf(buffer+len+y, "  CurrentSenseBufferHighAddr = 0x%08x\n",
-			ioc->facts0.CurrentSenseBufferHighAddr);
-	y += sprintf(buffer+len+y, "  MaxChainDepth = 0x%02x frames\n", ioc->facts0.MaxChainDepth);
-	y += sprintf(buffer+len+y, "  MinBlockSize = 0x%02x bytes\n", 4*ioc->facts0.BlockSize);
+			ioc->facts.CurrentSenseBufferHighAddr);
+	y += sprintf(buffer+len+y, "  MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
+	y += sprintf(buffer+len+y, "  MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
 
 	y += sprintf(buffer+len+y, "  RequestFrames @ 0x%p (Dma @ 0x%08x)\n",
 					ioc->req_alloc, ioc->req_alloc_dma);
@@ -2898,8 +3221,8 @@
 	y += sprintf(buffer+len+y, "    {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
 					ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
 	y += sprintf(buffer+len+y, "    {MaxReqSz=%d}   {MaxReqDepth=%d}\n",
-					4*ioc->facts0.RequestFrameSize,
-					ioc->facts0.GlobalCredits);
+					4*ioc->facts.RequestFrameSize,
+					ioc->facts.GlobalCredits);
 
 	y += sprintf(buffer+len+y, "  ReplyFrames   @ 0x%p (Dma @ 0x%08x)\n",
 					ioc->reply_alloc, ioc->reply_alloc_dma);
@@ -2907,8 +3230,8 @@
 	y += sprintf(buffer+len+y, "    {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
 					ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
 	y += sprintf(buffer+len+y, "    {MaxRepSz=%d}   {MaxRepDepth=%d}\n",
-					ioc->factsN.CurReplyFrameSize,
-					ioc->facts0.ReplyQueueDepth);
+					ioc->facts.CurReplyFrameSize,
+					ioc->facts.ReplyQueueDepth);
 
 	*size = y;
 }
@@ -3045,8 +3368,8 @@
 			/* CHECKME! What if evState unexpectedly says OFF (0)? */
 
 			/* Update EventState field in cached IocFacts */
-			if (ioc->factsN.Function) {
-				ioc->factsN.EventState = evState;
+			if (ioc->facts.Function) {
+				ioc->facts.EventState = evState;
 			}
 		}
 		break;
@@ -3182,6 +3505,9 @@
 	case MPI_IOCLOGINFO_FC_LINK_LINK_NOT_ESTABLISHED:
 		desc = "Not synchronized to signal or still negotiating (possible cable problem)";
 		break;
+	case MPI_IOCLOGINFO_FC_LINK_CRC_ERROR:
+		desc = "CRC check detected error on received frame";
+		break;
 	}
 
 	printk(KERN_INFO MYNAM ": %s: LogInfo(0x%08x): SubCl={%s}",
@@ -3259,6 +3585,8 @@
 EXPORT_SYMBOL(mpt_deregister);
 EXPORT_SYMBOL(mpt_event_register);
 EXPORT_SYMBOL(mpt_event_deregister);
+EXPORT_SYMBOL(mpt_reset_register);
+EXPORT_SYMBOL(mpt_reset_deregister);
 EXPORT_SYMBOL(mpt_get_msg_frame);
 EXPORT_SYMBOL(mpt_put_msg_frame);
 EXPORT_SYMBOL(mpt_free_msg_frame);
@@ -3299,6 +3627,7 @@
 		MptCallbacks[i] = NULL;
 		MptDriverClass[i] = MPTUNKNOWN_DRIVER;
 		MptEvHandlers[i] = NULL;
+		MptResetHandlers[i] = NULL;
 	}
 
 	/* NEW!  20010120 -sralston
@@ -3323,22 +3652,8 @@
 static void fusion_exit(void)
 {
 	MPT_ADAPTER *this;
-	int i;
 
 	dprintk((KERN_INFO MYNAM ": fusion_exit() called!\n"));
-
-	/*
-	 *  Paranoia; disable interrupts on all MPT adapters.
-	 */
-	for (i=0; i<MPT_MAX_ADAPTERS; i++) {
-		if ((this = mpt_adapters[i]) != NULL) {
-			/* Disable adapter interrupts! */
-			CHIPREG_WRITE32(&this->chip->IntMask, 0xFFFFFFFF);
-			/* Clear any lingering interrupt */
-			CHIPREG_WRITE32(&this->chip->IntStatus, 0);
-			this->active = 0;
-		}
-	}
 
 	/* Whups?  20010120 -sralston
 	 *  Moved this *above* removal of all MptAdapters!
diff -u --recursive --new-file v2.4.9/linux/drivers/message/fusion/mptbase.h linux/drivers/message/fusion/mptbase.h
--- v2.4.9/linux/drivers/message/fusion/mptbase.h	Wed Jul 25 17:10:20 2001
+++ linux/drivers/message/fusion/mptbase.h	Fri Sep  7 09:28:38 2001
@@ -12,7 +12,7 @@
  *  Originally By: Steven J. Ralston
  *  (mailto:Steve.Ralston@lsil.com)
  *
- *  $Id: mptbase.h,v 1.38 2001/03/22 10:54:30 sralston Exp $
+ *  $Id: mptbase.h,v 1.46.2.2.2.1 2001/08/24 20:07:05 sralston Exp $
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -63,8 +63,8 @@
 #include "lsi/mpi_init.h"	/* SCSI Host (initiator) protocol support */
 #include "lsi/mpi_lan.h"	/* LAN over FC protocol support */
 
-//#include "lsi/mpi_fc.h"	/* Fibre Channel (lowlevel) support */
-//#include "lsi/mpi_targ.h"	/* SCSI/FCP Target protcol support */
+#include "lsi/mpi_fc.h"		/* Fibre Channel (lowlevel) support */
+#include "lsi/mpi_targ.h"	/* SCSI/FCP Target protcol support */
 #include "lsi/fc_log.h"
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -77,9 +77,8 @@
 #define COPYRIGHT	"Copyright (c) 1999-2001 " MODULEAUTHOR
 #endif
 
-#define MPT_LINUX_VERSION_COMMON	"1.00.11"
-#define MPT_LINUX_VERSION_EXP		"0.09.66-EXP"
-#define MPT_LINUX_PACKAGE_NAME		"@(#)mptlinux-1.00.11"
+#define MPT_LINUX_VERSION_COMMON	"1.02.01"
+#define MPT_LINUX_PACKAGE_NAME		"@(#)mptlinux-1.02.01"
 #define WHAT_MAGIC_STRING		"@" "(" "#" ")"
 
 #define show_mptmod_ver(s,ver)  \
@@ -91,6 +90,7 @@
  */
 #define MPT_MAX_ADAPTERS		16
 #define MPT_MAX_PROTOCOL_DRIVERS	8
+#define MPT_MAX_FC_DEVICES		255
 
 #define MPT_MISCDEV_BASENAME		"mptctl"
 #define MPT_MISCDEV_PATHNAME		"/dev/" MPT_MISCDEV_BASENAME
@@ -262,8 +262,6 @@
 	struct _MPT_ADAPTER	*back;
 	int			 id;		/* Unique adapter id {0,1,2,...} */
 	int			 pci_irq;
-	IOCFactsReply_t		 facts0;
-	IOCFactsReply_t		 factsN;
 	char			 name[32];	/* "iocN"             */
 	char			*prod_name;	/* "LSIFC9x9"         */
 	u32			 mem_phys;	/* == f4020000 (mmap) */
@@ -275,10 +273,6 @@
 	int			 active;
 	int			 sod_reset;
 	unsigned long		 last_kickstart;
-	PortFactsReply_t	 pfacts0;
-	PortFactsReply_t	 pfactsN;
-	LANPage0_t		 lan_cnfg_page0;
-	LANPage1_t		 lan_cnfg_page1;
 	u8			*reply_alloc;		/* Reply frames alloc ptr */
 	dma_addr_t		 reply_alloc_dma;
 	MPT_FRAME_HDR		*reply_frames;		/* Reply frames - rounded up! */
@@ -292,24 +286,30 @@
 	dma_addr_t		 req_frames_dma;
 	int			 req_depth;
 	int			 req_sz;
-	spinlock_t		 FreeQlock;
 	MPT_Q_TRACKER		 FreeQ;
+	spinlock_t		 FreeQlock;
 		/* Pool of SCSI sense buffers for commands coming from
 		 * the SCSI mid-layer.  We have one 256 byte sense buffer
 		 * for each REQ entry.
 		 */
 	u8			*sense_buf_pool;
 	dma_addr_t		 sense_buf_pool_dma;
-	int			 hs_reply_idx;
-	u32			 hs_req[MPT_MAX_FRAME_SIZE/sizeof(u32)];
-	u16			 hs_reply[MPT_MAX_FRAME_SIZE/sizeof(u16)];
 	struct pci_dev		*pcidev;
-	struct _MPT_ADAPTER	*alt_ioc;
 /*	atomic_t		 userCnt;	*/
 	u8			*memmap;
 	int			 mtrr_reg;
 	struct Scsi_Host	*sh;
 	struct proc_dir_entry	*ioc_dentry;
+	struct _MPT_ADAPTER	*alt_ioc;
+	int			 hs_reply_idx;
+	u32			 hs_req[MPT_MAX_FRAME_SIZE/sizeof(u32)];
+	u16			 hs_reply[MPT_MAX_FRAME_SIZE/sizeof(u16)];
+	IOCFactsReply_t		 facts;
+	PortFactsReply_t	 pfacts[2];
+	LANPage0_t		 lan_cnfg_page0;
+	LANPage1_t		 lan_cnfg_page1;
+	u8			 FirstWhoInit;
+	u8			 pad1[3];
 } MPT_ADAPTER;
 
 
@@ -324,26 +324,25 @@
  *    0 = not Ok ...
  */
 typedef int (*MPT_CALLBACK)(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
-typedef int (*MPT_EVHANDLER)(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply);
 
-/*
- *  Fibre Channel (SCSI) target device...
- */
-typedef struct _FC_TARGET {
-	struct _FC_TARGET	*forw;
-	struct _FC_TARGET	*back;
-	int			 bus_id;
-	int			 target_id;
-	int			 lun_exists[32];
-	u8			 inquiry_data[36];
-	u8			 last_sense[256];
-} FC_TARGET;
-
-typedef struct _FCDEV_TRACKER {
-	FC_TARGET	*head;
-	FC_TARGET	*tail;
-} FCDEV_TRACKER;
+typedef int (*MPT_EVHANDLER)(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply);
+typedef int (*MPT_RESETHANDLER)(MPT_ADAPTER *ioc, int reset_phase);
+/* reset_phase defs */
+#define MPT_IOC_PRE_RESET		0
+#define MPT_IOC_POST_RESET		1
+
+/*
+ * Invent MPT host event (super-set of MPI Events)
+ * Fitted to 1030's 64-byte [max] request frame size
+ */
+typedef struct _MPT_HOST_EVENT {
+	EventNotificationReply_t	 MpiEvent;	/* 8 32-bit words! */
+	u32				 pad[6];
+	void				*next;
+} MPT_HOST_EVENT;
 
+#define MPT_HOSTEVENT_IOC_BRINGUP	0x91
+#define MPT_HOSTEVENT_IOC_RECOVER	0x92
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -523,6 +522,8 @@
 extern void	 mpt_deregister(int cb_idx);
 extern int	 mpt_event_register(int cb_idx, MPT_EVHANDLER ev_cbfunc);
 extern void	 mpt_event_deregister(int cb_idx);
+extern int	 mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func);
+extern void	 mpt_reset_deregister(int cb_idx);
 extern int	 mpt_register_ascqops_strings(/*ASCQ_Table_t*/void *ascqTable, int ascqtbl_sz, const char **opsTable);
 extern void	 mpt_deregister_ascqops_strings(void);
 extern MPT_FRAME_HDR	*mpt_get_msg_frame(int handle, int iocid);
@@ -532,7 +533,7 @@
 extern int	 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp);
 extern MPT_ADAPTER	*mpt_adapter_find_first(void);
 extern MPT_ADAPTER	*mpt_adapter_find_next(MPT_ADAPTER *prev);
-extern void	 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len);
+extern void	 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len, int showlan);
 extern void	 mpt_print_ioc_facts(MPT_ADAPTER *ioc, char *buf, int *size, int len);
 
 /*
diff -u --recursive --new-file v2.4.9/linux/drivers/message/fusion/mptctl.c linux/drivers/message/fusion/mptctl.c
--- v2.4.9/linux/drivers/message/fusion/mptctl.c	Mon Aug 27 12:41:42 2001
+++ linux/drivers/message/fusion/mptctl.c	Fri Sep  7 09:28:38 2001
@@ -27,7 +27,7 @@
  *  Originally By: Steven J. Ralston, Noah Romer
  *  (mailto:Steve.Ralston@lsil.com)
  *
- *  $Id: mptctl.c,v 1.23 2001/03/21 19:42:31 sralston Exp $
+ *  $Id: mptctl.c,v 1.25.4.1 2001/08/24 20:07:06 sralston Exp $
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -205,6 +205,22 @@
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *  struct file_operations functionality. 
+ *  Members:
+ *	llseek, write, read, ioctl, open, release
+ */
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,9)
+static loff_t
+mptctl_llseek(struct file *file, loff_t offset, int origin)
+{
+	return -ESPIPE;
+}
+#define no_llseek mptctl_llseek
+#endif
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 static ssize_t
 mptctl_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
 {
@@ -335,8 +351,8 @@
 	SGESimple32_t	*sgl;
 	SGESimple32_t	*sgOut, *sgIn;
 	dma_addr_t	 sgl_dma;
-	struct buflist	*buflist;
-	struct buflist	*bl;
+	struct buflist	*buflist = NULL;
+	struct buflist	*bl = NULL;
 	int		 numfrags = 0;
 	int		 maxfrags;
 	int		 n = 0;
@@ -421,7 +437,7 @@
 	sgIn = sgl;
 	bl = buflist;
 	for (i=0; i < numfrags; i++) {
-		nib = (sgIn->FlagsLength & 0xF0000000) >> 28;
+		nib = (le32_to_cpu(sgIn->FlagsLength) & 0xF0000000) >> 28;
 		/* skip ignore/chain. */
 		if (nib == 0 || nib == 3) {
 			;
@@ -654,7 +670,7 @@
 			u8 *kptr;
 			int len;
 
-			if ((sglbuf[i].FlagsLength >> 24) == 0x30)
+			if ((le32_to_cpu(sglbuf[i].FlagsLength) >> 24) == 0x30)
 				continue;
 
 			dma_addr = le32_to_cpu(sglbuf[i].Address);
@@ -679,12 +695,12 @@
 	int		 dir;
 	int		 n = 0;
 
-	if (sg->FlagsLength & 0x04000000)
+	if (le32_to_cpu(sg->FlagsLength) & 0x04000000)
 		dir = PCI_DMA_TODEVICE;
 	else
 		dir = PCI_DMA_FROMDEVICE;
 
-	nib = (sg->FlagsLength & 0xF0000000) >> 28;
+	nib = (le32_to_cpu(sg->FlagsLength) & 0xF0000000) >> 28;
 	while (! (nib & 0x4)) { /* eob */
 		/* skip ignore/chain. */
 		if (nib == 0 || nib == 3) {
@@ -703,7 +719,7 @@
 		}
 		sg++;
 		bl++;
-		nib = (sg->FlagsLength & 0xF0000000) >> 28;
+		nib = (le32_to_cpu(sg->FlagsLength) & 0xF0000000) >> 28;
 	}
 
 	/* we're at eob! */
@@ -1081,10 +1097,14 @@
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 
-static struct file_operations mptctl_fops = {
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,51)
-	owner:		THIS_MODULE,
+#define	owner_THIS_MODULE  owner:		THIS_MODULE,
+#else
+#define	owner_THIS_MODULE
 #endif
+
+static struct file_operations mptctl_fops = {
+	owner_THIS_MODULE
 	llseek:		no_llseek,
 	read:		mptctl_read,
 	write:		mptctl_write,
@@ -1162,48 +1182,6 @@
 	return ret;
 }
 
-#if 0		/* { */
-static int
-sparc32_mptfwxfer_ioctl(unsigned int fd, unsigned int cmd,
-			unsigned long arg, struct file *filp)
-{
-	struct mpt_fw_xfer32 kfw32;
-	struct mpt_fw_xfer kfw;
-	mm_segment_t old_fs;
-	int ret;
-
-	dprintk((KERN_INFO MYNAM "::sparc32_mptfwxfer_ioctl() called\n"));
-
-	if (copy_from_user(&kfw32, (char *)arg, sizeof(kfw32)))
-		return -EFAULT;
-
-	/* Verify intended MPT adapter */
-	iocnumX = kfw32.iocnum & 0xFF;
-	if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
-	    (iocp == NULL)) {
-		printk(KERN_ERR MYNAM "::sparc32_mptfwxfer_ioctl @%d - ioc%d not found!\n",
-				__LINE__, iocnumX);
-		return -ENODEV;
-	}
-
-	if ((ret = mptctl_syscall_down(iocp, nonblock)) != 0)
-		return ret;
-
-	kfw.iocnum = iocnum;
-	kfw.fwlen = kfw32.fwlen;
-	kfw.bufp = (void *)(unsigned long)kfw32.bufp;
-
-	old_fs = get_fs();
-	set_fs(KERNEL_DS);
-	ret = sys_ioctl(fd, MPTFWDOWNLOAD, (unsigned long)&kfw);
-	set_fs(old_fs);
-
-	up(&mptctl_syscall_sem_ioc[iocp->id]);
-
-	return ret;
-}
-#endif		/* #if 0 } */
-
 #endif		/*} linux >= 2.3.x */
 #endif		/*} sparc */
 
@@ -1228,8 +1206,7 @@
 	if (++where && err) goto out_fail;
 	err = register_ioctl32_conversion(MPTRWPERF_RESET, NULL);
 	if (++where && err) goto out_fail;
-	err = register_ioctl32_conversion(MPTFWDOWNLOAD32,
-					  sparc32_mptfwxfer_ioctl);
+	err = register_ioctl32_conversion(MPTFWDOWNLOAD32, sparc32_mptfwxfer_ioctl);
 	if (++where && err) goto out_fail;
 #endif		/*} linux >= 2.3.x */
 #endif		/*} sparc */
@@ -1247,7 +1224,7 @@
 	 *  Install our handler
 	 */
 	++where;
-	if ((mptctl_id = mpt_register(mptctl_reply, MPTCTL_DRIVER)) < 0) {
+	if ((mptctl_id = mpt_register(mptctl_reply, MPTCTL_DRIVER)) <= 0) {
 		printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n");
 		misc_deregister(&mptctl_miscdev);
 		err = -EBUSY;
@@ -1275,6 +1252,16 @@
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 void mptctl_exit(void)
 {
+
+#if defined(__sparc__) && defined(__sparc_v9__)		/*{*/
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)		/*{*/
+	unregister_ioctl32_conversion(MPTRWPERF);
+	unregister_ioctl32_conversion(MPTRWPERF_CHK);
+	unregister_ioctl32_conversion(MPTRWPERF_RESET);
+	unregister_ioctl32_conversion(MPTFWDOWNLOAD32);
+#endif		/*} linux >= 2.3.x */
+#endif		/*} sparc */
+
 	misc_deregister(&mptctl_miscdev);
 	printk(KERN_INFO MYNAM ": /dev/%s @ (major,minor=%d,%d)\n",
 			 mptctl_miscdev.name, MISC_MAJOR, mptctl_miscdev.minor);
diff -u --recursive --new-file v2.4.9/linux/drivers/message/fusion/mptlan.c linux/drivers/message/fusion/mptlan.c
--- v2.4.9/linux/drivers/message/fusion/mptlan.c	Wed Jul 25 17:10:20 2001
+++ linux/drivers/message/fusion/mptlan.c	Fri Sep  7 09:28:38 2001
@@ -26,7 +26,7 @@
  *  Copyright (c) 2000-2001 LSI Logic Corporation
  *  Originally By: Noah Romer
  *
- *  $Id: mptlan.c,v 1.25 2001/03/02 22:12:04 sralston Exp $
+ *  $Id: mptlan.c,v 1.32.2.2 2001/07/12 19:43:33 nromer Exp $
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -93,6 +93,12 @@
  *  Fusion MPT LAN private structures
  */
 
+struct NAA_Hosed {
+	u16 NAA;
+	u8 ieee[FC_ALEN];
+	struct NAA_Hosed *next;
+};
+
 struct BufferControl {
 	struct sk_buff	*skb;
 	dma_addr_t	dma;
@@ -153,6 +159,7 @@
 static int  mpt_lan_send_turbo(struct net_device *dev, u32 tmsg);
 static int  mpt_lan_send_reply(struct net_device *dev,
 			       LANSendReply_t *pSendRep);
+static int  mpt_lan_ioc_reset(MPT_ADAPTER *ioc, int reset_phase);
 static int  mpt_lan_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
 static unsigned short mpt_lan_type_trans(struct sk_buff *skb,
 					 struct net_device *dev);
@@ -168,6 +175,9 @@
 
 static struct net_device *mpt_landev[MPT_MAX_ADAPTERS+1];
 
+static struct NAA_Hosed *mpt_bad_naa = NULL;
+rwlock_t bad_naa_lock;
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  * Fusion MPT LAN external data
@@ -318,6 +328,41 @@
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 static int
+mpt_lan_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
+{
+	struct net_device *dev = mpt_landev[ioc->id];
+	struct mpt_lan_priv *priv = (struct mpt_lan_priv *) dev->priv;
+
+	dprintk((KERN_INFO MYNAM ": IOC %s_reset routed to LAN driver!\n",
+			reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"));
+
+	if (priv->mpt_rxfidx == NULL)
+		return (1);
+
+	if (reset_phase == MPT_IOC_PRE_RESET) {
+		int i;
+		unsigned long flags;
+		
+		netif_stop_queue(dev);
+
+		atomic_set(&priv->buckets_out, 0);
+
+		/* Reset Rx Free Tail index and re-populate the queue. */
+		spin_lock_irqsave(&priv->rxfidx_lock, flags);
+		priv->mpt_rxfidx_tail = -1;
+		for (i = 0; i < priv->max_buckets_out; i++)
+			priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = i;
+		spin_unlock_irqrestore(&priv->rxfidx_lock, flags);
+	} else {
+		mpt_lan_post_receive_buckets(dev);
+		netif_wake_queue(dev);
+	}
+
+	return 1;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+static int
 mpt_lan_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
 {
 	dprintk((KERN_INFO MYNAM ": MPT event routed to LAN driver!\n"));
@@ -356,7 +401,19 @@
 	struct mpt_lan_priv *priv = (struct mpt_lan_priv *) dev->priv;
 	int i;
 
-	mpt_lan_reset(dev);
+	if (mpt_lan_reset(dev) != 0) {
+		MPT_ADAPTER *mpt_dev = priv->mpt_dev;
+		
+		printk (KERN_WARNING MYNAM "/lan_open: lan_reset failed.");
+		
+		if (mpt_dev->active)
+			printk ("The ioc is active. Perhaps it needs to be"
+				" reset?\n");
+		else
+			printk ("The ioc in inactive, most likely in the "
+				"process of being reset. Please try again in "
+				"a moment.\n");
+	}
 
 	priv->mpt_txfidx = kmalloc(priv->tx_max_out * sizeof(int), GFP_KERNEL);
 	if (priv->mpt_txfidx == NULL)
@@ -402,7 +459,10 @@
 			IOC_AND_NETDEV_NAMES_s_s(dev));
 
 	if (mpt_event_register(LanCtx, mpt_lan_event_process) != 0) {
-		/* FIXME! */
+		printk (KERN_WARNING MYNAM "/lo: Unable to register for Event"
+			" Notifications. This is a bad thing! We're not going "
+			"to go ahead, but I'd be leery of system stability at "
+			"this point.\n");
 	}
 
 	netif_start_queue(dev);
@@ -422,6 +482,8 @@
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/* Send a LanReset message to the FW. This should result in the FW returning
+   any buckets it still has. */
 static int
 mpt_lan_reset(struct net_device *dev)
 {
@@ -660,6 +722,8 @@
 	dma_addr_t dma;
 	unsigned long flags;
 	int ctx;
+	struct NAA_Hosed *nh;
+	u16 cur_naa = 0x1000;
 
 	dioprintk((KERN_INFO MYNAM ": %s called, skb_addr = %p\n",
 			__FUNCTION__, skb));
@@ -707,8 +771,10 @@
 	priv->SendCtl[ctx].len = skb->len;
 
 	/* Message Header */
+	pSendReq->Reserved    = 0;
 	pSendReq->Function    = MPI_FUNCTION_LAN_SEND;
 	pSendReq->ChainOffset = 0;
+	pSendReq->Reserved2   = 0;
 	pSendReq->MsgFlags    = 0;
 	pSendReq->PortNumber  = priv->pnum;
 
@@ -725,7 +791,26 @@
 //			IOC_AND_NETDEV_NAMES_s_s(dev),
 //			ctx, skb, skb->data));
 
-	pTrans->TransactionDetails[0] = cpu_to_le32((0x1000          << 16) |
+	/* Munge the NAA for Tx packets to QLogic boards, which don't follow
+	   RFC 2625. The longer I look at this, the more my opinion of Qlogic
+	   drops. */
+	read_lock_irq(&bad_naa_lock);
+	for (nh = mpt_bad_naa; nh != NULL; nh=nh->next) {
+		if ((nh->ieee[0] == skb->mac.raw[0]) &&
+		    (nh->ieee[1] == skb->mac.raw[1]) &&
+		    (nh->ieee[2] == skb->mac.raw[2]) &&
+		    (nh->ieee[3] == skb->mac.raw[3]) &&
+		    (nh->ieee[4] == skb->mac.raw[4]) &&
+		    (nh->ieee[5] == skb->mac.raw[5])) {
+			cur_naa = nh->NAA;
+			dprintk ((KERN_INFO "mptlan/sdu_send: using NAA value "
+				  "= %04x.\n", cur_naa));
+			break;
+		}
+	}
+	read_unlock_irq(&bad_naa_lock);
+
+	pTrans->TransactionDetails[0] = cpu_to_le32((cur_naa         << 16) |
 						    (skb->mac.raw[0] <<  8) |
 						    (skb->mac.raw[1] <<  0));
 	pTrans->TransactionDetails[1] = cpu_to_le32((skb->mac.raw[2] << 24) |
@@ -735,9 +820,15 @@
 
 	pSimple = (SGESimple64_t *) &pTrans->TransactionDetails[2];
 
+	/* If we ever decide to send more than one Simple SGE per LANSend, then
+	   we will need to make sure that LAST_ELEMENT only gets set on the 
+	   last one. Otherwise, bad voodoo and evil funkiness will commence. */
 	pSimple->FlagsLength = cpu_to_le32(
-			((MPI_SGE_FLAGS_END_OF_BUFFER |
+			((MPI_SGE_FLAGS_LAST_ELEMENT | 
+			  MPI_SGE_FLAGS_END_OF_BUFFER |
 			  MPI_SGE_FLAGS_SIMPLE_ELEMENT |
+			  MPI_SGE_FLAGS_SYSTEM_ADDRESS |
+			  MPI_SGE_FLAGS_HOST_TO_IOC |
 			  MPI_SGE_FLAGS_64_BIT_ADDRESSING |
 			  MPI_SGE_FLAGS_END_OF_LIST) << MPI_SGE_FLAGS_SHIFT) |
 			skb->len);
@@ -1252,12 +1343,12 @@
 	priv->total_posted = 0;
 	priv->total_received = 0;
 	priv->max_buckets_out = max_buckets_out;
-	if (mpt_dev->pfacts0.MaxLanBuckets < max_buckets_out)
-		priv->max_buckets_out = mpt_dev->pfacts0.MaxLanBuckets;
+	if (mpt_dev->pfacts[0].MaxLanBuckets < max_buckets_out)
+		priv->max_buckets_out = mpt_dev->pfacts[0].MaxLanBuckets;
 
 	dprintk((KERN_INFO MYNAM "@%d: MaxLanBuckets=%d, max_buckets_out/priv=%d/%d\n",
 			__LINE__,
-			mpt_dev->pfacts0.MaxLanBuckets,
+			mpt_dev->pfacts[0].MaxLanBuckets,
 			max_buckets_out,
 			priv->max_buckets_out));
 
@@ -1316,7 +1407,11 @@
 
 	show_mptmod_ver(LANAME, LANVER);
 
-	if ((LanCtx = mpt_register(lan_reply, MPTLAN_DRIVER)) < 0) {
+	/* Init the global r/w lock for the bad_naa list. We want to do this 
+	   before any boards are initialized and may be used. */
+	rwlock_init(&bad_naa_lock);
+
+	if ((LanCtx = mpt_register(lan_reply, MPTLAN_DRIVER)) <= 0) {
 		printk (KERN_ERR MYNAM ": Failed to register with MPT base driver\n");
 		return -EBUSY;
 	}
@@ -1326,6 +1421,15 @@
 
 	dprintk((KERN_INFO MYNAM ": assigned context of %d\n", LanCtx));
 
+	if (mpt_reset_register(LanCtx, mpt_lan_ioc_reset) == 0) {
+		dprintk((KERN_INFO MYNAM ": Registered for IOC reset notifications\n"));
+	} else {
+		printk(KERN_ERR MYNAM ": Eieee! unable to register a reset "
+		       "handler with mptbase! The world is at an end! "
+		       "Everything is fading to black! Goodbye.\n");
+		return -EBUSY;
+	}
+
 	for (j = 0; j < MPT_MAX_ADAPTERS; j++) {
 		mpt_landev[j] = NULL;
 	}
@@ -1333,14 +1437,14 @@
 
 	curadapter = mpt_adapter_find_first();
 	while (curadapter != NULL) {
-		for (i = 0; i < curadapter->facts0.NumberOfPorts; i++) {
+		for (i = 0; i < curadapter->facts.NumberOfPorts; i++) {
 			printk (KERN_INFO MYNAM ": %s: PortNum=%x, ProtocolFlags=%02Xh (%c%c%c%c)\n",
 					curadapter->name,
-					curadapter->pfacts0.PortNumber,
-					curadapter->pfacts0.ProtocolFlags,
-					MPT_PROTOCOL_FLAGS_c_c_c_c(curadapter->pfacts0.ProtocolFlags));
+					curadapter->pfacts[i].PortNumber,
+					curadapter->pfacts[i].ProtocolFlags,
+					MPT_PROTOCOL_FLAGS_c_c_c_c(curadapter->pfacts[i].ProtocolFlags));
 
-			if (curadapter->pfacts0.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
+			if (curadapter->pfacts[i].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
 				dev = mpt_register_lan_device (curadapter, i);
 				if (dev != NULL) {
 					printk (KERN_INFO MYNAM ": %s: Fusion MPT LAN device registered as '%s'\n",
@@ -1361,7 +1465,7 @@
 				} else {
 					printk (KERN_ERR MYNAM ": %s: Unable to register port%d as a LAN device\n",
 							curadapter->name,
-							curadapter->pfacts0.PortNumber);
+							curadapter->pfacts[i].PortNumber);
 				}
 			} else {
 				printk (KERN_INFO MYNAM ": %s: Hmmm... LAN protocol seems to be disabled on this adapter port!\n",
@@ -1379,6 +1483,8 @@
 {
 	int i;
 
+	mpt_reset_deregister(LanCtx);
+
 	for (i = 0; mpt_landev[i] != NULL; i++) {
 		struct net_device *dev = mpt_landev[i];
 
@@ -1411,6 +1517,7 @@
 {
 	struct mpt_lan_ohdr *fch = (struct mpt_lan_ohdr *)skb->data;
 	struct fcllc *fcllc;
+	u16 source_naa = fch->stype, found = 0;
 
 	skb->mac.raw = skb->data;
 	skb_pull(skb, sizeof(struct mpt_lan_ohdr));
@@ -1444,11 +1551,80 @@
 		}
 	}
 
+	fcllc = (struct fcllc *)skb->data;
+
+	/* Workaround for QLogic not following RFC 2625 in regards to the NAA
+	   value. */
+
+	if ((source_naa & 0xF000) == 0)
+		source_naa = swab16(source_naa);
+
+	if (fcllc->ethertype == htons(ETH_P_ARP))
+	    dprintk ((KERN_INFO "mptlan/type_trans: got arp req/rep w/ naa of "
+		      "%04x.\n", source_naa));
+
+	if ((fcllc->ethertype == htons(ETH_P_ARP)) && 
+	   ((source_naa >> 12) !=  MPT_LAN_NAA_RFC2625)){
+		struct NAA_Hosed *nh, *prevnh;
+		int i;
+
+		dprintk ((KERN_INFO "mptlan/type_trans: ARP Req/Rep from "
+			  "system with non-RFC 2625 NAA value (%04x).\n",
+			  source_naa));
+
+		write_lock_irq(&bad_naa_lock);
+		for (prevnh = nh = mpt_bad_naa; nh != NULL;
+		     prevnh=nh, nh=nh->next) {
+			if ((nh->ieee[0] == fch->saddr[0]) &&
+			    (nh->ieee[1] == fch->saddr[1]) &&
+			    (nh->ieee[2] == fch->saddr[2]) &&
+			    (nh->ieee[3] == fch->saddr[3]) &&
+			    (nh->ieee[4] == fch->saddr[4]) &&
+			    (nh->ieee[5] == fch->saddr[5])) {
+				found = 1;
+				dprintk ((KERN_INFO "mptlan/type_trans: ARP Re"
+					 "q/Rep w/ bad NAA from system already"
+					 " in DB.\n"));
+				break;
+			}
+		}
+		
+		if ((!found) && (nh == NULL)) {
+
+			nh = kmalloc(sizeof(struct NAA_Hosed), GFP_KERNEL);
+			dprintk ((KERN_INFO "mptlan/type_trans: ARP Req/Rep w/"
+				 " bad NAA from system not yet in DB.\n"));
+
+			if (nh != NULL) {
+				nh->next = NULL;
+				if (!mpt_bad_naa)
+					mpt_bad_naa = nh;
+				if (prevnh)
+					prevnh->next = nh;
+				
+				nh->NAA = source_naa; /* Set the S_NAA value. */
+				for (i = 0; i < FC_ALEN; i++)
+					nh->ieee[i] = fch->saddr[i];
+				dprintk ((KERN_INFO "Got ARP from %02x:%02x:%02x:%02x:"
+					  "%02x:%02x with non-compliant S_NAA value.\n",
+					  fch->saddr[0], fch->saddr[1], fch->saddr[2],
+					  fch->saddr[3], fch->saddr[4],fch->saddr[5]));
+			} else {
+				printk (KERN_ERR "mptlan/type_trans: Unable to"
+					" kmalloc a NAA_Hosed struct.\n");
+			}
+		} else if (!found) {
+			printk (KERN_ERR "mptlan/type_trans: found not"
+				" set, but nh isn't null. Evil "
+				"funkiness abounds.\n");
+		}
+		write_unlock_irq(&bad_naa_lock);
+	}
+		
+
 	/* Strip the SNAP header from ARP packets since we don't 
 	 * pass them through to the 802.2/SNAP layers.
 	 */
-	fcllc = (struct fcllc *)skb->data;
-
 	if (fcllc->dsap == EXTENDED_SAP &&
 		(fcllc->ethertype == htons(ETH_P_IP) ||
 		 fcllc->ethertype == htons(ETH_P_ARP))) {
diff -u --recursive --new-file v2.4.9/linux/drivers/message/fusion/mptlan.h linux/drivers/message/fusion/mptlan.h
--- v2.4.9/linux/drivers/message/fusion/mptlan.h	Wed Jul 25 17:10:20 2001
+++ linux/drivers/message/fusion/mptlan.h	Fri Sep  7 09:28:38 2001
@@ -51,6 +51,9 @@
 #define MPT_LAN_MAX_MTU		65280		/* RFC2625 */
 #define MPT_LAN_MTU             16128		/* be nice to slab allocator */
 
+#define MPT_LAN_NAA_RFC2625     0x1
+#define MPT_LAN_NAA_QLOGIC      0x2
+
 /* MPT LAN Reset and Suspend Resource Flags Defines */
 
 #define MPT_LAN_RESOURCE_FLAG_RETURN_POSTED_BUCKETS    0x01
diff -u --recursive --new-file v2.4.9/linux/drivers/message/fusion/mptscsih.c linux/drivers/message/fusion/mptscsih.c
--- v2.4.9/linux/drivers/message/fusion/mptscsih.c	Wed Jul 25 17:10:20 2001
+++ linux/drivers/message/fusion/mptscsih.c	Fri Sep  7 09:28:38 2001
@@ -19,7 +19,7 @@
  *  Original author: Steven J. Ralston
  *  (mailto:Steve.Ralston@lsil.com)
  *
- *  $Id: mptscsih.c,v 1.24 2001/03/22 08:45:08 sralston Exp $
+ *  $Id: mptscsih.c,v 1.29 2001/06/18 18:59:05 sralston Exp $
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -95,7 +95,6 @@
 	u8			 *SgHunks;
 	dma_addr_t		  SgHunksDMA;
 	u32			  qtag_tick;
-	FCDEV_TRACKER		  TargetsQ;
 } MPT_SCSI_HOST;
 
 typedef struct _MPT_SCSI_DEV {
@@ -119,6 +118,7 @@
 static void	copy_sense_data(Scsi_Cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
 static u32	SCPNT_TO_MSGCTX(Scsi_Cmnd *sc);
 
+static int	mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
 static int	mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
 
 
@@ -205,7 +205,7 @@
 			dprintk((KERN_INFO MYNAM ": *NEW* SCSI device (%d:%d:%d)!\n",
 					   sc->device->id, sc->device->lun, sc->device->channel));
 			if ((sc->device->hostdata = kmalloc(sizeof(MPT_SCSI_DEV), GFP_ATOMIC)) == NULL) {
-				printk(KERN_ERR MYNAM ": ERROR: kmalloc(%d) FAILED!\n", (int)sizeof(MPT_SCSI_DEV));
+				printk(KERN_ERR MYNAM ": ERROR - kmalloc(%d) FAILED!\n", (int)sizeof(MPT_SCSI_DEV));
 			} else {
 				memset(sc->device->hostdata, 0, sizeof(MPT_SCSI_DEV));
 				mpt_sdev = (MPT_SCSI_DEV *) sc->device->hostdata;
@@ -555,8 +555,14 @@
 	if (! BeenHereDoneThat++) {
 		show_mptmod_ver(my_NAME, my_VERSION);
 
-		ScsiDoneCtx = mpt_register(mptscsih_io_done, MPTSCSIH_DRIVER);
-		ScsiTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSCSIH_DRIVER);
+		if ((ScsiDoneCtx = mpt_register(mptscsih_io_done, MPTSCSIH_DRIVER)) <= 0) {
+			printk(KERN_ERR MYNAM ": Failed to register callback1 with MPT base driver\n");
+			return mpt_scsi_hosts;
+		}
+		if ((ScsiTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSCSIH_DRIVER)) <= 0) {
+			printk(KERN_ERR MYNAM ": Failed to register callback2 with MPT base driver\n");
+			return mpt_scsi_hosts;
+		}
 
 #ifndef MPT_SCSI_USE_NEW_EH
 		Q_INIT(&mpt_scsih_taskQ, MPT_FRAME_HDR);
@@ -568,6 +574,12 @@
 		} else {
 			/* FIXME! */
 		}
+
+		if (mpt_reset_register(ScsiDoneCtx, mptscsih_ioc_reset) == 0) {
+			dprintk((KERN_INFO MYNAM ": Registered for IOC reset notifications\n"));
+		} else {
+			/* FIXME! */
+		}
 	}
 
 	dprintk((KERN_INFO MYNAM ": mpt_scsih_detect()\n"));
@@ -582,7 +594,7 @@
 		 *  Added sanity check on SCSI Initiator-mode enabled
 		 *  for this MPT adapter.
 		 */
-		if (!(this->pfacts0.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR)) {
+		if (!(this->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR)) {
 			printk(KERN_ERR MYNAM ": Skipping %s because SCSI Initiator mode is NOT enabled!\n",
 					this->name);
 			this = mpt_adapter_find_next(this);
@@ -612,10 +624,18 @@
 
 			/* Yikes!  This is important!
 			 * Otherwise, by default, linux only scans target IDs 0-7!
+			 *
+			 * BUG FIX!  20010618 -sralston & pdelaney
+			 * FC919 testing was encountering "duplicate" FC devices,
+			 * as it turns out because the 919 was returning 512
+			 * for PortFacts.MaxDevices, causing a wraparound effect
+			 * in SCSI IO requests.  So instead of using:
+			 *     sh->max_id = this->pfacts[0].MaxDevices - 1
+			 * we'll use a definitive max here.
 			 */
-			sh->max_id = this->pfacts0.MaxDevices - 1;
+			sh->max_id = MPT_MAX_FC_DEVICES;
 
-			sh->this_id = this->pfacts0.PortSCSIID;
+			sh->this_id = this->pfacts[0].PortSCSIID;
 
 			restore_flags(flags);
 
@@ -730,6 +750,9 @@
 #if 0
 			mptscsih_flush_pending();
 #endif
+			mpt_reset_deregister(ScsiDoneCtx);
+			dprintk((KERN_INFO MYNAM ": Deregistered for IOC reset notifications\n"));
+
 			mpt_event_deregister(ScsiDoneCtx);
 			dprintk((KERN_INFO MYNAM ": Deregistered for IOC event notifications\n"));
 
@@ -765,7 +788,7 @@
 
 	h = (MPT_SCSI_HOST *)SChost->hostdata;
 	info_kbuf[0] = '\0';
-	mpt_print_ioc_summary(h->ioc, info_kbuf, &size, 0);
+	mpt_print_ioc_summary(h->ioc, info_kbuf, &size, 0, 0);
 	info_kbuf[size-1] = '\0';
 
 	return info_kbuf;
@@ -1235,7 +1258,6 @@
 		dprintk((KERN_INFO MYNAM ": Queue depth now %d.\n", max_qd));
 	}
 
-	mb();
 	dmfprintk((KERN_INFO MYNAM ": Issued SCSI cmd (%p)\n", SCpnt));
 
 	return 0;
@@ -1265,6 +1287,7 @@
 	u32		*msg;
 	u32		 ctx2abort;
 	int		 i;
+	unsigned long	 flags;
 
 	printk(KERN_WARNING MYNAM ": Attempting _ABORT SCSI IO (=%p)\n", SCpnt);
 	printk(KERN_WARNING MYNAM ": IOs outstanding = %d\n", atomic_read(&queue_depth));
@@ -1309,41 +1332,59 @@
 	 *	 the controller, so it does not matter. -DaveM
 	 */
 	ctx2abort = SCPNT_TO_MSGCTX(SCpnt);
-	dprintk((KERN_INFO MYNAM ":DbG: ctx2abort = %08x\n", ctx2abort));
-	pScsiTm->TaskMsgContext = ctx2abort;
-
-	wmb();
+	if (ctx2abort == -1) {
+		printk(KERN_ERR MYNAM ": ERROR - ScsiLookup fail(#2) for SCpnt=%p\n", SCpnt);
+		SCpnt->result = DID_SOFT_ERROR << 16;
+		spin_lock_irqsave(&io_request_lock, flags);
+		SCpnt->scsi_done(SCpnt);
+		spin_unlock_irqrestore(&io_request_lock, flags);
+		mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
+	} else {
+		dprintk((KERN_INFO MYNAM ":DbG: ctx2abort = %08x\n", ctx2abort));
+		pScsiTm->TaskMsgContext = ctx2abort;
 
-/* MPI v0.10 requires SCSITaskMgmt requests be sent via Doorbell/handshake
-	mpt_put_msg_frame(hd->ioc->id, mf);
-*/
-/* FIXME!  Check return status! */
-	(void) mpt_send_handshake_request(ScsiTaskCtx, hd->ioc->id, sizeof(SCSITaskMgmt_t), msg);
 
-	wmb();
+		/* MPI v0.10 requires SCSITaskMgmt requests be sent via Doorbell/handshake
+			mpt_put_msg_frame(hd->ioc->id, mf);
+		*/
+		if ((i = mpt_send_handshake_request(ScsiTaskCtx, hd->ioc->id,
+					sizeof(SCSITaskMgmt_t), msg))
+		    != 0) {
+			printk(KERN_WARNING MYNAM
+					": WARNING[2] - IOC error (%d) processing TaskMgmt request (mf=%p:sc=%p)\n",
+					i, mf, SCpnt);
+			SCpnt->result = DID_SOFT_ERROR << 16;
+			spin_lock_irqsave(&io_request_lock, flags);
+			SCpnt->scsi_done(SCpnt);
+			spin_unlock_irqrestore(&io_request_lock, flags);
+			mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
+		}
+	}
 
-	return SUCCESS;
+	//return SUCCESS;
+	return FAILED;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
- *	mptscsih_bus_reset - Perform a SCSI BUS_RESET!	new_eh variant
+ *	mptscsih_dev_reset - Perform a SCSI TARGET_RESET!  new_eh variant
  *	@SCpnt: Pointer to Scsi_Cmnd structure, IO which reset is due to
  *
- *	(linux Scsi_Host_Template.eh_bus_reset_handler routine)
+ *	(linux Scsi_Host_Template.eh_dev_reset_handler routine)
  *
  *	Returns SUCCESS or FAILED.
  */
 int
-mptscsih_bus_reset(Scsi_Cmnd * SCpnt)
+mptscsih_dev_reset(Scsi_Cmnd * SCpnt)
 {
 	MPT_FRAME_HDR	*mf;
 	SCSITaskMgmt_t	*pScsiTm;
 	MPT_SCSI_HOST	*hd;
 	u32		*msg;
 	int		 i;
+	unsigned long	 flags;
 
-	printk(KERN_WARNING MYNAM ": Attempting _BUS_RESET (%p)\n", SCpnt);
+	printk(KERN_WARNING MYNAM ": Attempting _TARGET_RESET (%p)\n", SCpnt);
 	printk(KERN_WARNING MYNAM ": IOs outstanding = %d\n", atomic_read(&queue_depth));
 
 	hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata;
@@ -1356,7 +1397,7 @@
 	}
 
 	pScsiTm = (SCSITaskMgmt_t *) mf;
-	msg = (u32 *) mf;
+	msg = (u32*)mf;
 
 	pScsiTm->TargetID = SCpnt->target;
 	pScsiTm->Bus = hd->port;
@@ -1364,10 +1405,11 @@
 	pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
 
 	pScsiTm->Reserved = 0;
-	pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS;
+	pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
 	pScsiTm->Reserved1 = 0;
 	pScsiTm->MsgFlags = 0;
 
+	/* _TARGET_RESET goes to LUN 0 always! */
 	for (i = 0; i < 8; i++)
 		pScsiTm->LUN[i] = 0;
 
@@ -1377,38 +1419,47 @@
 
 	pScsiTm->TaskMsgContext = cpu_to_le32(0);
 
-	wmb();
-
 /* MPI v0.10 requires SCSITaskMgmt requests be sent via Doorbell/handshake
 	mpt_put_msg_frame(hd->ioc->id, mf);
 */
 /* FIXME!  Check return status! */
-	(void) mpt_send_handshake_request(ScsiTaskCtx, hd->ioc->id, sizeof(SCSITaskMgmt_t), msg);
-
-	wmb();
+	if ((i = mpt_send_handshake_request(ScsiTaskCtx, hd->ioc->id,
+				sizeof(SCSITaskMgmt_t), msg))
+	    != 0) {
+		printk(KERN_WARNING MYNAM
+				": WARNING[3] - IOC error (%d) processing TaskMgmt request (mf=%p:sc=%p)\n",
+				i, mf, SCpnt);
+		SCpnt->result = DID_SOFT_ERROR << 16;
+		spin_lock_irqsave(&io_request_lock, flags);
+		SCpnt->scsi_done(SCpnt);
+		spin_unlock_irqrestore(&io_request_lock, flags);
+		mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
+	}
 
-	return SUCCESS;
+	//return SUCCESS;
+	return FAILED;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
- *	mptscsih_dev_reset - Perform a SCSI TARGET_RESET!  new_eh variant
+ *	mptscsih_bus_reset - Perform a SCSI BUS_RESET!	new_eh variant
  *	@SCpnt: Pointer to Scsi_Cmnd structure, IO which reset is due to
  *
- *	(linux Scsi_Host_Template.eh_dev_reset_handler routine)
+ *	(linux Scsi_Host_Template.eh_bus_reset_handler routine)
  *
  *	Returns SUCCESS or FAILED.
  */
 int
-mptscsih_dev_reset(Scsi_Cmnd * SCpnt)
+mptscsih_bus_reset(Scsi_Cmnd * SCpnt)
 {
 	MPT_FRAME_HDR	*mf;
 	SCSITaskMgmt_t	*pScsiTm;
 	MPT_SCSI_HOST	*hd;
 	u32		*msg;
 	int		 i;
+	unsigned long	 flags;
 
-	printk(KERN_WARNING MYNAM ": Attempting _TARGET_RESET (%p)\n", SCpnt);
+	printk(KERN_WARNING MYNAM ": Attempting _BUS_RESET (%p)\n", SCpnt);
 	printk(KERN_WARNING MYNAM ": IOs outstanding = %d\n", atomic_read(&queue_depth));
 
 	hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata;
@@ -1421,7 +1472,7 @@
 	}
 
 	pScsiTm = (SCSITaskMgmt_t *) mf;
-	msg = (u32*)mf;
+	msg = (u32 *) mf;
 
 	pScsiTm->TargetID = SCpnt->target;
 	pScsiTm->Bus = hd->port;
@@ -1429,11 +1480,10 @@
 	pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
 
 	pScsiTm->Reserved = 0;
-	pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
+	pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS;
 	pScsiTm->Reserved1 = 0;
 	pScsiTm->MsgFlags = 0;
 
-	/* _TARGET_RESET goes to LUN 0 always! */
 	for (i = 0; i < 8; i++)
 		pScsiTm->LUN[i] = 0;
 
@@ -1443,15 +1493,22 @@
 
 	pScsiTm->TaskMsgContext = cpu_to_le32(0);
 
-	wmb();
-
 /* MPI v0.10 requires SCSITaskMgmt requests be sent via Doorbell/handshake
 	mpt_put_msg_frame(hd->ioc->id, mf);
 */
 /* FIXME!  Check return status! */
-	(void) mpt_send_handshake_request(ScsiTaskCtx, hd->ioc->id, sizeof(SCSITaskMgmt_t), msg);
-
-	wmb();
+	if ((i = mpt_send_handshake_request(ScsiTaskCtx, hd->ioc->id,
+				sizeof(SCSITaskMgmt_t), msg))
+	    != 0) {
+		printk(KERN_WARNING MYNAM
+				": WARNING[4] - IOC error (%d) processing TaskMgmt request (mf=%p:sc=%p)\n",
+				i, mf, SCpnt);
+		SCpnt->result = DID_SOFT_ERROR << 16;
+		spin_lock_irqsave(&io_request_lock, flags);
+		SCpnt->scsi_done(SCpnt);
+		spin_unlock_irqrestore(&io_request_lock, flags);
+		mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
+	}
 
 	return SUCCESS;
 }
@@ -1646,6 +1703,9 @@
 	spin_unlock_irqrestore(&mpt_scsih_taskQ_lock, flags);
 
 	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule_timeout(HZ/4);
+
 		/*
 		 *  We MUST remove item from taskQ *before* we format the
 		 *  frame as a SCSITaskMgmt request and send it down to the IOC.
@@ -1664,9 +1724,10 @@
 
 		SCpnt = (Scsi_Cmnd*)mf->u.frame.linkage.argp1;
 		if (SCpnt == NULL) {
-			printk(KERN_ERR MYNAM ": ERROR: TaskMgmt has NULL SCpnt! (%p:%p)\n", mf, SCpnt);
+			printk(KERN_ERR MYNAM ": ERROR - TaskMgmt has NULL SCpnt! (%p:%p)\n", mf, SCpnt);
 			continue;
 		}
+		hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata;
 		pScsiTm = (SCSITaskMgmt_t *) mf;
 
 		for (i = 0; i < 8; i++) {
@@ -1674,9 +1735,9 @@
 		}
 
 		task_type = mf->u.frame.linkage.arg1;
-		if (task_type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK)
-		{
-			printk(KERN_WARNING MYNAM ": Attempting _ABORT SCSI IO! (mf:sc=%p:%p)\n", mf, SCpnt);
+		if (task_type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
+			printk(KERN_WARNING MYNAM ": Attempting _ABORT SCSI IO! (mf=%p:sc=%p)\n",
+					mf, SCpnt);
 
 			/* Most important!  Set TaskMsgContext to SCpnt's MsgContext!
 			 * (the IO to be ABORT'd)
@@ -1686,11 +1747,20 @@
 			 *	 the controller, so it does not matter. -DaveM
 			 */
 			ctx2abort = SCPNT_TO_MSGCTX(SCpnt);
+			if (ctx2abort == -1) {
+				printk(KERN_ERR MYNAM ": ERROR - ScsiLookup fail(#1) for SCpnt=%p\n", SCpnt);
+				SCpnt->result = DID_SOFT_ERROR << 16;
+				spin_lock_irqsave(&io_request_lock, flags);
+				SCpnt->scsi_done(SCpnt);
+				spin_unlock_irqrestore(&io_request_lock, flags);
+				mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
+				continue;
+			}
 			pScsiTm->LUN[1] = SCpnt->lun;
 		}
 		else if (task_type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
 		{
-			printk(KERN_WARNING MYNAM ": Attempting _BUS_RESET! (against SCSI IO mf:sc=%p:%p)\n", mf, SCpnt);
+			printk(KERN_WARNING MYNAM ": Attempting _BUS_RESET! (against SCSI IO mf=%p:sc=%p)\n", mf, SCpnt);
 		}
 #if 0
 		else if (task_type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {}
@@ -1699,8 +1769,6 @@
 
 		printk(KERN_WARNING MYNAM ": IOs outstanding = %d\n", atomic_read(&queue_depth));
 
-		hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata;
-
 		pScsiTm->TargetID = SCpnt->target;
 		pScsiTm->Bus = hd->port;
 		pScsiTm->ChainOffset = 0;
@@ -1725,15 +1793,22 @@
 		 *		mpt_put_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
 		 *  SCSITaskMgmt requests MUST be sent ONLY via
 		 *  Doorbell/handshake now.   :-(
-		 *
-		 *  FIXME!  Check return status!
 		 */
-		(void) mpt_send_handshake_request(ScsiTaskCtx, hd->ioc->id, sizeof(SCSITaskMgmt_t), (u32*)mf);
-
-		/* Spin-Wait for TaskMgmt complete!!! */
-		while (mpt_scsih_active_taskmgmt_mf != NULL) {
-			current->state = TASK_INTERRUPTIBLE;
-			schedule_timeout(HZ/2);
+		if ((i = mpt_send_handshake_request(ScsiTaskCtx, hd->ioc->id,
+					sizeof(SCSITaskMgmt_t), (u32*) mf))
+		    != 0) {
+			printk(KERN_WARNING MYNAM ": WARNING[1] - IOC error (%d) processing TaskMgmt request (mf=%p:sc=%p)\n", i, mf, SCpnt);
+			SCpnt->result = DID_SOFT_ERROR << 16;
+			spin_lock_irqsave(&io_request_lock, flags);
+			SCpnt->scsi_done(SCpnt);
+			spin_unlock_irqrestore(&io_request_lock, flags);
+			mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
+		} else {
+			/* Spin-Wait for TaskMgmt complete!!! */
+			while (mpt_scsih_active_taskmgmt_mf != NULL) {
+				current->state = TASK_INTERRUPTIBLE;
+				schedule_timeout(HZ/4);
+			}
 		}
 	}
 
@@ -2002,6 +2077,22 @@
 #	include "../../scsi/scsi_module.c"
 #endif
 
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+static int
+mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
+{
+	dprintk((KERN_INFO MYNAM ": IOC %s_reset routed to SCSI host driver!\n",
+			reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"));
+
+	if (reset_phase == MPT_IOC_PRE_RESET) {
+		/* FIXME! Do pre-reset cleanup */
+	} else {
+		/* FIXME! Do post-reset cleanup */
+	}
+
+	return 1;		/* currently means nothing really */
+}
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 static int
diff -u --recursive --new-file v2.4.9/linux/drivers/message/fusion/scsi3.h linux/drivers/message/fusion/scsi3.h
--- v2.4.9/linux/drivers/message/fusion/scsi3.h	Wed Jul 25 17:10:20 2001
+++ linux/drivers/message/fusion/scsi3.h	Fri Sep  7 09:28:38 2001
@@ -8,7 +8,7 @@
  *  Written By: Steven J. Ralston (19960517)
  *  (mailto:Steve.Ralston@lsil.com)
  *
- *  $Id: scsi3.h,v 1.4 2001/01/06 15:54:25 sralston Exp $
+ *  $Id: scsi3.h,v 1.5 2001/04/06 14:31:32 sralston Exp $
  */
 
 #ifndef SCSI3_H_INCLUDED
@@ -64,12 +64,15 @@
 #define CMD_WriteVerify        0x2E
 #define CMD_Verify             0x2F
 #define CMD_ReadDefectData     0x37
+#define CMD_ReadLong           0x3E
 #define CMD_LogSelect          0x4C
 #define CMD_LogSense           0x4D
 #define CMD_ModeSelect10       0x55
 #define CMD_Reserve10          0x56
 #define CMD_Release10          0x57
 #define CMD_ModeSense10        0x5A
+#define CMD_PersistReserveIn   0x5E
+#define CMD_PersistReserveOut  0x5F
 #define CMD_ReportLuns         0xA0
 
 /*
diff -u --recursive --new-file v2.4.9/linux/drivers/mtd/ftl.c linux/drivers/mtd/ftl.c
--- v2.4.9/linux/drivers/mtd/ftl.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/ftl.c	Sat Sep  8 12:02:32 2001
@@ -1428,8 +1428,7 @@
     blksize_size[FTL_MAJOR] = ftl_blocksizes;
     ftl_gendisk.major = FTL_MAJOR;
     blk_init_queue(BLK_DEFAULT_QUEUE(FTL_MAJOR), &do_ftl_request);
-    ftl_gendisk.next = gendisk_head;
-    gendisk_head = &ftl_gendisk;
+    add_gendisk(&ftl_gendisk);
     
     register_mtd_user(&ftl_notifier);
     
@@ -1438,19 +1437,13 @@
 
 mod_exit_t cleanup_ftl(void)
 {
-    struct gendisk *gd, **gdp;
-
     unregister_mtd_user(&ftl_notifier);
 
     unregister_blkdev(FTL_MAJOR, "ftl");
     blk_cleanup_queue(BLK_DEFAULT_QUEUE(FTL_MAJOR));
     blksize_size[FTL_MAJOR] = NULL;
 
-    for (gdp = &gendisk_head; *gdp; gdp = &((*gdp)->next))
-	if (*gdp == &ftl_gendisk) {
-	    gd = *gdp; *gdp = gd->next;
-	    break;
-	}
+    del_gendisk(&ftl_gendisk);
 }
 
 module_init(init_ftl);
diff -u --recursive --new-file v2.4.9/linux/drivers/mtd/nftlcore.c linux/drivers/mtd/nftlcore.c
--- v2.4.9/linux/drivers/mtd/nftlcore.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/nftlcore.c	Sun Sep  9 18:59:43 2001
@@ -1024,11 +1024,6 @@
  *
  ****************************************************************************/
 
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define init_nftl init_module
-#define cleanup_nftl cleanup_module
-#endif
-
 static struct mtd_notifier nftl_notifier = {
 	add:	NFTL_notify_add,
 	remove:	NFTL_notify_remove
@@ -1045,22 +1040,19 @@
 #endif
 
 	if (register_blkdev(MAJOR_NR, "nftl", &nftl_fops)){
-		printk("unable to register NFTL block device on major %d\n", MAJOR_NR);
+		printk("unable to register NFTL block device on major %d\n",
+		       MAJOR_NR);
 		return -EBUSY;
 	} else {
-#if LINUX_VERSION_CODE < 0x20320
-		blk_dev[MAJOR_NR].request_fn = nftl_request;
-#else
 		blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &nftl_request);
-#endif
+
 		/* set block size to 1kB each */
 		for (i = 0; i < 256; i++) {
 			nftl_blocksizes[i] = 1024;
 		}
 		blksize_size[MAJOR_NR] = nftl_blocksizes;
 
-		nftl_gendisk.next = gendisk_head;
-		gendisk_head = &nftl_gendisk;
+		add_gendisk(&nftl_gendisk);
 	}
 	
 	register_mtd_user(&nftl_notifier);
@@ -1070,24 +1062,12 @@
 
 static void __exit cleanup_nftl(void)
 {
-	struct gendisk *gd, **gdp;
-
   	unregister_mtd_user(&nftl_notifier);
   	unregister_blkdev(MAJOR_NR, "nftl");
   	
-#if LINUX_VERSION_CODE < 0x20320
-  	blk_dev[MAJOR_NR].request_fn = 0;
-#else
   	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
-#endif	
 
-	/* remove ourself from generic harddisk list
-	   FIXME: why can't I found this partition on /proc/partition */
-  	for (gdp = &gendisk_head; *gdp; gdp = &((*gdp)->next))
-    		if (*gdp == &nftl_gendisk) {
-      			gd = *gdp; *gdp = gd->next;
-      			break;
-		}
+	del_gendisk(&nftl_gendisk);
 }
 
 module_init(init_nftl);
diff -u --recursive --new-file v2.4.9/linux/drivers/net/8139too.c linux/drivers/net/8139too.c
--- v2.4.9/linux/drivers/net/8139too.c	Mon Aug 27 12:41:42 2001
+++ linux/drivers/net/8139too.c	Sun Sep  2 07:59:04 2001
@@ -1610,6 +1610,7 @@
 	unsigned long timeout;
 
 	daemonize ();
+	reparent_to_init();
 	spin_lock_irq(&current->sigmask_lock);
 	sigemptyset(&current->blocked);
 	recalc_sigpending(current);
diff -u --recursive --new-file v2.4.9/linux/drivers/net/Makefile linux/drivers/net/Makefile
--- v2.4.9/linux/drivers/net/Makefile	Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/Makefile	Sun Sep  2 07:24:13 2001
@@ -137,12 +137,8 @@
 obj-$(CONFIG_PPPOE) += pppox.o pppoe.o
 
 obj-$(CONFIG_SLIP) += slip.o
-ifeq ($(CONFIG_SLIP),y)
-  obj-$(CONFIG_SLIP_COMPRESSED) += slhc.o
-else
-  ifeq ($(CONFIG_SLIP),m)
-    obj-$(CONFIG_SLIP_COMPRESSED) += slhc.o
-  endif
+ifeq ($(CONFIG_SLIP_COMPRESSED),y)
+  obj-$(CONFIG_SLIP) += slhc.o
 endif
 
 obj-$(CONFIG_STRIP) += strip.o
diff -u --recursive --new-file v2.4.9/linux/drivers/net/appletalk/cops.c linux/drivers/net/appletalk/cops.c
--- v2.4.9/linux/drivers/net/appletalk/cops.c	Wed May 16 10:31:27 2001
+++ linux/drivers/net/appletalk/cops.c	Sun Sep  9 10:45:43 2001
@@ -1013,6 +1013,8 @@
 
 #ifdef MODULE
 static struct net_device cops0_dev = { init: cops_probe };
+
+MODULE_LICENSE("GPL");
 MODULE_PARM(io, "i");
 MODULE_PARM(irq, "i");
 MODULE_PARM(board_type, "i");
diff -u --recursive --new-file v2.4.9/linux/drivers/net/appletalk/ipddp.c linux/drivers/net/appletalk/ipddp.c
--- v2.4.9/linux/drivers/net/appletalk/ipddp.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/net/appletalk/ipddp.c	Sun Sep  9 10:45:43 2001
@@ -283,6 +283,7 @@
 
 static struct net_device dev_ipddp;
 
+MODULE_LICENSE("GPL");
 MODULE_PARM(ipddp_mode, "i");
 
 static int __init ipddp_init_module(void)
diff -u --recursive --new-file v2.4.9/linux/drivers/net/appletalk/ltpc.c linux/drivers/net/appletalk/ltpc.c
--- v2.4.9/linux/drivers/net/appletalk/ltpc.c	Wed Apr 18 14:40:05 2001
+++ linux/drivers/net/appletalk/ltpc.c	Sun Sep  9 10:45:43 2001
@@ -1255,6 +1255,8 @@
 static struct net_device dev_ltpc;
 
 #ifdef MODULE
+
+MODULE_LICENSE("GPL");
 MODULE_PARM(debug, "i");
 MODULE_PARM(io, "i");
 MODULE_PARM(irq, "i");
diff -u --recursive --new-file v2.4.9/linux/drivers/net/au1000_eth.c linux/drivers/net/au1000_eth.c
--- v2.4.9/linux/drivers/net/au1000_eth.c	Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/au1000_eth.c	Sun Sep  9 10:43:01 2001
@@ -39,7 +39,7 @@
 #include <linux/errno.h>
 #include <linux/in.h>
 #include <linux/ioport.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/init.h>
diff -u --recursive --new-file v2.4.9/linux/drivers/net/cs89x0.c linux/drivers/net/cs89x0.c
--- v2.4.9/linux/drivers/net/cs89x0.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/net/cs89x0.c	Sun Sep  9 10:45:43 2001
@@ -1111,7 +1111,7 @@
 					(unsigned long)lp->dma_buff,
 					(unsigned long)virt_to_bus(lp->dma_buff));
 			}
-			if ((unsigned long)virt_to_bus(lp->dma_buff) >= MAX_DMA_ADDRESS ||
+			if ((unsigned long) lp->dma_buff >= MAX_DMA_ADDRESS ||
 			    !dma_page_eq(lp->dma_buff, lp->dma_buff+lp->dmasize*1024-1)) {
 				printk(KERN_ERR "%s: not usable as DMA buffer\n", dev->name);
 				goto release_irq;
diff -u --recursive --new-file v2.4.9/linux/drivers/net/declance.c linux/drivers/net/declance.c
--- v2.4.9/linux/drivers/net/declance.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/net/declance.c	Sun Sep  9 10:45:43 2001
@@ -1006,7 +1006,7 @@
 	lance_set_multicast(dev);
 }
 
-static int __init dec_lance_init(const int type)
+static int __init dec_lance_init(struct net_device *dev, const int type)
 {
 	static unsigned version_printed;
 	struct net_device *dev;
@@ -1015,7 +1015,6 @@
 	int i, ret;
 	unsigned long esar_base;
 	unsigned char *esar;
-	struct net_device *dev;
 
 #ifndef CONFIG_TC
 	system_base = KN01_LANCE_BASE;
@@ -1026,12 +1025,12 @@
 	if (dec_lance_debug && version_printed++ == 0)
 		printk(version);
 
-	dev = init_etherdev(NULL, sizeof(struct lance_private));
+	dev = init_etherdev(0, sizeof(struct lance_private));
 	if (!dev)
 		return -ENOMEM;
 
 	/* init_etherdev ensures the data structures used by the LANCE are aligned. */
-	lp = dev->priv;
+	lp = (struct lance_private *) dev->priv;
 	spin_lock_init(&lp->lock);
 
 	switch (type) {
@@ -1217,6 +1216,7 @@
 /* Find all the lance cards on the system and initialize them */
 static int __init dec_lance_probe(void)
 {
+	struct net_device *dev = NULL;
 	static int called;
 
 #ifdef MODULE
@@ -1255,7 +1255,7 @@
 	}
 #endif
 
-	return dec_lance_init(type);
+	return dec_lance_init(dev, type);
 }
 
 static void __exit dec_lance_cleanup(void)
diff -u --recursive --new-file v2.4.9/linux/drivers/net/dgrs.c linux/drivers/net/dgrs.c
--- v2.4.9/linux/drivers/net/dgrs.c	Mon Aug 27 12:41:42 2001
+++ linux/drivers/net/dgrs.c	Sun Sep  9 10:45:43 2001
@@ -1292,6 +1292,7 @@
 		if (!devN) 
 			goto fail;
 		memcpy(devN, dev, dev_size);
+		memset(devN->name, 0, sizeof(devN->name));
 		devN->priv = ((void *)devN) + sizeof(struct net_device);
 		privN = (DGRS_PRIV *)devN->priv;
 			/* ... and zero out VM areas */
diff -u --recursive --new-file v2.4.9/linux/drivers/net/dmfe.c linux/drivers/net/dmfe.c
--- v2.4.9/linux/drivers/net/dmfe.c	Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/dmfe.c	Sun Sep  9 10:45:43 2001
@@ -61,7 +61,7 @@
 #include <linux/ptrace.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/init.h>
diff -u --recursive --new-file v2.4.9/linux/drivers/net/gt96100eth.c linux/drivers/net/gt96100eth.c
--- v2.4.9/linux/drivers/net/gt96100eth.c	Fri Apr 13 20:26:07 2001
+++ linux/drivers/net/gt96100eth.c	Sun Sep  9 10:45:43 2001
@@ -1,7 +1,7 @@
 /*
  * Copyright 2000 MontaVista Software Inc.
  * Author: MontaVista Software, Inc.
- *         	stevel@mvista.com or support@mvista.com
+ *         	stevel@mvista.com or source@mvista.com
  *
  * ########################################################################
  *
@@ -29,7 +29,6 @@
 #endif
 
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -38,7 +37,7 @@
 #include <linux/errno.h>
 #include <linux/in.h>
 #include <linux/ioport.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/init.h>
diff -u --recursive --new-file v2.4.9/linux/drivers/net/gt96100eth.h linux/drivers/net/gt96100eth.h
--- v2.4.9/linux/drivers/net/gt96100eth.h	Fri Apr 13 20:26:07 2001
+++ linux/drivers/net/gt96100eth.h	Sun Sep  9 10:45:43 2001
@@ -1,7 +1,7 @@
 /*
  * Copyright 2000 MontaVista Software Inc.
  * Author: MontaVista Software, Inc.
- *         	stevel@mvista.com or support@mvista.com
+ *         	stevel@mvista.com or source@mvista.com
  *
  * ########################################################################
  *
@@ -27,7 +27,6 @@
 #ifndef _GT96100ETH_H
 #define _GT96100ETH_H
 
-#include <linux/config.h>
 #include <asm/galileo-boards/gt96100.h>
 
 /* Keep the ring sizes a power of two for efficiency. */
diff -u --recursive --new-file v2.4.9/linux/drivers/net/irda/irda-usb.c linux/drivers/net/irda/irda-usb.c
--- v2.4.9/linux/drivers/net/irda/irda-usb.c	Sun Aug 12 13:27:59 2001
+++ linux/drivers/net/irda/irda-usb.c	Sun Sep  9 10:45:43 2001
@@ -44,7 +44,6 @@
 
 #include <net/irda/irda-usb.h>
 
-static u32 min_turn_times[]  = { 10000, 5000, 1000, 500, 100, 50, 10, 0 }; /* us */
 static int qos_mtt_bits = 0;
 
 static void irda_usb_dump_class_desc(struct irda_class_desc *desc);
@@ -76,7 +75,8 @@
 	{ USB_DEVICE(0x50f, 0x180), driver_info: IUC_SPEED_BUG | IUC_NO_WINDOW },
 	/* Extended Systems, Inc.,  XTNDAccess IrDA USB (ESI-9685) */
 	{ USB_DEVICE(0x8e9, 0x100), driver_info: IUC_SPEED_BUG | IUC_NO_WINDOW },
-	{ match_flags: USB_DEVICE_ID_MATCH_INT_CLASS,
+	{ match_flags: USB_DEVICE_ID_MATCH_INT_CLASS |
+	               USB_DEVICE_ID_MATCH_INT_SUBCLASS,
 	  bInterfaceClass: USB_CLASS_APP_SPEC,
 	  bInterfaceSubClass: USB_CLASS_IRDA,
 	  driver_info: IUC_DEFAULT, },
diff -u --recursive --new-file v2.4.9/linux/drivers/net/irda/toshoboe.c linux/drivers/net/irda/toshoboe.c
--- v2.4.9/linux/drivers/net/irda/toshoboe.c	Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/irda/toshoboe.c	Sun Sep  9 10:45:43 2001
@@ -695,7 +695,6 @@
 {
   struct toshoboe_cb *self;
   struct net_device *dev;
-  struct pm_dev *pmdev;
   int i = 0;
   int ok = 0;
   int err;
@@ -844,11 +843,6 @@
           goto freebufs;
   }
   pci_set_drvdata(pci_dev,self);
-
-/*  pmdev = pm_register (PM_PCI_DEV, PM_PCI_ID(pci_dev), toshoboe_pmproc);
-  if (pmdev)
-	  pmdev->data = self;
-	  */
 
   printk (KERN_WARNING "ToshOboe: Using ");
 #ifdef ONETASK
diff -u --recursive --new-file v2.4.9/linux/drivers/net/jazzsonic.c linux/drivers/net/jazzsonic.c
--- v2.4.9/linux/drivers/net/jazzsonic.c	Thu Apr 12 12:15:25 2001
+++ linux/drivers/net/jazzsonic.c	Sun Sep  9 10:43:01 2001
@@ -47,11 +47,12 @@
 /*
  * Macros to access SONIC registers
  */
-#define SONIC_READ(reg) \
-	*((volatile unsigned int *)base_addr+reg)
+#define SONIC_READ(reg) (*((volatile unsigned int *)base_addr+reg))
 
-#define SONIC_WRITE(reg,val) \
-	*((volatile unsigned int *)base_addr+reg) = val
+#define SONIC_WRITE(reg,val)						\
+do {									\
+	*((volatile unsigned int *)base_addr+reg) = val;		\
+}
 
 
 /* use 0 for production, 1 for verification, >2 for debug */
@@ -65,8 +66,8 @@
  * Base address and interrupt of the SONIC controller on JAZZ boards
  */
 static struct {
-    unsigned int port;
-    unsigned int irq;
+	unsigned int port;
+	unsigned int irq;
 } sonic_portlist[] = { {JAZZ_ETHERNET_BASE, JAZZ_ETHERNET_IRQ}, {0, 0}};
 
 /*
@@ -76,14 +77,15 @@
  */
 static unsigned short known_revisions[] =
 {
-  0x04,				/* Mips Magnum 4000 */
-  0xffff			/* end of list */
+	0x04,			/* Mips Magnum 4000 */
+	0xffff			/* end of list */
 };
 
 /* Index to functions, as function prototypes. */
 
 extern int sonic_probe(struct net_device *dev);
-static int sonic_probe1(struct net_device *dev, unsigned int base_addr, unsigned int irq);
+static int sonic_probe1(struct net_device *dev, unsigned int base_addr,
+                        unsigned int irq);
 
 
 /*
@@ -92,164 +94,170 @@
  */
 int __init sonic_probe(struct net_device *dev)
 {
-    unsigned int base_addr = dev ? dev->base_addr : 0;
-    int i;
+	unsigned int base_addr = dev ? dev->base_addr : 0;
+	int i;
 
-    /*
-     * Don't probe if we're not running on a Jazz board.
-     */
-    if (mips_machgroup != MACH_GROUP_JAZZ)
+	/*
+	 * Don't probe if we're not running on a Jazz board.
+	 */
+	if (mips_machgroup != MACH_GROUP_JAZZ)
+		return -ENODEV;
+	if (base_addr >= KSEG0)	/* Check a single specified location. */
+		return sonic_probe1(dev, base_addr, dev->irq);
+	else if (base_addr != 0)	/* Don't probe at all. */
+		return -ENXIO;
+
+	for (i = 0; sonic_portlist[i].port; i++) {
+		int base_addr = sonic_portlist[i].port;
+		if (check_region(base_addr, 0x100))
+			continue;
+		if (sonic_probe1(dev, base_addr, sonic_portlist[i].irq) == 0)
+			return 0;
+	}
 	return -ENODEV;
-    if (base_addr >= KSEG0)	/* Check a single specified location. */
-	return sonic_probe1(dev, base_addr, dev->irq);
-    else if (base_addr != 0)	/* Don't probe at all. */
-	return -ENXIO;
-    
-    for (i = 0; sonic_portlist[i].port; i++) {
-	int base_addr = sonic_portlist[i].port;
-	if (check_region(base_addr, 0x100))
-	    continue;
-	if (sonic_probe1(dev, base_addr, sonic_portlist[i].irq) == 0)
-	    return 0;
-    }
-    return -ENODEV;
 }
 
-static int __init sonic_probe1(struct net_device *dev,
-                               unsigned int base_addr, unsigned int irq)
+static int __init sonic_probe1(struct net_device *dev, unsigned int base_addr,
+                               unsigned int irq)
 {
-    static unsigned version_printed;
-    unsigned int silicon_revision;
-    unsigned int val;
-    struct sonic_local *lp;
-    int i;
-    
-    /*
-     * get the Silicon Revision ID. If this is one of the known
-     * one assume that we found a SONIC ethernet controller at
-     * the expected location.
-     */
-    silicon_revision = SONIC_READ(SONIC_SR);
-    if (sonic_debug > 1)
-      printk("SONIC Silicon Revision = 0x%04x\n",silicon_revision);
-
-    i = 0;
-    while ((known_revisions[i] != 0xffff) &&
-	   (known_revisions[i] != silicon_revision))
-      i++;
-	
-    if (known_revisions[i] == 0xffff) {
-	printk("SONIC ethernet controller not found (0x%4x)\n",
-	       silicon_revision);
-	return -ENODEV;
-    }
-    
-    if (!request_region(base_addr, 0x100, dev->name))
-    	return -EBUSY;
-    
-    if (sonic_debug  &&  version_printed++ == 0)
-      printk(version);
-
-    printk("%s: %s found at 0x%08x, ",
-	   dev->name, "SONIC ethernet", base_addr);
+	static unsigned version_printed;
+	unsigned int silicon_revision;
+	unsigned int val;
+	struct sonic_local *lp;
+	int i;
 
-    /* Fill in the 'dev' fields. */
-    dev->base_addr = base_addr;
-    dev->irq = irq;
-
-    /*
-     * Put the sonic into software reset, then
-     * retrieve and print the ethernet address.
-     */
-    SONIC_WRITE(SONIC_CMD,SONIC_CR_RST);
-    SONIC_WRITE(SONIC_CEP,0);
-    for (i=0; i<3; i++) {
-	val = SONIC_READ(SONIC_CAP0-i);
-	dev->dev_addr[i*2] = val;
-	dev->dev_addr[i*2+1] = val >> 8;
-    }
-
-    printk("HW Address ");
-    for (i = 0; i < 6; i++) {
-	printk("%2.2x", dev->dev_addr[i]);
-	if (i<5)
-	  printk(":");
-    }
-    
-    printk(" IRQ %d\n", irq);
-    
-    /* Initialize the device structure. */
-    if (dev->priv == NULL) {
 	/*
-	 * the memory be located in the same 64kb segment
+	 * get the Silicon Revision ID. If this is one of the known
+	 * one assume that we found a SONIC ethernet controller at
+	 * the expected location.
 	 */
-	lp = NULL;
+	silicon_revision = SONIC_READ(SONIC_SR);
+	if (sonic_debug > 1)
+		printk("SONIC Silicon Revision = 0x%04x\n",silicon_revision);
+
 	i = 0;
-	do {
-	    lp = (struct sonic_local *)kmalloc(sizeof(*lp), GFP_KERNEL);
-	    if ((unsigned long)lp >> 16 != ((unsigned long)lp + sizeof(*lp) ) >> 16) {
-		/* FIXME, free the memory later */
-		kfree (lp);
-		lp = NULL;
-	    }
-	} while (lp == NULL && i++ < 20);
-	
-	if (lp == NULL) {
-	    printk ("%s: couldn't allocate memory for descriptors\n",
-	            dev->name);
-	    return -ENOMEM;
+	while (known_revisions[i] != 0xffff
+	       && known_revisions[i] != silicon_revision)
+		i++;
+
+	if (known_revisions[i] == 0xffff) {
+		printk("SONIC ethernet controller not found (0x%4x)\n",
+		       silicon_revision);
+		return -ENODEV;
 	}
-	
-	memset(lp, 0, sizeof(struct sonic_local));
-	
-	/* get the virtual dma address */
-	lp->cda_laddr = vdma_alloc(PHYSADDR(lp),sizeof(*lp));
-	if (lp->cda_laddr == ~0UL) {
-	    printk ("%s: couldn't get DMA page entry for descriptors\n",
-	            dev->name);
-	    return -ENOMEM;
+    
+	if (!request_region(base_addr, 0x100, dev->name))
+		return -EBUSY;
+
+	if (sonic_debug  &&  version_printed++ == 0)
+		printk(version);
+
+	printk("%s: Sonic ethernet found at 0x%08lx, ", dev->name, base_addr);
+
+	/* Fill in the 'dev' fields. */
+	dev->base_addr = base_addr;
+	dev->irq = irq;
+
+	/*
+	 * Put the sonic into software reset, then
+	 * retrieve and print the ethernet address.
+	 */
+	SONIC_WRITE(SONIC_CMD,SONIC_CR_RST);
+	SONIC_WRITE(SONIC_CEP,0);
+	for (i=0; i<3; i++) {
+		val = SONIC_READ(SONIC_CAP0-i);
+		dev->dev_addr[i*2] = val;
+		dev->dev_addr[i*2+1] = val >> 8;
 	}
 
-	lp->tda_laddr = lp->cda_laddr + sizeof (lp->cda);
-	lp->rra_laddr = lp->tda_laddr + sizeof (lp->tda);
-	lp->rda_laddr = lp->rra_laddr + sizeof (lp->rra);
-	
-	/* allocate receive buffer area */
-	/* FIXME, maybe we should use skbs */
-	if ((lp->rba = (char *)kmalloc(SONIC_NUM_RRS * SONIC_RBSIZE, GFP_KERNEL)) == NULL) {
-	    printk ("%s: couldn't allocate receive buffers\n",dev->name);
-	    return -ENOMEM;
+	printk("HW Address ");
+	for (i = 0; i < 6; i++) {
+		printk("%2.2x", dev->dev_addr[i]);
+		if (i<5)
+			printk(":");
 	}
-	
-	/* get virtual dma address */
-	if ((lp->rba_laddr = vdma_alloc(PHYSADDR(lp->rba),SONIC_NUM_RRS * SONIC_RBSIZE)) == ~0UL) {
-	    printk ("%s: couldn't get DMA page entry for receive buffers\n",dev->name);
-	    return -ENOMEM;
+
+	printk(" IRQ %d\n", irq);
+    
+	/* Initialize the device structure. */
+	if (dev->priv == NULL) {
+		/*
+		 * the memory be located in the same 64kb segment
+		 */
+		lp = NULL;
+		i = 0;
+		do {
+			lp = kmalloc(sizeof(*lp), GFP_KERNEL);
+			if ((unsigned long) lp >> 16
+			    != ((unsigned long)lp + sizeof(*lp) ) >> 16) {
+				/* FIXME, free the memory later */
+				kfree(lp);
+				lp = NULL;
+			}
+		} while (lp == NULL && i++ < 20);
+
+		if (lp == NULL) {
+			printk("%s: couldn't allocate memory for descriptors\n",
+			       dev->name);
+			return -ENOMEM;
+		}
+
+		memset(lp, 0, sizeof(struct sonic_local));
+
+		/* get the virtual dma address */
+		lp->cda_laddr = vdma_alloc(PHYSADDR(lp),sizeof(*lp));
+		if (lp->cda_laddr == ~0UL) {
+			printk("%s: couldn't get DMA page entry for "
+			       "descriptors\n", dev->name);
+			return -ENOMEM;
+		}
+
+		lp->tda_laddr = lp->cda_laddr + sizeof (lp->cda);
+		lp->rra_laddr = lp->tda_laddr + sizeof (lp->tda);
+		lp->rda_laddr = lp->rra_laddr + sizeof (lp->rra);
+	
+		/* allocate receive buffer area */
+		/* FIXME, maybe we should use skbs */
+		lp->rba = kmalloc(SONIC_NUM_RRS * SONIC_RBSIZE, GFP_KERNEL);
+		if (!lp->rba) {
+			printk("%s: couldn't allocate receive buffers\n",
+			       dev->name);
+			return -ENOMEM;
+		}
+
+		/* get virtual dma address */
+		lp->rba_laddr = vdma_alloc(PHYSADDR(lp->rba),
+		                           SONIC_NUM_RRS * SONIC_RBSIZE);
+		if (lp->rba_laddr == ~0UL) {
+			printk("%s: couldn't get DMA page entry for receive "
+			       "buffers\n",dev->name);
+			return -ENOMEM;
+		}
+
+		/* now convert pointer to KSEG1 pointer */
+		lp->rba = (char *)KSEG1ADDR(lp->rba);
+		flush_cache_all();
+		dev->priv = (struct sonic_local *)KSEG1ADDR(lp);
 	}
-	
-	/* now convert pointer to KSEG1 pointer */
-	lp->rba = (char *)KSEG1ADDR(lp->rba);
-	flush_cache_all();
-	dev->priv = (struct sonic_local *)KSEG1ADDR(lp);
-    }
-
-    lp = (struct sonic_local *)dev->priv;
-    dev->open = sonic_open;
-    dev->stop = sonic_close;
-    dev->hard_start_xmit = sonic_send_packet;
-    dev->get_stats	= sonic_get_stats;
-    dev->set_multicast_list = &sonic_multicast_list;
-
-    /*
-     * clear tally counter
-     */
-    SONIC_WRITE(SONIC_CRCT,0xffff);
-    SONIC_WRITE(SONIC_FAET,0xffff);
-    SONIC_WRITE(SONIC_MPT,0xffff);
-
-    /* Fill in the fields of the device structure with ethernet values. */
-    ether_setup(dev);
-    return 0;
+
+	lp = (struct sonic_local *)dev->priv;
+	dev->open = sonic_open;
+	dev->stop = sonic_close;
+	dev->hard_start_xmit = sonic_send_packet;
+	dev->get_stats	= sonic_get_stats;
+	dev->set_multicast_list = &sonic_multicast_list;
+	dev->watchdog_timeo = TX_TIMEOUT;
+
+	/*
+	 * clear tally counter
+	 */
+	SONIC_WRITE(SONIC_CRCT,0xffff);
+	SONIC_WRITE(SONIC_FAET,0xffff);
+	SONIC_WRITE(SONIC_MPT,0xffff);
+
+	/* Fill in the fields of the device structure with ethernet values. */
+	ether_setup(dev);
+	return 0;
 }
 
 /*
diff -u --recursive --new-file v2.4.9/linux/drivers/net/lp486e.c linux/drivers/net/lp486e.c
--- v2.4.9/linux/drivers/net/lp486e.c	Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/lp486e.c	Sun Sep  9 10:45:43 2001
@@ -7,7 +7,7 @@
         Written 1993 by Donald Becker.
         Copyright 1993 United States Government as represented by the Director,
         National Security Agency.  This software may only be used and
-	distributed according to the terms of the GNU Public License
+	distributed according to the terms of the GNU General Public License
 	as modified by SRC, incorporated herein by reference.
 
         The author may be reached as becker@scyld.com, or C/O
@@ -67,7 +67,7 @@
 #include <linux/ptrace.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
diff -u --recursive --new-file v2.4.9/linux/drivers/net/macsonic.c linux/drivers/net/macsonic.c
--- v2.4.9/linux/drivers/net/macsonic.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/net/macsonic.c	Sat Sep  1 11:01:28 2001
@@ -135,8 +135,9 @@
 		unsigned long desc_base, desc_top;
 		if ((lp->sonic_desc = 
 		     kmalloc(SIZEOF_SONIC_DESC
-			     * SONIC_BUS_SCALE(lp->dma_bitmode), GFP_DMA)) == NULL) {
+			     * SONIC_BUS_SCALE(lp->dma_bitmode), GFP_KERNEL | GFP_DMA)) == NULL) {
 			printk(KERN_ERR "%s: couldn't allocate descriptor buffers\n", dev->name);
+			return -ENOMEM;
 		}
 		desc_base = (unsigned long) lp->sonic_desc;
 		desc_top = desc_base + SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode);
@@ -165,7 +166,7 @@
 
 	/* FIXME, maybe we should use skbs */
 	if ((lp->rba = (char *)
-	     kmalloc(SONIC_NUM_RRS * SONIC_RBSIZE, GFP_DMA)) == NULL) {
+	     kmalloc(SONIC_NUM_RRS * SONIC_RBSIZE, GFP_KERNEL | GFP_DMA)) == NULL) {
 		printk(KERN_ERR "%s: couldn't allocate receive buffers\n", dev->name);
 		return -ENOMEM;
 	}
diff -u --recursive --new-file v2.4.9/linux/drivers/net/net_init.c linux/drivers/net/net_init.c
--- v2.4.9/linux/drivers/net/net_init.c	Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/net_init.c	Fri Sep  7 16:18:50 2001
@@ -165,9 +165,16 @@
 	setup(dev);
 	
 	if (new_device) {
+		int err;
+
 		rtnl_lock();
-		register_netdevice(dev);
+		err = register_netdevice(dev);
 		rtnl_unlock();
+
+		if (err < 0) {
+			kfree(dev);
+			dev = NULL;
+		}
 	}
 	return dev;
 }
diff -u --recursive --new-file v2.4.9/linux/drivers/net/ni5010.c linux/drivers/net/ni5010.c
--- v2.4.9/linux/drivers/net/ni5010.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/net/ni5010.c	Fri Sep  7 09:28:38 2001
@@ -575,7 +575,6 @@
 	outb(0xff, EDLC_XCLR);	/* Clear all pending xmit IRQ's */
 	
 	if (xmit_stat & XS_COLL){
-                printk("ether collision\n"); /* FIXME: remove */
 		PRINTK((KERN_DEBUG "%s: collision detected, retransmitting\n", 
 			dev->name));
 		outw(NI5010_BUFSIZE - lp->o_pkt_size, IE_GP);
diff -u --recursive --new-file v2.4.9/linux/drivers/net/ns83820.c linux/drivers/net/ns83820.c
--- v2.4.9/linux/drivers/net/ns83820.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/ns83820.c	Sun Sep  9 10:45:43 2001
@@ -0,0 +1,1429 @@
+#define VERSION "0.11"
+/* ns83820.c by Benjamin LaHaise <bcrl@redhat.com>
+ *
+ * $Revision: 1.34.2.2 $
+ *
+ * Copyright 2001 Benjamin LaHaise.
+ * Copyright 2001 Red Hat.
+ *
+ * Mmmm, chocolate vanilla mocha...
+ *
+ *
+ * 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
+ *
+ *
+ * ChangeLog
+ * =========
+ *	20010414	0.1 - created
+ *	20010622	0.2 - basic rx and tx.
+ *	20010711	0.3 - added duplex and link state detection support.
+ *	20010713	0.4 - zero copy, no hangs.
+ *			0.5 - 64 bit dma support (davem will hate me for this)
+ *			    - disable jumbo frames to avoid tx hangs
+ *			    - work around tx deadlocks on my 1.02 card via
+ *			      fiddling with TXCFG
+ *	20010810	0.6 - use pci dma api for ringbuffers, work on ia64
+ *	20010816	0.7 - misc cleanups
+ *	20010826	0.8 - fix critical zero copy bugs
+ *			0.9 - internal experiment
+ *	20010827	0.10 - fix ia64 unaligned access.
+ *	20010906	0.11 - accept all packets with checksum errors as
+ *			       otherwise fragments get lost
+			     - fix >> 32 bugs
+ *
+ * Driver Overview
+ * ===============
+ *
+ * This driver was originally written for the National Semiconductor
+ * 83820 chip, a 10/100/1000 Mbps 64 bit PCI ethernet NIC.  Hopefully
+ * this code will turn out to be a) clean, b) correct, and c) fast.
+ * With that in mind, I'm aiming to split the code up as much as
+ * reasonably possible.  At present there are X major sections that
+ * break down into a) packet receive, b) packet transmit, c) link
+ * management, d) initialization and configuration.  Where possible,
+ * these code paths are designed to run in parallel.
+ *
+ * This driver has been tested and found to work with the following
+ * cards (in no particular order):
+ *
+ *	Cameo		SOHO-GA2000T	SOHO-GA2500T
+ *	D-Link		DGE-500T
+ *	PureData	PDP8023Z-TG
+ *	SMC		SMC9462TX
+ *
+ * Reports of success or failure would be greatly appreciated.
+ */
+//#define dprintk		printk
+#define dprintk(x...)		do { } while (0)
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/delay.h>
+#include <linux/smp_lock.h>
+#include <linux/tqueue.h>
+#include <linux/init.h>
+#include <linux/ip.h>	/* for iph */
+#include <linux/in.h>	/* for IPPROTO_... */
+#include <linux/eeprom.h>
+//#include <linux/skbrefill.h>
+
+/* Dprintk is used for more interesting debug events */
+#undef Dprintk
+#define	Dprintk			dprintk
+
+#if !defined(GCC_VERSION) || (GCC_VERSION < 2096)
+#define __builtin_expect(x,y)	(x)
+#endif
+
+#ifdef CONFIG_HIGHMEM64G
+#define USE_64BIT_ADDR
+#elif defined(__ia64__)
+#define USE_64BIT_ADDR
+#endif
+
+/* Tell davem to fix the pci dma api.  Grrr. */
+/* stolen from acenic.c */
+#ifdef CONFIG_HIGHMEM
+#if defined(CONFIG_X86)
+#define DMAADDR_OFFSET  0
+#if defined(CONFIG_HIGHMEM64G)
+typedef u64 dmaaddr_high_t;
+#else
+typedef u32 dmaaddr_high_t;
+#endif
+#elif defined(CONFIG_PPC)
+#define DMAADDR_OFFSET PCI_DRAM_OFFSET
+typedef unsigned long dmaaddr_high_t;
+#endif
+
+static inline dmaaddr_high_t
+pci_map_single_high(struct pci_dev *hwdev, struct page *page,
+		    int offset, size_t size, int dir)
+{
+	u64 phys;
+	phys = page - mem_map;
+	phys <<= PAGE_SHIFT;
+	phys += offset;
+	phys += DMAADDR_OFFSET;
+	return phys;
+}
+#else
+
+typedef unsigned long dmaaddr_high_t;
+
+static inline dmaaddr_high_t
+pci_map_single_high(struct pci_dev *hwdev, struct page *page,
+		    int offset, size_t size, int dir)
+{
+	return pci_map_single(hwdev, page_address(page) + offset, size, dir);
+}
+#endif
+
+/* tunables */
+#define RX_BUF_SIZE	6144	/* 8192 */
+#define NR_RX_DESC	256
+
+#define NR_TX_DESC	256
+
+/* register defines */
+#define CFGCS		0x04
+
+#define CR_TXE		0x00000001
+#define CR_TXD		0x00000002
+#define CR_RXE		0x00000004
+#define CR_RXD		0x00000008
+#define CR_TXR		0x00000010
+#define CR_RXR		0x00000020
+#define CR_SWI		0x00000080
+#define CR_RST		0x00000100
+
+#define PTSCR_EEBIST_EN	0x00000002
+#define PTSCR_EELOAD_EN	0x00000004
+
+#define ISR_TXDESC3	0x40000000
+#define ISR_TXDESC2	0x20000000
+#define ISR_TXDESC1	0x10000000
+#define ISR_TXDESC0	0x08000000
+#define ISR_RXDESC3	0x04000000
+#define ISR_RXDESC2	0x02000000
+#define ISR_RXDESC1	0x01000000
+#define ISR_RXDESC0	0x00800000
+#define ISR_TXRCMP	0x00400000
+#define ISR_RXRCMP	0x00200000
+#define ISR_DPERR	0x00100000
+#define ISR_SSERR	0x00080000
+#define ISR_RMABT	0x00040000
+#define ISR_RTABT	0x00020000
+#define ISR_RXSOVR	0x00010000
+#define ISR_HIBINT	0x00008000
+#define ISR_PHY		0x00004000
+#define ISR_PME		0x00002000
+#define ISR_SWI		0x00001000
+#define ISR_MIB		0x00000800
+#define ISR_TXURN	0x00000400
+#define ISR_TXIDLE	0x00000200
+#define ISR_TXERR	0x00000100
+#define ISR_TXDESC	0x00000080
+#define ISR_TXOK	0x00000040
+#define ISR_RXORN	0x00000020
+#define ISR_RXIDLE	0x00000010
+#define ISR_RXEARLY	0x00000008
+#define ISR_RXERR	0x00000004
+#define ISR_RXDESC	0x00000002
+#define ISR_RXOK	0x00000001
+
+#define TXCFG_CSI	0x80000000
+#define TXCFG_HBI	0x40000000
+#define TXCFG_MLB	0x20000000
+#define TXCFG_ATP	0x10000000
+#define TXCFG_ECRETRY	0x00800000
+#define TXCFG_BRST_DIS	0x00080000
+#define TXCFG_MXDMA1024	0x00000000
+#define TXCFG_MXDMA512	0x00700000
+#define TXCFG_MXDMA256	0x00600000
+#define TXCFG_MXDMA128	0x00500000
+#define TXCFG_MXDMA64	0x00400000
+#define TXCFG_MXDMA32	0x00300000
+#define TXCFG_MXDMA16	0x00200000
+#define TXCFG_MXDMA8	0x00100000
+
+#define CFG_LNKSTS	0x80000000
+#define CFG_SPDSTS	0x60000000
+#define CFG_SPDSTS1	0x40000000
+#define CFG_SPDSTS0	0x20000000
+#define CFG_DUPSTS	0x10000000
+#define CFG_TBI_EN	0x01000000
+#define CFG_MODE_1000	0x00400000
+#define CFG_PINT_CTL	0x001c0000
+#define CFG_PINT_DUPSTS	0x00100000
+#define CFG_PINT_LNKSTS	0x00080000
+#define CFG_PINT_SPDSTS	0x00040000
+#define CFG_TMRTEST	0x00020000
+#define CFG_MRM_DIS	0x00010000
+#define CFG_MWI_DIS	0x00008000
+#define CFG_T64ADDR	0x00004000
+#define CFG_PCI64_DET	0x00002000
+#define CFG_DATA64_EN	0x00001000
+#define CFG_M64ADDR	0x00000800
+#define CFG_PHY_RST	0x00000400
+#define CFG_PHY_DIS	0x00000200
+#define CFG_EXTSTS_EN	0x00000100
+#define CFG_REQALG	0x00000080
+#define CFG_SB		0x00000040
+#define CFG_POW		0x00000020
+#define CFG_EXD		0x00000010
+#define CFG_PESEL	0x00000008
+#define CFG_BROM_DIS	0x00000004
+#define CFG_EXT_125	0x00000002
+#define CFG_BEM		0x00000001
+
+#define EXTSTS_UDPPKT	0x00200000
+#define EXTSTS_TCPPKT	0x00080000
+#define EXTSTS_IPPKT	0x00020000
+
+#define SPDSTS_POLARITY	(CFG_SPDSTS1 | CFG_SPDSTS0 | CFG_DUPSTS)
+
+#define MIBC_MIBS	0x00000008
+#define MIBC_ACLR	0x00000004
+#define MIBC_FRZ	0x00000002
+#define MIBC_WRN	0x00000001
+
+#define RXCFG_AEP	0x80000000
+#define RXCFG_ARP	0x40000000
+#define RXCFG_STRIPCRC	0x20000000
+#define RXCFG_RX_FD	0x10000000
+#define RXCFG_ALP	0x08000000
+#define RXCFG_AIRL	0x04000000
+#define RXCFG_MXDMA	0x00700000
+#define RXCFG_MXDMA0	0x00100000
+#define RXCFG_MXDMA64	0x00600000
+#define RXCFG_DRTH	0x0000003e
+#define RXCFG_DRTH0	0x00000002
+
+#define RFCR_RFEN	0x80000000
+#define RFCR_AAB	0x40000000
+#define RFCR_AAM	0x20000000
+#define RFCR_AAU	0x10000000
+#define RFCR_APM	0x08000000
+#define RFCR_APAT	0x07800000
+#define RFCR_APAT3	0x04000000
+#define RFCR_APAT2	0x02000000
+#define RFCR_APAT1	0x01000000
+#define RFCR_APAT0	0x00800000
+#define RFCR_AARP	0x00400000
+#define RFCR_MHEN	0x00200000
+#define RFCR_UHEN	0x00100000
+#define RFCR_ULM	0x00080000
+
+#define VRCR_RUDPE	0x00000080
+#define VRCR_RTCPE	0x00000040
+#define VRCR_RIPE	0x00000020
+#define VRCR_IPEN	0x00000010
+#define VRCR_DUTF	0x00000008
+#define VRCR_DVTF	0x00000004
+#define VRCR_VTREN	0x00000002
+#define VRCR_VTDEN	0x00000001
+
+#define VTCR_PPCHK	0x00000008
+#define VTCR_GCHK	0x00000004
+#define VTCR_VPPTI	0x00000002
+#define VTCR_VGTI	0x00000001
+
+#define CR		0x00
+#define CFG		0x04
+#define MEAR		0x08
+#define PTSCR		0x0c
+#define	ISR		0x10
+#define	IMR		0x14
+#define	IER		0x18
+#define	IHR		0x1c
+#define TXDP		0x20
+#define TXDP_HI		0x24
+#define TXCFG		0x28
+#define GPIOR		0x2c
+#define RXDP		0x30
+#define RXDP_HI		0x34
+#define RXCFG		0x38
+#define PQCR		0x3c
+#define WCSR		0x40
+#define PCR		0x44
+#define RFCR		0x48
+#define RFDR		0x4c
+
+#define SRR		0x58
+
+#define VRCR		0xbc
+#define VTCR		0xc0
+#define VDR		0xc4
+#define CCSR		0xcc
+
+#define __kick_rx(dev)	writel(CR_RXE, dev->base + CR)
+
+#define kick_rx(dev) do { \
+	dprintk("kick_rx: maybe kicking\n"); \
+	if (test_and_clear_bit(0, &dev->rx_info.idle)) { \
+		dprintk("actually kicking\n"); \
+		writel(dev->rx_info.phy_descs + (4 * DESC_SIZE * dev->rx_info.next_rx), dev->base + RXDP); \
+		if (dev->rx_info.next_rx == dev->rx_info.next_empty) \
+			printk(KERN_DEBUG "%s: uh-oh: next_rx == next_empty???\n", dev->net_dev.name);\
+		__kick_rx(dev); \
+	} \
+} while(0)
+
+#ifdef USE_64BIT_ADDR
+typedef u64	hw_addr_t;
+#else
+typedef u32	hw_addr_t;
+#endif
+
+#define HW_ADDR_LEN	(sizeof(hw_addr_t))
+
+#define LINK		0
+#define BUFPTR		(LINK + HW_ADDR_LEN/4)
+#define CMDSTS		(BUFPTR + HW_ADDR_LEN/4)
+#define EXTSTS		(CMDSTS + 4/4)
+#define DRV_NEXT	(EXTSTS + 4/4)
+
+#define CMDSTS_OWN	0x80000000
+#define CMDSTS_MORE	0x40000000
+#define CMDSTS_INTR	0x20000000
+#define CMDSTS_ERR	0x10000000
+#define CMDSTS_OK	0x08000000
+
+#define CMDSTS_DEST_MASK	0x01800000
+#define CMDSTS_DEST_SELF	0x00800000
+#define CMDSTS_DEST_MULTI	0x01000000
+
+#define DESC_SIZE	8		/* Should be cache line sized */
+
+struct rx_info {
+	spinlock_t	lock;
+	int		up;
+	long		idle;
+
+	struct sk_buff	*skbs[NR_RX_DESC];
+
+	unsigned	next_rx, next_empty;
+
+	u32		*descs;
+	dma_addr_t	phy_descs;
+};
+
+
+struct ns83820 {
+	struct net_device	net_dev;
+	u8			*base;
+
+	struct pci_dev		*pci_dev;
+	struct ns83820		*next_dev;
+
+	struct rx_info		rx_info;
+
+	unsigned		ihr;
+	struct tq_struct	tq_refill;
+
+	/* protects everything below.  irqsave when using. */
+	spinlock_t		misc_lock;
+
+	u32			CFG_cache;
+
+	u32			MEAR_cache;
+	u32			IMR_cache;
+	struct eeprom		ee;
+
+
+	spinlock_t	tx_lock;
+
+	long		tx_idle;
+	u32		tx_done_idx;
+	u32		tx_idx;
+	volatile u32	tx_free_idx;	/* idx of free desc chain */
+	u32		tx_intr_idx;
+
+	struct sk_buff	*tx_skbs[NR_TX_DESC];
+
+	char		pad[16] __attribute__((aligned(16)));
+	u32		*tx_descs;
+	dma_addr_t	tx_phy_descs;
+};
+
+//free = (tx_done_idx + NR_TX_DESC-2 - free_idx) % NR_TX_DESC
+#define start_tx_okay(dev)	\
+	(((NR_TX_DESC-2 + dev->tx_done_idx - dev->tx_free_idx) % NR_TX_DESC) > NR_TX_DESC/2)
+
+static struct ns83820	*ns83820_chain;
+
+
+/* Packet Receiver
+ *
+ * The hardware supports linked lists of receive descriptors for
+ * which ownership is transfered back and forth by means of an
+ * ownership bit.  While the hardware does support the use of a
+ * ring for receive descriptors, we only make use of a chain in
+ * an attempt to reduce bus traffic under heavy load scenarios.
+ * This will also make bugs a bit more obvious.  The current code
+ * only makes use of a single rx chain; I hope to implement
+ * priority based rx for version 1.0.  Goal: even under overload
+ * conditions, still route realtime traffic with as low jitter as
+ * possible.
+ */
+#ifdef USE_64BIT_ADDR
+static inline void build_rx_desc64(struct ns83820 *dev, u32 *desc, u64 link, u64 buf, u32 cmdsts, u32 extsts)
+{
+	desc[0] = link;
+	desc[1] = link >> 32;
+	desc[2] = buf;
+	desc[3] = buf >> 32;
+	desc[5] = extsts;
+	mb();
+	desc[4] = cmdsts;
+}
+
+#define build_rx_desc	build_rx_desc64
+#else
+
+static inline void build_rx_desc32(struct ns83820 *dev, u32 *desc, u32 link, u32 buf, u32 cmdsts, u32 extsts)
+{
+	desc[0] = link;
+	desc[1] = buf;
+	desc[3] = extsts;
+	mb();
+	desc[2] = cmdsts;
+}
+
+#define build_rx_desc	build_rx_desc32
+#endif
+
+#define nr_rx_empty(dev) ((NR_RX_DESC-2 + dev->rx_info.next_rx - dev->rx_info.next_empty) % NR_RX_DESC)
+static inline int ns83820_add_rx_skb(struct ns83820 *dev, struct sk_buff *skb)
+{
+	unsigned next_empty;
+	u32 cmdsts;
+	u32 *sg;
+	hw_addr_t buf;
+
+	next_empty = dev->rx_info.next_empty;
+
+	/* don't overrun last rx marker */
+	if (nr_rx_empty(dev) <= 2) {
+		kfree_skb(skb);
+		return 1;
+	}
+
+#if 0
+	dprintk("next_empty[%d] nr_used[%d] next_rx[%d]\n",
+		dev->rx_info.next_empty,
+		dev->rx_info.nr_used,
+		dev->rx_info.next_rx
+		);
+#endif
+
+	sg = dev->rx_info.descs + (next_empty * DESC_SIZE);
+	if (dev->rx_info.skbs[next_empty])
+		BUG();
+	dev->rx_info.skbs[next_empty] = skb;
+
+	dev->rx_info.next_empty = (next_empty + 1) % NR_RX_DESC;
+	cmdsts = RX_BUF_SIZE | CMDSTS_INTR;
+	buf = pci_map_single(dev->pci_dev, skb->tail, RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+	build_rx_desc(dev, sg, 0, buf, cmdsts, 0);
+	/* update link of previous rx */
+	if (next_empty != dev->rx_info.next_rx)
+		dev->rx_info.descs[((NR_RX_DESC + next_empty - 1) % NR_RX_DESC) * DESC_SIZE] = dev->rx_info.phy_descs + (next_empty * DESC_SIZE * 4);
+
+	return 0;
+}
+
+static int rx_refill(struct ns83820 *dev, int gfp)
+{
+	unsigned i;
+	long flags = 0;
+
+	dprintk("rx_refill(%p)\n", dev);
+	if (gfp == GFP_ATOMIC)
+		spin_lock_irqsave(&dev->rx_info.lock, flags);
+	for (i=0; i<NR_RX_DESC; i++) {
+		struct sk_buff *skb;
+		long res;
+		skb = __dev_alloc_skb(RX_BUF_SIZE+16, gfp);
+		if (!skb)
+			break;
+
+		res = (long)skb->tail & 0xf;
+		res = 0x10 - res;
+		res &= 0xf;
+		skb_reserve(skb, res);
+
+		skb->dev = &dev->net_dev;
+		if (gfp != GFP_ATOMIC)
+			spin_lock_irqsave(&dev->rx_info.lock, flags);
+		res = ns83820_add_rx_skb(dev, skb);
+		if (gfp != GFP_ATOMIC)
+			spin_unlock_irqrestore(&dev->rx_info.lock, flags);
+		if (res) {
+			i = 1;
+			break;
+		}
+	}
+	if (gfp == GFP_ATOMIC)
+		spin_unlock_irqrestore(&dev->rx_info.lock, flags);
+
+	return i ? 0 : -ENOMEM;
+}
+
+/* REFILL */
+static inline void queue_refill(void *_dev)
+{
+	struct ns83820 *dev = _dev;
+
+	rx_refill(dev, GFP_KERNEL);
+	if (dev->rx_info.up)
+		kick_rx(dev);
+}
+
+static inline void clear_rx_desc(struct ns83820 *dev, unsigned i)
+{
+	build_rx_desc(dev, dev->rx_info.descs + (DESC_SIZE * i), 0, 0, CMDSTS_OWN, 0);
+}
+
+static void phy_intr(struct ns83820 *dev)
+{
+	static char *speeds[] = { "10", "100", "1000", "1000(?)" };
+	u32 cfg, new_cfg;
+
+	new_cfg = dev->CFG_cache & ~(CFG_SB | CFG_MODE_1000 | CFG_SPDSTS);
+	cfg = readl(dev->base + CFG) ^ SPDSTS_POLARITY;
+
+	if (cfg & CFG_SPDSTS1)
+		new_cfg |= CFG_MODE_1000 | CFG_SB;
+	else
+		new_cfg &= ~CFG_MODE_1000 | CFG_SB;
+
+	if ((cfg & CFG_LNKSTS) && ((new_cfg ^ dev->CFG_cache) & CFG_MODE_1000)) {
+		writel(new_cfg, dev->base + CFG);
+		dev->CFG_cache = new_cfg;
+	}
+
+	dev->CFG_cache &= ~CFG_SPDSTS;
+	dev->CFG_cache |= cfg & CFG_SPDSTS;
+
+	if (cfg & CFG_LNKSTS) {
+		netif_start_queue(&dev->net_dev);
+		netif_wake_queue(&dev->net_dev);
+	} else {
+		netif_stop_queue(&dev->net_dev);
+	}
+
+	if (cfg & CFG_LNKSTS)
+		printk(KERN_INFO "%s: link now %s mbps, %s duplex and up.\n",
+			dev->net_dev.name,
+			speeds[((cfg / CFG_SPDSTS0) & 3)],
+			(cfg & CFG_DUPSTS) ? "full" : "half");
+	else
+		printk(KERN_INFO "%s: link now down.\n", dev->net_dev.name);
+}
+
+static int ns83820_setup_rx(struct ns83820 *dev)
+{
+	unsigned i;
+	int ret;
+
+	dprintk("ns83820_setup_rx(%p)\n", dev);
+
+	dev->rx_info.idle = 1;
+	dev->rx_info.next_rx = 0;
+	dev->rx_info.next_empty = 0;
+
+	for (i=0; i<NR_RX_DESC; i++)
+		clear_rx_desc(dev, i);
+
+	writel(0, dev->base + RXDP_HI);
+	writel(dev->rx_info.phy_descs, dev->base + RXDP);
+
+	ret = rx_refill(dev, GFP_KERNEL);
+	if (!ret) {
+		dprintk("starting receiver\n");
+		/* prevent the interrupt handler from stomping on us */
+		spin_lock_irq(&dev->rx_info.lock);
+
+		writel(0x0001, dev->base + CCSR);
+		writel(0, dev->base + RFCR);
+		writel(0x7fc00000, dev->base + RFCR);
+		writel(0xffc00000, dev->base + RFCR);
+
+		dev->rx_info.up = 1;
+
+		phy_intr(dev);
+
+		/* Okay, let it rip */
+		spin_lock(&dev->misc_lock);
+		dev->IMR_cache |= ISR_PHY;
+		dev->IMR_cache |= ISR_RXRCMP;
+		//dev->IMR_cache |= ISR_RXERR;
+		//dev->IMR_cache |= ISR_RXOK;
+		dev->IMR_cache |= ISR_RXORN;
+		dev->IMR_cache |= ISR_RXSOVR;
+		dev->IMR_cache |= ISR_RXDESC;
+		dev->IMR_cache |= ISR_RXIDLE;
+		dev->IMR_cache |= ISR_TXDESC;
+		//dev->IMR_cache |= ISR_TXIDLE;
+
+		writel(dev->IMR_cache, dev->base + IMR);
+		writel(1, dev->base + IER);
+		spin_unlock(&dev->misc_lock);
+
+		kick_rx(dev);
+
+		spin_unlock_irq(&dev->rx_info.lock);
+	}
+	return ret;
+}
+
+static void ns83820_cleanup_rx(struct ns83820 *dev)
+{
+	unsigned i;
+	long flags;
+
+	dprintk("ns83820_cleanup_rx(%p)\n", dev);
+
+	/* disable receive interrupts */
+	spin_lock_irqsave(&dev->misc_lock, flags);
+	dev->IMR_cache &= ~(ISR_RXOK | ISR_RXDESC | ISR_RXERR | ISR_RXEARLY | ISR_RXIDLE);
+	writel(dev->IMR_cache, dev->base + IMR);
+	spin_unlock_irqrestore(&dev->misc_lock, flags);
+
+	/* synchronize with the interrupt handler and kill it */
+	dev->rx_info.up = 0;
+	synchronize_irq();
+
+	/* touch the pci bus... */
+	readl(dev->base + IMR);
+
+	/* assumes the transmitter is already disabled and reset */
+	writel(0, dev->base + RXDP_HI);
+	writel(0, dev->base + RXDP);
+
+	for (i=0; i<NR_RX_DESC; i++) {
+		struct sk_buff *skb = dev->rx_info.skbs[i];
+		dev->rx_info.skbs[i] = NULL;
+		clear_rx_desc(dev, i);
+		if (skb)
+			kfree_skb(skb);
+	}
+}
+
+/* rx_irq
+ *	
+ */
+static void FASTCALL(rx_irq(struct ns83820 *dev));
+static void rx_irq(struct ns83820 *dev)
+{
+	struct rx_info *info = &dev->rx_info;
+	unsigned next_rx;
+	u32 cmdsts, *desc;
+	long flags;
+	int nr = 0;
+
+	dprintk("rx_irq(%p)\n", dev);
+	dprintk("rxdp: %08x, descs: %08lx next_rx[%d]: %p next_empty[%d]: %p\n",
+		readl(dev->base + RXDP),
+		(dev->rx_info.phy_descs),
+		dev->rx_info.next_rx,
+		(dev->rx_info.descs + (DESC_SIZE * dev->rx_info.next_rx)),
+		dev->rx_info.next_empty,
+		(dev->rx_info.descs + (DESC_SIZE * dev->rx_info.next_empty))
+		);
+
+	spin_lock_irqsave(&info->lock, flags);
+	if (!info->up)
+		goto out;
+
+	dprintk("walking descs\n");
+	next_rx = info->next_rx;
+	desc = info->descs + (DESC_SIZE * next_rx);
+	while ((CMDSTS_OWN & (cmdsts = desc[CMDSTS])) &&
+	       (cmdsts != CMDSTS_OWN)) {
+		struct sk_buff *skb;
+		u32 extsts = desc[EXTSTS];
+		dmaaddr_high_t bufptr = *(hw_addr_t *)(desc + BUFPTR);
+
+		dprintk("cmdsts: %08x\n", cmdsts);
+		dprintk("link: %08x\n", desc[LINK]);
+		dprintk("extsts: %08x\n", desc[EXTSTS]);
+
+		skb = info->skbs[next_rx];
+		info->skbs[next_rx] = NULL;
+		info->next_rx = (next_rx + 1) % NR_RX_DESC;
+
+		barrier();
+		clear_rx_desc(dev, next_rx);
+
+		pci_unmap_single(dev->pci_dev, bufptr,
+				 RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+		if (CMDSTS_OK & cmdsts) {
+#ifndef __i386__
+			struct sk_buff *tmp;
+#endif
+			int len = cmdsts & 0xffff;
+			if (!skb)
+				BUG();
+			skb_put(skb, len);
+#ifndef __i386__	/* I hate the network stack sometimes */
+			tmp = __dev_alloc_skb(RX_BUF_SIZE+16, GFP_ATOMIC);
+			if (!tmp)
+				goto done;
+			tmp->dev = &dev->net_dev;
+			skb_reserve(tmp, 2);
+			memcpy(skb_put(tmp, len), skb->data, len);
+			kfree_skb(skb);
+			skb = tmp;
+#endif
+			if ((extsts & 0x002a0000) && !(extsts & 0x00540000)) {
+				skb->ip_summed = CHECKSUM_UNNECESSARY;
+			} else {
+				skb->ip_summed = CHECKSUM_NONE;
+			}
+			skb->protocol = eth_type_trans(skb, &dev->net_dev);
+			switch (netif_rx(skb)) {
+			case NET_RX_SUCCESS:
+				dev->ihr = 3;
+				break;
+			case NET_RX_CN_LOW:
+				dev->ihr = 3;
+				break;
+			case NET_RX_CN_MOD:
+				dev->ihr = dev->ihr + 1;
+				break;
+			case NET_RX_CN_HIGH:
+				dev->ihr += dev->ihr/2 + 1;
+				break;
+			case NET_RX_DROP:
+				dev->ihr = 255;
+				break;
+			}
+			if (dev->ihr > 255)
+				dev->ihr = 255;
+#ifndef __i386__
+		done:;
+#endif
+		} else {
+			static int err;
+			if (err++ < 20) {
+				Dprintk("error packet: cmdsts: %08x extsts: %08x\n", cmdsts, extsts);
+			}
+			kfree_skb(skb);
+		}
+
+		nr++;
+		next_rx = info->next_rx;
+		desc = info->descs + (DESC_SIZE * next_rx);
+	}
+	info->next_rx = next_rx;
+
+out:
+	if (0 && !nr) {
+		Dprintk("dazed: cmdsts_f: %08x\n", cmdsts);
+	}
+
+	spin_unlock_irqrestore(&info->lock, flags);
+}
+
+
+/* Packet Transmit code
+ */
+static inline void kick_tx(struct ns83820 *dev)
+{
+	dprintk("kick_tx(%p): tx_idle=%ld, tx_idx=%d free_idx=%d\n",
+		dev, dev->tx_idle, dev->tx_idx, dev->tx_free_idx);
+	writel(CR_TXE, dev->base + CR);
+}
+
+/* no spinlock needed on the transmit irq path as the interrupt handler is serialized */
+static void do_tx_done(struct ns83820 *dev)
+{
+	u32 cmdsts, tx_done_idx, *desc;
+
+	dprintk("do_tx_done(%p)\n", dev);
+	tx_done_idx = dev->tx_done_idx;
+	desc = dev->tx_descs + (tx_done_idx * DESC_SIZE);
+
+	dprintk("tx_done_idx=%d free_idx=%d cmdsts=%08x\n",
+		tx_done_idx, dev->tx_free_idx, desc[CMDSTS]);
+	while ((tx_done_idx != dev->tx_free_idx) &&
+	       !(CMDSTS_OWN & (cmdsts = desc[CMDSTS])) ) {
+		struct sk_buff *skb;
+
+		dprintk("tx_done_idx=%d free_idx=%d cmdsts=%08x\n",
+			tx_done_idx, dev->tx_free_idx, desc[CMDSTS]);
+		skb = dev->tx_skbs[tx_done_idx];
+		dev->tx_skbs[tx_done_idx] = NULL;
+		dprintk("done(%p)\n", skb);
+		if (skb) {
+			pci_unmap_single(dev->pci_dev,
+					*(hw_addr_t *)(desc + BUFPTR),
+					skb->len,
+					PCI_DMA_TODEVICE);
+			dev_kfree_skb_irq(skb);
+		}
+
+		tx_done_idx = (tx_done_idx + 1) % NR_TX_DESC;
+		dev->tx_done_idx = tx_done_idx;
+		desc[CMDSTS] = 0;
+		barrier();
+		desc = dev->tx_descs + (tx_done_idx * DESC_SIZE);
+	}
+
+	/* Allow network stack to resume queueing packets after we've
+	 * finished transmitting at least 1/4 of the packets in the queue.
+	 */
+	if (netif_queue_stopped(&dev->net_dev) && start_tx_okay(dev)) {
+		dprintk("start_queue(%p)\n", dev);
+		netif_start_queue(&dev->net_dev);
+		netif_wake_queue(&dev->net_dev);
+	}
+}
+
+static void ns83820_cleanup_tx(struct ns83820 *dev)
+{
+	unsigned i;
+
+	for (i=0; i<NR_TX_DESC; i++) {
+		struct sk_buff *skb = dev->tx_skbs[i];
+		dev->tx_skbs[i] = NULL;
+		if (skb)
+			dev_kfree_skb(skb);
+	}
+
+	memset(dev->tx_descs, 0, NR_TX_DESC * DESC_SIZE * 4);
+	set_bit(0, &dev->tx_idle);
+}
+
+/* transmit routine.  This code relies on the network layer serializing
+ * its calls in, but will run happily in parallel with the interrupt
+ * handler.  This code currently has provisions for fragmenting tx buffers
+ * while trying to track down a bug in either the zero copy code or
+ * the tx fifo (hence the MAX_FRAG_LEN).
+ */
+#define MAX_FRAG_LEN	8192	/* disabled for now */
+static int ns83820_hard_start_xmit(struct sk_buff *skb, struct net_device *_dev)
+{
+	struct ns83820 *dev = (struct ns83820 *)_dev;
+	u32 free_idx, cmdsts, extsts;
+	int nr_free, nr_frags;
+	unsigned tx_done_idx;
+	dmaaddr_high_t buf;
+	unsigned len;
+	skb_frag_t *frag;
+	int stopped = 0;
+	int do_intr = 0;
+	volatile u32 *first_desc;
+
+	dprintk("ns83820_hard_start_xmit\n");
+
+	nr_frags =  skb_shinfo(skb)->nr_frags;
+again:
+	if (__builtin_expect(dev->CFG_cache & CFG_LNKSTS, 0)) {
+		netif_stop_queue(&dev->net_dev);
+		if (__builtin_expect(dev->CFG_cache & CFG_LNKSTS, 0))
+			return 1;
+		netif_start_queue(&dev->net_dev);
+	}
+
+	free_idx = dev->tx_free_idx;
+	tx_done_idx = dev->tx_done_idx;
+	nr_free = (tx_done_idx + NR_TX_DESC-2 - free_idx) % NR_TX_DESC;
+	nr_free -= 1;
+	if ((nr_free <= nr_frags) || (nr_free <= 8192 / MAX_FRAG_LEN)) {
+		dprintk("stop_queue - not enough(%p)\n", dev);
+		netif_stop_queue(&dev->net_dev);
+
+		/* Check again: we may have raced with a tx done irq */
+		if (dev->tx_done_idx != tx_done_idx) {
+			dprintk("restart queue(%p)\n", dev);
+			netif_start_queue(&dev->net_dev);
+			goto again;
+		}
+		return 1;
+	}
+
+	if (free_idx == dev->tx_intr_idx) {
+		do_intr = 1;
+		dev->tx_intr_idx = (dev->tx_intr_idx + NR_TX_DESC/2) % NR_TX_DESC;
+	}
+
+	nr_free -= nr_frags;
+	if (nr_free < 1) {
+		dprintk("stop_queue - last entry(%p)\n", dev);
+		netif_stop_queue(&dev->net_dev);
+		stopped = 1;
+	}
+
+	frag = skb_shinfo(skb)->frags;
+	if (!nr_frags)
+		frag = 0;
+	extsts = 0;
+	if (skb->ip_summed == CHECKSUM_HW) {
+		extsts |= EXTSTS_IPPKT;
+		if (IPPROTO_TCP == skb->nh.iph->protocol)
+			extsts |= EXTSTS_TCPPKT;
+		else if (IPPROTO_UDP == skb->nh.iph->protocol)
+			extsts |= EXTSTS_UDPPKT;
+	}
+
+	len = skb->len;
+	if (nr_frags)
+		len -= skb->data_len;
+	buf = pci_map_single(dev->pci_dev, skb->data, len, PCI_DMA_TODEVICE);
+
+	first_desc = dev->tx_descs + (free_idx * DESC_SIZE);
+
+	for (;;) {
+		volatile u32 *desc = dev->tx_descs + (free_idx * DESC_SIZE);
+		u32 residue = 0;
+#if 0
+		if (len > MAX_FRAG_LEN) {
+			residue = len;
+			/* align the start address of the next fragment */
+			len = MAX_FRAG_LEN;
+			residue -= len;
+		}
+#endif
+
+		dprintk("frag[%3u]: %4u @ 0x%x%08Lx\n", free_idx, len,
+			(unsigned long long)buf);
+		free_idx = (free_idx + 1) % NR_TX_DESC;
+		desc[LINK] = dev->tx_phy_descs + (free_idx * DESC_SIZE * 4);
+		*(hw_addr_t *)(desc + BUFPTR) = buf;
+		desc[EXTSTS] = extsts;
+
+		cmdsts = ((nr_frags|residue) ? CMDSTS_MORE : do_intr ? CMDSTS_INTR : 0);
+		cmdsts |= (desc == first_desc) ? 0 : CMDSTS_OWN;
+		cmdsts |= len;
+		desc[CMDSTS] = cmdsts;
+
+		if (residue) {
+			buf += len;
+			len = residue;
+			continue;
+		}
+
+		if (!nr_frags)
+			break;
+
+		buf = pci_map_single_high(dev->pci_dev, frag->page, 0,
+					  frag->size, PCI_DMA_TODEVICE);
+		dprintk("frag: buf=%08Lx  page=%08lx\n",
+			(long long)buf, (long)(frag->page - mem_map));
+		len = frag->size;
+		frag++;
+		nr_frags--;
+	}
+	dprintk("done pkt\n");
+	dev->tx_skbs[free_idx] = skb;
+	first_desc[CMDSTS] |= CMDSTS_OWN;
+	dev->tx_free_idx = free_idx;
+	kick_tx(dev);
+
+	/* Check again: we may have raced with a tx done irq */
+	if (stopped && (dev->tx_done_idx != tx_done_idx) && start_tx_okay(dev))
+		netif_start_queue(&dev->net_dev);
+
+	return 0;
+}
+
+static void ns83820_irq(int foo, void *data, struct pt_regs *regs)
+{
+	struct ns83820 *dev = data;
+	int count = 0;
+	u32 isr;
+	dprintk("ns83820_irq(%p)\n", dev);
+
+	dev->ihr = 0;
+
+	while (count++ < 32 && (isr = readl(dev->base + ISR))) {
+		dprintk("irq: %08x\n", isr);
+
+		if (isr & ~(ISR_PHY | ISR_RXDESC | ISR_RXEARLY | ISR_RXOK | ISR_RXERR | ISR_TXIDLE | ISR_TXOK | ISR_TXDESC))
+			Dprintk("odd isr? 0x%08x\n", isr);
+
+	if ((ISR_RXEARLY | ISR_RXIDLE | ISR_RXORN | ISR_RXDESC | ISR_RXOK | ISR_RXERR) & isr) {
+ 		if (ISR_RXIDLE & isr) {
+			dev->rx_info.idle = 1;
+			Dprintk("oh dear, we are idle\n");
+		}
+
+		if ((ISR_RXDESC) & isr) {
+			rx_irq(dev);
+			writel(4, dev->base + IHR);
+		}
+
+		if (nr_rx_empty(dev) >= NR_RX_DESC/4) {
+			if (dev->rx_info.up) {
+				rx_refill(dev, GFP_ATOMIC);
+				kick_rx(dev);
+			}
+		}
+
+		if (dev->rx_info.up && nr_rx_empty(dev) > NR_RX_DESC*3/4)
+			schedule_task(&dev->tq_refill);
+		else
+			kick_rx(dev);
+		if (dev->rx_info.idle)
+			Dprintk("BAD\n");
+	}
+
+	if (ISR_RXSOVR & isr)
+		Dprintk("overrun\n");
+	if (ISR_RXORN & isr)
+		Dprintk("overrun\n");
+
+	if ((ISR_RXRCMP & isr) && dev->rx_info.up)
+		writel(CR_RXE, dev->base + CR);
+
+	if (ISR_TXIDLE & isr) {
+		u32 txdp;
+		txdp = readl(dev->base + TXDP);
+		dprintk("txdp: %08x\n", txdp);
+		txdp -= dev->tx_phy_descs;
+		dev->tx_idx = txdp / (DESC_SIZE * 4);
+		if (dev->tx_idx >= NR_TX_DESC) {
+			printk(KERN_ALERT "%s: BUG -- txdp out of range\n", dev->net_dev.name);
+			dev->tx_idx = 0;
+		}
+		if (dev->tx_idx != dev->tx_free_idx)
+			writel(CR_TXE, dev->base + CR);
+			//kick_tx(dev);
+		else
+			dev->tx_idle = 1;
+		mb();
+		if (dev->tx_idx != dev->tx_free_idx)
+			kick_tx(dev);
+	}
+
+	/* Defer tx ring processing until more than a minimum amount of
+	 * work has accumulated
+	 */
+	if ((ISR_TXDESC | ISR_TXIDLE) & isr)
+		do_tx_done(dev);
+
+	if (ISR_PHY & isr)
+		phy_intr(dev);
+	}
+
+#if 0	/* Still working on the interrupt mitigation strategy */
+	if (dev->ihr)
+		writel(dev->ihr, dev->base + IHR);
+#endif
+}
+
+static void ns83820_do_reset(struct ns83820 *dev, u32 which)
+{
+	Dprintk("resetting chip...\n");
+	writel(which, dev->base + CR);
+	do {
+		schedule();
+	} while (readl(dev->base + CR) & which);
+	Dprintk("okay!\n");
+}
+
+static int ns83820_stop(struct net_device *_dev)
+{
+	struct ns83820 *dev = (struct ns83820 *)_dev;
+
+	/* FIXME: protect against interrupt handler? */
+
+	/* disable interrupts */
+	writel(0, dev->base + IMR);
+	writel(0, dev->base + IER);
+	readl(dev->base + IER);
+
+	dev->rx_info.up = 0;
+	synchronize_irq();
+
+	ns83820_do_reset(dev, CR_RST);
+
+	synchronize_irq();
+
+	dev->IMR_cache &= ~(ISR_TXURN | ISR_TXIDLE | ISR_TXERR | ISR_TXDESC | ISR_TXOK);
+	ns83820_cleanup_rx(dev);
+	ns83820_cleanup_tx(dev);
+
+	return 0;
+}
+
+static int ns83820_open(struct net_device *_dev)
+{
+	struct ns83820 *dev = (struct ns83820 *)_dev;
+	unsigned i;
+	u32 desc;
+	int ret;
+
+	dprintk("ns83820_open\n");
+
+	writel(0, dev->base + PQCR);
+
+	ret = ns83820_setup_rx(dev);
+	if (ret)
+		goto failed;
+
+	memset(dev->tx_descs, 0, 4 * NR_TX_DESC * DESC_SIZE);
+	for (i=0; i<NR_TX_DESC; i++) {
+		*(hw_addr_t *)(dev->tx_descs + (i * DESC_SIZE) + LINK)
+				= dev->tx_phy_descs
+				  + ((i+1) % NR_TX_DESC) * DESC_SIZE * 4;
+	}
+
+	dev->tx_idx = 0;
+	dev->tx_done_idx = 0;
+	desc = dev->tx_phy_descs;
+	writel(0, dev->base + TXDP_HI);
+	writel(desc, dev->base + TXDP);
+
+//printk("IMR: %08x / %08x\n", readl(dev->base + IMR), dev->IMR_cache);
+
+	set_bit(0, &dev->tx_idle);
+	netif_start_queue(&dev->net_dev);	/* FIXME: wait for phy to come up */
+
+	return 0;
+
+failed:
+	ns83820_stop(_dev);
+	return ret;
+}
+
+#if 0	/* FIXME: implement this! */
+static void ns83820_tx_timeout(struct net_device *_dev)
+{
+	struct ns83820 *dev = (struct ns83820 *)_dev;
+
+	printk("ns83820_tx_timeout\n");
+}
+#endif
+
+static void ns83820_getmac(struct ns83820 *dev, u8 *mac)
+{
+	unsigned i;
+	for (i=0; i<3; i++) {
+		u32 data;
+#if 0	/* I've left this in as an example of how to use eeprom.h */
+		data = eeprom_readw(&dev->ee, 0xa + 2 - i);
+#else
+		writel(i*2, dev->base + RFCR);
+		data = readl(dev->base + RFDR);
+#endif
+		*mac++ = data;
+		*mac++ = data >> 8;
+	}
+}
+
+static int ns83820_change_mtu(struct net_device *_dev, int new_mtu)
+{
+	if (new_mtu > RX_BUF_SIZE)
+		return -EINVAL;
+	_dev->mtu = new_mtu;
+	return 0;
+}
+
+static int ns83820_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
+{
+	struct ns83820 *dev;
+	long addr;
+	int err;
+
+	dev = (struct ns83820 *)alloc_etherdev((sizeof *dev) - (sizeof dev->net_dev));
+	err = -ENOMEM;
+	if (!dev)
+		goto out;
+
+	spin_lock_init(&dev->rx_info.lock);
+	spin_lock_init(&dev->tx_lock);
+	spin_lock_init(&dev->misc_lock);
+	dev->pci_dev = pci_dev;
+
+	dev->ee.cache = &dev->MEAR_cache;
+	dev->ee.lock = &dev->misc_lock;
+	dev->net_dev.owner = THIS_MODULE;
+
+	PREPARE_TQUEUE(&dev->tq_refill, queue_refill, dev);
+
+	err = pci_enable_device(pci_dev);
+	if (err) {
+		printk(KERN_INFO "ns83820: pci_enable_dev: %d\n", err);
+		goto out_free;
+	}
+
+	pci_set_master(pci_dev);
+	addr = pci_resource_start(pci_dev, 1);
+	dev->base = ioremap_nocache(addr, PAGE_SIZE);
+	dev->tx_descs = pci_alloc_consistent(pci_dev,
+			4 * DESC_SIZE * NR_TX_DESC, &dev->tx_phy_descs);
+	dev->rx_info.descs = pci_alloc_consistent(pci_dev,
+			4 * DESC_SIZE * NR_RX_DESC, &dev->rx_info.phy_descs);
+	err = -ENOMEM;
+	if (!dev->base || !dev->tx_descs || !dev->rx_info.descs)
+		goto out_disable;
+
+	dprintk("%p: %08lx  %p: %08lx\n", dev->tx_descs, dev->tx_phy_descs,
+		dev->rx_info.descs, dev->rx_info.phy_descs);
+	/* disable interrupts */
+	writel(0, dev->base + IMR);
+	writel(0, dev->base + IER);
+	readl(dev->base + IER);
+
+	dev->IMR_cache = 0;
+
+	setup_ee_mem_bitbanger(&dev->ee, (long)dev->base + MEAR, 3, 2, 1, 0,
+		0);
+
+	err = request_irq(pci_dev->irq, ns83820_irq, SA_SHIRQ,
+			  dev->net_dev.name, dev);
+	if (err) {
+		printk(KERN_INFO "ns83820: unable to register irq %d\n",
+			pci_dev->irq);
+		goto out_unmap;
+	}
+
+	dev->net_dev.open = ns83820_open;
+	dev->net_dev.stop = ns83820_stop;
+	dev->net_dev.hard_start_xmit = ns83820_hard_start_xmit;
+	dev->net_dev.change_mtu = ns83820_change_mtu;
+	//FIXME: dev->net_dev.tx_timeout = ns83820_tx_timeout;
+
+	lock_kernel();
+	dev->next_dev = ns83820_chain;
+	ns83820_chain = dev;
+	unlock_kernel();
+
+	ns83820_do_reset(dev, CR_RST);
+
+	dprintk("start bist\n");
+	writel(PTSCR_EEBIST_EN, dev->base + PTSCR);
+	do {
+		schedule();
+	} while (readl(dev->base + PTSCR) & PTSCR_EEBIST_EN);
+	dprintk("done bist\n");
+
+	dprintk("start eeload\n");
+	writel(PTSCR_EELOAD_EN, dev->base + PTSCR);
+	do {
+		schedule();
+	} while (readl(dev->base + PTSCR) & PTSCR_EELOAD_EN);
+	dprintk("done eeload\n");
+
+	/* I love config registers */
+	dev->CFG_cache = readl(dev->base + CFG);
+
+	if ((dev->CFG_cache & CFG_PCI64_DET)) {
+		printk("%s: enabling 64 bit PCI.\n", dev->net_dev.name);
+		dev->CFG_cache |= CFG_T64ADDR | CFG_DATA64_EN;
+	} else {
+		printk("%s: disabling 64 bit PCI.\n", dev->net_dev.name);
+		dev->CFG_cache &= ~(CFG_T64ADDR | CFG_DATA64_EN);
+	}
+	dev->CFG_cache &= (CFG_TBI_EN  | CFG_MRM_DIS   | CFG_MWI_DIS |
+			   CFG_T64ADDR | CFG_DATA64_EN | CFG_EXT_125 |
+			   CFG_M64ADDR);
+	dev->CFG_cache |= CFG_PINT_DUPSTS | CFG_PINT_LNKSTS | CFG_PINT_SPDSTS |
+			  CFG_EXTSTS_EN   | CFG_EXD         | CFG_PESEL;
+	dev->CFG_cache |= CFG_REQALG;
+	dev->CFG_cache |= CFG_POW;
+#ifdef USE_64BIT_ADDR
+	dev->CFG_cache |= CFG_M64ADDR;
+	printk("using 64 bit addressing\n");
+#endif
+#ifdef __LITTLE_ENDIAN
+	dev->CFG_cache &= ~CFG_BEM;
+#elif defined(__BIG_ENDIAN)
+	dev->CFG_cache |= CFG_BEM;
+#else
+#error This driver only works for big or little endian!!!
+#endif
+
+	writel(dev->CFG_cache, dev->base + CFG);
+	dprintk("CFG: %08x\n", dev->CFG_cache);
+
+	if (readl(dev->base + SRR))
+		writel(readl(dev->base+0x20c) | 0xfe00, dev->base + 0x20c);
+
+	/* Note!  The DMA burst size interacts with packet
+	 * transmission, such that the largest packet that
+	 * can be transmitted is 8192 - FLTH - burst size.
+	 * If only the transmit fifo was larger...
+	 */
+	writel(TXCFG_CSI | TXCFG_HBI | TXCFG_ATP | TXCFG_MXDMA1024
+		| ((1600 / 32) * 0x100),
+		dev->base + TXCFG);
+
+	/* Flush the interrupt holdoff timer */
+	writel(0x000, dev->base + IHR);
+	writel(0x100, dev->base + IHR);
+
+	/* Set Rx to full duplex, don't accept runt, errored, long or length
+	 * range errored packets.  Set MXDMA to 7 => 512 word burst
+	 */
+	writel(RXCFG_AEP | RXCFG_ARP | RXCFG_AIRL | RXCFG_RX_FD
+		| RXCFG_ALP
+		| RXCFG_MXDMA | 0, dev->base + RXCFG);
+
+	/* Disable priority queueing */
+	writel(0, dev->base + PQCR);
+
+	/* Enable IP checksum validation and detetion of VLAN headers.
+	 * Note: do not set the reject options as at least the 0x102
+	 * revision of the chip does not properly accept IP fragments
+	 * at least for UDP.
+	 */
+	writel(VRCR_IPEN | VRCR_VTDEN, dev->base + VRCR);
+
+	/* Enable per-packet TCP/UDP/IP checksumming */
+	writel(VTCR_PPCHK, dev->base + VTCR);
+
+	/* Disable Pause frames */
+	writel(0, dev->base + PCR);
+
+	/* Disable Wake On Lan */
+	writel(0, dev->base + WCSR);
+
+	ns83820_getmac(dev, dev->net_dev.dev_addr);
+
+	/* Yes, we support dumb IP checksum on transmit */
+	dev->net_dev.features |= NETIF_F_SG;
+	dev->net_dev.features |= NETIF_F_IP_CSUM;
+#if defined(USE_64BIT_ADDR) || defined(CONFIG_HIGHMEM4G)
+	dev->net_dev.features |= NETIF_F_HIGHDMA;
+#endif
+
+	register_netdev(&dev->net_dev);
+
+	printk(KERN_INFO "%s: ns83820.c v" VERSION ": DP83820 %02x:%02x:%02x:%02x:%02x:%02x pciaddr=0x%08lx irq=%d rev 0x%x\n",
+		dev->net_dev.name,
+		dev->net_dev.dev_addr[0], dev->net_dev.dev_addr[1],
+		dev->net_dev.dev_addr[2], dev->net_dev.dev_addr[3],
+		dev->net_dev.dev_addr[4], dev->net_dev.dev_addr[5],
+		addr, pci_dev->irq,
+		(unsigned)readl(dev->base + SRR)
+		);
+
+	return 0;
+
+out_unmap:
+	iounmap(dev->base);
+out_disable:
+	pci_free_consistent(pci_dev, 4 * DESC_SIZE * NR_TX_DESC, dev->tx_descs, dev->tx_phy_descs);
+	pci_free_consistent(pci_dev, 4 * DESC_SIZE * NR_RX_DESC, dev->rx_info.descs, dev->rx_info.phy_descs);
+	pci_disable_device(pci_dev);
+out_free:
+	kfree(dev);
+out:
+	return err;
+}
+
+static struct pci_device_id pci_device_id[] __devinitdata = {
+	{ 0x100b, 0x0022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+	{ 0, },
+};
+
+static struct pci_driver driver = {
+	name:		"ns83820",
+	id_table:	pci_device_id,
+	probe:		ns83820_probe,
+#if 0	/* FIXME: implement */
+	remove:		,
+	suspend:	,
+	resume:		,
+#endif
+};
+
+
+static int __init ns83820_init(void)
+{
+	printk(KERN_INFO "ns83820.c: National Semiconductor DP83820 10/100/100 driver.\n");
+	return pci_module_init(&driver);
+}
+
+static void ns83820_exit(void)
+{
+	struct ns83820	*dev;
+
+	for (dev = ns83820_chain; dev; ) {
+		struct ns83820 *next = dev->next_dev;
+
+		writel(0, dev->base + IMR);	/* paranoia */
+		writel(0, dev->base + IER);
+		readl(dev->base + IER);
+
+		unregister_netdev(&dev->net_dev);
+		free_irq(dev->pci_dev->irq, dev);
+		iounmap(dev->base);
+		pci_free_consistent(dev->pci_dev, 4 * DESC_SIZE * NR_TX_DESC,
+				dev->tx_descs, dev->tx_phy_descs);
+		pci_free_consistent(dev->pci_dev, 4 * DESC_SIZE * NR_RX_DESC,
+				dev->rx_info.descs, dev->rx_info.phy_descs);
+		pci_disable_device(dev->pci_dev);
+		kfree(dev);
+		dev = next;
+	}
+	pci_unregister_driver(&driver);
+	ns83820_chain = NULL;
+}
+
+MODULE_AUTHOR("Benjamin LaHaise <bcrl@redhat.com>");
+MODULE_DESCRIPTION("National Semiconductor DP83820 10/100/1000 driver");
+MODULE_DEVICE_TABLE(pci, pci_device_id);
+module_init(ns83820_init);
+module_exit(ns83820_exit);
diff -u --recursive --new-file v2.4.9/linux/drivers/net/pcnet32.c linux/drivers/net/pcnet32.c
--- v2.4.9/linux/drivers/net/pcnet32.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/net/pcnet32.c	Sun Sep  9 10:50:48 2001
@@ -179,6 +179,7 @@
  * v1.25kf Added No Interrupt on successful Tx for some Tx's <kaf@fc.hp.com>
  * v1.26   Converted to pci_alloc_consistent, Jamey Hicks / George France
  *                                           <jamey@crl.dec.com>
+ * v1.26p Fix oops on rmmod+insmod; plug i/o resource leak - Paul Gortmaker
  */
 
 
@@ -471,7 +472,7 @@
 
 
 
-static int __init
+static int __devinit
 pcnet32_probe_pci(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
     static int card_idx;
@@ -506,10 +507,11 @@
  *  Called from both pcnet32_probe_vlbus and pcnet_probe_pci.  
  *  pdev will be NULL when called from pcnet32_probe_vlbus.
  */
-static int __init
+static int __devinit
 pcnet32_probe1(unsigned long ioaddr, unsigned char irq_line, int shared, int card_idx, struct pci_dev *pdev)
 {
     struct pcnet32_private *lp;
+    struct resource *res;
     dma_addr_t lp_dma_addr;
     int i,media,fdx = 0, mii = 0, fset = 0;
 #ifdef DO_DXSUFLO
@@ -643,7 +645,7 @@
 	}
 	if( memcmp( promaddr, dev->dev_addr, 6) )
 	{
-	    printk(" warning PROM address does not match CSR address");
+	    printk(" warning PROM address does not match CSR address\n");
 #if defined(__i386__)
 	    printk(KERN_WARNING "%s: Probably a Compaq, using the PROM address of", dev->name);
 	    memcpy(dev->dev_addr, promaddr, 6);
@@ -682,11 +684,15 @@
     }
 
     dev->base_addr = ioaddr;
-    request_region(ioaddr, PCNET32_TOTAL_SIZE, chipname);
+    res = request_region(ioaddr, PCNET32_TOTAL_SIZE, chipname);
+    if (res == NULL)
+	return -EBUSY;
     
     /* pci_alloc_consistent returns page-aligned memory, so we do not have to check the alignment */
-    if ((lp = pci_alloc_consistent(pdev, sizeof(*lp), &lp_dma_addr)) == NULL)
+    if ((lp = pci_alloc_consistent(pdev, sizeof(*lp), &lp_dma_addr)) == NULL) {
+	release_resource(res);
 	return -ENOMEM;
+    }
 
     memset(lp, 0, sizeof(*lp));
     lp->dma_addr = lp_dma_addr;
@@ -715,6 +721,7 @@
     if (a == NULL) {
       printk(KERN_ERR "pcnet32: No access methods\n");
       pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr);
+      release_resource(res);
       return -ENODEV;
     }
     lp->a = *a;
@@ -762,6 +769,7 @@
 	else {
 	    printk(", failed to detect IRQ line.\n");
 	    pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr);
+	    release_resource(res);
 	    return -ENODEV;
 	}
     }
@@ -1579,6 +1587,8 @@
 	next_dev = lp->next;
 	unregister_netdev(pcnet32_dev);
 	release_region(pcnet32_dev->base_addr, PCNET32_TOTAL_SIZE);
+	if (lp->pci_dev != NULL)
+	    pci_unregister_driver(&pcnet32_driver);
         pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr);
 	kfree(pcnet32_dev);
 	pcnet32_dev = next_dev;
diff -u --recursive --new-file v2.4.9/linux/drivers/net/ppp_generic.c linux/drivers/net/ppp_generic.c
--- v2.4.9/linux/drivers/net/ppp_generic.c	Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/ppp_generic.c	Sun Sep  9 10:45:43 2001
@@ -636,7 +636,7 @@
 
 		if (copy_from_user(&uprog, (void *) arg, sizeof(uprog)))
 			break;
-		if (uprog.len > 0) {
+		if (uprog.len > 0 && uprog.len < 65536) {
 			err = -ENOMEM;
 			len = uprog.len * sizeof(struct sock_filter);
 			code = kmalloc(len, GFP_KERNEL);
diff -u --recursive --new-file v2.4.9/linux/drivers/net/sis900.c linux/drivers/net/sis900.c
--- v2.4.9/linux/drivers/net/sis900.c	Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/sis900.c	Sun Sep  9 10:45:43 2001
@@ -600,7 +600,7 @@
 /**
  * 	sis900_set_capability: - set the media capability of network adapter.
  *	@net_dev : the net device to probe for
- *	@mii_phy : default PHY
+ *	@phy : default PHY
  *
  *	Set the media capability of network adapter according to
  *	mii status register. It's necessary before auto-negotiate.
@@ -1190,6 +1190,7 @@
 
 /**
  *	sis900_set_mode: - Set the media mode of mac register.
+ *	@ioaddr: the address of the device
  *	@speed : the transmit speed to be determined
  *	@duplex: the duplex mode to be determined
  *
diff -u --recursive --new-file v2.4.9/linux/drivers/net/sk98lin/h/skdrv1st.h linux/drivers/net/sk98lin/h/skdrv1st.h
--- v2.4.9/linux/drivers/net/sk98lin/h/skdrv1st.h	Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/sk98lin/h/skdrv1st.h	Sun Sep  9 10:45:43 2001
@@ -113,7 +113,7 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <asm/byteorder.h>
diff -u --recursive --new-file v2.4.9/linux/drivers/net/smc9194.c linux/drivers/net/smc9194.c
--- v2.4.9/linux/drivers/net/smc9194.c	Wed Jul 25 17:10:22 2001
+++ linux/drivers/net/smc9194.c	Sat Sep  8 12:14:25 2001
@@ -88,7 +88,11 @@
  . Do you want to use 32 bit xfers?  This should work on all chips, as
  . the chipset is designed to accommodate them.
 */
+#ifdef __sh__
+#undef USE_32_BIT
+#else
 #define USE_32_BIT 1
+#endif
 
 /*
  .the SMC9194 can be at any of the following port addresses.  To change,
@@ -983,12 +987,6 @@
 		retval = -ENODEV;
 		goto err_out;
 	}
-	if (dev->irq == 2) {
-		/* Fixup for users that don't know that IRQ 2 is really IRQ 9,
-		 * or don't know which one to set.
-		 */
-		dev->irq = 9;
-	}
 
 	/* now, print out the card info, in a short format.. */
 
@@ -1369,13 +1367,11 @@
 			packet_length & 0x3  );
 #else
 		PRINTK3((" Reading %d words and %d byte(s) \n",
-			(packet_length >> 1 ), packet_length & 1 );
-		if ( packet_length & 1 )
-			*(data++) = inb( ioaddr + DATA_1 );
-		insw(ioaddr + DATA_1 , data, (packet_length + 1 ) >> 1);
+			(packet_length >> 1 ), packet_length & 1 ));
+		insw(ioaddr + DATA_1 , data, packet_length >> 1);
 		if ( packet_length & 1 ) {
 			data += packet_length & ~1;
-			*((data++) = inb( ioaddr + DATA_1 );
+			*(data++) = inb( ioaddr + DATA_1 );
 		}
 #endif
 #if	SMC_DEBUG > 2
diff -u --recursive --new-file v2.4.9/linux/drivers/net/smc9194.h linux/drivers/net/smc9194.h
--- v2.4.9/linux/drivers/net/smc9194.h	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/smc9194.h	Sat Sep  8 12:13:55 2001
@@ -169,7 +169,8 @@
 	/* 5 */ "SMC91C95",
 	NULL,
 	/* 7 */ "SMC91C100", 
-	NULL, NULL, NULL, NULL, 
+	/* 8 */ "SMC91C100FD", 
+	NULL, NULL, NULL, 
 	NULL, NULL, NULL};  
 
 /* 
diff -u --recursive --new-file v2.4.9/linux/drivers/net/starfire.c linux/drivers/net/starfire.c
--- v2.4.9/linux/drivers/net/starfire.c	Sun Aug 12 13:27:59 2001
+++ linux/drivers/net/starfire.c	Fri Sep  7 09:28:38 2001
@@ -89,13 +89,29 @@
 	- Initialize the TxMode register properly
 	- Don't dereference dev->priv after freeing it
 
+	LK1.3.4 (Ion Badulescu)
+	- Fixed initialization timing problems
+	- Fixed interrupt mask definitions
+
 TODO:
 	- implement tx_timeout() properly
 */
 
 #define DRV_NAME	"starfire"
-#define DRV_VERSION	"1.03+LK1.3.3"
-#define DRV_RELDATE	"July 05, 2001"
+#define DRV_VERSION	"1.03+LK1.3.4"
+#define DRV_RELDATE	"August 14, 2001"
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <asm/processor.h>		/* Processor type for cache alignment. */
+#include <asm/uaccess.h>
+#include <asm/io.h>
 
 /*
  * Adaptec's license for their Novell drivers (which is where I got the
@@ -124,6 +140,10 @@
 #define ZEROCOPY
 #endif
 
+#ifdef HAS_FIRMWARE
+#include "starfire_firmware.h"
+#endif /* HAS_FIRMWARE */
+
 /* The user-configurable values.
    These may be modified when a driver module is loaded.*/
 
@@ -196,22 +216,6 @@
 #define skb_first_frag_len(skb)	(skb->len)
 #endif /* not ZEROCOPY */
 
-#include <linux/version.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <asm/processor.h>		/* Processor type for cache alignment. */
-#include <asm/uaccess.h>
-#include <asm/io.h>
-
-#ifdef HAS_FIRMWARE
-#include "starfire_firmware.h"
-#endif /* HAS_FIRMWARE */
-
 /* 2.2.x compatibility code */
 #if LINUX_VERSION_CODE < 0x20300
 
@@ -242,7 +246,6 @@
 /* These identify the driver base version and may not be removed. */
 static char version[] __devinitdata =
 KERN_INFO "starfire.c:v1.03 7/26/2000  Written by Donald Becker <becker@scyld.com>\n"
-KERN_INFO " Updates and info at http://www.scyld.com/network/starfire.html\n"
 KERN_INFO " (unofficial 2.2/2.4 kernel port, version " DRV_VERSION ", " DRV_RELDATE ")\n";
 
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
@@ -417,7 +420,7 @@
 	/* not quite bits */
 	IntrRxDone=IntrRxQ2Done | IntrRxQ1Done,
 	IntrRxEmpty=IntrRxDescQ1Low | IntrRxDescQ2Low,
-	IntrNormalMask=0xf0, IntrAbnormalMask=0x3f0e,
+	IntrNormalMask=0xff00, IntrAbnormalMask=0x3ff00fe,
 };
 
 /* Bits in the RxFilterMode register. */
@@ -656,10 +659,7 @@
 
 #ifdef ZEROCOPY
 	/* Starfire can do SG and TCP/UDP checksumming */
-	dev->features |= NETIF_F_SG;
-#ifdef HAS_FIRMWARE
-	dev->features |= NETIF_F_IP_CSUM;
-#endif /* HAS_FIRMWARE */
+	dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
 #endif /* ZEROCOPY */
 
 	/* Serial EEPROM reads are hidden by the hardware. */
@@ -745,7 +745,7 @@
 		int mii_status;
 		for (phy = 0; phy < 32 && phy_idx < PHY_CNT; phy++) {
 			mdio_write(dev, phy, MII_BMCR, BMCR_RESET);
-			udelay(500);
+			mdelay(100);
 			boguscnt = 1000;
 			while (--boguscnt > 0)
 				if ((mdio_read(dev, phy, MII_BMCR) & BMCR_RESET) == 0)
@@ -768,6 +768,14 @@
 		np->phy_cnt = phy_idx;
 	}
 
+#ifdef ZEROCOPY
+	printk(KERN_INFO "%s: scatter-gather and hardware TCP cksumming enabled.\n",
+	       dev->name,
+#else  /* not ZEROCOPY */
+	printk(KERN_INFO "%s: scatter-gather and hardware TCP cksumming disabled.\n",
+	       dev->name);
+#endif /* not ZEROCOPY */
+
 	return 0;
 
 err_out_cleardev:
@@ -931,6 +939,7 @@
 	/* Configure the PCI bus bursts and FIFO thresholds. */
 	np->tx_mode = 0x0C04;		/* modified when link is up. */
 	writel(0x8000 | np->tx_mode, ioaddr + TxMode);
+	udelay(1000);
 	writel(np->tx_mode, ioaddr + TxMode);
 	np->tx_threshold = 4;
 	writel(np->tx_threshold, ioaddr + TxThreshold);
@@ -1546,6 +1555,7 @@
 		if (np->tx_mode != new_tx_mode) {
 			np->tx_mode = new_tx_mode;
 			writel(np->tx_mode | 0x8000, ioaddr + TxMode);
+			udelay(1000);
 			writel(np->tx_mode, ioaddr + TxMode);
 		}
 	} else {
diff -u --recursive --new-file v2.4.9/linux/drivers/net/starfire_firmware.pl linux/drivers/net/starfire_firmware.pl
--- v2.4.9/linux/drivers/net/starfire_firmware.pl	Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/starfire_firmware.pl	Fri Sep  7 09:28:38 2001
@@ -0,0 +1,31 @@
+#!/usr/bin/perl
+
+# This script can be used to generate a new starfire_firmware.h
+# from GFP_RX.DAT and GFP_TX.DAT, files included with the DDK
+# and also with the Novell drivers.
+
+open FW, "GFP_RX.DAT" || die;
+open FWH, ">starfire_firmware.h" || die;
+
+printf(FWH "static u32 firmware_rx[] = {\n");
+$counter = 0;
+while ($foo = <FW>) {
+  chomp;
+  printf(FWH "  0x%s, 0x0000%s,\n", substr($foo, 4, 8), substr($foo, 0, 4));
+  $counter++;
+}
+
+close FW;
+open FW, "GFP_TX.DAT" || die;
+
+printf(FWH "};\t/* %d Rx instructions */\n#define FIRMWARE_RX_SIZE %d\n\nstatic u32 firmware_tx[] = {\n", $counter, $counter);
+$counter = 0;
+while ($foo = <FW>) {
+  chomp;
+  printf(FWH "  0x%s, 0x0000%s,\n", substr($foo, 4, 8), substr($foo, 0, 4));
+  $counter++;
+}
+
+close FW;
+printf(FWH "};\t/* %d Tx instructions */\n#define FIRMWARE_TX_SIZE %d\n", $counter, $counter);
+close(FWH);
diff -u --recursive --new-file v2.4.9/linux/drivers/net/tulip/tulip_core.c linux/drivers/net/tulip/tulip_core.c
--- v2.4.9/linux/drivers/net/tulip/tulip_core.c	Sun Aug 12 13:27:59 2001
+++ linux/drivers/net/tulip/tulip_core.c	Sun Sep  9 16:28:20 2001
@@ -1503,6 +1503,10 @@
 #ifdef CONFIG_TULIP_MWI
 	if (!force_csr0 && (tp->flags & HAS_PCI_MWI))
 		tulip_mwi_config (pdev, dev);
+#else
+	/* MWI is broken for DC21143 rev 65... */
+	if (chip_idx == DC21143 && chip_rev == 65)
+		tp->csr0 &= ~MWI;
 #endif
 
 	/* Stop the chip's Tx and Rx processes. */
diff -u --recursive --new-file v2.4.9/linux/drivers/net/via-rhine.c linux/drivers/net/via-rhine.c
--- v2.4.9/linux/drivers/net/via-rhine.c	Wed Jul 25 17:10:22 2001
+++ linux/drivers/net/via-rhine.c	Fri Sep  7 09:28:38 2001
@@ -69,6 +69,10 @@
 	- Manfred Spraul: use "singlecopy" for unaligned buffers
 	                  don't allocate bounce buffers for !ReqTxAlign cards
 
+	LK1.1.11:
+	- David Woodhouse: Set dev->base_addr before the first time we call
+					   wait_for_reset(). It's a lot happier that way.
+					   Free np->tx_bufs only if we actually allocated it.
 */
 
 
@@ -151,7 +155,7 @@
 
 /* These identify the driver base version and may not be removed. */
 static char version[] __devinitdata =
-KERN_INFO "via-rhine.c:v1.10-LK1.1.10  07/12/2001  Written by Donald Becker\n"
+KERN_INFO "via-rhine.c:v1.10-LK1.1.11  20/08/2001  Written by Donald Becker\n"
 KERN_INFO "  http://www.scyld.com/network/via-rhine.html\n";
 
 static char shortname[] __devinitdata = "via-rhine";
@@ -584,6 +588,8 @@
 
 	/* Reset the chip to erase previous misconfiguration. */
 	writew(CmdReset, ioaddr + ChipCmd);
+
+	dev->base_addr = ioaddr;
 	wait_for_reset(dev, shortname);
 
 	/* Reload the station address from the EEPROM. */
@@ -609,7 +615,6 @@
 		writeb(readb(ioaddr + ConfigA) & 0xFE, ioaddr + ConfigA);
 	}
 
-	dev->base_addr = ioaddr;
 	dev->irq = pdev->irq;
 
 	np = dev->priv;
@@ -758,8 +763,11 @@
 			    TX_RING_SIZE * sizeof(struct tx_desc),
 			    np->rx_ring, np->rx_ring_dma);
 
-	pci_free_consistent(np->pdev, PKT_BUF_SZ * TX_RING_SIZE,
-						np->tx_bufs, np->tx_bufs_dma);
+	if (np->tx_bufs)
+		pci_free_consistent(np->pdev, PKT_BUF_SZ * TX_RING_SIZE,
+							np->tx_bufs, np->tx_bufs_dma);
+
+	np->tx_bufs = NULL;
 
 }
 
diff -u --recursive --new-file v2.4.9/linux/drivers/net/wan/dscc4.c linux/drivers/net/wan/dscc4.c
--- v2.4.9/linux/drivers/net/wan/dscc4.c	Fri Apr 20 11:54:22 2001
+++ linux/drivers/net/wan/dscc4.c	Sat Sep  1 11:01:28 2001
@@ -348,7 +348,7 @@
 {
 	struct sk_buff *skb;
 
-	skb = dev_alloc_skb(RX_MAX(dev->mtu+2));
+	skb = dev_alloc_skb(RX_MAX(HDLC_MAX_MRU+2));
 	priv->rx_skbuff[cur] = skb;
 	if (!skb) {
 		priv->rx_fd[cur--].data = (u32) NULL;
@@ -428,9 +428,9 @@
 	int pkt_len;
 
 	skb = dpriv->rx_skbuff[cur];
-	pkt_len = TO_SIZE(rx_fd->state2);
-	pci_dma_sync_single(pdev, rx_fd->data, pkt_len, PCI_DMA_FROMDEVICE);
-	if((skb->data[pkt_len - 1] & FrameOk) == FrameOk) {
+	pkt_len = TO_SIZE(rx_fd->state2) - 1;
+	pci_dma_sync_single(pdev, rx_fd->data, pkt_len + 1, PCI_DMA_FROMDEVICE);
+	if((skb->data[pkt_len] & FrameOk) == FrameOk) {
 		pci_unmap_single(pdev, rx_fd->data, skb->len, PCI_DMA_FROMDEVICE);
 		dpriv->stats.rx_packets++;
 		dpriv->stats.rx_bytes += pkt_len;
@@ -442,11 +442,11 @@
 			netif_rx(skb);
 		try_get_rx_skb(dpriv, cur, dev);
 	} else {
-		if(skb->data[pkt_len - 1] & FrameRdo)
+		if(skb->data[pkt_len] & FrameRdo)
 			dpriv->stats.rx_fifo_errors++;
-		else if(!(skb->data[pkt_len - 1] | ~FrameCrc))
+		else if(!(skb->data[pkt_len] | ~FrameCrc))
 			dpriv->stats.rx_crc_errors++;
-		else if(!(skb->data[pkt_len - 1] | ~FrameVfr))
+		else if(!(skb->data[pkt_len] | ~FrameVfr))
 			dpriv->stats.rx_length_errors++;
 		else
 			dpriv->stats.rx_errors++;
@@ -760,7 +760,7 @@
 	/* FIXME: VIS */
 	writel(readl(ioaddr + CCR0) | 0x80001000, ioaddr + CCR0);
 
-	writel(LengthCheck | (dev->mtu >> 5), ioaddr + RLCR);
+	writel(LengthCheck | (HDLC_MAX_MRU >> 5), ioaddr + RLCR);
 
 	/* no address recognition/crc-CCITT/cts enabled */
 	writel(readl(ioaddr + CCR1) | 0x021c8000, ioaddr + CCR1);
@@ -1224,7 +1224,7 @@
 		       dev->name, SOURCE_ID(state), state );
 		return;
 	}
-	if (state & 0x0df80c01) {
+	if (state & 0x0df80c00) {
 		printk(KERN_DEBUG "%s (Tx): state=%08x (UFO alert)\n",
 		       dev->name, state);
 		return;
@@ -1377,7 +1377,7 @@
 		       dev->name, SOURCE_ID(state), state);
 		goto try;
 	}
-	if (state & 0x0df80c01) {
+	if (state & 0x0df80c00) {
 		printk(KERN_DEBUG "%s (Rx): state=%08x (UFO alert)\n",
 		       dev->name, state);
 		goto try;
@@ -1609,7 +1609,7 @@
 	        rx_fd->state1 = HiDesc; /* Hi, no Hold */
 	        rx_fd->state2 = 0x00000000;
 	        rx_fd->end = 0xbabeface;
-	        rx_fd->state1 |= ((u32)(dev->mtu & RxSizeMax)) << 16;
+	        rx_fd->state1 |= ((u32)(HDLC_MAX_MRU & RxSizeMax)) << 16;
 		try_get_rx_skb(dpriv, i, dev);
 		i++;
 		rx_fd->next = (u32)(dpriv->rx_fd_dma + i*sizeof(struct RxFD));
@@ -1720,7 +1720,7 @@
 	hdlc = &dpriv->hdlc;
 	/* XXX: Don't look at the next line */
 	hdlc->netdev.base_addr = (unsigned long)dev;
-	// FIXME: set hdlc->set_mode ?
+	hdlc->set_mode = NULL;
 	hdlc->open = dscc4_hdlc_open;
 	hdlc->close = dscc4_hdlc_close;
 	hdlc->ioctl = dscc4_hdlc_ioctl;
diff -u --recursive --new-file v2.4.9/linux/drivers/net/wan/farsync.c linux/drivers/net/wan/farsync.c
--- v2.4.9/linux/drivers/net/wan/farsync.c	Mon Aug 27 12:41:43 2001
+++ linux/drivers/net/wan/farsync.c	Sun Sep  9 10:45:53 2001
@@ -1200,7 +1200,8 @@
                 /* Sanity check the parameters. We don't support partial writes
                  * when going over the top
                  */
-                if ( wrthdr.size + wrthdr.offset > FST_MEMSIZE )
+                if ( wrthdr.size > FST_MEMSIZE || wrthdr.offset > FST_MEMSIZE
+                                || wrthdr.size + wrthdr.offset > FST_MEMSIZE )
                 {
                         return -ENXIO;
                 }
@@ -1829,3 +1830,4 @@
 module_init ( fst_init );
 module_exit ( fst_cleanup_module );
 
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.9/linux/drivers/net/wan/hostess_sv11.c linux/drivers/net/wan/hostess_sv11.c
--- v2.4.9/linux/drivers/net/wan/hostess_sv11.c	Wed Apr 18 14:40:07 2001
+++ linux/drivers/net/wan/hostess_sv11.c	Sun Sep  9 10:50:48 2001
@@ -400,7 +400,6 @@
 static int io=0x200;
 static int irq=9;
 
-#ifdef LINUX_21
 MODULE_PARM(io,"i");
 MODULE_PARM_DESC(io, "The I/O base of the Comtrol Hostess SV11 card");
 MODULE_PARM(dma,"i");
@@ -408,9 +407,9 @@
 MODULE_PARM(irq,"i");
 MODULE_PARM_DESC(irq, "The interrupt line setting for the Comtrol Hostess SV11 card");
 
-MODULE_AUTHOR("Bulding Number Three Ltd");
+MODULE_AUTHOR("Alan Cox");
+MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Modular driver for the Comtrol Hostess SV11");
-#endif
 
 static struct sv11_device *sv11_unit;
 
diff -u --recursive --new-file v2.4.9/linux/drivers/net/wan/sbni.c linux/drivers/net/wan/sbni.c
--- v2.4.9/linux/drivers/net/wan/sbni.c	Mon Aug 27 12:41:43 2001
+++ linux/drivers/net/wan/sbni.c	Sun Sep  9 10:50:48 2001
@@ -11,7 +11,7 @@
  *	at http://www.granch.com (English) or http://www.granch.ru (Russian)
  *
  *	This software may be used and distributed according to the terms
- *	of the GNU Public License.
+ *	of the GNU General Public License.
  *
  *
  *  5.0.1	Jun 22 2001
@@ -1473,6 +1473,8 @@
 MODULE_PARM(	mac,	"1-" __MODULE_STRING( SBNI_MAX_NUM_CARDS ) "i" );
 
 MODULE_PARM(	skip_pci_probe,	"i" );
+
+MODULE_LICENSE("GPL");
 
 
 int
diff -u --recursive --new-file v2.4.9/linux/drivers/net/wan/sdla_chdlc.c linux/drivers/net/wan/sdla_chdlc.c
--- v2.4.9/linux/drivers/net/wan/sdla_chdlc.c	Mon Aug 27 12:41:43 2001
+++ linux/drivers/net/wan/sdla_chdlc.c	Sat Sep  8 12:32:09 2001
@@ -48,6 +48,7 @@
 * Aug 07, 1998	David Fong	Initial version.
 *****************************************************************************/
 
+#include <linux/module.h>
 #include <linux/version.h>
 #include <linux/kernel.h>	/* printk(), and other useful stuff */
 #include <linux/stddef.h>	/* offsetof(), etc. */
diff -u --recursive --new-file v2.4.9/linux/drivers/net/wan/sdla_fr.c linux/drivers/net/wan/sdla_fr.c
--- v2.4.9/linux/drivers/net/wan/sdla_fr.c	Mon Aug 27 12:41:43 2001
+++ linux/drivers/net/wan/sdla_fr.c	Sat Sep  8 12:32:09 2001
@@ -138,6 +138,7 @@
 * Jan 02, 1997	Gene Kozin	Initial version.
 *****************************************************************************/
 
+#include <linux/module.h>
 #include <linux/version.h>
 #include <linux/kernel.h>	/* printk(), and other useful stuff */
 #include <linux/stddef.h>	/* offsetof(), etc. */
diff -u --recursive --new-file v2.4.9/linux/drivers/net/wan/sdla_ft1.c linux/drivers/net/wan/sdla_ft1.c
--- v2.4.9/linux/drivers/net/wan/sdla_ft1.c	Mon Aug 27 12:41:43 2001
+++ linux/drivers/net/wan/sdla_ft1.c	Sat Sep  8 12:32:09 2001
@@ -20,6 +20,7 @@
 * Aug 07, 1998	David Fong	Initial version.
 *****************************************************************************/
 
+#include <linux/module.h>
 #include <linux/version.h>
 #include <linux/kernel.h>	/* printk(), and other useful stuff */
 #include <linux/stddef.h>	/* offsetof(), etc. */
diff -u --recursive --new-file v2.4.9/linux/drivers/net/wan/sdla_ppp.c linux/drivers/net/wan/sdla_ppp.c
--- v2.4.9/linux/drivers/net/wan/sdla_ppp.c	Mon Aug 27 12:41:43 2001
+++ linux/drivers/net/wan/sdla_ppp.c	Sat Sep  8 12:32:09 2001
@@ -90,6 +90,7 @@
 * Jan 06, 1997	Gene Kozin	Initial version.
 *****************************************************************************/
 
+#include <linux/module.h>
 #include <linux/version.h>
 #include <linux/kernel.h>	/* printk(), and other useful stuff */
 #include <linux/stddef.h>	/* offsetof(), etc. */
diff -u --recursive --new-file v2.4.9/linux/drivers/net/wan/sdla_x25.c linux/drivers/net/wan/sdla_x25.c
--- v2.4.9/linux/drivers/net/wan/sdla_x25.c	Mon Aug 27 12:41:43 2001
+++ linux/drivers/net/wan/sdla_x25.c	Sat Sep  8 12:32:09 2001
@@ -81,6 +81,7 @@
  * 	Includes 
  *=====================================================*/
 
+#include <linux/module.h>
 #include <linux/version.h>
 #include <linux/kernel.h>	/* printk(), and other useful stuff */
 #include <linux/stddef.h>	/* offsetof(), etc. */
diff -u --recursive --new-file v2.4.9/linux/drivers/net/wan/sealevel.c linux/drivers/net/wan/sealevel.c
--- v2.4.9/linux/drivers/net/wan/sealevel.c	Wed Apr 18 14:40:07 2001
+++ linux/drivers/net/wan/sealevel.c	Sun Sep  9 10:50:48 2001
@@ -9,6 +9,7 @@
  *	2 of the License, or (at your option) any later version.
  *
  *	(c) Copyright 1999 Building Number Three Ltd
+ *	(c) Copyright 2001 Alan Cox.
  *
  */
 
@@ -455,7 +456,8 @@
 MODULE_PARM(slow,"i");
 MODULE_PARM_DESC(slow, "Set this for an older Sealevel card such as the 4012");
 
-MODULE_AUTHOR("Bulding Number Three Ltd");
+MODULE_AUTHOR("Alan Cox");
+MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Modular driver for the SeaLevel 4021");
 #endif
 
diff -u --recursive --new-file v2.4.9/linux/drivers/net/wan/wanpipe_multppp.c linux/drivers/net/wan/wanpipe_multppp.c
--- v2.4.9/linux/drivers/net/wan/wanpipe_multppp.c	Mon Aug 27 12:41:43 2001
+++ linux/drivers/net/wan/wanpipe_multppp.c	Sat Sep  8 12:32:09 2001
@@ -17,6 +17,7 @@
 *  		module.
 *****************************************************************************/
 
+#include <linux/module.h>
 #include <linux/version.h>
 #include <linux/kernel.h>	/* printk(), and other useful stuff */
 #include <linux/stddef.h>	/* offsetof(), etc. */
diff -u --recursive --new-file v2.4.9/linux/drivers/net/wan/z85230.c linux/drivers/net/wan/z85230.c
--- v2.4.9/linux/drivers/net/wan/z85230.c	Tue Mar  6 19:44:37 2001
+++ linux/drivers/net/wan/z85230.c	Sun Sep  9 10:50:48 2001
@@ -1739,7 +1739,7 @@
 /*
  *	Module support
  */
-static const char banner[] __initdata = KERN_INFO "Generic Z85C30/Z85230 interface driver v0.02\n";
+static char banner[] __initdata = KERN_INFO "Generic Z85C30/Z85230 interface driver v0.02\n";
 
 static int __init z85230_init_driver(void)
 {
@@ -1752,3 +1752,7 @@
 {
 }
 module_exit(z85230_cleanup_driver);
+
+MODULE_AUTHOR("Red Hat Inc.");
+MODULE_DESCRIPTION("Z85x30 synchronous driver core");
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.9/linux/drivers/net/wireless/airport.c linux/drivers/net/wireless/airport.c
--- v2.4.9/linux/drivers/net/wireless/airport.c	Mon Aug 27 12:41:43 2001
+++ linux/drivers/net/wireless/airport.c	Mon Aug 27 09:00:37 2001
@@ -5,6 +5,10 @@
  *
  * Copyright notice & release notes in file orinoco.c
  * 
+ * Note specific to airport stub:
+ * 
+ *  0.05 : first version of the new split driver
+ *  0.06 : fix possible hang on powerup, add sleep support
  */
 
 #include <linux/module.h>
@@ -25,9 +29,12 @@
 #include <linux/etherdevice.h>
 #include <linux/wireless.h>
 #include <linux/list.h>
+#include <linux/adb.h>
+#include <linux/pmu.h>
 
 #include <asm/prom.h>
 #include <asm/feature.h>
+#include <asm/irq.h>
 
 #include "hermes.h"
 #include "orinoco.h"
@@ -40,10 +47,18 @@
 	struct device_node* node;
 	int irq_requested;
 	int ndev_registered;
+	int open;
 	/* Common structure (fully included), see orinoco.h */
 	struct dldwd_priv priv;
 } dldwd_card_t;
 
+#ifdef CONFIG_PMAC_PBOOK
+static int airport_sleep_notify(struct pmu_sleep_notifier *self, int when);
+static struct pmu_sleep_notifier airport_sleep_notifier = {
+	airport_sleep_notify, SLEEP_LEVEL_NET,
+};
+#endif
+
 /*
  * Function prototypes
  */
@@ -69,24 +84,15 @@
 static int airport_init(struct net_device *dev)
 {
 	dldwd_priv_t *priv = dev->priv;
-	dldwd_card_t* card = (dldwd_card_t *)priv->card;
 	int rc;
 	
 	TRACE_ENTER(priv->ndev.name);
 
 	MOD_INC_USE_COUNT;
 
-	feature_set_airport_power(card->node, 1);
-	current->state = TASK_UNINTERRUPTIBLE;
-	schedule_timeout(HZ);
-
 	rc = dldwd_init(dev);
-	if (rc) {	
-		feature_set_airport_power(card->node, 0);
-		current->state = TASK_UNINTERRUPTIBLE;
-		schedule_timeout(HZ);
-	}
-	priv->hw_ready = 1;
+	if (!rc)
+		priv->hw_ready = 1;
 
 	MOD_DEC_USE_COUNT;
 
@@ -97,18 +103,20 @@
 airport_open(struct net_device *dev)
 {
 	dldwd_priv_t *priv = dev->priv;
+	dldwd_card_t* card = (dldwd_card_t *)priv->card;
 	int rc;
 
 	TRACE_ENTER(priv->ndev.name);
 
-	netif_device_attach(dev);
 	rc = dldwd_reset(priv);
 	if (rc)
 		airport_stop(dev);
-	else
-		netif_start_queue(dev);
+	else {
+		card->open = 1;
+		netif_device_attach(dev);
+	}
 
-	TRACE_EXIT(priv->ndev.name);
+//	TRACE_EXIT(priv->ndev.name);
 
 	return rc;
 }
@@ -117,18 +125,66 @@
 airport_stop(struct net_device *dev)
 {
 	dldwd_priv_t *priv = dev->priv;
+	dldwd_card_t* card = (dldwd_card_t *)priv->card;
 
 	TRACE_ENTER(priv->ndev.name);
 
 	netif_stop_queue(dev);
-
 	dldwd_shutdown(priv);
+	card->open = 0;
 
 	TRACE_EXIT(priv->ndev.name);
 
 	return 0;
 }
 
+#ifdef CONFIG_PMAC_PBOOK
+static int
+airport_sleep_notify(struct pmu_sleep_notifier *self, int when)
+{
+	dldwd_priv_t *priv;
+	struct net_device *ndev;
+	dldwd_card_t* card;
+	int rc;
+	
+	if (!airport_dev)
+		return PBOOK_SLEEP_OK;
+	priv = airport_dev;
+	ndev = &priv->ndev;
+	card = (dldwd_card_t *)priv->card;
+
+	switch (when) {
+	case PBOOK_SLEEP_REQUEST:
+		break;
+	case PBOOK_SLEEP_REJECT:
+		break;
+	case PBOOK_SLEEP_NOW:
+		printk(KERN_INFO "%s: Airport entering sleep mode\n", ndev->name);
+		netif_device_detach(ndev);
+		if (card->open)
+			dldwd_shutdown(priv);
+		disable_irq(ndev->irq);
+		feature_set_airport_power(card->node, 0);
+		priv->hw_ready = 0;
+		break;
+	case PBOOK_WAKE:
+		printk(KERN_INFO "%s: Airport waking up\n", ndev->name);
+		feature_set_airport_power(card->node, 1);
+		mdelay(200);
+		hermes_reset(&priv->hw);
+		priv->hw_ready = 1;		
+		rc = dldwd_reset(priv);
+		if (rc)
+			printk(KERN_ERR "airport: Error %d re-initing card !\n", rc);
+		else if (card->open)
+			netif_device_attach(ndev);
+		enable_irq(ndev->irq);
+		break;
+	}
+	return PBOOK_SLEEP_OK;
+}
+#endif /* CONFIG_PMAC_PBOOK */
+
 static dldwd_priv_t*
 airport_attach(struct device_node* of_node)
 {
@@ -175,6 +231,14 @@
 
 	hermes_struct_init(hw, ndev->base_addr);
 		
+	/* Power up card */
+	feature_set_airport_power(card->node, 1);
+	current->state = TASK_UNINTERRUPTIBLE;
+	schedule_timeout(HZ);
+
+	/* Reset it before we get the interrupt */
+	hermes_reset(hw);
+
 	if (request_irq(ndev->irq, dldwd_interrupt, 0, "Airport", (void *)priv)) {
 		printk(KERN_ERR "airport: Couldn't get IRQ %d\n", ndev->irq);
 		goto failed;
@@ -198,6 +262,9 @@
 		printk(KERN_ERR "airport: Failed to create /proc node for %s\n",
 		       ndev->name);
 
+#ifdef CONFIG_PMAC_PBOOK
+	pmu_register_sleep_notifier(&airport_sleep_notifier);
+#endif
 	return priv;
 	
 failed:
@@ -219,6 +286,9 @@
 	/* Unregister proc entry */
 	dldwd_proc_dev_cleanup(priv);
 
+#ifdef CONFIG_PMAC_PBOOK
+	pmu_unregister_sleep_notifier(&airport_sleep_notifier);
+#endif
 	if (card->ndev_registered)
 		unregister_netdev(&priv->ndev);
 	card->ndev_registered = 0;
@@ -265,8 +335,6 @@
 		airport_detach(airport_dev);
 	airport_dev = NULL;
 }
-
-MODULE_DESCRIPTION("Apple Airport driver");
 
 module_init(init_airport);
 module_exit(exit_airport);
diff -u --recursive --new-file v2.4.9/linux/drivers/parport/ChangeLog linux/drivers/parport/ChangeLog
--- v2.4.9/linux/drivers/parport/ChangeLog	Mon Aug 27 12:41:43 2001
+++ linux/drivers/parport/ChangeLog	Fri Sep  7 18:15:17 2001
@@ -1,3 +1,13 @@
+2001-08-30  Tim Waugh  <twaugh@redhat.com>
+
+	* parport_serial.c (parport_serial_pci_probe): Clean-up on partial
+	registration failure.
+
+2001-08-14  Tim Waugh  <twaugh@redhat.com>
+
+	* parport_pc.c (parport_pc_init_superio): Allow for more than one
+	SuperIO device.  Patch from Rich Lio (ITE).
+
 2001-08-11  Tim Waugh  <twaugh@redhat.com>
 
 	* parport_pc.c: Support for Titan Electronics cards.
diff -u --recursive --new-file v2.4.9/linux/drivers/parport/parport_pc.c linux/drivers/parport/parport_pc.c
--- v2.4.9/linux/drivers/parport/parport_pc.c	Mon Aug 27 12:41:43 2001
+++ linux/drivers/parport/parport_pc.c	Fri Sep  7 18:15:17 2001
@@ -2756,17 +2756,20 @@
 {
 	const struct pci_device_id *id;
 	struct pci_dev *pdev;
+	int ret = 0;
 
 	pci_for_each_dev(pdev) {
 		id = pci_match_device (parport_pc_pci_tbl, pdev);
 		if (id == NULL || id->driver_data >= last_sio)
 			continue;
 
-		return parport_pc_superio_info[id->driver_data].probe
-			(pdev, autoirq, autodma);
+		if (parport_pc_superio_info[id->driver_data].probe
+			(pdev, autoirq, autodma)) {
+			ret++;
+		}
 	}
 
-	return 0; /* zero devices found */
+	return ret; /* number of devices found */
 }
 #else
 static struct pci_driver parport_pc_pci_driver;
diff -u --recursive --new-file v2.4.9/linux/drivers/parport/parport_serial.c linux/drivers/parport/parport_serial.c
--- v2.4.9/linux/drivers/parport/parport_serial.c	Wed Jul 25 17:10:22 2001
+++ linux/drivers/parport/parport_serial.c	Fri Sep  7 18:15:17 2001
@@ -296,7 +296,16 @@
 		return err;
 	}
 
-	if (serial_register (dev, id) + parport_register (dev, id)) {
+	if (parport_register (dev, id)) {
+		pci_set_drvdata (dev, NULL);
+		kfree (priv);
+		return -ENODEV;
+	}
+
+	if (serial_register (dev, id)) {
+		int i;
+		for (i = 0; i < priv->num_par; i++)
+			parport_pc_unregister_port (priv->port[i]);
 		pci_set_drvdata (dev, NULL);
 		kfree (priv);
 		return -ENODEV;
diff -u --recursive --new-file v2.4.9/linux/drivers/pci/Makefile linux/drivers/pci/Makefile
--- v2.4.9/linux/drivers/pci/Makefile	Tue Jul  3 17:08:20 2001
+++ linux/drivers/pci/Makefile	Sun Sep  9 10:50:48 2001
@@ -25,8 +25,11 @@
 #
 obj-$(CONFIG_ALPHA) += setup-bus.o setup-irq.o
 obj-$(CONFIG_ARM) += setup-bus.o setup-irq.o
+obj-$(CONFIG_PARISC) += setup-bus.o
 obj-$(CONFIG_SUPERH) += setup-bus.o setup-irq.o
 obj-$(CONFIG_ALL_PPC) += setup-bus.o
+obj-$(CONFIG_DDB5476) += setup-bus.o
+obj-$(CONFIG_SGI_IP27) += setup-irq.o
 
 ifndef CONFIG_X86
 obj-y += syscall.o
diff -u --recursive --new-file v2.4.9/linux/drivers/pci/names.c linux/drivers/pci/names.c
--- v2.4.9/linux/drivers/pci/names.c	Mon Oct  2 12:00:16 2000
+++ linux/drivers/pci/names.c	Mon Aug 27 08:47:07 2001
@@ -32,9 +32,9 @@
  * real memory.. Parse the same file multiple times
  * to get all the info.
  */
-#define VENDOR( vendor, name )		static const char __vendorstr_##vendor[] __initdata = name;
+#define VENDOR( vendor, name )		static char __vendorstr_##vendor[] __initdata = name;
 #define ENDVENDOR()
-#define DEVICE( vendor, device, name ) 	static const char __devicestr_##vendor##device[] __initdata = name;
+#define DEVICE( vendor, device, name ) 	static char __devicestr_##vendor##device[] __initdata = name;
 #include "devlist.h"
 
 
@@ -43,7 +43,7 @@
 #define DEVICE( vendor, device, name )	{ 0x##device, 0, __devicestr_##vendor##device },
 #include "devlist.h"
 
-static const struct pci_vendor_info __initdata pci_vendor_list[] = {
+static struct pci_vendor_info __initdata pci_vendor_list[] = {
 #define VENDOR( vendor, name )		{ 0x##vendor, sizeof(__devices_##vendor) / sizeof(struct pci_device_info), __vendorstr_##vendor, __devices_##vendor },
 #define ENDVENDOR()
 #define DEVICE( vendor, device, name )
diff -u --recursive --new-file v2.4.9/linux/drivers/pci/pci.c linux/drivers/pci/pci.c
--- v2.4.9/linux/drivers/pci/pci.c	Mon Aug 27 12:41:44 2001
+++ linux/drivers/pci/pci.c	Sat Sep  1 11:01:28 2001
@@ -307,8 +307,8 @@
 
 /**
  * pci_save_state - save the PCI configuration space of a device before suspending
- * @dev - PCI device that we're dealing with
- * @buffer - buffer to hold config space context
+ * @dev: - PCI device that we're dealing with
+ * @buffer: - buffer to hold config space context
  *
  * @buffer must be large enough to hold the entire PCI 2.2 config space 
  * (>= 64 bytes).
@@ -327,8 +327,8 @@
 
 /** 
  * pci_restore_state - Restore the saved state of a PCI device
- * @dev - PCI device that we're dealing with
- * @buffer - saved PCI config space
+ * @dev: - PCI device that we're dealing with
+ * @buffer: - saved PCI config space
  *
  */
 int 
@@ -489,6 +489,7 @@
 /**
  *	pci_request_regions - Reserved PCI I/O and memory resources
  *	@pdev: PCI device whose resources are to be reserved
+ *	@res_name: Name to be associated with resource.
  *
  *	Mark all PCI regions associated with PCI device @pdev as
  *	being reserved by owner @res_name.  Do not access any
diff -u --recursive --new-file v2.4.9/linux/drivers/pci/pci.ids linux/drivers/pci/pci.ids
--- v2.4.9/linux/drivers/pci/pci.ids	Mon Aug 27 12:41:44 2001
+++ linux/drivers/pci/pci.ids	Fri Sep  7 09:28:38 2001
@@ -749,6 +749,7 @@
 	0620  620 Host
 	0630  630 Host
 	0730  730 Host
+	0735  735 Host
 	0900  SiS900 10/100 Ethernet
 		1039 0900  SiS900 10/100 Ethernet Adapter
 	3602  83C602
@@ -781,6 +782,7 @@
 		1569 6326  SiS6326 GUI Accelerator
 	7001  7001
 	7007  OHCI Compliant FireWire Controller
+	7012  SiS7012 PCI Audio Accelerator
 	7016  SiS7016 10/100 Ethernet Adapter
 		1039 7016  SiS7016 10/100 Ethernet Adapter
 	7018  SiS PCI Audio Accelerator
@@ -809,6 +811,7 @@
 103a  Seiko Epson Corporation
 103b  Tatung Co. of America
 103c  Hewlett-Packard Company
+	1005  A4977A Visualize EG
 	1030  J2585A
 	1031  J2585B
 		103c 1040  J2973A DeskDirect 10BaseT NIC
@@ -1952,7 +1955,7 @@
 	0505  VT82C505
 	0561  VT82C561
 	0571  Bus Master IDE
-	0576  VT82C576 3V [Apollo Master]
+	0576  VT82C576 [Apollo Master]
 	0585  VT82C585VP [Apollo VP1/VPX]
 	0586  VT82C586/A/B PCI-to-ISA [Apollo VP]
 		1106 0000  MVP3 ISA Bridge
@@ -1975,7 +1978,7 @@
 	0926  VT82C926 [Amazon]
 	1000  VT82C570MV
 	1106  VT82C570MV
-	1571  VT82C416MV
+	1571  VT82C576 IDE [Apollo Master]
 	1595  VT82C595/97 [Apollo VP2/97]
 	3038  UHCI USB
 		1234 0925  MVP3 USB Controller
@@ -1996,6 +1999,7 @@
 	3074  VT8233 PCI to ISA Bridge
 	3091  VT8633 [Apollo Pro266]
 	3099  VT8367 [KT266]
+	3109  VT8233C PCI to ISA Bridge
 	5030  VT82C596 ACPI [Apollo PRO]
 	6100  VT85C100A [Rhine II]
 	8231  VT8231 [PCI-to-ISA Bridge]
@@ -2636,6 +2640,7 @@
 11d2  Intercom Inc.
 11d3  Trancell Systems Inc
 11d4  Analog Devices
+	1889  AD1889 sound chip
 11d5  Ikon Corporation
 	0115  10115
 	0117  10117
diff -u --recursive --new-file v2.4.9/linux/drivers/pcmcia/yenta.c linux/drivers/pcmcia/yenta.c
--- v2.4.9/linux/drivers/pcmcia/yenta.c	Wed Jul 25 17:10:22 2001
+++ linux/drivers/pcmcia/yenta.c	Wed Aug 29 06:13:40 2001
@@ -702,6 +702,12 @@
 	u32 start, end;
 	u32 align, size, min, max;
 	unsigned offset;
+	unsigned mask;
+
+	/* The granularity of the memory limit is 4kB, on IO it's 4 bytes */
+	mask = ~0xfff;
+	if (type & IORESOURCE_IO)
+		mask = ~3;
 
 	offset = 0x1c + 8*nr;
 	bus = socket->dev->subordinate;
@@ -715,8 +721,8 @@
 	if (!root)
 		return;
 
-	start = config_readl(socket, offset);
-	end = config_readl(socket, offset+4) | 0xfff;
+	start = config_readl(socket, offset) & mask;
+	end = config_readl(socket, offset+4) | ~mask;
 	if (start && end > start) {
 		res->start = start;
 		res->end = end;
@@ -729,7 +735,7 @@
 	if (type & IORESOURCE_IO) {
 		align = 1024;
 		size = 256;
-		min = PCIBIOS_MIN_IO;
+		min = 0x4000;
 		max = 0xffff;
 	}
 		
diff -u --recursive --new-file v2.4.9/linux/drivers/s390/block/dasd.c linux/drivers/s390/block/dasd.c
--- v2.4.9/linux/drivers/s390/block/dasd.c	Sun Aug 12 13:27:59 2001
+++ linux/drivers/s390/block/dasd.c	Sat Sep  8 12:02:32 2001
@@ -714,10 +714,9 @@
 
 	INIT_BLK_DEV (major, do_dasd_request, dasd_get_queue, NULL);
 
-	major_info->gendisk.major = major;
-	major_info->gendisk.next = gendisk_head;
 	major_info->gendisk.sizes = blk_size[major];
-	gendisk_head = &major_info->gendisk;
+	major_info->gendisk.major = major;
+	add_gendisk (&major_info->gendisk);
 	return major;
 
         /* error handling - free the prior allocated memory */  
@@ -775,7 +774,6 @@
 {
 	int rc = 0;
 	int major;
-	struct gendisk *dd, *prev = NULL;
 	unsigned long flags;
 
 	if (major_info == NULL) {
@@ -784,20 +782,8 @@
 	major = major_info->gendisk.major;
 	INIT_BLK_DEV (major, NULL, NULL, NULL);
 
-	/* do the gendisk stuff */
-	for (dd = gendisk_head; dd; dd = dd->next) {
-		if (dd == &major_info->gendisk) {
-			if (prev)
-				prev->next = dd->next;
-			else
-				gendisk_head = dd->next;
-			break;
-		}
-		prev = dd;
-	}
-	if (dd == NULL) {
-		return -ENOENT;
-	}
+	del_gendisk (&major_info->gendisk);
+
 	kfree (major_info->dasd_device);
 	kfree (major_info->gendisk.part);
 
@@ -2140,13 +2126,7 @@
 	}
 	for (i = (1 << DASD_PARTN_BITS) - 1; i >= 0; i--) {
                 int major = device->major_info->gendisk.major;
-		int minor = start + i;
-		kdev_t devi = MKDEV (major, minor);
-		struct super_block *sb = get_super (devi);
-		sync_dev (devi);
-		if (sb)
-			invalidate_inodes (sb);
-		invalidate_buffers (devi);
+		invalidate_device(MKDEV (major, start+i), 1);
 	}
         dasd_destroy_partitions(device);
         dasd_setup_partitions(device);
@@ -2517,7 +2497,6 @@
 		rc = -ENODEV;
                 goto out;
 	}
-	fsync_dev (inp->i_rdev);	/* sync the device */
         count = atomic_dec_return (&device->open_count);
         if ( count == 0) {
                 invalidate_buffers (inp->i_rdev);
diff -u --recursive --new-file v2.4.9/linux/drivers/s390/block/xpram.c linux/drivers/s390/block/xpram.c
--- v2.4.9/linux/drivers/s390/block/xpram.c	Sun Aug 12 13:28:00 2001
+++ linux/drivers/s390/block/xpram.c	Mon Aug 27 14:20:21 2001
@@ -625,8 +625,7 @@
 	 */
 	if (!atomic_dec_return(&(dev->usage))) {
 		/* but flush it right now */
-		fsync_dev(inode->i_rdev);
-		invalidate_buffers(inode->i_rdev);
+		/* Everything is already flushed by caller -- AV */
 	}
 	MOD_DEC_USE_COUNT;
 	return(0);
diff -u --recursive --new-file v2.4.9/linux/drivers/s390/char/tuball.c linux/drivers/s390/char/tuball.c
--- v2.4.9/linux/drivers/s390/char/tuball.c	Sun Aug 12 13:28:00 2001
+++ linux/drivers/s390/char/tuball.c	Fri Sep  7 09:28:38 2001
@@ -449,7 +449,7 @@
 			
 			tub3270_con_devno = dp->devno;
 			tubp->cmd = TBC_CONOPEN;
-			tubp->flags |= TUB_OPEN_STET;
+			tubp->flags |= TUB_OPEN_STET | TUB_INPUT_HACK;
 			tty3270_size(tubp, &flags);
 			tty3270_aid_init(tubp);
 			tty3270_scl_init(tubp);
diff -u --recursive --new-file v2.4.9/linux/drivers/s390/char/tubfs.c linux/drivers/s390/char/tubfs.c
--- v2.4.9/linux/drivers/s390/char/tubfs.c	Sun Aug 12 13:28:00 2001
+++ linux/drivers/s390/char/tubfs.c	Fri Sep  7 09:28:38 2001
@@ -42,11 +42,11 @@
 {
 	char name[16];
 
-	sprintf(name, "tub%x", tubp->devno);
+	sprintf(name, "tub%.3x", tubp->devno);
 	devfs_register(fs3270_devfs_dir, name, DEVFS_FL_DEFAULT,
 		       IBM_FS3270_MAJOR, tubp->minor,
 		       S_IFCHR | S_IRUSR | S_IWUSR, &fs3270_fops, NULL);
-	sprintf(name, "tty%x", tubp->devno);
+	sprintf(name, "tty%.3x", tubp->devno);
 	tty_register_devfs_name(&tty3270_driver, 0, tubp->minor,
 				fs3270_devfs_dir, name);
 }
@@ -56,12 +56,12 @@
 	char name[16];
 	devfs_handle_t handle;
 
-	sprintf(name, "tub%x", tubp->devno);
+	sprintf(name, "tub%.3x", tubp->devno);
 	handle = devfs_find_handle (fs3270_devfs_dir, name,
 				    IBM_FS3270_MAJOR, tubp->minor,
 				    DEVFS_SPECIAL_CHR, 0);
 	devfs_unregister (handle);
-	sprintf(name, "tty%x", tubp->devno);
+	sprintf(name, "tty%.3x", tubp->devno);
 	handle = devfs_find_handle (fs3270_devfs_dir, name,
 				    IBM_TTY3270_MAJOR, tubp->minor,
 				    DEVFS_SPECIAL_CHR, 0);
@@ -88,7 +88,7 @@
 	fs3270_devfs_tub = 
 		devfs_register(fs3270_devfs_dir, "tub", DEVFS_FL_DEFAULT,
 			       IBM_FS3270_MAJOR, 0,
-			       S_IFCHR | S_IRUSR | S_IWUSR, 
+			       S_IFCHR | S_IRUGO | S_IWUGO, 
 			       &fs3270_fops, NULL);
 #else
 	rc = register_chrdev(IBM_FS3270_MAJOR, "fs3270", &fs3270_fops);
diff -u --recursive --new-file v2.4.9/linux/drivers/s390/char/tubio.h linux/drivers/s390/char/tubio.h
--- v2.4.9/linux/drivers/s390/char/tubio.h	Sun Aug 12 13:28:00 2001
+++ linux/drivers/s390/char/tubio.h	Fri Sep  7 09:28:38 2001
@@ -282,6 +282,7 @@
 #define	TUB_UNSOL_DE	0x0200
 #define	TUB_OPEN_STET	0x0400		/* No screen clear on open */
 #define	TUB_UE_BUSY	0x0800
+#define	TUB_INPUT_HACK	0x1000		/* Early init of command line */
 
 #ifdef CONFIG_TN3270_CONSOLE
 /*
@@ -372,7 +373,7 @@
 		if (MAJOR(current->tty->device) == IBM_TTY3270_MAJOR)
 			minor = MINOR(current->tty->device);
 	}
-	if (minor >= tubnummins && minor > 0)
+	if (minor <= tubnummins && minor > 0)
 		tubp = (*tubminors)[minor];
 	return tubp;
 }
diff -u --recursive --new-file v2.4.9/linux/drivers/s390/char/tubtty.c linux/drivers/s390/char/tubtty.c
--- v2.4.9/linux/drivers/s390/char/tubtty.c	Sun Aug 12 13:28:00 2001
+++ linux/drivers/s390/char/tubtty.c	Fri Sep  7 09:28:38 2001
@@ -993,7 +993,7 @@
 	if (tty)
 		len += sprintf(buf+len,
 				"    write_wait=%.8x read_wait=%.8x\n",
-				tty->write_wait, tty->read_wait);
+				(int)&tty->write_wait, (int)&tty->read_wait);
 
 	if (tty && ((mp = tty->termios)))
 		len += sprintf(buf+len,"    iflag=%.8x oflag=%.8x "
diff -u --recursive --new-file v2.4.9/linux/drivers/s390/char/tubttybld.c linux/drivers/s390/char/tubttybld.c
--- v2.4.9/linux/drivers/s390/char/tubttybld.c	Wed Apr 11 19:02:28 2001
+++ linux/drivers/s390/char/tubttybld.c	Fri Sep  7 09:28:38 2001
@@ -34,6 +34,8 @@
 	TUB_BUFADR(GEOM_INPUT, cpp);
 	*(*cpp)++ = '\0';
 	tubp->tty_oucol = tubp->tty_nextlogx = 0;
+	*(*cpp)++ = TO_SBA;
+	TUB_BUFADR(tubp->tty_nextlogx, cpp);
 }
 
 static void
@@ -376,12 +378,16 @@
 		printk(KERN_WARNING "tty3270_build unknown command %d\n", tubp->cmd);
 		return 0;
 	case TBC_OPEN:
+tbc_open:
+		tubp->flags &= ~TUB_INPUT_HACK;
 		chancmd = TC_EWRITEA;
 		tty3270_clear_input_area(tubp, &cp);
 		tty3270_set_status_area(tubp, &cp);
 		tty3270_clear_log_area(tubp, &cp);
 		break;
 	case TBC_UPDLOG:
+		if (tubp->flags & TUB_INPUT_HACK)
+			goto tbc_open;
 		chancmd = TC_WRITE;
 		writecc = TW_NONE;
 		tty3270_update_log_area(tubp, &cp);
diff -u --recursive --new-file v2.4.9/linux/drivers/sbus/char/pcikbd.c linux/drivers/sbus/char/pcikbd.c
--- v2.4.9/linux/drivers/sbus/char/pcikbd.c	Mon Aug 27 12:41:44 2001
+++ linux/drivers/sbus/char/pcikbd.c	Tue Aug 28 07:09:44 2001
@@ -1,4 +1,4 @@
-/* $Id: pcikbd.c,v 1.59 2001/08/13 14:40:08 davem Exp $
+/* $Id: pcikbd.c,v 1.61 2001/08/18 09:40:46 davem Exp $
  * pcikbd.c: Ultra/AX PC keyboard support.
  *
  * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
@@ -22,6 +22,7 @@
 #include <linux/miscdevice.h>
 #include <linux/kbd_ll.h>
 #include <linux/kbd_kern.h>
+#include <linux/vt_kern.h>
 #include <linux/delay.h>
 #include <linux/spinlock.h>
 #include <linux/smp_lock.h>
@@ -224,6 +225,17 @@
 	"\r\000/";					/* 0x60 - 0x6f */
 #endif
 
+#define DEFAULT_KEYB_REP_DELAY	250
+#define DEFAULT_KEYB_REP_RATE	30	/* cps */
+
+static struct kbd_repeat kbdrate = {
+	DEFAULT_KEYB_REP_DELAY,
+	DEFAULT_KEYB_REP_RATE
+};
+
+static unsigned char parse_kbd_rate(struct kbd_repeat *r);
+static int write_kbd_rate(unsigned char r);
+
 int pcikbd_setkeycode(unsigned int scancode, unsigned int keycode)
 {
 	if(scancode < SC_LIM || scancode > 255 || keycode > 127)
@@ -335,12 +347,7 @@
 		printk("Prom Leave: Enable Keyboard: no ACK\n");
 
 	/* Reset keyboard rate */
-	pcikbd_write(KBD_DATA_REG, KBD_CMD_SET_RATE);
-	if(pcikbd_wait_for_input() != KBD_REPLY_ACK)
-		printk("Prom Leave: Set rate: no ACK\n");
-	pcikbd_write(KBD_DATA_REG, 0x00);
-	if(pcikbd_wait_for_input() != KBD_REPLY_ACK)
-		printk("Prom Leave: Set rate: no ACK\n");
+	write_kbd_rate(parse_kbd_rate(&kbdrate));
 }
 
 int pcikbd_translate(unsigned char scancode, unsigned char *keycode,
@@ -478,8 +485,81 @@
 		send_data(KBD_CMD_ENABLE);
 }
 
-int pcikbd_rate(struct kbd_repeat *rep)
+static unsigned char parse_kbd_rate(struct kbd_repeat *r)
+{
+	static struct r2v {
+		int rate;
+		unsigned char val;
+	} kbd_rates[]={	{ 5,  0x14 },
+			{ 7,  0x10 },
+			{ 10, 0x0c },
+			{ 15, 0x08 },
+			{ 20, 0x04 },
+			{ 25, 0x02 },
+			{ 30, 0x00 } };
+	static struct d2v {
+		int delay;
+		unsigned char val;
+	} kbd_delays[]={ { 250,  0 },
+			 { 500,  1 },
+			 { 750,  2 },
+			 { 1000, 3 } };
+	int rate = 0, delay = 0;
+
+	if (r != NULL) {
+		int i, new_rate = 30, new_delay = 250;
+		if (r->rate <= 0)
+			r->rate = kbdrate.rate;
+		if (r->delay <= 0)
+			r->delay = kbdrate.delay;
+
+		for (i = 0; i < sizeof(kbd_rates) / sizeof(struct r2v); i++) {
+			if (kbd_rates[i].rate == r->rate) {
+				new_rate = kbd_rates[i].rate;
+				rate = kbd_rates[i].val;
+				break;
+			}
+		}
+		for (i=0; i < sizeof(kbd_delays) / sizeof(struct d2v); i++) {
+			if (kbd_delays[i].delay == r->delay) {
+				new_delay = kbd_delays[i].delay;
+				delay = kbd_delays[i].val;
+				break;
+			}
+		}
+		r->rate = new_rate;
+		r->delay = new_delay;
+	}
+	return (delay << 5) | rate;
+}
+
+static int write_kbd_rate(unsigned char r)
+{
+	if (!send_data(KBD_CMD_SET_RATE) || !send_data(r)) {
+		/* re-enable kbd if any errors */
+		send_data(KBD_CMD_ENABLE);
+		return 0;
+	}
+
+	return 1;
+}
+
+static int pcikbd_rate(struct kbd_repeat *rep)
 {
+	unsigned char r;
+	struct kbd_repeat old_rep;
+
+	if (rep == NULL)
+		return -EINVAL;
+
+	r = parse_kbd_rate(rep);
+	memcpy(&old_rep, &kbdrate, sizeof(struct kbd_repeat));
+	if (write_kbd_rate(r)) {
+		memcpy(&kbdrate,rep,sizeof(struct kbd_repeat));
+		memcpy(rep,&old_rep,sizeof(struct kbd_repeat));
+		return 0;
+	}
+
 	return -EIO;
 }
 
@@ -641,12 +721,7 @@
 	if(pcikbd_wait_for_input() != KBD_REPLY_ACK)
 		return "Enable keyboard: no ACK";
 
-	pcikbd_write(KBD_DATA_REG, KBD_CMD_SET_RATE);
-	if(pcikbd_wait_for_input() != KBD_REPLY_ACK)
-		return "Set rate: no ACK";
-	pcikbd_write(KBD_DATA_REG, 0x00);
-	if(pcikbd_wait_for_input() != KBD_REPLY_ACK)
-		return "Set rate: no ACK";
+	write_kbd_rate(parse_kbd_rate(&kbdrate));
 
 	return NULL; /* success */
 }
@@ -744,6 +819,7 @@
 	}
 
 	kd_mksound = nop_kd_mksound;
+	kbd_rate = pcikbd_rate;
 
 #ifdef __sparc_v9__
 	edev = 0;
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/3w-xxxx.c linux/drivers/scsi/3w-xxxx.c
--- v2.4.9/linux/drivers/scsi/3w-xxxx.c	Mon Aug 27 12:41:44 2001
+++ linux/drivers/scsi/3w-xxxx.c	Fri Sep  7 09:28:37 2001
@@ -90,6 +90,16 @@
    1.02.00.007 - Fix possible null pointer dereferences in tw_ioctl().
                  Remove check for invalid done function pointer from
                  tw_scsi_queue().
+   1.02.00.008 - Set max sectors per io to TW_MAX_SECTORS in tw_findcards().
+                 Add tw_decode_error() for printing readable error messages.
+                 Print some useful information on certain aen codes.
+                 Add tw_decode_bits() for interpreting status register output.
+                 Make scsi_set_pci_device() for kernels >= 2.4.4
+                 Fix bug where aen's could be lost before a reset.
+                 Re-add spinlocks in tw_scsi_detect().
+                 Fix possible null pointer dereference in tw_aen_drain_queue()
+                 during initialization.
+                 Clear pci parity errors during initialization and during io.
 */
 
 #include <linux/module.h>
@@ -135,7 +145,7 @@
 };
 
 /* Globals */
-char *tw_driver_version="1.02.00.007";
+char *tw_driver_version="1.02.00.008";
 TW_Device_Extension *tw_device_extension_list[TW_MAX_SLOT];
 int tw_device_extension_count = 0;
 
@@ -147,6 +157,7 @@
 	TW_Param *param;
 	unsigned short aen;
 
+	dprintk(KERN_WARNING "3w-xxxx: tw_aen_complete()\n");
 	if (tw_dev->alignment_virtual_address[request_id] == NULL) {
 		printk(KERN_WARNING "3w-xxxx: tw_aen_complete(): Bad alignment virtual address.\n");
 		return 1;
@@ -154,6 +165,27 @@
 	param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
 	aen = *(unsigned short *)(param->data);
 	dprintk(KERN_NOTICE "3w-xxxx: tw_aen_complete(): Queue'd code 0x%x\n", aen);
+
+	/* Print some useful info when certain aen codes come out */
+	switch (aen & 0x0ff) {
+		case TW_AEN_APORT_TIMEOUT:
+			printk(KERN_WARNING "3w-xxxx: scsi%d: Received drive timeout AEN on port %d, check drive and drive cables.\n", tw_dev->host->host_no,  aen >> 8);
+			break;
+		case TW_AEN_DRIVE_ERROR:
+			printk(KERN_WARNING "3w-xxxx: scsi%d: Received drive error AEN on port %d, check/replace cabling, or possible bad drive.\n", tw_dev->host->host_no, aen >> 8);
+			break;
+		case TW_AEN_SMART_FAIL:
+			printk(KERN_WARNING "3w-xxxx: scsi%d: Received S.M.A.R.T. threshold AEN on port %d, check drive/cooling, or possible bad drive.\n", tw_dev->host->host_no, aen >> 8);
+			break;
+		case TW_AEN_SBUF_FAIL:
+			printk(KERN_WARNING "3w-xxxx: scsi%d: Received SBUF integrity check failure AEN, reseat card or bad card.\n", tw_dev->host->host_no);
+			break;
+		default:
+			printk(KERN_WARNING "3w-xxxx: Received AEN 0x%x\n", aen);
+	}
+
+	tw_dev->aen_count++;
+
 	/* Now queue the code */
 	tw_dev->aen_queue[tw_dev->aen_tail] = aen;
 	if (tw_dev->aen_tail == TW_Q_LENGTH - 1) {
@@ -201,7 +233,7 @@
 	response_que_addr = tw_dev->registers.response_que_addr;
 
 	if (tw_poll_status(tw_dev, TW_STATUS_ATTENTION_INTERRUPT, 15)) {
-		printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): No attention interrupt for card %d\n", tw_dev->host->host_no);
+		printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): No attention interrupt for card %d.\n", tw_device_extension_count);
 		return 1;
 	}
 
@@ -258,6 +290,7 @@
 			status_reg_value = inl(status_reg_addr);
 			if (tw_check_bits(status_reg_value)) {
 				printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Unexpected bits.\n");
+				tw_decode_bits(tw_dev, status_reg_value);
 				return 1;
 			}
 			if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
@@ -322,6 +355,22 @@
 						dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue(): Found TW_AEN_QUEUE_FULL.\n");
 						queue = 1;
 						break;
+					case TW_AEN_APORT_TIMEOUT:
+						printk(KERN_WARNING "3w-xxxx: Received drive timeout AEN on port %d, check drive and drive cables.\n", aen >> 8);
+						queue = 1;
+						break;
+					case TW_AEN_DRIVE_ERROR:
+						printk(KERN_WARNING "3w-xxxx: Received drive error AEN on port %d, check/replace cabling, or possible bad drive.\n", aen >> 8);
+						queue = 1;
+						break;
+					case TW_AEN_SMART_FAIL:
+						printk(KERN_WARNING "3w-xxxx: Received S.M.A.R.T. threshold AEN on port %d, check drive/cooling, or possible bad drive.\n", aen >> 8);
+						queue = 1;
+						break;
+					case TW_AEN_SBUF_FAIL:
+						printk(KERN_WARNING "3w-xxxx: Received SBUF integrity check failure AEN, reseat card or bad card.\n");
+						queue = 1;
+						break;
 					default:
 						dprintk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Unknown AEN code 0x%x.\n", aen_code);
 						queue = 1;
@@ -378,6 +427,7 @@
 	status_reg_value = inl(status_reg_addr);
 	if (tw_check_bits(status_reg_value)) {
 		printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Unexpected bits.\n");
+		tw_decode_bits(tw_dev, status_reg_value);
 		return 1;
 	}
 	if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
@@ -552,6 +602,40 @@
 	}
 } /* End tw_copy_mem_info() */
 
+/* This function will print readable messages from statsu register errors */
+void tw_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value)
+{
+	dprintk(KERN_WARNING "3w-xxxx: tw_decode_bits()\n");
+	switch (status_reg_value & TW_STATUS_UNEXPECTED_BITS) {
+	case TW_STATUS_PCI_PARITY_ERROR:
+		printk(KERN_WARNING "3w-xxxx: PCI Parity Error: Reseat card, move card, or buggy device on the bus.\n");
+		outl(TW_CONTROL_CLEAR_PARITY_ERROR, tw_dev->registers.control_reg_addr);
+		pci_write_config_word(tw_dev->tw_pci_dev, PCI_STATUS, TW_PCI_CLEAR_PARITY_ERRORS);
+		break;
+	case TW_STATUS_MICROCONTROLLER_ERROR:
+		printk(KERN_WARNING "3w-xxxx: Microcontroller Error.\n");
+		break;
+  }
+} /* End tw_decode_bits() */
+
+/* This function will print readable messages from flags and status values */
+void tw_decode_error(TW_Device_Extension *tw_dev, unsigned char status, unsigned char flags, unsigned char unit)
+{
+	dprintk(KERN_WARNING "3w-xxxx: tw_decode_error()\n");
+	switch (status) {
+	case 0xc7:
+		switch (flags) {
+		case 0x1b: 
+			printk(KERN_WARNING "3w-xxxx: scsi%d: Drive timeout on unit %d, check drive and drive cables.\n", tw_dev->host->host_no, unit);
+			break;
+		case 0x51:
+			printk(KERN_WARNING "3w-xxxx: scsi%d: Unrecoverable drive error on unit %d, check/replace cabling, or possible bad drive.\n", tw_dev->host->host_no, unit);
+			break;
+		}
+		break;
+	}
+} /* End tw_decode_error() */
+
 /* This function will disable interrupts on the controller */  
 void tw_disable_interrupts(TW_Device_Extension *tw_dev) 
 {
@@ -575,6 +659,7 @@
 
 	if (tw_check_bits(status_reg_value)) {
 		printk(KERN_WARNING "3w-xxxx: tw_empty_response_queue(): Unexpected bits 1.\n");
+		tw_decode_bits(tw_dev, status_reg_value);
 		return 1;
 	}
   
@@ -583,6 +668,7 @@
 		status_reg_value = inl(status_reg_addr);
 		if (tw_check_bits(status_reg_value)) {
 			printk(KERN_WARNING "3w-xxxx: tw_empty_response_queue(): Unexpected bits 2.\n");
+			tw_decode_bits(tw_dev, status_reg_value);
 			return 1;
 		}
 	}
@@ -645,6 +731,11 @@
 			/* Save pci_dev struct to device extension */
 			tw_dev->tw_pci_dev = tw_pci_dev;
 
+			/* Check for errors and clear them */
+			status_reg_value = inl(tw_dev->registers.status_reg_addr);
+			if (TW_STATUS_ERRORS(status_reg_value)) 
+			  tw_decode_bits(tw_dev, status_reg_value);
+			
 			/* Poll status register for 60 secs for 'Controller Ready' flag */
 			if (tw_poll_status(tw_dev, TW_STATUS_MICROCONTROLLER_READY, 60)) {
 				printk(KERN_WARNING "3w-xxxx: tw_findcards(): Microcontroller not ready for card %d.\n", numcards);
@@ -738,10 +829,18 @@
 				continue;
 			}
 
+			/* Set max sectors per io */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7)
+			host->max_sectors = TW_MAX_SECTORS;
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4)
 			scsi_set_pci_device(host, tw_pci_dev);
+#endif
+
 			status_reg_value = inl(tw_dev->registers.status_reg_addr);
 
-			dprintk(KERN_NOTICE "scsi%d : Found a 3ware Storage Controller at 0x%x, IRQ: %d P-chip: %d.%d\n", host->host_no,
+			printk(KERN_NOTICE "scsi%d : Found a 3ware Storage Controller at 0x%x, IRQ: %d, P-chip: %d.%d\n", host->host_no,
 				(u32)(tw_pci_dev->resource[0].start), tw_pci_dev->irq, 
 				(status_reg_value & TW_STATUS_MAJOR_VERSION_MASK) >> 28, 
 				(status_reg_value & TW_STATUS_MINOR_VERSION_MASK) >> 24);
@@ -881,6 +980,7 @@
 		status_reg_value = inl(status_reg_addr);
 		if (tw_check_bits(status_reg_value)) {
 			printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Unexpected bits.\n");
+			tw_decode_bits(tw_dev, status_reg_value);
 			return 1;
 		}
 		if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
@@ -1034,6 +1134,7 @@
 		status_reg_value = inl(status_reg_addr);
 		if (tw_check_bits(status_reg_value)) {
 			printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Unexpected bits.\n");
+			tw_decode_bits(tw_dev, status_reg_value);
 			return 1;
 		}
 		if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
@@ -1136,6 +1237,7 @@
 			status_reg_value = inl(status_reg_addr);
 			if (tw_check_bits(status_reg_value)) {
 				printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Unexpected bits.\n");
+				tw_decode_bits(tw_dev, status_reg_value);
 				return 1;
 			}
 			if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
@@ -1143,14 +1245,12 @@
 				request_id = (unsigned char)response_queue.u.response_id;
 				if (request_id != 0) {
 					/* unexpected request id */
-					printk(KERN_WARNING "3w-xxxx: tw_initia
-lize_units(): Unexpected request id.\n");
+					printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Unexpected request id.\n");
 					return 1;
 				}
 				if (command_packet->status != 0) {
 					/* bad response */
-					printk(KERN_WARNING "3w-xxxx: tw_initia
-lize_units(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
+					printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
 					return 1;
 				}
 				found = 1;
@@ -1159,8 +1259,7 @@
 		}
 		if (found == 0) {
 			/* response never received */
-			printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): No
- response.\n");
+			printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): No response.\n");
 			return 1;
 		}
 
@@ -1177,12 +1276,12 @@
 	/* Now allocate raid5 bounce buffers */
 	if ((num_raid_five != 0) && (tw_dev->tw_pci_dev->device == TW_DEVICE_ID)) {
 		for (i=0;i<TW_Q_LENGTH;i++) {
-			tw_allocate_memory(tw_dev, i, sizeof(TW_Sector)*256, 2);
+			tw_allocate_memory(tw_dev, i, sizeof(TW_Sector)*TW_MAX_SECTORS, 2);
 			if (tw_dev->bounce_buffer[i] == NULL) {
 				printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bounce buffer allocation failed.\n");
 				return 1;
 			}
-			memset(tw_dev->bounce_buffer[i], 0, sizeof(TW_Sector)*256);
+			memset(tw_dev->bounce_buffer[i], 0, sizeof(TW_Sector)*TW_MAX_SECTORS);
 		}
 	}
   
@@ -1282,12 +1381,17 @@
 				error = 0;
 				if (command_packet->status != 0) {
 					printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Bad response, status = 0x%x, flags = 0x%x, unit = 0x%x.\n", command_packet->status, command_packet->flags, command_packet->byte3.unit);
+					tw_decode_error(tw_dev, command_packet->status, command_packet->flags, command_packet->byte3.unit);
 					error = 1;
 				}
 				if (tw_dev->state[request_id] != TW_S_POSTED) {
 					printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Received a request id (%d) (opcode = 0x%x) that wasn't posted.\n", request_id, command_packet->byte0.opcode);
 					error = 1;
 				}
+				if (TW_STATUS_ERRORS(status_reg_value)) {
+				  tw_decode_bits(tw_dev, status_reg_value);
+				  error = 1;
+				}
 				dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Response queue request id: %d.\n", request_id);
 				/* Check for internal command */
 				if (tw_dev->srb[request_id] == 0) {
@@ -1299,6 +1403,7 @@
 					status_reg_value = inl(status_reg_addr);
 					if (tw_check_bits(status_reg_value)) {
 						printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n");
+						tw_decode_bits(tw_dev, status_reg_value);
 					}
 		} else {
 				switch (tw_dev->srb[request_id]->cmnd[0]) {
@@ -1344,6 +1449,7 @@
 					status_reg_value = inl(status_reg_addr);
 					if (tw_check_bits(status_reg_value)) {
 						printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n");
+						tw_decode_bits(tw_dev, status_reg_value);
 					}
 				}
 			}
@@ -1400,7 +1506,7 @@
 	param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
 	memset(param, 0, sizeof(TW_Sector));
 
-	dprintk(KERN_NOTICE "opcode = %d table_id = %d parameter_id = %d parameter_size_bytes = %d\n", ioctl->opcode, ioctl->table_id, ioctl->parameter_id,, ioctl->parameter_size_bytes);
+	dprintk(KERN_NOTICE "opcode = %d table_id = %d parameter_id = %d parameter_size_bytes = %d\n", ioctl->opcode, ioctl->table_id, ioctl->parameter_id, ioctl->parameter_size_bytes);
 	opcode = ioctl->opcode;
 
 	switch (opcode) {
@@ -1571,8 +1677,10 @@
 	status_reg_addr = tw_dev->registers.status_reg_addr;
 	status_reg_value = inl(status_reg_addr);
 
-	if (tw_check_bits(status_reg_value)) 
+	if (tw_check_bits(status_reg_value)) {
 		printk(KERN_WARNING "3w-xxxx: tw_post_command_packet(): Unexpected bits.\n");
+		tw_decode_bits(tw_dev, status_reg_value);
+	}
 
 	if ((status_reg_value & TW_STATUS_COMMAND_QUEUE_FULL) == 0) {
 		/* We successfully posted the command packet */
@@ -1737,13 +1845,17 @@
 	
 	dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_detect()\n");
 
+	printk(KERN_WARNING "3ware Storage Controller device driver for Linux v%s.\n", tw_driver_version);
+
 	/* Check if the kernel has PCI interface compiled in */
 	if (!pci_present()) {
 		printk(KERN_WARNING "3w-xxxx: tw_scsi_detect(): No pci interface present.\n");
 		return 0;
 	}
 
+	spin_unlock_irq(&io_request_lock);
 	ret = tw_findcards(tw_host);
+	spin_lock_irq(&io_request_lock);
 
 	return ret;
 } /* End tw_scsi_detect() */
@@ -1767,6 +1879,11 @@
 		return (FAILED);
 	}
 
+	/* We have to let AEN requests through before the reset */
+	spin_unlock_irq(&io_request_lock);
+	mdelay(TW_AEN_WAIT_TIME);
+	spin_lock_irq(&io_request_lock);
+
 	spin_lock(&tw_dev->tw_lock);
 	tw_dev->num_aborts++;
 
@@ -1827,6 +1944,11 @@
 		return (FAILED);
 	}
 
+	/* We have to let AEN requests through before the reset */
+	spin_unlock_irq(&io_request_lock);
+	mdelay(TW_AEN_WAIT_TIME);
+	spin_lock_irq(&io_request_lock);
+
 	spin_lock(&tw_dev->tw_lock);
 	tw_dev->num_resets++;
 
@@ -2446,6 +2568,7 @@
 		status_reg_value = inl(status_reg_addr);
 		if (tw_check_bits(status_reg_value)) {
 			printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Unexpected bits.\n");
+			tw_decode_bits(tw_dev, status_reg_value);
 			return 1;
 		}
 		if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/3w-xxxx.h linux/drivers/scsi/3w-xxxx.h
--- v2.4.9/linux/drivers/scsi/3w-xxxx.h	Tue Jul  3 17:08:20 2001
+++ linux/drivers/scsi/3w-xxxx.h	Fri Sep  7 09:28:37 2001
@@ -69,6 +69,7 @@
 #define TW_CONTROL_ENABLE_INTERRUPTS	       0x00000080
 #define TW_CONTROL_DISABLE_INTERRUPTS	       0x00000040
 #define TW_CONTROL_ISSUE_HOST_INTERRUPT	       0x00000020
+#define TW_CONTROL_CLEAR_PARITY_ERROR          0x00800000
 
 /* Status register bit definitions */
 #define TW_STATUS_MAJOR_VERSION_MASK	       0xF0000000
@@ -100,6 +101,7 @@
 #define TW_DEVICE_ID (0x1000)	/* Storage Controller */
 #define TW_DEVICE_ID2 (0x1001)  /* 7000 series controller */
 #define TW_NUMDEVICES 2
+#define TW_PCI_CLEAR_PARITY_ERRORS 0xc100
 
 /* Command packet opcodes */
 #define TW_OP_NOP	      0x0
@@ -122,6 +124,10 @@
 #define TW_AEN_REBUILD_DONE      0x0005
 #define TW_AEN_QUEUE_FULL        0x00ff
 #define TW_AEN_TABLE_UNDEFINED   0x15
+#define TW_AEN_APORT_TIMEOUT     0x0009
+#define TW_AEN_DRIVE_ERROR       0x000A
+#define TW_AEN_SMART_FAIL        0x000F
+#define TW_AEN_SBUF_FAIL         0x0024
 
 /* Misc defines */
 #define TW_ALIGNMENT			      0x200 /* 16 D-WORDS */
@@ -143,6 +149,12 @@
 #define TW_MAX_AEN_TRIES                      100
 #define TW_UNIT_ONLINE                        1
 #define TW_IN_INTR                            1
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,7)
+#define TW_MAX_SECTORS                        256
+#else
+#define TW_MAX_SECTORS                        128
+#endif 
+#define TW_AEN_WAIT_TIME                      1000
 
 /* Macros */
 #define TW_STATUS_ERRORS(x) \
@@ -308,6 +320,8 @@
 int tw_check_errors(TW_Device_Extension *tw_dev);
 void tw_clear_attention_interrupt(TW_Device_Extension *tw_dev);
 void tw_clear_host_interrupt(TW_Device_Extension *tw_dev);
+void tw_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value);
+void tw_decode_error(TW_Device_Extension *tw_dev, unsigned char status, unsigned char flags, unsigned char unit);
 void tw_disable_interrupts(TW_Device_Extension *tw_dev);
 int tw_empty_response_que(TW_Device_Extension *tw_dev);
 void tw_enable_interrupts(TW_Device_Extension *tw_dev);
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/53c700-mem.c linux/drivers/scsi/53c700-mem.c
--- v2.4.9/linux/drivers/scsi/53c700-mem.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/53c700-mem.c	Sun Sep  9 11:18:52 2001
@@ -0,0 +1,1842 @@
+/* WARNING: GENERATED FILE (from 53c700.c), DO NOT MODIFY */
+#define MEM_MAPPED
+/* -*- mode: c; c-basic-offset: 8 -*- */
+
+/* NCR (or Symbios) 53c700 and 53c700-66 Driver
+ *
+ * Copyright (C) 2001 by James.Bottomley@HansenPartnership.com
+**-----------------------------------------------------------------------------
+**  
+**  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+**
+**-----------------------------------------------------------------------------
+ */
+
+/* Notes:
+ *
+ * This driver is designed exclusively for these chips (virtually the
+ * earliest of the scripts engine chips).  They need their own drivers
+ * because they are missing so many of the scripts and snazzy register
+ * features of their elder brothers (the 710, 720 and 770).
+ *
+ * The 700 is the lowliest of the line, it can only do async SCSI.
+ * The 700-66 can at least do synchronous SCSI up to 10MHz.
+ * 
+ * The 700 chip has no host bus interface logic of its own.  However,
+ * it is usually mapped to a location with well defined register
+ * offsets.  Therefore, if you can determine the base address and the
+ * irq your board incorporating this chip uses, you can probably use
+ * this driver to run it (although you'll probably have to write a
+ * minimal wrapper for the purpose---see the NCR_D700 driver for
+ * details about how to do this).
+ *
+ *
+ * TODO List:
+ *
+ * 1. Better statistics in the proc fs
+ *
+ * 2. Implement message queue (queues SCSI messages like commands) and make
+ *    the abort and device reset functions use them.
+ * */
+
+/* CHANGELOG
+ *
+ * Version 2.3
+ *
+ * More endianness/cache coherency changes.
+ *
+ * Better bad device handling (handles devices lying about tag
+ * queueing support and devices which fail to provide sense data on
+ * contingent allegiance conditions)
+ *
+ * Many thanks to Richard Hirst <rhirst@linuxcare.com> for patiently
+ * debugging this driver on the parisc architecture and suggesting
+ * many improvements and bug fixes.
+ *
+ * Thanks also go to Linuxcare Inc. for providing several PARISC
+ * machines for me to debug the driver on.
+ *
+ * Version 2.2
+ *
+ * Made the driver mem or io mapped; added endian invariance; added
+ * dma cache flushing operations for architectures which need it;
+ * added support for more varied clocking speeds.
+ *
+ * Version 2.1
+ *
+ * Initial modularisation from the D700.  See NCR_D700.c for the rest of
+ * the changelog.
+ * */
+#define NCR_700_VERSION "2.3"
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/mca.h>
+#include <asm/dma.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/byteorder.h>
+#include <linux/blk.h>
+#include <linux/module.h>
+
+#include "scsi.h"
+#include "hosts.h"
+#include "constants.h"
+
+#include "53c700.h"
+
+#ifdef NCR_700_DEBUG
+#define STATIC
+#else
+#define STATIC static
+#endif
+
+MODULE_AUTHOR("James Bottomley");
+MODULE_DESCRIPTION("53c700 and 53c700-66 Driver");
+MODULE_LICENSE("GPL");
+
+/* This is the script */
+#include "53c700_d.h"
+
+
+STATIC int NCR_700_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+STATIC int NCR_700_abort(Scsi_Cmnd * SCpnt);
+STATIC int NCR_700_bus_reset(Scsi_Cmnd * SCpnt);
+STATIC int NCR_700_dev_reset(Scsi_Cmnd * SCpnt);
+STATIC int NCR_700_host_reset(Scsi_Cmnd * SCpnt);
+STATIC int NCR_700_proc_directory_info(char *, char **, off_t, int, int, int);
+STATIC void NCR_700_chip_setup(struct Scsi_Host *host);
+STATIC void NCR_700_chip_reset(struct Scsi_Host *host);
+
+static char *NCR_700_phase[] = {
+	"",
+	"after selection",
+	"before command phase",
+	"after command phase",
+	"after status phase",
+	"after data in phase",
+	"after data out phase",
+	"during data phase",
+};
+
+static char *NCR_700_condition[] = {
+	"",
+	"NOT MSG_OUT",
+	"UNEXPECTED PHASE",
+	"NOT MSG_IN",
+	"UNEXPECTED MSG",
+	"MSG_IN",
+	"SDTR_MSG RECEIVED",
+	"REJECT_MSG RECEIVED",
+	"DISCONNECT_MSG RECEIVED",
+	"MSG_OUT",
+	"DATA_IN",
+	
+};
+
+static char *NCR_700_fatal_messages[] = {
+	"unexpected message after reselection",
+	"still MSG_OUT after message injection",
+	"not MSG_IN after selection",
+	"Illegal message length received",
+};
+
+static char *NCR_700_SBCL_bits[] = {
+	"IO ",
+	"CD ",
+	"MSG ",
+	"ATN ",
+	"SEL ",
+	"BSY ",
+	"ACK ",
+	"REQ ",
+};
+
+static char *NCR_700_SBCL_to_phase[] = {
+	"DATA_OUT",
+	"DATA_IN",
+	"CMD_OUT",
+	"STATE",
+	"ILLEGAL PHASE",
+	"ILLEGAL PHASE",
+	"MSG OUT",
+	"MSG IN",
+};
+
+static __u8 NCR_700_SDTR_msg[] = {
+	0x01,			/* Extended message */
+	0x03,			/* Extended message Length */
+	0x01,			/* SDTR Extended message */
+	NCR_700_MIN_PERIOD,
+	NCR_700_MAX_OFFSET
+};
+
+struct Scsi_Host * __init
+NCR_700_detect(Scsi_Host_Template *tpnt,
+	       struct NCR_700_Host_Parameters *hostdata)
+{
+	__u32 *script = kmalloc(sizeof(SCRIPT), GFP_KERNEL);
+	__u32 pScript;
+	struct Scsi_Host *host;
+	static int banner = 0;
+	int j;
+
+	/* Fill in the missing routines from the host template */
+	tpnt->queuecommand = NCR_700_queuecommand;
+	tpnt->eh_abort_handler = NCR_700_abort;
+	tpnt->eh_device_reset_handler = NCR_700_dev_reset;
+	tpnt->eh_bus_reset_handler = NCR_700_bus_reset;
+	tpnt->eh_host_reset_handler = NCR_700_host_reset;
+	tpnt->can_queue = NCR_700_COMMAND_SLOTS_PER_HOST;
+	tpnt->sg_tablesize = NCR_700_SG_SEGMENTS;
+	tpnt->cmd_per_lun = NCR_700_MAX_TAGS;
+	tpnt->use_clustering = DISABLE_CLUSTERING;
+	tpnt->use_new_eh_code = 1;
+	tpnt->proc_info = NCR_700_proc_directory_info;
+	
+	if(tpnt->name == NULL)
+		tpnt->name = "53c700";
+	if(tpnt->proc_name == NULL)
+		tpnt->proc_name = "53c700";
+	
+
+	if((host = scsi_register(tpnt, 4)) == NULL)
+		return NULL;
+	if(script == NULL) {
+		printk(KERN_ERR "53c700: Failed to allocate script, detatching\n");
+		scsi_unregister(host);
+		return NULL;
+	}
+
+	hostdata->slots = kmalloc(sizeof(struct NCR_700_command_slot) * NCR_700_COMMAND_SLOTS_PER_HOST, GFP_KERNEL);
+	if(hostdata->slots == NULL) {
+		printk(KERN_ERR "53c700: Failed to allocate command slots, detatching\n");
+		scsi_unregister(host);
+		return NULL;
+	}
+	memset(hostdata->slots, 0, sizeof(struct NCR_700_command_slot) * NCR_700_COMMAND_SLOTS_PER_HOST);
+	for(j = 0; j < NCR_700_COMMAND_SLOTS_PER_HOST; j++) {
+		if(j == 0)
+			hostdata->free_list = &hostdata->slots[j];
+		else
+			hostdata->slots[j-1].ITL_forw = &hostdata->slots[j];
+		hostdata->slots[j].state = NCR_700_SLOT_FREE;
+	}
+	host->hostdata[0] = (__u32)hostdata;
+	for(j = 0; j < sizeof(SCRIPT)/sizeof(SCRIPT[0]); j++) {
+		script[j] = bS_to_host(SCRIPT[j]);
+	}
+	/* bus physical address of script */
+	pScript = virt_to_bus(script);
+	/* adjust all labels to be bus physical */
+	for(j = 0; j < PATCHES; j++) {
+		script[LABELPATCHES[j]] = bS_to_host(pScript + SCRIPT[LABELPATCHES[j]]);
+	}
+	/* now patch up fixed addresses */
+	script_patch_32(script, MessageLocation,
+			virt_to_bus(&hostdata->msgout[0]));
+	script_patch_32(script, StatusAddress,
+			virt_to_bus(&hostdata->status));
+	script_patch_32(script, ReceiveMsgAddress,
+			virt_to_bus(&hostdata->msgin[0]));
+
+	hostdata->script = script;
+	hostdata->pScript = pScript;
+	hostdata->state = NCR_700_HOST_FREE;
+	spin_lock_init(&hostdata->lock);
+	hostdata->cmd = NULL;
+	host->max_id = 7;
+	host->max_lun = NCR_700_MAX_LUNS;
+	host->unique_id = hostdata->base;
+	host->base = hostdata->base;
+	host->hostdata[0] = (unsigned long)hostdata;
+	/* kick the chip */
+	NCR_700_writeb(0xff, host, CTEST9_REG);
+	hostdata->rev = (NCR_700_readb(host, CTEST7_REG)<<4) & 0x0f;
+	hostdata->fast = (NCR_700_readb(host, CTEST9_REG) == 0);
+	if(banner == 0) {
+		printk(KERN_NOTICE "53c700: Version " NCR_700_VERSION " By James.Bottomley@HansenPartnership.com\n");
+		banner = 1;
+	}
+	printk(KERN_NOTICE "scsi%d: %s rev %d %s\n", host->host_no,
+	       hostdata->fast ? "53c700-66" : "53c700",
+	       hostdata->rev, hostdata->differential ?
+	       "(Differential)" : "");
+	/* reset the chip */
+	NCR_700_chip_reset(host);
+	NCR_700_writeb(ASYNC_OPERATION , host, SXFER_REG);
+
+	return host;
+}
+
+int
+NCR_700_release(struct Scsi_Host *host)
+{
+	struct NCR_700_Host_Parameters *hostdata = 
+		(struct NCR_700_Host_Parameters *)host->hostdata[0];
+
+	kfree(hostdata->script);
+	return 1;
+}
+
+static inline __u8
+NCR_700_identify(int can_disconnect, __u8 lun)
+{
+	return IDENTIFY_BASE |
+		((can_disconnect) ? 0x40 : 0) |
+		(lun & NCR_700_LUN_MASK);
+}
+
+/*
+ * Function : static int datapath_residual (Scsi_Host *host)
+ *
+ * Purpose : return residual data count of what's in the chip.  If you
+ * really want to know what this function is doing, it's almost a
+ * direct transcription of the algorithm described in the 53c710
+ * guide, except that the DBC and DFIFO registers are only 6 bits
+ * wide.
+ *
+ * Inputs : host - SCSI host */
+static inline int
+NCR_700_data_residual (struct Scsi_Host *host) {
+	int count, synchronous;
+	unsigned int ddir;
+
+	count = ((NCR_700_readb(host, DFIFO_REG) & 0x3f) -
+		 (NCR_700_readl(host, DBC_REG) & 0x3f)) & 0x3f;
+	
+	synchronous = NCR_700_readb(host, SXFER_REG) & 0x0f;
+	
+	/* get the data direction */
+	ddir = NCR_700_readb(host, CTEST0_REG) & 0x01;
+
+	if (ddir) {
+		/* Receive */
+		if (synchronous) 
+			count += (NCR_700_readb(host, SSTAT2_REG) & 0xf0) >> 4;
+		else
+			if (NCR_700_readb(host, SSTAT1_REG) & SIDL_REG_FULL)
+				++count;
+	} else {
+		/* Send */
+		__u8 sstat = NCR_700_readb(host, SSTAT1_REG);
+		if (sstat & SODL_REG_FULL)
+			++count;
+		if (synchronous && (sstat & SODR_REG_FULL))
+			++count;
+	}
+	return count;
+}
+
+/* print out the SCSI wires and corresponding phase from the SBCL register
+ * in the chip */
+static inline char *
+sbcl_to_string(__u8 sbcl)
+{
+	int i;
+	static char ret[256];
+
+	ret[0]='\0';
+	for(i=0; i<8; i++) {
+		if((1<<i) & sbcl) 
+			strcat(ret, NCR_700_SBCL_bits[i]);
+	}
+	strcat(ret, NCR_700_SBCL_to_phase[sbcl & 0x07]);
+	return ret;
+}
+
+static inline __u8
+bitmap_to_number(__u8 bitmap)
+{
+	__u8 i;
+
+	for(i=0; i<8 && !(bitmap &(1<<i)); i++)
+		;
+	return i;
+}
+
+/* Pull a slot off the free list */
+STATIC struct NCR_700_command_slot *
+find_empty_slot(struct NCR_700_Host_Parameters *hostdata)
+{
+	struct NCR_700_command_slot *slot = hostdata->free_list;
+
+	if(slot == NULL) {
+		/* sanity check */
+		if(hostdata->command_slot_count != NCR_700_COMMAND_SLOTS_PER_HOST)
+			printk(KERN_ERR "SLOTS FULL, but count is %d, should be %d\n", hostdata->command_slot_count, NCR_700_COMMAND_SLOTS_PER_HOST);
+		return NULL;
+	}
+
+	if(slot->state != NCR_700_SLOT_FREE)
+		/* should panic! */
+		printk(KERN_ERR "BUSY SLOT ON FREE LIST!!!\n");
+		
+
+	hostdata->free_list = slot->ITL_forw;
+	slot->ITL_forw = NULL;
+
+
+	/* NOTE: set the state to busy here, not queued, since this
+	 * indicates the slot is in use and cannot be run by the IRQ
+	 * finish routine.  If we cannot queue the command when it
+	 * is properly build, we then change to NCR_700_SLOT_QUEUED */
+	slot->state = NCR_700_SLOT_BUSY;
+	hostdata->command_slot_count++;
+	
+	return slot;
+}
+
+STATIC void 
+free_slot(struct NCR_700_command_slot *slot,
+	  struct NCR_700_Host_Parameters *hostdata)
+{
+	int hash;
+	struct NCR_700_command_slot **forw, **back;
+
+
+	if((slot->state & NCR_700_SLOT_MASK) != NCR_700_SLOT_MAGIC) {
+		printk(KERN_ERR "53c700: SLOT %p is not MAGIC!!!\n", slot);
+	}
+	if(slot->state == NCR_700_SLOT_FREE) {
+		printk(KERN_ERR "53c700: SLOT %p is FREE!!!\n", slot);
+	}
+	/* remove from queues */
+	if(slot->tag != NCR_700_NO_TAG) {
+		hash = hash_ITLQ(slot->cmnd->target, slot->cmnd->lun,
+				 slot->tag);
+		if(slot->ITLQ_forw == NULL)
+			back = &hostdata->ITLQ_Hash_back[hash];
+		else
+			back = &slot->ITLQ_forw->ITLQ_back;
+
+		if(slot->ITLQ_back == NULL)
+			forw = &hostdata->ITLQ_Hash_forw[hash];
+		else
+			forw = &slot->ITLQ_back->ITLQ_forw;
+
+		*forw = slot->ITLQ_forw;
+		*back = slot->ITLQ_back;
+	}
+	hash = hash_ITL(slot->cmnd->target, slot->cmnd->lun);
+	if(slot->ITL_forw == NULL)
+		back = &hostdata->ITL_Hash_back[hash];
+	else
+		back = &slot->ITL_forw->ITL_back;
+	
+	if(slot->ITL_back == NULL)
+		forw = &hostdata->ITL_Hash_forw[hash];
+	else
+		forw = &slot->ITL_back->ITL_forw;
+	
+	*forw = slot->ITL_forw;
+	*back = slot->ITL_back;
+	
+	slot->resume_offset = 0;
+	slot->cmnd = NULL;
+	slot->state = NCR_700_SLOT_FREE;
+	slot->ITL_forw = hostdata->free_list;
+	hostdata->free_list = slot;
+	hostdata->command_slot_count--;
+}
+
+
+/* This routine really does very little.  The command is indexed on
+   the ITL and (if tagged) the ITLQ lists in _queuecommand */
+STATIC void
+save_for_reselection(struct NCR_700_Host_Parameters *hostdata,
+		     Scsi_Cmnd *SCp, __u32 dsp)
+{
+	/* Its just possible that this gets executed twice */
+	if(SCp != NULL) {
+		struct NCR_700_command_slot *slot =
+			(struct NCR_700_command_slot *)SCp->host_scribble;
+
+		slot->resume_offset = dsp;
+	}
+	hostdata->state = NCR_700_HOST_FREE;
+	hostdata->cmd = NULL;
+}
+
+/* Most likely nexus is the oldest in each case */
+STATIC inline struct NCR_700_command_slot *
+find_ITL_Nexus(struct NCR_700_Host_Parameters *hostdata, __u8 pun, __u8 lun)
+{
+	int hash = hash_ITL(pun, lun);
+	struct NCR_700_command_slot *slot = hostdata->ITL_Hash_back[hash];
+	while(slot != NULL && !(slot->cmnd->target == pun &&
+				slot->cmnd->lun == lun))
+		slot = slot->ITL_back;
+	return slot;
+}
+
+STATIC inline struct NCR_700_command_slot *
+find_ITLQ_Nexus(struct NCR_700_Host_Parameters *hostdata, __u8 pun,
+		__u8 lun, __u8 tag)
+{
+	int hash = hash_ITLQ(pun, lun, tag);
+	struct NCR_700_command_slot *slot = hostdata->ITLQ_Hash_back[hash];
+
+	while(slot != NULL && !(slot->cmnd->target == pun 
+	      && slot->cmnd->lun == lun && slot->tag == tag))
+		slot = slot->ITLQ_back;
+
+#ifdef NCR_700_TAG_DEBUG
+	if(slot != NULL) {
+		struct NCR_700_command_slot *n = slot->ITLQ_back;
+		while(n != NULL && n->cmnd->target != pun
+		      && n->cmnd->lun != lun && n->tag != tag)
+			n = n->ITLQ_back;
+
+		if(n != NULL && n->cmnd->target == pun && n->cmnd->lun == lun
+		   && n->tag == tag) {
+			printk(KERN_WARNING "53c700: WARNING: DUPLICATE tag %d\n",
+			       tag);
+		}
+	}
+#endif
+	return slot;
+}
+
+
+
+/* This translates the SDTR message offset and period to a value
+ * which can be loaded into the SXFER_REG.
+ *
+ * NOTE: According to SCSI-2, the true transfer period (in ns) is
+ *       actually four times this period value */
+STATIC inline __u8
+NCR_700_offset_period_to_sxfer(struct NCR_700_Host_Parameters *hostdata,
+			       __u8 offset, __u8 period)
+{
+	int XFERP;
+
+	if(period*4 < NCR_700_MIN_PERIOD) {
+		printk(KERN_WARNING "53c700: Period %dns is less than SCSI-2 minimum, setting to %d\n", period*4, NCR_700_MIN_PERIOD);
+		period = NCR_700_MIN_PERIOD/4;
+	}
+	XFERP = (period*4 * hostdata->sync_clock)/1000 - 4;
+	if(offset > NCR_700_MAX_OFFSET) {
+		printk(KERN_WARNING "53c700: Offset %d exceeds maximum, setting to %d\n",
+		       offset, NCR_700_MAX_OFFSET);
+		offset = NCR_700_MAX_OFFSET;
+	}
+	if(XFERP < NCR_700_MIN_XFERP) {
+		printk(KERN_WARNING "53c700: XFERP %d is less than minium, setting to %d\n",
+		       XFERP,  NCR_700_MIN_XFERP);
+		XFERP =  NCR_700_MIN_XFERP;
+	}
+	return (offset & 0x0f) | (XFERP & 0x07)<<4;
+}
+	
+
+STATIC inline void
+NCR_700_scsi_done(struct NCR_700_Host_Parameters *hostdata,
+	       Scsi_Cmnd *SCp, int result)
+{
+	hostdata->state = NCR_700_HOST_FREE;
+	hostdata->cmd = NULL;
+
+	if(SCp != NULL) {
+		struct NCR_700_command_slot *slot = 
+			(struct NCR_700_command_slot *)SCp->host_scribble;
+
+		if(SCp->cmnd[0] == REQUEST_SENSE && SCp->cmnd[6] == NCR_700_INTERNAL_SENSE_MAGIC) {
+#ifdef NCR_700_DEBUG
+			printk(" ORIGINAL CMD %p RETURNED %d, new return is %d sense is",
+			       SCp, SCp->cmnd[7], result);
+			print_sense("53c700", SCp);
+#endif
+			if(result == 0)
+				result = SCp->cmnd[7];
+		}
+			
+		free_slot(slot, hostdata);
+
+		SCp->host_scribble = NULL;
+		SCp->result = result;
+		SCp->scsi_done(SCp);
+		if(NCR_700_get_depth(SCp->device) == 0 ||
+		   NCR_700_get_depth(SCp->device) > NCR_700_MAX_TAGS)
+			printk(KERN_ERR "Invalid depth in NCR_700_scsi_done(): %d\n",
+			       NCR_700_get_depth(SCp->device));
+		NCR_700_set_depth(SCp->device, NCR_700_get_depth(SCp->device) - 1);
+	} else {
+		printk(KERN_ERR "53c700: SCSI DONE HAS NULL SCp\n");
+	}
+}
+
+
+STATIC void
+NCR_700_internal_bus_reset(struct Scsi_Host *host)
+{
+	/* Bus reset */
+	NCR_700_writeb(ASSERT_RST, host, SCNTL1_REG);
+	udelay(50);
+	NCR_700_writeb(0, host, SCNTL1_REG);
+
+}
+
+STATIC void
+NCR_700_chip_setup(struct Scsi_Host *host)
+{
+	struct NCR_700_Host_Parameters *hostdata = 
+		(struct NCR_700_Host_Parameters *)host->hostdata[0];
+
+	NCR_700_writeb(1 << host->this_id, host, SCID_REG);
+	NCR_700_writeb(0, host, SBCL_REG);
+	NCR_700_writeb(0, host, SXFER_REG);
+
+	NCR_700_writeb(PHASE_MM_INT | SEL_TIMEOUT_INT | GROSS_ERR_INT | UX_DISC_INT
+	     | RST_INT | PAR_ERR_INT | SELECT_INT, host, SIEN_REG);
+
+	NCR_700_writeb(ABORT_INT | INT_INST_INT | ILGL_INST_INT, host, DIEN_REG);
+	NCR_700_writeb(BURST_LENGTH_8, host, DMODE_REG);
+	NCR_700_writeb(FULL_ARBITRATION | PARITY | AUTO_ATN, host, SCNTL0_REG);
+	NCR_700_writeb(LAST_DIS_ENBL | ENABLE_ACTIVE_NEGATION|GENERATE_RECEIVE_PARITY,
+	     host, CTEST8_REG);
+	NCR_700_writeb(ENABLE_SELECT, host, SCNTL1_REG);
+	if(hostdata->clock > 75) {
+		printk(KERN_ERR "53c700: Clock speed %dMHz is too high: 75Mhz is the maximum this chip can be driven at\n", hostdata->clock);
+		/* do the best we can, but the async clock will be out
+		 * of spec: sync divider 2, async divider 3 */
+		DEBUG(("53c700: sync 2 async 3\n"));
+		NCR_700_writeb(SYNC_DIV_2_0, host, SBCL_REG);
+		NCR_700_writeb(ASYNC_DIV_3_0, host, DCNTL_REG);
+		hostdata->sync_clock = hostdata->clock/2;
+	} else	if(hostdata->clock > 50  && hostdata->clock <= 75) {
+		/* sync divider 1.5, async divider 3 */
+		DEBUG(("53c700: sync 1.5 async 3\n"));
+		NCR_700_writeb(SYNC_DIV_1_5, host, SBCL_REG);
+		NCR_700_writeb(ASYNC_DIV_3_0, host, DCNTL_REG);
+		hostdata->sync_clock = hostdata->clock*2;
+		hostdata->sync_clock /= 3;
+		
+	} else if(hostdata->clock > 37 && hostdata->clock <= 50) {
+		/* sync divider 1, async divider 2 */
+		DEBUG(("53c700: sync 1 async 2\n"));
+		NCR_700_writeb(SYNC_DIV_1_0, host, SBCL_REG);
+		NCR_700_writeb(ASYNC_DIV_2_0, host, DCNTL_REG);
+		hostdata->sync_clock = hostdata->clock;
+	} else if(hostdata->clock > 25 && hostdata->clock <=37) {
+		/* sync divider 1, async divider 1.5 */
+		DEBUG(("53c700: sync 1 async 1.5\n"));
+		NCR_700_writeb(SYNC_DIV_1_0, host, SBCL_REG);
+		NCR_700_writeb(ASYNC_DIV_1_5, host, DCNTL_REG);
+		hostdata->sync_clock = hostdata->clock;
+	} else {
+		DEBUG(("53c700: sync 1 async 1\n"));
+		NCR_700_writeb(SYNC_DIV_1_0, host, SBCL_REG);
+		NCR_700_writeb(ASYNC_DIV_1_0, host, DCNTL_REG);
+		/* sync divider 1, async divider 1 */
+	}
+}
+
+STATIC void
+NCR_700_chip_reset(struct Scsi_Host *host)
+{
+	/* Chip reset */
+	NCR_700_writeb(SOFTWARE_RESET, host, DCNTL_REG);
+	udelay(100);
+
+	NCR_700_writeb(0, host, DCNTL_REG);
+
+	mdelay(1000);
+
+	NCR_700_chip_setup(host);
+}
+
+/* The heart of the message processing engine is that the instruction
+ * immediately after the INT is the normal case (and so must be CLEAR
+ * ACK).  If we want to do something else, we call that routine in
+ * scripts and set temp to be the normal case + 8 (skipping the CLEAR
+ * ACK) so that the routine returns correctly to resume its activity
+ * */
+STATIC __u32
+process_extended_message(struct Scsi_Host *host, 
+			 struct NCR_700_Host_Parameters *hostdata,
+			 Scsi_Cmnd *SCp, __u32 dsp, __u32 dsps)
+{
+	__u32 resume_offset = dsp, temp = dsp + 8;
+	__u8 pun = 0xff, lun = 0xff;
+
+	if(SCp != NULL) {
+		pun = SCp->target;
+		lun = SCp->lun;
+	}
+
+	switch(hostdata->msgin[2]) {
+	case A_SDTR_MSG:
+		if(SCp != NULL && NCR_700_is_flag_set(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION)) {
+			__u8 period = hostdata->msgin[3];
+			__u8 offset = hostdata->msgin[4];
+			__u8 sxfer;
+
+			if(offset != 0 && period != 0)
+				sxfer = NCR_700_offset_period_to_sxfer(hostdata, offset, period);
+			else 
+				sxfer = 0;
+			
+			if(sxfer != NCR_700_get_SXFER(SCp->device)) {
+				printk(KERN_INFO "scsi%d: (%d:%d) Synchronous at offset %d, period %dns\n",
+				       host->host_no, pun, lun,
+				       offset, period*4);
+				
+				NCR_700_set_SXFER(SCp->device, sxfer);
+			}
+			
+
+			NCR_700_set_flag(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC);
+			NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION);
+			
+			NCR_700_writeb(NCR_700_get_SXFER(SCp->device),
+				       host, SXFER_REG);
+
+		} else {
+			/* SDTR message out of the blue, reject it */
+			printk(KERN_WARNING "scsi%d Unexpected SDTR msg\n",
+			       host->host_no);
+			hostdata->msgout[0] = A_REJECT_MSG;
+			dma_cache_wback((unsigned long)hostdata->msgout, sizeof(hostdata->msgout));
+			script_patch_16(hostdata->script, MessageCount, 1);
+			/* SendMsgOut returns, so set up the return
+			 * address */
+			resume_offset = hostdata->pScript + Ent_SendMessageWithATN;
+		}
+		break;
+	
+	case A_WDTR_MSG:
+		printk(KERN_INFO "scsi%d: (%d:%d), Unsolicited WDTR after CMD, Rejecting\n",
+		       host->host_no, pun, lun);
+		hostdata->msgout[0] = A_REJECT_MSG;
+		dma_cache_wback((unsigned long)hostdata->msgout, sizeof(hostdata->msgout));
+		script_patch_16(hostdata->script, MessageCount, 1);
+		resume_offset = hostdata->pScript + Ent_SendMessageWithATN;
+
+		break;
+
+	default:
+		printk(KERN_INFO "scsi%d (%d:%d): Unexpected message %s: ",
+		       host->host_no, pun, lun,
+		       NCR_700_phase[(dsps & 0xf00) >> 8]);
+		print_msg(hostdata->msgin);
+		printk("\n");
+		/* just reject it */
+		hostdata->msgout[0] = A_REJECT_MSG;
+		dma_cache_wback((unsigned long)hostdata->msgout, sizeof(hostdata->msgout));
+		script_patch_16(hostdata->script, MessageCount, 1);
+		/* SendMsgOut returns, so set up the return
+		 * address */
+		resume_offset = hostdata->pScript + Ent_SendMessageWithATN;
+	}
+	NCR_700_writel(temp, host, TEMP_REG);
+	return resume_offset;
+}
+
+STATIC __u32
+process_message(struct Scsi_Host *host,	struct NCR_700_Host_Parameters *hostdata,
+		Scsi_Cmnd *SCp, __u32 dsp, __u32 dsps)
+{
+	/* work out where to return to */
+	__u32 temp = dsp + 8, resume_offset = dsp;
+	__u8 pun = 0xff, lun = 0xff;
+
+	dma_cache_inv((unsigned long)hostdata->msgin, sizeof(hostdata->msgin));
+
+	if(SCp != NULL) {
+		pun = SCp->target;
+		lun = SCp->lun;
+	}
+
+#ifdef NCR_700_DEBUG
+	printk("scsi%d (%d:%d): message %s: ", host->host_no, pun, lun,
+	       NCR_700_phase[(dsps & 0xf00) >> 8]);
+	print_msg(hostdata->msgin);
+	printk("\n");
+#endif
+
+	switch(hostdata->msgin[0]) {
+
+	case A_EXTENDED_MSG:
+		return process_extended_message(host, hostdata, SCp,
+						dsp, dsps);
+
+	case A_REJECT_MSG:
+		if(SCp != NULL && NCR_700_is_flag_set(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION)) {
+			/* Rejected our sync negotiation attempt */
+			NCR_700_set_SXFER(SCp->device, 0);
+			NCR_700_set_flag(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC);
+			NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION);
+		} else if(SCp != NULL && NCR_700_is_flag_set(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING)) {
+			/* rejected our first simple tag message */
+			printk(KERN_WARNING "scsi%d (%d:%d) Rejected first tag queue attempt, turning off tag queueing\n", host->host_no, pun, lun);
+			NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING);
+			hostdata->tag_negotiated &= ~(1<<SCp->target);
+		} else {
+			printk(KERN_WARNING "scsi%d (%d:%d) Unexpected REJECT Message %s\n",
+			       host->host_no, pun, lun,
+			       NCR_700_phase[(dsps & 0xf00) >> 8]);
+			/* however, just ignore it */
+		}
+		break;
+
+	case A_PARITY_ERROR_MSG:
+		printk(KERN_ERR "scsi%d (%d:%d) Parity Error!\n", host->host_no,
+		       pun, lun);
+		NCR_700_internal_bus_reset(host);
+		break;
+	case A_SIMPLE_TAG_MSG:
+		printk(KERN_INFO "scsi%d (%d:%d) SIMPLE TAG %d %s\n", host->host_no,
+		       pun, lun, hostdata->msgin[1],
+		       NCR_700_phase[(dsps & 0xf00) >> 8]);
+		/* just ignore it */
+		break;
+	default:
+		printk(KERN_INFO "scsi%d (%d:%d): Unexpected message %s: ",
+		       host->host_no, pun, lun,
+		       NCR_700_phase[(dsps & 0xf00) >> 8]);
+
+		print_msg(hostdata->msgin);
+		printk("\n");
+		/* just reject it */
+		hostdata->msgout[0] = A_REJECT_MSG;
+		dma_cache_wback((unsigned long)hostdata->msgout, sizeof(hostdata->msgout));
+		script_patch_16(hostdata->script, MessageCount, 1);
+		/* SendMsgOut returns, so set up the return
+		 * address */
+		resume_offset = hostdata->pScript + Ent_SendMessageWithATN;
+
+		break;
+	}
+	NCR_700_writel(temp, host, TEMP_REG);
+	return resume_offset;
+}
+
+STATIC __u32
+process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp,
+			 struct Scsi_Host *host,
+			 struct NCR_700_Host_Parameters *hostdata)
+{
+	__u32 resume_offset = 0;
+	__u8 pun = 0xff, lun=0xff;
+
+	if(SCp != NULL) {
+		pun = SCp->target;
+		lun = SCp->lun;
+	}
+
+	if(dsps == A_GOOD_STATUS_AFTER_STATUS) {
+		dma_cache_inv((unsigned long)hostdata->status, sizeof(hostdata->status));
+		DEBUG(("  COMMAND COMPLETE, status=%02x\n",
+		       hostdata->status));
+		/* OK, if TCQ still on, we know it works */
+		NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING);
+		/* check for contingent allegiance contitions */
+		if(status_byte(hostdata->status) == CHECK_CONDITION ||
+		   status_byte(hostdata->status) == COMMAND_TERMINATED) {
+			struct NCR_700_command_slot *slot =
+				(struct NCR_700_command_slot *)SCp->host_scribble;
+			if(SCp->cmnd[0] == REQUEST_SENSE) {
+				/* OOPS: bad device, returning another
+				 * contingent allegiance condition */
+				printk(KERN_ERR "scsi%d (%d:%d) broken device is looping in contingent allegiance: ignoring\n", host->host_no, pun, lun);
+				NCR_700_scsi_done(hostdata, SCp, hostdata->status);
+			} else {
+
+				DEBUG(("  cmd %p has status %d, requesting sense\n",
+				       SCp, hostdata->status));
+				/* we can destroy the command here because the
+				 * contingent allegiance condition will cause a 
+				 * retry which will re-copy the command from the
+				 * saved data_cmnd */
+				SCp->cmnd[0] = REQUEST_SENSE;
+				SCp->cmnd[1] = (SCp->lun & 0x7) << 5;
+				SCp->cmnd[2] = 0;
+				SCp->cmnd[3] = 0;
+				SCp->cmnd[4] = sizeof(SCp->sense_buffer);
+				SCp->cmnd[5] = 0;
+				SCp->cmd_len = 6;
+				/* Here's a quiet hack: the REQUEST_SENSE command is
+				 * six bytes, so store a flag indicating that this
+				 * was an internal sense request and the original
+				 * status at the end of the command */
+				SCp->cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC;
+				SCp->cmnd[7] = hostdata->status;
+				slot->SG[0].ins = bS_to_host(SCRIPT_MOVE_DATA_IN | sizeof(SCp->sense_buffer));
+				slot->SG[0].pAddr = bS_to_host(virt_to_bus(SCp->sense_buffer));
+				slot->SG[1].ins = bS_to_host(SCRIPT_RETURN);
+				slot->SG[1].pAddr = 0;
+				slot->resume_offset = hostdata->pScript;
+				dma_cache_wback((unsigned long)slot->SG, sizeof(slot->SG[0])*2);
+				dma_cache_inv((unsigned long)SCp->sense_buffer, sizeof(SCp->sense_buffer));
+				
+				/* queue the command for reissue */
+				slot->state = NCR_700_SLOT_QUEUED;
+				hostdata->state = NCR_700_HOST_FREE;
+				hostdata->cmd = NULL;
+			}
+		} else {
+			if(status_byte(hostdata->status) == GOOD &&
+			   SCp->cmnd[0] == INQUIRY && SCp->use_sg == 0) {
+				/* Piggy back the tag queueing support
+				 * on this command */
+				if(((char *)SCp->request_buffer)[7] & 0x02) {
+					printk(KERN_INFO "scsi%d: (%d:%d) Enabling Tag Command Queuing\n", host->host_no, pun, lun);
+					hostdata->tag_negotiated |= (1<<SCp->target);
+					NCR_700_set_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING);
+				} else {
+					NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING);
+					hostdata->tag_negotiated &= ~(1<<SCp->target);
+				}
+			}
+			NCR_700_scsi_done(hostdata, SCp, hostdata->status);
+		}
+	} else if((dsps & 0xfffff0f0) == A_UNEXPECTED_PHASE) {
+		__u8 i = (dsps & 0xf00) >> 8;
+
+		printk(KERN_ERR "scsi%d: (%d:%d), UNEXPECTED PHASE %s (%s)\n",
+		       host->host_no, pun, lun,
+		       NCR_700_phase[i],
+		       sbcl_to_string(NCR_700_readb(host, SBCL_REG)));
+		printk(KERN_ERR "         len = %d, cmd =", SCp->cmd_len);
+		print_command(SCp->cmnd);
+
+		NCR_700_internal_bus_reset(host);
+	} else if((dsps & 0xfffff000) == A_FATAL) {
+		int i = (dsps & 0xfff);
+
+		printk(KERN_ERR "scsi%d: (%d:%d) FATAL ERROR: %s\n",
+		       host->host_no, pun, lun, NCR_700_fatal_messages[i]);
+		if(dsps == A_FATAL_ILLEGAL_MSG_LENGTH) {
+			printk(KERN_ERR "     msg begins %02x %02x\n",
+			       hostdata->msgin[0], hostdata->msgin[1]);
+		}
+		NCR_700_internal_bus_reset(host);
+	} else if((dsps & 0xfffff0f0) == A_DISCONNECT) {
+#ifdef NCR_700_DEBUG
+		__u8 i = (dsps & 0xf00) >> 8;
+
+		printk("scsi%d: (%d:%d), DISCONNECTED (%d) %s\n",
+		       host->host_no, pun, lun,
+		       i, NCR_700_phase[i]);
+#endif
+		save_for_reselection(hostdata, SCp, dsp);
+
+	} else if(dsps == A_RESELECTION_IDENTIFIED) {
+		__u8 lun;
+		struct NCR_700_command_slot *slot;
+		__u8 reselection_id = hostdata->reselection_id;
+
+		dma_cache_inv((unsigned long)hostdata->msgin, sizeof(hostdata->msgin));
+
+		lun = hostdata->msgin[0] & 0x1f;
+
+		hostdata->reselection_id = 0xff;
+		DEBUG(("scsi%d: (%d:%d) RESELECTED!\n",
+		       host->host_no, reselection_id, lun));
+		/* clear the reselection indicator */
+		if(hostdata->msgin[1] == A_SIMPLE_TAG_MSG) {
+			slot = find_ITLQ_Nexus(hostdata, reselection_id,
+					       lun, hostdata->msgin[2]);
+		} else {
+			slot = find_ITL_Nexus(hostdata, reselection_id, lun);
+		}
+	retry:
+		if(slot == NULL) {
+			struct NCR_700_command_slot *s = find_ITL_Nexus(hostdata, reselection_id, lun);
+			printk(KERN_ERR "scsi%d: (%d:%d) RESELECTED but no saved command (MSG = %02x %02x %02x)!!\n",
+			       host->host_no, reselection_id, lun,
+			       hostdata->msgin[0], hostdata->msgin[1],
+			       hostdata->msgin[2]);
+			printk(KERN_ERR " OUTSTANDING TAGS:");
+			while(s != NULL) {
+				if(s->cmnd->target == reselection_id &&
+				   s->cmnd->lun == lun) {
+					printk("%d ", s->tag);
+					if(s->tag == hostdata->msgin[2]) {
+						printk(" ***FOUND*** \n");
+						slot = s;
+						goto retry;
+					}
+						
+				}
+				s = s->ITL_back;
+			}
+			printk("\n");
+		} else {
+			if(hostdata->state != NCR_700_HOST_BUSY)
+				printk(KERN_ERR "scsi%d: FATAL, host not busy during valid reselection!\n",
+				       host->host_no);
+			resume_offset = slot->resume_offset;
+			hostdata->cmd = slot->cmnd;
+
+			/* re-patch for this command */
+			script_patch_32_abs(hostdata->script, CommandAddress, 
+					    virt_to_bus(slot->cmnd->cmnd));
+			script_patch_16(hostdata->script,
+					CommandCount, slot->cmnd->cmd_len);
+			script_patch_32_abs(hostdata->script, SGScriptStartAddress,
+					    virt_to_bus(&slot->SG[0].ins));
+
+			/* Note: setting SXFER only works if we're
+			 * still in the MESSAGE phase, so it is vital
+			 * that ACK is still asserted when we process
+			 * the reselection message.  The resume offset
+			 * should therefore always clear ACK */
+			NCR_700_writeb(NCR_700_get_SXFER(hostdata->cmd->device),
+				       host, SXFER_REG);
+			
+		}
+	} else if(dsps == A_RESELECTED_DURING_SELECTION) {
+
+		/* This section is full of debugging code because I've
+		 * never managed to reach it.  I think what happens is
+		 * that, because the 700 runs with selection
+		 * interrupts enabled the whole time that we take a
+		 * selection interrupt before we manage to get to the
+		 * reselected script interrupt */
+
+		__u8 reselection_id = NCR_700_readb(host, SFBR_REG);
+		struct NCR_700_command_slot *slot;
+		
+		/* Take out our own ID */
+		reselection_id &= ~(1<<host->this_id);
+		
+		printk(KERN_INFO "scsi%d: (%d:%d) RESELECTION DURING SELECTION, dsp=%p[%04x] state=%d, count=%d\n",
+		       host->host_no, reselection_id, lun, (void *)dsp, dsp - hostdata->pScript, hostdata->state, hostdata->command_slot_count);
+
+		{
+			/* FIXME: DEBUGGING CODE */
+			__u32 SG = (__u32)bus_to_virt(hostdata->script[A_SGScriptStartAddress_used[0]]);
+			int i;
+
+			for(i=0; i< NCR_700_COMMAND_SLOTS_PER_HOST; i++) {
+				if(SG >= (__u32)(&hostdata->slots[i].SG[0])
+				   && SG <= (__u32)(&hostdata->slots[i].SG[NCR_700_SG_SEGMENTS]))
+					break;
+			}
+			printk(KERN_INFO "IDENTIFIED SG segment as being %p in slot %p, cmd %p, slot->resume_offset=%p\n", (void *)SG, &hostdata->slots[i], hostdata->slots[i].cmnd, (void *)hostdata->slots[i].resume_offset);
+			SCp =  hostdata->slots[i].cmnd;
+		}
+
+		if(SCp != NULL) {
+			slot = (struct NCR_700_command_slot *)SCp->host_scribble;
+			/* change slot from busy to queued to redo command */
+			slot->state = NCR_700_SLOT_QUEUED;
+		}
+		hostdata->cmd = NULL;
+		
+		if(reselection_id == 0) {
+			if(hostdata->reselection_id == 0xff) {
+				printk(KERN_ERR "scsi%d: Invalid reselection during selection!!\n", host->host_no);
+				return 0;
+			} else {
+				printk(KERN_ERR "scsi%d: script reselected and we took a selection interrupt\n",
+				       host->host_no);
+				reselection_id = hostdata->reselection_id;
+			}
+		} else {
+			
+			/* convert to real ID */
+			reselection_id = bitmap_to_number(reselection_id);
+		}
+		hostdata->reselection_id = reselection_id;
+		hostdata->msgin[1] = 0;
+		dma_cache_wback((unsigned long)hostdata->msgin, sizeof(hostdata->msgin));
+		if(hostdata->tag_negotiated & (1<<reselection_id)) {
+			resume_offset = hostdata->pScript + Ent_GetReselectionWithTag;
+		} else {
+			resume_offset = hostdata->pScript + Ent_GetReselectionData;
+		}
+	} else if(dsps == A_COMPLETED_SELECTION_AS_TARGET) {
+		/* we've just disconnected from the bus, do nothing since
+		 * a return here will re-run the queued command slot
+		 * that may have been interrupted by the initial selection */
+		DEBUG((" SELECTION COMPLETED\n"));
+	} else if((dsps & 0xfffff0f0) == A_MSG_IN) { 
+		resume_offset = process_message(host, hostdata, SCp,
+						dsp, dsps);
+	} else if((dsps &  0xfffff000) == 0) {
+		__u8 i = (dsps & 0xf0) >> 4, j = (dsps & 0xf00) >> 8;
+		printk(KERN_ERR "scsi%d: (%d:%d), unhandled script condition %s %s at %04x\n",
+		       host->host_no, pun, lun, NCR_700_condition[i],
+		       NCR_700_phase[j], dsp - hostdata->pScript);
+		if(SCp != NULL) {
+			print_command(SCp->cmnd);
+
+			if(SCp->use_sg) {
+				for(i = 0; i < SCp->use_sg + 1; i++) {
+					printk(KERN_INFO " SG[%d].length = %d, move_insn=%08x, addr %08x\n", i, ((struct scatterlist *)SCp->buffer)[i].length, ((struct NCR_700_command_slot *)SCp->host_scribble)->SG[i].ins, ((struct NCR_700_command_slot *)SCp->host_scribble)->SG[i].pAddr);
+				}
+			}
+		}	       
+		NCR_700_internal_bus_reset(host);
+	} else if((dsps & 0xfffff000) == A_DEBUG_INTERRUPT) {
+		printk(KERN_NOTICE "scsi%d (%d:%d) DEBUG INTERRUPT %d AT %p[%04x], continuing\n",
+		       host->host_no, pun, lun, dsps & 0xfff, (void *)dsp, dsp - hostdata->pScript);
+		resume_offset = dsp;
+	} else {
+		printk(KERN_ERR "scsi%d: (%d:%d), unidentified script interrupt 0x%x at %04x\n",
+		       host->host_no, pun, lun, dsps, dsp - hostdata->pScript);
+		NCR_700_internal_bus_reset(host);
+	}
+	return resume_offset;
+}
+
+/* We run the 53c700 with selection interrupts always enabled.  This
+ * means that the chip may be selected as soon as the bus frees.  On a
+ * busy bus, this can be before the scripts engine finishes its
+ * processing.  Therefore, part of the selection processing has to be
+ * to find out what the scripts engine is doing and complete the
+ * function if necessary (i.e. process the pending disconnect or save
+ * the interrupted initial selection */
+STATIC inline __u32
+process_selection(struct Scsi_Host *host, __u32 dsp)
+{
+	__u8 id = 0;	/* Squash compiler warning */
+	int count = 0;
+	__u32 resume_offset = 0;
+	struct NCR_700_Host_Parameters *hostdata =
+		(struct NCR_700_Host_Parameters *)host->hostdata[0];
+	Scsi_Cmnd *SCp = hostdata->cmd;
+	__u8 sbcl;
+
+	for(count = 0; count < 5; count++) {
+		id = NCR_700_readb(host, SFBR_REG);
+
+		/* Take out our own ID */
+		id &= ~(1<<host->this_id);
+		if(id != 0) 
+			break;
+		udelay(5);
+	}
+	sbcl = NCR_700_readb(host, SBCL_REG);
+	if((sbcl & SBCL_IO) == 0) {
+		/* mark as having been selected rather than reselected */
+		id = 0xff;
+	} else {
+		/* convert to real ID */
+		hostdata->reselection_id = id = bitmap_to_number(id);
+		DEBUG(("scsi%d:  Reselected by %d\n",
+		       host->host_no, id));
+	}
+	if(hostdata->state == NCR_700_HOST_BUSY && SCp != NULL) {
+		struct NCR_700_command_slot *slot =
+			(struct NCR_700_command_slot *)SCp->host_scribble;
+		DEBUG(("  ID %d WARNING: RESELECTION OF BUSY HOST, saving cmd %p, slot %p, addr %x [%04x], resume %x!\n", id, hostdata->cmd, slot, dsp, dsp - hostdata->pScript, resume_offset));
+		
+		switch(dsp - hostdata->pScript) {
+		case Ent_Disconnect1:
+		case Ent_Disconnect2:
+			save_for_reselection(hostdata, SCp, Ent_Disconnect2 + hostdata->pScript);
+			break;
+		case Ent_Disconnect3:
+		case Ent_Disconnect4:
+			save_for_reselection(hostdata, SCp, Ent_Disconnect4 + hostdata->pScript);
+			break;
+		case Ent_Disconnect5:
+		case Ent_Disconnect6:
+			save_for_reselection(hostdata, SCp, Ent_Disconnect6 + hostdata->pScript);
+			break;
+		case Ent_Disconnect7:
+		case Ent_Disconnect8:
+			save_for_reselection(hostdata, SCp, Ent_Disconnect8 + hostdata->pScript);
+			break;
+		case Ent_Finish1:
+		case Ent_Finish2:
+			process_script_interrupt(A_GOOD_STATUS_AFTER_STATUS, dsp, SCp, host, hostdata);
+			break;
+			
+		default:
+			slot->state = NCR_700_SLOT_QUEUED;
+			break;
+			}
+	}
+	hostdata->state = NCR_700_HOST_BUSY;
+	hostdata->cmd = NULL;
+	hostdata->msgin[1] = 0;
+	dma_cache_wback((unsigned long)hostdata->msgin, sizeof(hostdata->msgin));
+
+	if(id == 0xff) {
+		/* Selected as target, Ignore */
+		resume_offset = hostdata->pScript + Ent_SelectedAsTarget;
+	} else if(hostdata->tag_negotiated & (1<<id)) {
+		resume_offset = hostdata->pScript + Ent_GetReselectionWithTag;
+	} else {
+		resume_offset = hostdata->pScript + Ent_GetReselectionData;
+	}
+	return resume_offset;
+}
+
+
+STATIC int
+NCR_700_start_command(Scsi_Cmnd *SCp)
+{
+	struct NCR_700_command_slot *slot =
+		(struct NCR_700_command_slot *)SCp->host_scribble;
+	struct NCR_700_Host_Parameters *hostdata =
+		(struct NCR_700_Host_Parameters *)SCp->host->hostdata[0];
+	unsigned long flags;
+	__u16 count = 1;	/* for IDENTIFY message */
+	
+	save_flags(flags);
+	cli();
+	if(hostdata->state != NCR_700_HOST_FREE) {
+		/* keep this inside the lock to close the race window where
+		 * the running command finishes on another CPU while we don't
+		 * change the state to queued on this one */
+		slot->state = NCR_700_SLOT_QUEUED;
+		restore_flags(flags);
+
+		DEBUG(("scsi%d: host busy, queueing command %p, slot %p\n",
+		       SCp->host->host_no, slot->cmnd, slot));
+		return 0;
+	}
+	hostdata->state = NCR_700_HOST_BUSY;
+	hostdata->cmd = SCp;
+	slot->state = NCR_700_SLOT_BUSY;
+	/* keep interrupts disabled until we have the command correctly
+	 * set up so we cannot take a selection interrupt */
+
+	hostdata->msgout[0] = NCR_700_identify(SCp->cmnd[0] != REQUEST_SENSE,
+					    SCp->lun);
+	/* for INQUIRY or REQUEST_SENSE commands, we cannot be sure
+	 * if the negotiated transfer parameters still hold, so
+	 * always renegotiate them */
+	if(SCp->cmnd[0] == INQUIRY || SCp->cmnd[0] == REQUEST_SENSE) {
+		NCR_700_clear_flag(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC);
+	}
+
+	/* REQUEST_SENSE is asking for contingent I_T_L status.  If a
+	 * contingent allegiance condition exists, the device will
+	 * refuse all tags, so send the request sense as untagged */
+	if((hostdata->tag_negotiated & (1<<SCp->target))
+	   && (slot->tag != NCR_700_NO_TAG && SCp->cmnd[0] != REQUEST_SENSE)) {
+		hostdata->msgout[count++] = A_SIMPLE_TAG_MSG;
+		hostdata->msgout[count++] = slot->tag;
+	}
+
+	if(hostdata->fast &&
+	   NCR_700_is_flag_clear(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC)) {
+		memcpy(&hostdata->msgout[count], NCR_700_SDTR_msg,
+		       sizeof(NCR_700_SDTR_msg));
+		count += sizeof(NCR_700_SDTR_msg);
+		NCR_700_set_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION);
+	}
+
+	dma_cache_wback((unsigned long)hostdata->msgout, count);
+
+	script_patch_16(hostdata->script, MessageCount, count);
+
+
+	script_patch_ID(hostdata->script,
+			Device_ID, 1<<SCp->target);
+
+	script_patch_32_abs(hostdata->script, CommandAddress, 
+			virt_to_bus(SCp->cmnd));
+	script_patch_16(hostdata->script, CommandCount, SCp->cmd_len);
+	/* finally plumb the beginning of the SG list into the script
+	 * */
+	script_patch_32_abs(hostdata->script, SGScriptStartAddress,
+			    virt_to_bus(&slot->SG[0].ins));
+	NCR_700_writeb(CLR_FIFO, SCp->host, DFIFO_REG);
+
+	/* set the synchronous period/offset */
+	if(slot->resume_offset == 0)
+		slot->resume_offset = hostdata->pScript;
+	NCR_700_writeb(NCR_700_get_SXFER(SCp->device),
+	     SCp->host, SXFER_REG);
+	/* allow interrupts here so that if we're selected we can take
+	 * a selection interrupt.  The script start may not be
+	 * effective in this case, but the selection interrupt will
+	 * save our command in that case */
+	NCR_700_writel(slot->temp, SCp->host, TEMP_REG);
+	NCR_700_writel(slot->resume_offset, SCp->host, DSP_REG);
+	restore_flags(flags);
+
+	return 1;
+}
+
+void
+NCR_700_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct Scsi_Host *host = (struct Scsi_Host *)dev_id;
+	struct NCR_700_Host_Parameters *hostdata =
+		(struct NCR_700_Host_Parameters *)host->hostdata[0];
+	__u8 istat;
+	__u32 resume_offset = 0;
+	__u8 pun = 0xff, lun = 0xff;
+	unsigned long flags;
+
+	/* Unfortunately, we have to take the io_request_lock here
+	 * rather than the host lock hostdata->lock because we're
+	 * looking to exclude queuecommand from messing with the
+	 * registers while we're processing the interrupt.  Since
+	 * queuecommand is called holding io_request_lock, and we have
+	 * to take io_request_lock before we call the command
+	 * scsi_done, we would get a deadlock if we took
+	 * hostdata->lock here and in queuecommand (because the order
+	 * of locking in queuecommand: 1) io_request_lock then 2)
+	 * hostdata->lock would be the reverse of taking it in this
+	 * routine */
+	spin_lock_irqsave(&io_request_lock, flags);
+	if((istat = NCR_700_readb(host, ISTAT_REG))
+	      & (SCSI_INT_PENDING | DMA_INT_PENDING)) {
+		__u32 dsps;
+		__u8 sstat0 = 0, dstat = 0;
+		__u32 dsp;
+		Scsi_Cmnd *SCp = hostdata->cmd;
+		enum NCR_700_Host_State state;
+
+		state = hostdata->state;
+		SCp = hostdata->cmd;
+
+		if(istat & SCSI_INT_PENDING) {
+			udelay(10);
+
+			sstat0 = NCR_700_readb(host, SSTAT0_REG);
+		}
+
+		if(istat & DMA_INT_PENDING) {
+			udelay(10);
+
+			dstat = NCR_700_readb(host, DSTAT_REG);
+		}
+
+		dsps = NCR_700_readl(host, DSPS_REG);
+		dsp = NCR_700_readl(host, DSP_REG);
+
+		DEBUG(("scsi%d: istat %02x sstat0 %02x dstat %02x dsp %04x[%08x] dsps 0x%x\n",
+		       host->host_no, istat, sstat0, dstat,
+		       (dsp - (__u32)virt_to_bus(hostdata->script))/4,
+		       dsp, dsps));
+
+		if(SCp != NULL) {
+			pun = SCp->target;
+			lun = SCp->lun;
+		}
+
+		if(sstat0 & SCSI_RESET_DETECTED) {
+			Scsi_Device *SDp;
+			int i;
+
+			hostdata->state = NCR_700_HOST_BUSY;
+
+			printk(KERN_ERR "scsi%d: Bus Reset detected, executing command %p, slot %p, dsp %p[%04x]\n",
+			       host->host_no, SCp, SCp == NULL ? NULL : SCp->host_scribble, (void *)dsp, dsp - hostdata->pScript);
+
+			/* clear all the negotiated parameters */
+			for(SDp = host->host_queue; SDp != NULL; SDp = SDp->next)
+				SDp->hostdata = 0;
+			
+			/* clear all the slots and their pending commands */
+			for(i = 0; i < NCR_700_COMMAND_SLOTS_PER_HOST; i++) {
+				Scsi_Cmnd *SCp;
+				struct NCR_700_command_slot *slot =
+					&hostdata->slots[i];
+
+				if(slot->state == NCR_700_SLOT_FREE)
+					continue;
+				
+				SCp = slot->cmnd;
+				printk(KERN_ERR " failing command because of reset, slot %p, cmnd %p\n",
+				       slot, SCp);
+				free_slot(slot, hostdata);
+				SCp->host_scribble = NULL;
+				NCR_700_set_depth(SCp->device, 0);
+				/* NOTE: deadlock potential here: we
+				 * rely on mid-layer guarantees that
+				 * scsi_done won't try to issue the
+				 * command again otherwise we'll
+				 * deadlock on the
+				 * hostdata->state_lock */
+				SCp->result = DID_RESET << 16;
+				SCp->scsi_done(SCp);
+			}
+			mdelay(25);
+			NCR_700_chip_setup(host);
+
+			hostdata->state = NCR_700_HOST_FREE;
+			hostdata->cmd = NULL;
+			goto out_unlock;
+		} else if(sstat0 & SELECTION_TIMEOUT) {
+			DEBUG(("scsi%d: (%d:%d) selection timeout\n",
+			       host->host_no, pun, lun));
+			NCR_700_scsi_done(hostdata, SCp, DID_NO_CONNECT<<16);
+		} else if(sstat0 & PHASE_MISMATCH) {
+			struct NCR_700_command_slot *slot = (SCp == NULL) ? NULL :
+				(struct NCR_700_command_slot *)SCp->host_scribble;
+
+			if(dsp == Ent_SendMessage + 8 + hostdata->pScript) {
+				/* It wants to reply to some part of
+				 * our message */
+#ifdef NCR_700_DEBUG
+				__u32 temp = NCR_700_readl(host, TEMP_REG);
+				int count = (hostdata->script[Ent_SendMessage/4] & 0xffffff) - ((NCR_700_readl(host, DBC_REG) & 0xffffff) + NCR_700_data_residual(host));
+				printk("scsi%d (%d:%d) PHASE MISMATCH IN SEND MESSAGE %d remain, return %p[%04x], phase %s\n", host->host_no, pun, lun, count, (void *)temp, temp - hostdata->pScript, sbcl_to_string(NCR_700_readb(host, SBCL_REG)));
+#endif
+				resume_offset = hostdata->pScript + Ent_SendMessagePhaseMismatch;
+			} else if(dsp >= virt_to_bus(&slot->SG[0].ins) &&
+				  dsp <= virt_to_bus(&slot->SG[NCR_700_SG_SEGMENTS].ins)) {
+				int data_transfer = NCR_700_readl(host, DBC_REG) & 0xffffff;
+				int SGcount = (dsp - virt_to_bus(&slot->SG[0].ins))/sizeof(struct NCR_700_SG_List);
+				int residual = NCR_700_data_residual(host);
+				int i;
+#ifdef NCR_700_DEBUG
+				printk("scsi%d: (%d:%d) Expected phase mismatch in slot->SG[%d], transferred 0x%x\n",
+				       host->host_no, pun, lun,
+				       SGcount, data_transfer);
+				print_command(SCp->cmnd);
+				if(residual) {
+					printk("scsi%d: (%d:%d) Expected phase mismatch in slot->SG[%d], transferred 0x%x, residual %d\n",
+				       host->host_no, pun, lun,
+				       SGcount, data_transfer, residual);
+				}
+#endif
+				data_transfer += residual;
+
+				if(data_transfer != 0) {
+					int count; 
+					__u32 pAddr;
+
+					SGcount--;
+
+					count = (bS_to_cpu(slot->SG[SGcount].ins) & 0x00ffffff);
+					DEBUG(("DATA TRANSFER MISMATCH, count = %d, transferred %d\n", count, count-data_transfer));
+					slot->SG[SGcount].ins &= bS_to_host(0xff000000);
+					slot->SG[SGcount].ins |= bS_to_host(data_transfer);
+					pAddr = bS_to_cpu(slot->SG[SGcount].pAddr);
+					pAddr += (count - data_transfer);
+					slot->SG[SGcount].pAddr = bS_to_host(pAddr);
+				}
+				/* set the executed moves to nops */
+				for(i=0; i<SGcount; i++) {
+					slot->SG[i].ins = bS_to_host(SCRIPT_NOP);
+					slot->SG[i].pAddr = 0;
+				}
+				dma_cache_wback((unsigned long)slot->SG, sizeof(slot->SG));
+				/* and pretend we disconnected after
+				 * the command phase */
+				resume_offset = hostdata->pScript + Ent_MsgInDuringData;
+			} else {
+				__u8 sbcl = NCR_700_readb(host, SBCL_REG);
+				printk(KERN_ERR "scsi%d: (%d:%d) phase mismatch at %04x, phase %s\n",
+				       host->host_no, pun, lun, dsp - hostdata->pScript, sbcl_to_string(sbcl));
+				NCR_700_internal_bus_reset(host);
+			}
+
+		} else if(sstat0 & SCSI_GROSS_ERROR) {
+			printk(KERN_ERR "scsi%d: (%d:%d) GROSS ERROR\n",
+			       host->host_no, pun, lun);
+			NCR_700_scsi_done(hostdata, SCp, DID_ERROR<<16);
+		} else if(dstat & SCRIPT_INT_RECEIVED) {
+			DEBUG(("scsi%d: (%d:%d) ====>SCRIPT INTERRUPT<====\n",
+			       host->host_no, pun, lun));
+			resume_offset = process_script_interrupt(dsps, dsp, SCp, host, hostdata);
+		} else if(dstat & (ILGL_INST_DETECTED)) {
+			printk(KERN_ERR "scsi%d: (%d:%d) Illegal Instruction detected at 0x%p[0x%x]!!!\n"
+			       "         Please email James.Bottomley@HansenPartnership.com with the details\n",
+			       host->host_no, pun, lun,
+			       (void *)dsp, dsp - hostdata->pScript);
+			NCR_700_scsi_done(hostdata, SCp, DID_ERROR<<16);
+		} else if(dstat & (WATCH_DOG_INTERRUPT|ABORTED)) {
+			printk(KERN_ERR "scsi%d: (%d:%d) serious DMA problem, dstat=%02x\n",
+			       host->host_no, pun, lun, dstat);
+			NCR_700_scsi_done(hostdata, SCp, DID_ERROR<<16);
+		}
+
+		
+		/* NOTE: selection interrupt processing MUST occur
+		 * after script interrupt processing to correctly cope
+		 * with the case where we process a disconnect and
+		 * then get reselected before we process the
+		 * disconnection */
+		if(sstat0 & SELECTED) {
+			/* FIXME: It currently takes at least FOUR
+			 * interrupts to complete a command that
+			 * disconnects: one for the disconnect, one
+			 * for the reselection, one to get the
+			 * reselection data and one to complete the
+			 * command.  If we guess the reselected
+			 * command here and prepare it, we only need
+			 * to get a reselection data interrupt if we
+			 * guessed wrongly.  Since the interrupt
+			 * overhead is much greater than the command
+			 * setup, this would be an efficient
+			 * optimisation particularly as we probably
+			 * only have one outstanding command on a
+			 * target most of the time */
+
+			resume_offset = process_selection(host, dsp);
+
+		}
+
+	}
+
+	if(resume_offset) {
+		if(hostdata->state != NCR_700_HOST_BUSY) {
+			printk(KERN_ERR "scsi%d: Driver error: resume at %p [%04x] with non busy host!\n",
+			       host->host_no, (void *)resume_offset, resume_offset - hostdata->pScript);
+			hostdata->state = NCR_700_HOST_BUSY;
+		}
+
+		DEBUG(("Attempting to resume at %x\n", resume_offset));
+		NCR_700_writeb(CLR_FIFO, host, DFIFO_REG);
+		NCR_700_writel(resume_offset, host, DSP_REG);
+	} 
+	/* There is probably a technical no-no about this: If we're a
+	 * shared interrupt and we got this interrupt because the
+	 * other device needs servicing not us, we're still going to
+	 * check our queued commands here---of course, there shouldn't
+	 * be any outstanding.... */
+	if(hostdata->state == NCR_700_HOST_FREE) {
+		int i;
+
+		for(i = 0; i < NCR_700_COMMAND_SLOTS_PER_HOST; i++) {
+			/* fairness: always run the queue from the last
+			 * position we left off */
+			int j = (i + hostdata->saved_slot_position)
+				% NCR_700_COMMAND_SLOTS_PER_HOST;
+			
+			if(hostdata->slots[j].state != NCR_700_SLOT_QUEUED)
+				continue;
+			if(NCR_700_start_command(hostdata->slots[j].cmnd)) {
+				DEBUG(("scsi%d: Issuing saved command slot %p, cmd %p\t\n",
+				       host->host_no, &hostdata->slots[j],
+				       hostdata->slots[j].cmnd));
+				hostdata->saved_slot_position = j + 1;
+			}
+
+			break;
+		}
+	}
+ out_unlock:
+	spin_unlock_irqrestore(&io_request_lock, flags);
+}
+
+/* FIXME: Need to put some proc information in and plumb it
+ * into the scsi proc system */
+STATIC int
+NCR_700_proc_directory_info(char *proc_buf, char **startp,
+			 off_t offset, int bytes_available,
+			 int host_no, int write)
+{
+	static char buf[4096];	/* 1 page should be sufficient */
+	int len = 0;
+	struct Scsi_Host *host = scsi_hostlist;
+	struct NCR_700_Host_Parameters *hostdata;
+	Scsi_Device *SDp;
+
+	while(host != NULL && host->host_no != host_no)
+		host = host->next;
+
+	if(host == NULL)
+		return 0;
+
+	if(write) {
+		/* FIXME: Clear internal statistics here */
+		return 0;
+	}
+	hostdata = (struct NCR_700_Host_Parameters *)host->hostdata[0];
+	len += sprintf(&buf[len], "Total commands outstanding: %d\n", hostdata->command_slot_count);
+	len += sprintf(&buf[len],"\
+Target	Depth  Active  Next Tag\n\
+======	=====  ======  ========\n");
+	for(SDp = host->host_queue; SDp != NULL; SDp = SDp->next) {
+		len += sprintf(&buf[len]," %2d:%2d   %4d    %4d      %4d\n", SDp->id, SDp->lun, SDp->queue_depth, NCR_700_get_depth(SDp), SDp->current_tag);
+	}
+	if((len -= offset) <= 0)
+		return 0;
+	if(len > bytes_available)
+		len = bytes_available;
+	memcpy(proc_buf, buf + offset, len);
+	return len;
+}
+
+STATIC int
+NCR_700_queuecommand(Scsi_Cmnd *SCp, void (*done)(Scsi_Cmnd *))
+{
+	struct NCR_700_Host_Parameters *hostdata = 
+		(struct NCR_700_Host_Parameters *)SCp->host->hostdata[0];
+	__u32 move_ins;
+	struct NCR_700_command_slot *slot;
+	int hash;
+
+	if(hostdata->command_slot_count >= NCR_700_COMMAND_SLOTS_PER_HOST) {
+		/* We're over our allocation, this should never happen
+		 * since we report the max allocation to the mid layer */
+		printk(KERN_WARNING "scsi%d: Command depth has gone over queue depth\n", SCp->host->host_no);
+		return 1;
+	}
+	if(NCR_700_get_depth(SCp->device) != 0 && !(hostdata->tag_negotiated & (1<<SCp->target))) {
+		DEBUG((KERN_ERR "scsi%d (%d:%d) has non zero depth %d\n",
+		       SCp->host->host_no, SCp->target, SCp->lun,
+		       NCR_700_get_depth(SCp->device)));
+		return 1;
+	}
+	if(NCR_700_get_depth(SCp->device) >= NCR_700_MAX_TAGS) {
+		DEBUG((KERN_ERR "scsi%d (%d:%d) has max tag depth %d\n",
+		       SCp->host->host_no, SCp->target, SCp->lun,
+		       NCR_700_get_depth(SCp->device)));
+		return 1;
+	}
+	NCR_700_set_depth(SCp->device, NCR_700_get_depth(SCp->device) + 1);
+
+	/* begin the command here */
+	/* no need to check for NULL, test for command_slot_cound above
+	 * ensures a slot is free */
+	slot = find_empty_slot(hostdata);
+
+	slot->cmnd = SCp;
+
+	SCp->scsi_done = done;
+	SCp->host_scribble = (unsigned char *)slot;
+	SCp->SCp.ptr = NULL;
+	SCp->SCp.buffer = NULL;
+
+#ifdef NCR_700_DEBUG
+	printk("53c700: scsi%d, command ", SCp->host->host_no);
+	print_command(SCp->cmnd);
+#endif
+
+	if(hostdata->tag_negotiated &(1<<SCp->target)) {
+
+		struct NCR_700_command_slot *old =
+			find_ITL_Nexus(hostdata, SCp->target, SCp->lun);
+#ifdef NCR_700_TAG_DEBUG
+		struct NCR_700_command_slot *found;
+#endif
+		
+		if(old != NULL && old->tag == SCp->device->current_tag) {
+			printk(KERN_WARNING "scsi%d (%d:%d) Tag clock back to current, queueing\n", SCp->host->host_no, SCp->target, SCp->lun);
+			return 1;
+		}
+		slot->tag = SCp->device->current_tag++;
+#ifdef NCR_700_TAG_DEBUG
+		while((found = find_ITLQ_Nexus(hostdata, SCp->target, SCp->lun, slot->tag)) != NULL) {
+			printk("\n\n**ERROR** already using tag %d, but oldest is %d\n", slot->tag, (old == NULL) ? -1 : old->tag);
+			printk("  FOUND = %p, tag = %d, pun = %d, lun = %d\n",
+			       found, found->tag, found->cmnd->target, found->cmnd->lun);
+			slot->tag = SCp->device->current_tag++;
+			printk("   Tag list is: ");
+			while(old != NULL) {
+				if(old->cmnd->target == SCp->target &&
+				   old->cmnd->lun == SCp->lun)
+					printk("%d ", old->tag);
+				old = old->ITL_back;
+			}
+			printk("\n\n");
+		}
+#endif
+		hash = hash_ITLQ(SCp->target, SCp->lun, slot->tag);
+		/* link into the ITLQ hash queues */
+		slot->ITLQ_forw = hostdata->ITLQ_Hash_forw[hash];
+		hostdata->ITLQ_Hash_forw[hash] = slot;
+#ifdef NCR_700_TAG_DEBUG
+		if(slot->ITLQ_forw != NULL && slot->ITLQ_forw->ITLQ_back != NULL) {
+			printk(KERN_ERR "scsi%d (%d:%d) ITLQ_back is not NULL!!!!\n", SCp->host->host_no, SCp->target, SCp->lun);
+		}
+#endif
+		if(slot->ITLQ_forw != NULL)
+			slot->ITLQ_forw->ITLQ_back = slot;
+		else
+			hostdata->ITLQ_Hash_back[hash] = slot;
+		slot->ITLQ_back = NULL;
+	} else {
+		slot->tag = NCR_700_NO_TAG;
+	}
+	/* link into the ITL hash queues */
+	hash = hash_ITL(SCp->target, SCp->lun);
+	slot->ITL_forw = hostdata->ITL_Hash_forw[hash];
+	hostdata->ITL_Hash_forw[hash] = slot;
+#ifdef NCR_700_TAG_DEBUG
+	if(slot->ITL_forw != NULL && slot->ITL_forw->ITL_back != NULL) {
+		printk(KERN_ERR "scsi%d (%d:%d) ITL_back is not NULL!!!!\n",
+		       SCp->host->host_no, SCp->target, SCp->lun);
+	}
+#endif
+	if(slot->ITL_forw != NULL)
+		slot->ITL_forw->ITL_back = slot;
+	else
+		hostdata->ITL_Hash_back[hash] = slot;
+	slot->ITL_back = NULL;
+
+		
+	/* This is f****g ridiculous; every low level HBA driver has
+	 * to determine the direction of the commands, why isn't this
+	 * done inside the scsi_lib !!??? */
+	switch (SCp->cmnd[0]) {
+	case REQUEST_SENSE:
+		/* clear the internal sense magic */
+		SCp->cmnd[6] = 0;
+		/* fall through */
+	case INQUIRY:
+	case MODE_SENSE:
+	case READ_6:
+	case READ_10:
+	case READ_12:
+	case READ_CAPACITY:
+	case READ_BLOCK_LIMITS:
+	case READ_TOC:
+		move_ins = SCRIPT_MOVE_DATA_IN;
+		break;
+	case MODE_SELECT:
+	case WRITE_6:
+	case WRITE_10:
+	case WRITE_12:
+		move_ins = SCRIPT_MOVE_DATA_OUT;
+		break;
+	case TEST_UNIT_READY:
+	case ALLOW_MEDIUM_REMOVAL:
+	case START_STOP:
+		move_ins = 0;
+		break;
+	default:
+		/* OK, get it from the command */
+		switch(SCp->sc_data_direction) {
+		case SCSI_DATA_UNKNOWN:
+		default:
+			printk(KERN_ERR "53c700: Unknown command for data direction ");
+			print_command(SCp->cmnd);
+			
+			move_ins = 0;
+			break;
+		case SCSI_DATA_NONE:
+			move_ins = 0;
+			break;
+		case SCSI_DATA_READ:
+			move_ins = SCRIPT_MOVE_DATA_IN;
+			break;
+		case SCSI_DATA_WRITE:
+			move_ins = SCRIPT_MOVE_DATA_OUT;
+			break;
+		}
+	}
+
+	/* now build the scatter gather list */
+	if(move_ins != 0) {
+		int i;
+
+		for(i = 0; i < (SCp->use_sg ? SCp->use_sg : 1); i++) {
+			void *vPtr;
+			__u32 count;
+
+			if(SCp->use_sg) {
+				vPtr = (((struct scatterlist *)SCp->buffer)[i].address);
+				count = ((struct scatterlist *)SCp->buffer)[i].length;
+			} else {
+				vPtr = SCp->request_buffer;
+				count = SCp->request_bufflen;
+			}
+			slot->SG[i].ins = bS_to_host(move_ins | count);
+			DEBUG((" scatter block %d: move %d[%08x] from 0x%lx\n",
+			       i, count, slot->SG[i].ins, 
+			       virt_to_bus(vPtr)));
+			dma_cache_wback_inv((unsigned long)vPtr, count);
+			slot->SG[i].pAddr = bS_to_host(virt_to_bus(vPtr));
+		}
+		slot->SG[i].ins = bS_to_host(SCRIPT_RETURN);
+		slot->SG[i].pAddr = 0;
+		dma_cache_wback((unsigned long)slot->SG, sizeof(slot->SG));
+		DEBUG((" SETTING %08lx to %x\n",
+		       virt_to_bus(&slot->SG[i].ins), 
+		       slot->SG[i].ins));
+	}
+	slot->resume_offset = 0;
+	NCR_700_start_command(SCp);
+	return 0;
+}
+
+STATIC int
+NCR_700_abort(Scsi_Cmnd * SCp)
+{
+	struct NCR_700_command_slot *slot;
+	struct NCR_700_Host_Parameters *hostdata = 
+		(struct NCR_700_Host_Parameters *)SCp->host->hostdata[0];
+
+	printk(KERN_INFO "scsi%d (%d:%d) New error handler wants to abort command\n\t",
+	       SCp->host->host_no, SCp->target, SCp->lun);
+	print_command(SCp->cmnd);
+
+	slot = find_ITL_Nexus(hostdata, SCp->target, SCp->lun);
+	while(slot != NULL && slot->cmnd != SCp)
+		slot = slot->ITL_back;
+
+	if(slot == NULL)
+		/* no outstanding command to abort */
+		return SUCCESS;
+	if(SCp->cmnd[0] == TEST_UNIT_READY) {
+		/* FIXME: This is because of a problem in the new
+		 * error handler.  When it is in error recovery, it
+		 * will send a TUR to a device it thinks may still be
+		 * showing a problem.  If the TUR isn't responded to,
+		 * it will abort it and mark the device off line.
+		 * Unfortunately, it does no other error recovery, so
+		 * this would leave us with an outstanding command
+		 * occupying a slot.  Rather than allow this to
+		 * happen, we issue a bus reset to force all
+		 * outstanding commands to terminate here. */
+		NCR_700_internal_bus_reset(SCp->host);
+		/* still drop through and return failed */
+	}
+	return FAILED;
+
+}
+
+STATIC int
+NCR_700_bus_reset(Scsi_Cmnd * SCp)
+{
+	printk(KERN_INFO "scsi%d (%d:%d) New error handler wants BUS reset, cmd %p\n\t",
+	       SCp->host->host_no, SCp->target, SCp->lun, SCp);
+	print_command(SCp->cmnd);
+	NCR_700_internal_bus_reset(SCp->host);
+	return SUCCESS;
+}
+
+STATIC int
+NCR_700_dev_reset(Scsi_Cmnd * SCp)
+{
+	printk(KERN_INFO "scsi%d (%d:%d) New error handler wants device reset\n\t",
+	       SCp->host->host_no, SCp->target, SCp->lun);
+	print_command(SCp->cmnd);
+	
+	return FAILED;
+}
+
+STATIC int
+NCR_700_host_reset(Scsi_Cmnd * SCp)
+{
+	printk(KERN_INFO "scsi%d (%d:%d) New error handler wants HOST reset\n\t",
+	       SCp->host->host_no, SCp->target, SCp->lun);
+	print_command(SCp->cmnd);
+
+	NCR_700_internal_bus_reset(SCp->host);
+	NCR_700_chip_reset(SCp->host);
+	return SUCCESS;
+}
+
+EXPORT_SYMBOL(NCR_700_detect);
+EXPORT_SYMBOL(NCR_700_release);
+EXPORT_SYMBOL(NCR_700_intr);
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/53c700.c linux/drivers/scsi/53c700.c
--- v2.4.9/linux/drivers/scsi/53c700.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/53c700.c	Sun Sep  9 10:50:48 2001
@@ -0,0 +1,1840 @@
+/* -*- mode: c; c-basic-offset: 8 -*- */
+
+/* NCR (or Symbios) 53c700 and 53c700-66 Driver
+ *
+ * Copyright (C) 2001 by James.Bottomley@HansenPartnership.com
+**-----------------------------------------------------------------------------
+**  
+**  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+**
+**-----------------------------------------------------------------------------
+ */
+
+/* Notes:
+ *
+ * This driver is designed exclusively for these chips (virtually the
+ * earliest of the scripts engine chips).  They need their own drivers
+ * because they are missing so many of the scripts and snazzy register
+ * features of their elder brothers (the 710, 720 and 770).
+ *
+ * The 700 is the lowliest of the line, it can only do async SCSI.
+ * The 700-66 can at least do synchronous SCSI up to 10MHz.
+ * 
+ * The 700 chip has no host bus interface logic of its own.  However,
+ * it is usually mapped to a location with well defined register
+ * offsets.  Therefore, if you can determine the base address and the
+ * irq your board incorporating this chip uses, you can probably use
+ * this driver to run it (although you'll probably have to write a
+ * minimal wrapper for the purpose---see the NCR_D700 driver for
+ * details about how to do this).
+ *
+ *
+ * TODO List:
+ *
+ * 1. Better statistics in the proc fs
+ *
+ * 2. Implement message queue (queues SCSI messages like commands) and make
+ *    the abort and device reset functions use them.
+ * */
+
+/* CHANGELOG
+ *
+ * Version 2.3
+ *
+ * More endianness/cache coherency changes.
+ *
+ * Better bad device handling (handles devices lying about tag
+ * queueing support and devices which fail to provide sense data on
+ * contingent allegiance conditions)
+ *
+ * Many thanks to Richard Hirst <rhirst@linuxcare.com> for patiently
+ * debugging this driver on the parisc architecture and suggesting
+ * many improvements and bug fixes.
+ *
+ * Thanks also go to Linuxcare Inc. for providing several PARISC
+ * machines for me to debug the driver on.
+ *
+ * Version 2.2
+ *
+ * Made the driver mem or io mapped; added endian invariance; added
+ * dma cache flushing operations for architectures which need it;
+ * added support for more varied clocking speeds.
+ *
+ * Version 2.1
+ *
+ * Initial modularisation from the D700.  See NCR_D700.c for the rest of
+ * the changelog.
+ * */
+#define NCR_700_VERSION "2.3"
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/mca.h>
+#include <asm/dma.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/byteorder.h>
+#include <linux/blk.h>
+#include <linux/module.h>
+
+#include "scsi.h"
+#include "hosts.h"
+#include "constants.h"
+
+#include "53c700.h"
+
+#ifdef NCR_700_DEBUG
+#define STATIC
+#else
+#define STATIC static
+#endif
+
+MODULE_AUTHOR("James Bottomley");
+MODULE_DESCRIPTION("53c700 and 53c700-66 Driver");
+MODULE_LICENSE("GPL");
+
+/* This is the script */
+#include "53c700_d.h"
+
+
+STATIC int NCR_700_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+STATIC int NCR_700_abort(Scsi_Cmnd * SCpnt);
+STATIC int NCR_700_bus_reset(Scsi_Cmnd * SCpnt);
+STATIC int NCR_700_dev_reset(Scsi_Cmnd * SCpnt);
+STATIC int NCR_700_host_reset(Scsi_Cmnd * SCpnt);
+STATIC int NCR_700_proc_directory_info(char *, char **, off_t, int, int, int);
+STATIC void NCR_700_chip_setup(struct Scsi_Host *host);
+STATIC void NCR_700_chip_reset(struct Scsi_Host *host);
+
+static char *NCR_700_phase[] = {
+	"",
+	"after selection",
+	"before command phase",
+	"after command phase",
+	"after status phase",
+	"after data in phase",
+	"after data out phase",
+	"during data phase",
+};
+
+static char *NCR_700_condition[] = {
+	"",
+	"NOT MSG_OUT",
+	"UNEXPECTED PHASE",
+	"NOT MSG_IN",
+	"UNEXPECTED MSG",
+	"MSG_IN",
+	"SDTR_MSG RECEIVED",
+	"REJECT_MSG RECEIVED",
+	"DISCONNECT_MSG RECEIVED",
+	"MSG_OUT",
+	"DATA_IN",
+	
+};
+
+static char *NCR_700_fatal_messages[] = {
+	"unexpected message after reselection",
+	"still MSG_OUT after message injection",
+	"not MSG_IN after selection",
+	"Illegal message length received",
+};
+
+static char *NCR_700_SBCL_bits[] = {
+	"IO ",
+	"CD ",
+	"MSG ",
+	"ATN ",
+	"SEL ",
+	"BSY ",
+	"ACK ",
+	"REQ ",
+};
+
+static char *NCR_700_SBCL_to_phase[] = {
+	"DATA_OUT",
+	"DATA_IN",
+	"CMD_OUT",
+	"STATE",
+	"ILLEGAL PHASE",
+	"ILLEGAL PHASE",
+	"MSG OUT",
+	"MSG IN",
+};
+
+static __u8 NCR_700_SDTR_msg[] = {
+	0x01,			/* Extended message */
+	0x03,			/* Extended message Length */
+	0x01,			/* SDTR Extended message */
+	NCR_700_MIN_PERIOD,
+	NCR_700_MAX_OFFSET
+};
+
+struct Scsi_Host * __init
+NCR_700_detect(Scsi_Host_Template *tpnt,
+	       struct NCR_700_Host_Parameters *hostdata)
+{
+	__u32 *script = kmalloc(sizeof(SCRIPT), GFP_KERNEL);
+	__u32 pScript;
+	struct Scsi_Host *host;
+	static int banner = 0;
+	int j;
+
+	/* Fill in the missing routines from the host template */
+	tpnt->queuecommand = NCR_700_queuecommand;
+	tpnt->eh_abort_handler = NCR_700_abort;
+	tpnt->eh_device_reset_handler = NCR_700_dev_reset;
+	tpnt->eh_bus_reset_handler = NCR_700_bus_reset;
+	tpnt->eh_host_reset_handler = NCR_700_host_reset;
+	tpnt->can_queue = NCR_700_COMMAND_SLOTS_PER_HOST;
+	tpnt->sg_tablesize = NCR_700_SG_SEGMENTS;
+	tpnt->cmd_per_lun = NCR_700_MAX_TAGS;
+	tpnt->use_clustering = DISABLE_CLUSTERING;
+	tpnt->use_new_eh_code = 1;
+	tpnt->proc_info = NCR_700_proc_directory_info;
+	
+	if(tpnt->name == NULL)
+		tpnt->name = "53c700";
+	if(tpnt->proc_name == NULL)
+		tpnt->proc_name = "53c700";
+	
+
+	if((host = scsi_register(tpnt, 4)) == NULL)
+		return NULL;
+	if(script == NULL) {
+		printk(KERN_ERR "53c700: Failed to allocate script, detatching\n");
+		scsi_unregister(host);
+		return NULL;
+	}
+
+	hostdata->slots = kmalloc(sizeof(struct NCR_700_command_slot) * NCR_700_COMMAND_SLOTS_PER_HOST, GFP_KERNEL);
+	if(hostdata->slots == NULL) {
+		printk(KERN_ERR "53c700: Failed to allocate command slots, detatching\n");
+		scsi_unregister(host);
+		return NULL;
+	}
+	memset(hostdata->slots, 0, sizeof(struct NCR_700_command_slot) * NCR_700_COMMAND_SLOTS_PER_HOST);
+	for(j = 0; j < NCR_700_COMMAND_SLOTS_PER_HOST; j++) {
+		if(j == 0)
+			hostdata->free_list = &hostdata->slots[j];
+		else
+			hostdata->slots[j-1].ITL_forw = &hostdata->slots[j];
+		hostdata->slots[j].state = NCR_700_SLOT_FREE;
+	}
+	host->hostdata[0] = (__u32)hostdata;
+	for(j = 0; j < sizeof(SCRIPT)/sizeof(SCRIPT[0]); j++) {
+		script[j] = bS_to_host(SCRIPT[j]);
+	}
+	/* bus physical address of script */
+	pScript = virt_to_bus(script);
+	/* adjust all labels to be bus physical */
+	for(j = 0; j < PATCHES; j++) {
+		script[LABELPATCHES[j]] = bS_to_host(pScript + SCRIPT[LABELPATCHES[j]]);
+	}
+	/* now patch up fixed addresses */
+	script_patch_32(script, MessageLocation,
+			virt_to_bus(&hostdata->msgout[0]));
+	script_patch_32(script, StatusAddress,
+			virt_to_bus(&hostdata->status));
+	script_patch_32(script, ReceiveMsgAddress,
+			virt_to_bus(&hostdata->msgin[0]));
+
+	hostdata->script = script;
+	hostdata->pScript = pScript;
+	hostdata->state = NCR_700_HOST_FREE;
+	spin_lock_init(&hostdata->lock);
+	hostdata->cmd = NULL;
+	host->max_id = 7;
+	host->max_lun = NCR_700_MAX_LUNS;
+	host->unique_id = hostdata->base;
+	host->base = hostdata->base;
+	host->hostdata[0] = (unsigned long)hostdata;
+	/* kick the chip */
+	NCR_700_writeb(0xff, host, CTEST9_REG);
+	hostdata->rev = (NCR_700_readb(host, CTEST7_REG)<<4) & 0x0f;
+	hostdata->fast = (NCR_700_readb(host, CTEST9_REG) == 0);
+	if(banner == 0) {
+		printk(KERN_NOTICE "53c700: Version " NCR_700_VERSION " By James.Bottomley@HansenPartnership.com\n");
+		banner = 1;
+	}
+	printk(KERN_NOTICE "scsi%d: %s rev %d %s\n", host->host_no,
+	       hostdata->fast ? "53c700-66" : "53c700",
+	       hostdata->rev, hostdata->differential ?
+	       "(Differential)" : "");
+	/* reset the chip */
+	NCR_700_chip_reset(host);
+	NCR_700_writeb(ASYNC_OPERATION , host, SXFER_REG);
+
+	return host;
+}
+
+int
+NCR_700_release(struct Scsi_Host *host)
+{
+	struct NCR_700_Host_Parameters *hostdata = 
+		(struct NCR_700_Host_Parameters *)host->hostdata[0];
+
+	kfree(hostdata->script);
+	return 1;
+}
+
+static inline __u8
+NCR_700_identify(int can_disconnect, __u8 lun)
+{
+	return IDENTIFY_BASE |
+		((can_disconnect) ? 0x40 : 0) |
+		(lun & NCR_700_LUN_MASK);
+}
+
+/*
+ * Function : static int datapath_residual (Scsi_Host *host)
+ *
+ * Purpose : return residual data count of what's in the chip.  If you
+ * really want to know what this function is doing, it's almost a
+ * direct transcription of the algorithm described in the 53c710
+ * guide, except that the DBC and DFIFO registers are only 6 bits
+ * wide.
+ *
+ * Inputs : host - SCSI host */
+static inline int
+NCR_700_data_residual (struct Scsi_Host *host) {
+	int count, synchronous;
+	unsigned int ddir;
+
+	count = ((NCR_700_readb(host, DFIFO_REG) & 0x3f) -
+		 (NCR_700_readl(host, DBC_REG) & 0x3f)) & 0x3f;
+	
+	synchronous = NCR_700_readb(host, SXFER_REG) & 0x0f;
+	
+	/* get the data direction */
+	ddir = NCR_700_readb(host, CTEST0_REG) & 0x01;
+
+	if (ddir) {
+		/* Receive */
+		if (synchronous) 
+			count += (NCR_700_readb(host, SSTAT2_REG) & 0xf0) >> 4;
+		else
+			if (NCR_700_readb(host, SSTAT1_REG) & SIDL_REG_FULL)
+				++count;
+	} else {
+		/* Send */
+		__u8 sstat = NCR_700_readb(host, SSTAT1_REG);
+		if (sstat & SODL_REG_FULL)
+			++count;
+		if (synchronous && (sstat & SODR_REG_FULL))
+			++count;
+	}
+	return count;
+}
+
+/* print out the SCSI wires and corresponding phase from the SBCL register
+ * in the chip */
+static inline char *
+sbcl_to_string(__u8 sbcl)
+{
+	int i;
+	static char ret[256];
+
+	ret[0]='\0';
+	for(i=0; i<8; i++) {
+		if((1<<i) & sbcl) 
+			strcat(ret, NCR_700_SBCL_bits[i]);
+	}
+	strcat(ret, NCR_700_SBCL_to_phase[sbcl & 0x07]);
+	return ret;
+}
+
+static inline __u8
+bitmap_to_number(__u8 bitmap)
+{
+	__u8 i;
+
+	for(i=0; i<8 && !(bitmap &(1<<i)); i++)
+		;
+	return i;
+}
+
+/* Pull a slot off the free list */
+STATIC struct NCR_700_command_slot *
+find_empty_slot(struct NCR_700_Host_Parameters *hostdata)
+{
+	struct NCR_700_command_slot *slot = hostdata->free_list;
+
+	if(slot == NULL) {
+		/* sanity check */
+		if(hostdata->command_slot_count != NCR_700_COMMAND_SLOTS_PER_HOST)
+			printk(KERN_ERR "SLOTS FULL, but count is %d, should be %d\n", hostdata->command_slot_count, NCR_700_COMMAND_SLOTS_PER_HOST);
+		return NULL;
+	}
+
+	if(slot->state != NCR_700_SLOT_FREE)
+		/* should panic! */
+		printk(KERN_ERR "BUSY SLOT ON FREE LIST!!!\n");
+		
+
+	hostdata->free_list = slot->ITL_forw;
+	slot->ITL_forw = NULL;
+
+
+	/* NOTE: set the state to busy here, not queued, since this
+	 * indicates the slot is in use and cannot be run by the IRQ
+	 * finish routine.  If we cannot queue the command when it
+	 * is properly build, we then change to NCR_700_SLOT_QUEUED */
+	slot->state = NCR_700_SLOT_BUSY;
+	hostdata->command_slot_count++;
+	
+	return slot;
+}
+
+STATIC void 
+free_slot(struct NCR_700_command_slot *slot,
+	  struct NCR_700_Host_Parameters *hostdata)
+{
+	int hash;
+	struct NCR_700_command_slot **forw, **back;
+
+
+	if((slot->state & NCR_700_SLOT_MASK) != NCR_700_SLOT_MAGIC) {
+		printk(KERN_ERR "53c700: SLOT %p is not MAGIC!!!\n", slot);
+	}
+	if(slot->state == NCR_700_SLOT_FREE) {
+		printk(KERN_ERR "53c700: SLOT %p is FREE!!!\n", slot);
+	}
+	/* remove from queues */
+	if(slot->tag != NCR_700_NO_TAG) {
+		hash = hash_ITLQ(slot->cmnd->target, slot->cmnd->lun,
+				 slot->tag);
+		if(slot->ITLQ_forw == NULL)
+			back = &hostdata->ITLQ_Hash_back[hash];
+		else
+			back = &slot->ITLQ_forw->ITLQ_back;
+
+		if(slot->ITLQ_back == NULL)
+			forw = &hostdata->ITLQ_Hash_forw[hash];
+		else
+			forw = &slot->ITLQ_back->ITLQ_forw;
+
+		*forw = slot->ITLQ_forw;
+		*back = slot->ITLQ_back;
+	}
+	hash = hash_ITL(slot->cmnd->target, slot->cmnd->lun);
+	if(slot->ITL_forw == NULL)
+		back = &hostdata->ITL_Hash_back[hash];
+	else
+		back = &slot->ITL_forw->ITL_back;
+	
+	if(slot->ITL_back == NULL)
+		forw = &hostdata->ITL_Hash_forw[hash];
+	else
+		forw = &slot->ITL_back->ITL_forw;
+	
+	*forw = slot->ITL_forw;
+	*back = slot->ITL_back;
+	
+	slot->resume_offset = 0;
+	slot->cmnd = NULL;
+	slot->state = NCR_700_SLOT_FREE;
+	slot->ITL_forw = hostdata->free_list;
+	hostdata->free_list = slot;
+	hostdata->command_slot_count--;
+}
+
+
+/* This routine really does very little.  The command is indexed on
+   the ITL and (if tagged) the ITLQ lists in _queuecommand */
+STATIC void
+save_for_reselection(struct NCR_700_Host_Parameters *hostdata,
+		     Scsi_Cmnd *SCp, __u32 dsp)
+{
+	/* Its just possible that this gets executed twice */
+	if(SCp != NULL) {
+		struct NCR_700_command_slot *slot =
+			(struct NCR_700_command_slot *)SCp->host_scribble;
+
+		slot->resume_offset = dsp;
+	}
+	hostdata->state = NCR_700_HOST_FREE;
+	hostdata->cmd = NULL;
+}
+
+/* Most likely nexus is the oldest in each case */
+STATIC inline struct NCR_700_command_slot *
+find_ITL_Nexus(struct NCR_700_Host_Parameters *hostdata, __u8 pun, __u8 lun)
+{
+	int hash = hash_ITL(pun, lun);
+	struct NCR_700_command_slot *slot = hostdata->ITL_Hash_back[hash];
+	while(slot != NULL && !(slot->cmnd->target == pun &&
+				slot->cmnd->lun == lun))
+		slot = slot->ITL_back;
+	return slot;
+}
+
+STATIC inline struct NCR_700_command_slot *
+find_ITLQ_Nexus(struct NCR_700_Host_Parameters *hostdata, __u8 pun,
+		__u8 lun, __u8 tag)
+{
+	int hash = hash_ITLQ(pun, lun, tag);
+	struct NCR_700_command_slot *slot = hostdata->ITLQ_Hash_back[hash];
+
+	while(slot != NULL && !(slot->cmnd->target == pun 
+	      && slot->cmnd->lun == lun && slot->tag == tag))
+		slot = slot->ITLQ_back;
+
+#ifdef NCR_700_TAG_DEBUG
+	if(slot != NULL) {
+		struct NCR_700_command_slot *n = slot->ITLQ_back;
+		while(n != NULL && n->cmnd->target != pun
+		      && n->cmnd->lun != lun && n->tag != tag)
+			n = n->ITLQ_back;
+
+		if(n != NULL && n->cmnd->target == pun && n->cmnd->lun == lun
+		   && n->tag == tag) {
+			printk(KERN_WARNING "53c700: WARNING: DUPLICATE tag %d\n",
+			       tag);
+		}
+	}
+#endif
+	return slot;
+}
+
+
+
+/* This translates the SDTR message offset and period to a value
+ * which can be loaded into the SXFER_REG.
+ *
+ * NOTE: According to SCSI-2, the true transfer period (in ns) is
+ *       actually four times this period value */
+STATIC inline __u8
+NCR_700_offset_period_to_sxfer(struct NCR_700_Host_Parameters *hostdata,
+			       __u8 offset, __u8 period)
+{
+	int XFERP;
+
+	if(period*4 < NCR_700_MIN_PERIOD) {
+		printk(KERN_WARNING "53c700: Period %dns is less than SCSI-2 minimum, setting to %d\n", period*4, NCR_700_MIN_PERIOD);
+		period = NCR_700_MIN_PERIOD/4;
+	}
+	XFERP = (period*4 * hostdata->sync_clock)/1000 - 4;
+	if(offset > NCR_700_MAX_OFFSET) {
+		printk(KERN_WARNING "53c700: Offset %d exceeds maximum, setting to %d\n",
+		       offset, NCR_700_MAX_OFFSET);
+		offset = NCR_700_MAX_OFFSET;
+	}
+	if(XFERP < NCR_700_MIN_XFERP) {
+		printk(KERN_WARNING "53c700: XFERP %d is less than minium, setting to %d\n",
+		       XFERP,  NCR_700_MIN_XFERP);
+		XFERP =  NCR_700_MIN_XFERP;
+	}
+	return (offset & 0x0f) | (XFERP & 0x07)<<4;
+}
+	
+
+STATIC inline void
+NCR_700_scsi_done(struct NCR_700_Host_Parameters *hostdata,
+	       Scsi_Cmnd *SCp, int result)
+{
+	hostdata->state = NCR_700_HOST_FREE;
+	hostdata->cmd = NULL;
+
+	if(SCp != NULL) {
+		struct NCR_700_command_slot *slot = 
+			(struct NCR_700_command_slot *)SCp->host_scribble;
+
+		if(SCp->cmnd[0] == REQUEST_SENSE && SCp->cmnd[6] == NCR_700_INTERNAL_SENSE_MAGIC) {
+#ifdef NCR_700_DEBUG
+			printk(" ORIGINAL CMD %p RETURNED %d, new return is %d sense is",
+			       SCp, SCp->cmnd[7], result);
+			print_sense("53c700", SCp);
+#endif
+			if(result == 0)
+				result = SCp->cmnd[7];
+		}
+			
+		free_slot(slot, hostdata);
+
+		SCp->host_scribble = NULL;
+		SCp->result = result;
+		SCp->scsi_done(SCp);
+		if(NCR_700_get_depth(SCp->device) == 0 ||
+		   NCR_700_get_depth(SCp->device) > NCR_700_MAX_TAGS)
+			printk(KERN_ERR "Invalid depth in NCR_700_scsi_done(): %d\n",
+			       NCR_700_get_depth(SCp->device));
+		NCR_700_set_depth(SCp->device, NCR_700_get_depth(SCp->device) - 1);
+	} else {
+		printk(KERN_ERR "53c700: SCSI DONE HAS NULL SCp\n");
+	}
+}
+
+
+STATIC void
+NCR_700_internal_bus_reset(struct Scsi_Host *host)
+{
+	/* Bus reset */
+	NCR_700_writeb(ASSERT_RST, host, SCNTL1_REG);
+	udelay(50);
+	NCR_700_writeb(0, host, SCNTL1_REG);
+
+}
+
+STATIC void
+NCR_700_chip_setup(struct Scsi_Host *host)
+{
+	struct NCR_700_Host_Parameters *hostdata = 
+		(struct NCR_700_Host_Parameters *)host->hostdata[0];
+
+	NCR_700_writeb(1 << host->this_id, host, SCID_REG);
+	NCR_700_writeb(0, host, SBCL_REG);
+	NCR_700_writeb(0, host, SXFER_REG);
+
+	NCR_700_writeb(PHASE_MM_INT | SEL_TIMEOUT_INT | GROSS_ERR_INT | UX_DISC_INT
+	     | RST_INT | PAR_ERR_INT | SELECT_INT, host, SIEN_REG);
+
+	NCR_700_writeb(ABORT_INT | INT_INST_INT | ILGL_INST_INT, host, DIEN_REG);
+	NCR_700_writeb(BURST_LENGTH_8, host, DMODE_REG);
+	NCR_700_writeb(FULL_ARBITRATION | PARITY | AUTO_ATN, host, SCNTL0_REG);
+	NCR_700_writeb(LAST_DIS_ENBL | ENABLE_ACTIVE_NEGATION|GENERATE_RECEIVE_PARITY,
+	     host, CTEST8_REG);
+	NCR_700_writeb(ENABLE_SELECT, host, SCNTL1_REG);
+	if(hostdata->clock > 75) {
+		printk(KERN_ERR "53c700: Clock speed %dMHz is too high: 75Mhz is the maximum this chip can be driven at\n", hostdata->clock);
+		/* do the best we can, but the async clock will be out
+		 * of spec: sync divider 2, async divider 3 */
+		DEBUG(("53c700: sync 2 async 3\n"));
+		NCR_700_writeb(SYNC_DIV_2_0, host, SBCL_REG);
+		NCR_700_writeb(ASYNC_DIV_3_0, host, DCNTL_REG);
+		hostdata->sync_clock = hostdata->clock/2;
+	} else	if(hostdata->clock > 50  && hostdata->clock <= 75) {
+		/* sync divider 1.5, async divider 3 */
+		DEBUG(("53c700: sync 1.5 async 3\n"));
+		NCR_700_writeb(SYNC_DIV_1_5, host, SBCL_REG);
+		NCR_700_writeb(ASYNC_DIV_3_0, host, DCNTL_REG);
+		hostdata->sync_clock = hostdata->clock*2;
+		hostdata->sync_clock /= 3;
+		
+	} else if(hostdata->clock > 37 && hostdata->clock <= 50) {
+		/* sync divider 1, async divider 2 */
+		DEBUG(("53c700: sync 1 async 2\n"));
+		NCR_700_writeb(SYNC_DIV_1_0, host, SBCL_REG);
+		NCR_700_writeb(ASYNC_DIV_2_0, host, DCNTL_REG);
+		hostdata->sync_clock = hostdata->clock;
+	} else if(hostdata->clock > 25 && hostdata->clock <=37) {
+		/* sync divider 1, async divider 1.5 */
+		DEBUG(("53c700: sync 1 async 1.5\n"));
+		NCR_700_writeb(SYNC_DIV_1_0, host, SBCL_REG);
+		NCR_700_writeb(ASYNC_DIV_1_5, host, DCNTL_REG);
+		hostdata->sync_clock = hostdata->clock;
+	} else {
+		DEBUG(("53c700: sync 1 async 1\n"));
+		NCR_700_writeb(SYNC_DIV_1_0, host, SBCL_REG);
+		NCR_700_writeb(ASYNC_DIV_1_0, host, DCNTL_REG);
+		/* sync divider 1, async divider 1 */
+	}
+}
+
+STATIC void
+NCR_700_chip_reset(struct Scsi_Host *host)
+{
+	/* Chip reset */
+	NCR_700_writeb(SOFTWARE_RESET, host, DCNTL_REG);
+	udelay(100);
+
+	NCR_700_writeb(0, host, DCNTL_REG);
+
+	mdelay(1000);
+
+	NCR_700_chip_setup(host);
+}
+
+/* The heart of the message processing engine is that the instruction
+ * immediately after the INT is the normal case (and so must be CLEAR
+ * ACK).  If we want to do something else, we call that routine in
+ * scripts and set temp to be the normal case + 8 (skipping the CLEAR
+ * ACK) so that the routine returns correctly to resume its activity
+ * */
+STATIC __u32
+process_extended_message(struct Scsi_Host *host, 
+			 struct NCR_700_Host_Parameters *hostdata,
+			 Scsi_Cmnd *SCp, __u32 dsp, __u32 dsps)
+{
+	__u32 resume_offset = dsp, temp = dsp + 8;
+	__u8 pun = 0xff, lun = 0xff;
+
+	if(SCp != NULL) {
+		pun = SCp->target;
+		lun = SCp->lun;
+	}
+
+	switch(hostdata->msgin[2]) {
+	case A_SDTR_MSG:
+		if(SCp != NULL && NCR_700_is_flag_set(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION)) {
+			__u8 period = hostdata->msgin[3];
+			__u8 offset = hostdata->msgin[4];
+			__u8 sxfer;
+
+			if(offset != 0 && period != 0)
+				sxfer = NCR_700_offset_period_to_sxfer(hostdata, offset, period);
+			else 
+				sxfer = 0;
+			
+			if(sxfer != NCR_700_get_SXFER(SCp->device)) {
+				printk(KERN_INFO "scsi%d: (%d:%d) Synchronous at offset %d, period %dns\n",
+				       host->host_no, pun, lun,
+				       offset, period*4);
+				
+				NCR_700_set_SXFER(SCp->device, sxfer);
+			}
+			
+
+			NCR_700_set_flag(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC);
+			NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION);
+			
+			NCR_700_writeb(NCR_700_get_SXFER(SCp->device),
+				       host, SXFER_REG);
+
+		} else {
+			/* SDTR message out of the blue, reject it */
+			printk(KERN_WARNING "scsi%d Unexpected SDTR msg\n",
+			       host->host_no);
+			hostdata->msgout[0] = A_REJECT_MSG;
+			dma_cache_wback((unsigned long)hostdata->msgout, sizeof(hostdata->msgout));
+			script_patch_16(hostdata->script, MessageCount, 1);
+			/* SendMsgOut returns, so set up the return
+			 * address */
+			resume_offset = hostdata->pScript + Ent_SendMessageWithATN;
+		}
+		break;
+	
+	case A_WDTR_MSG:
+		printk(KERN_INFO "scsi%d: (%d:%d), Unsolicited WDTR after CMD, Rejecting\n",
+		       host->host_no, pun, lun);
+		hostdata->msgout[0] = A_REJECT_MSG;
+		dma_cache_wback((unsigned long)hostdata->msgout, sizeof(hostdata->msgout));
+		script_patch_16(hostdata->script, MessageCount, 1);
+		resume_offset = hostdata->pScript + Ent_SendMessageWithATN;
+
+		break;
+
+	default:
+		printk(KERN_INFO "scsi%d (%d:%d): Unexpected message %s: ",
+		       host->host_no, pun, lun,
+		       NCR_700_phase[(dsps & 0xf00) >> 8]);
+		print_msg(hostdata->msgin);
+		printk("\n");
+		/* just reject it */
+		hostdata->msgout[0] = A_REJECT_MSG;
+		dma_cache_wback((unsigned long)hostdata->msgout, sizeof(hostdata->msgout));
+		script_patch_16(hostdata->script, MessageCount, 1);
+		/* SendMsgOut returns, so set up the return
+		 * address */
+		resume_offset = hostdata->pScript + Ent_SendMessageWithATN;
+	}
+	NCR_700_writel(temp, host, TEMP_REG);
+	return resume_offset;
+}
+
+STATIC __u32
+process_message(struct Scsi_Host *host,	struct NCR_700_Host_Parameters *hostdata,
+		Scsi_Cmnd *SCp, __u32 dsp, __u32 dsps)
+{
+	/* work out where to return to */
+	__u32 temp = dsp + 8, resume_offset = dsp;
+	__u8 pun = 0xff, lun = 0xff;
+
+	dma_cache_inv((unsigned long)hostdata->msgin, sizeof(hostdata->msgin));
+
+	if(SCp != NULL) {
+		pun = SCp->target;
+		lun = SCp->lun;
+	}
+
+#ifdef NCR_700_DEBUG
+	printk("scsi%d (%d:%d): message %s: ", host->host_no, pun, lun,
+	       NCR_700_phase[(dsps & 0xf00) >> 8]);
+	print_msg(hostdata->msgin);
+	printk("\n");
+#endif
+
+	switch(hostdata->msgin[0]) {
+
+	case A_EXTENDED_MSG:
+		return process_extended_message(host, hostdata, SCp,
+						dsp, dsps);
+
+	case A_REJECT_MSG:
+		if(SCp != NULL && NCR_700_is_flag_set(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION)) {
+			/* Rejected our sync negotiation attempt */
+			NCR_700_set_SXFER(SCp->device, 0);
+			NCR_700_set_flag(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC);
+			NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION);
+		} else if(SCp != NULL && NCR_700_is_flag_set(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING)) {
+			/* rejected our first simple tag message */
+			printk(KERN_WARNING "scsi%d (%d:%d) Rejected first tag queue attempt, turning off tag queueing\n", host->host_no, pun, lun);
+			NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING);
+			hostdata->tag_negotiated &= ~(1<<SCp->target);
+		} else {
+			printk(KERN_WARNING "scsi%d (%d:%d) Unexpected REJECT Message %s\n",
+			       host->host_no, pun, lun,
+			       NCR_700_phase[(dsps & 0xf00) >> 8]);
+			/* however, just ignore it */
+		}
+		break;
+
+	case A_PARITY_ERROR_MSG:
+		printk(KERN_ERR "scsi%d (%d:%d) Parity Error!\n", host->host_no,
+		       pun, lun);
+		NCR_700_internal_bus_reset(host);
+		break;
+	case A_SIMPLE_TAG_MSG:
+		printk(KERN_INFO "scsi%d (%d:%d) SIMPLE TAG %d %s\n", host->host_no,
+		       pun, lun, hostdata->msgin[1],
+		       NCR_700_phase[(dsps & 0xf00) >> 8]);
+		/* just ignore it */
+		break;
+	default:
+		printk(KERN_INFO "scsi%d (%d:%d): Unexpected message %s: ",
+		       host->host_no, pun, lun,
+		       NCR_700_phase[(dsps & 0xf00) >> 8]);
+
+		print_msg(hostdata->msgin);
+		printk("\n");
+		/* just reject it */
+		hostdata->msgout[0] = A_REJECT_MSG;
+		dma_cache_wback((unsigned long)hostdata->msgout, sizeof(hostdata->msgout));
+		script_patch_16(hostdata->script, MessageCount, 1);
+		/* SendMsgOut returns, so set up the return
+		 * address */
+		resume_offset = hostdata->pScript + Ent_SendMessageWithATN;
+
+		break;
+	}
+	NCR_700_writel(temp, host, TEMP_REG);
+	return resume_offset;
+}
+
+STATIC __u32
+process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp,
+			 struct Scsi_Host *host,
+			 struct NCR_700_Host_Parameters *hostdata)
+{
+	__u32 resume_offset = 0;
+	__u8 pun = 0xff, lun=0xff;
+
+	if(SCp != NULL) {
+		pun = SCp->target;
+		lun = SCp->lun;
+	}
+
+	if(dsps == A_GOOD_STATUS_AFTER_STATUS) {
+		dma_cache_inv((unsigned long)hostdata->status, sizeof(hostdata->status));
+		DEBUG(("  COMMAND COMPLETE, status=%02x\n",
+		       hostdata->status));
+		/* OK, if TCQ still on, we know it works */
+		NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING);
+		/* check for contingent allegiance contitions */
+		if(status_byte(hostdata->status) == CHECK_CONDITION ||
+		   status_byte(hostdata->status) == COMMAND_TERMINATED) {
+			struct NCR_700_command_slot *slot =
+				(struct NCR_700_command_slot *)SCp->host_scribble;
+			if(SCp->cmnd[0] == REQUEST_SENSE) {
+				/* OOPS: bad device, returning another
+				 * contingent allegiance condition */
+				printk(KERN_ERR "scsi%d (%d:%d) broken device is looping in contingent allegiance: ignoring\n", host->host_no, pun, lun);
+				NCR_700_scsi_done(hostdata, SCp, hostdata->status);
+			} else {
+
+				DEBUG(("  cmd %p has status %d, requesting sense\n",
+				       SCp, hostdata->status));
+				/* we can destroy the command here because the
+				 * contingent allegiance condition will cause a 
+				 * retry which will re-copy the command from the
+				 * saved data_cmnd */
+				SCp->cmnd[0] = REQUEST_SENSE;
+				SCp->cmnd[1] = (SCp->lun & 0x7) << 5;
+				SCp->cmnd[2] = 0;
+				SCp->cmnd[3] = 0;
+				SCp->cmnd[4] = sizeof(SCp->sense_buffer);
+				SCp->cmnd[5] = 0;
+				SCp->cmd_len = 6;
+				/* Here's a quiet hack: the REQUEST_SENSE command is
+				 * six bytes, so store a flag indicating that this
+				 * was an internal sense request and the original
+				 * status at the end of the command */
+				SCp->cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC;
+				SCp->cmnd[7] = hostdata->status;
+				slot->SG[0].ins = bS_to_host(SCRIPT_MOVE_DATA_IN | sizeof(SCp->sense_buffer));
+				slot->SG[0].pAddr = bS_to_host(virt_to_bus(SCp->sense_buffer));
+				slot->SG[1].ins = bS_to_host(SCRIPT_RETURN);
+				slot->SG[1].pAddr = 0;
+				slot->resume_offset = hostdata->pScript;
+				dma_cache_wback((unsigned long)slot->SG, sizeof(slot->SG[0])*2);
+				dma_cache_inv((unsigned long)SCp->sense_buffer, sizeof(SCp->sense_buffer));
+				
+				/* queue the command for reissue */
+				slot->state = NCR_700_SLOT_QUEUED;
+				hostdata->state = NCR_700_HOST_FREE;
+				hostdata->cmd = NULL;
+			}
+		} else {
+			if(status_byte(hostdata->status) == GOOD &&
+			   SCp->cmnd[0] == INQUIRY && SCp->use_sg == 0) {
+				/* Piggy back the tag queueing support
+				 * on this command */
+				if(((char *)SCp->request_buffer)[7] & 0x02) {
+					printk(KERN_INFO "scsi%d: (%d:%d) Enabling Tag Command Queuing\n", host->host_no, pun, lun);
+					hostdata->tag_negotiated |= (1<<SCp->target);
+					NCR_700_set_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING);
+				} else {
+					NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING);
+					hostdata->tag_negotiated &= ~(1<<SCp->target);
+				}
+			}
+			NCR_700_scsi_done(hostdata, SCp, hostdata->status);
+		}
+	} else if((dsps & 0xfffff0f0) == A_UNEXPECTED_PHASE) {
+		__u8 i = (dsps & 0xf00) >> 8;
+
+		printk(KERN_ERR "scsi%d: (%d:%d), UNEXPECTED PHASE %s (%s)\n",
+		       host->host_no, pun, lun,
+		       NCR_700_phase[i],
+		       sbcl_to_string(NCR_700_readb(host, SBCL_REG)));
+		printk(KERN_ERR "         len = %d, cmd =", SCp->cmd_len);
+		print_command(SCp->cmnd);
+
+		NCR_700_internal_bus_reset(host);
+	} else if((dsps & 0xfffff000) == A_FATAL) {
+		int i = (dsps & 0xfff);
+
+		printk(KERN_ERR "scsi%d: (%d:%d) FATAL ERROR: %s\n",
+		       host->host_no, pun, lun, NCR_700_fatal_messages[i]);
+		if(dsps == A_FATAL_ILLEGAL_MSG_LENGTH) {
+			printk(KERN_ERR "     msg begins %02x %02x\n",
+			       hostdata->msgin[0], hostdata->msgin[1]);
+		}
+		NCR_700_internal_bus_reset(host);
+	} else if((dsps & 0xfffff0f0) == A_DISCONNECT) {
+#ifdef NCR_700_DEBUG
+		__u8 i = (dsps & 0xf00) >> 8;
+
+		printk("scsi%d: (%d:%d), DISCONNECTED (%d) %s\n",
+		       host->host_no, pun, lun,
+		       i, NCR_700_phase[i]);
+#endif
+		save_for_reselection(hostdata, SCp, dsp);
+
+	} else if(dsps == A_RESELECTION_IDENTIFIED) {
+		__u8 lun;
+		struct NCR_700_command_slot *slot;
+		__u8 reselection_id = hostdata->reselection_id;
+
+		dma_cache_inv((unsigned long)hostdata->msgin, sizeof(hostdata->msgin));
+
+		lun = hostdata->msgin[0] & 0x1f;
+
+		hostdata->reselection_id = 0xff;
+		DEBUG(("scsi%d: (%d:%d) RESELECTED!\n",
+		       host->host_no, reselection_id, lun));
+		/* clear the reselection indicator */
+		if(hostdata->msgin[1] == A_SIMPLE_TAG_MSG) {
+			slot = find_ITLQ_Nexus(hostdata, reselection_id,
+					       lun, hostdata->msgin[2]);
+		} else {
+			slot = find_ITL_Nexus(hostdata, reselection_id, lun);
+		}
+	retry:
+		if(slot == NULL) {
+			struct NCR_700_command_slot *s = find_ITL_Nexus(hostdata, reselection_id, lun);
+			printk(KERN_ERR "scsi%d: (%d:%d) RESELECTED but no saved command (MSG = %02x %02x %02x)!!\n",
+			       host->host_no, reselection_id, lun,
+			       hostdata->msgin[0], hostdata->msgin[1],
+			       hostdata->msgin[2]);
+			printk(KERN_ERR " OUTSTANDING TAGS:");
+			while(s != NULL) {
+				if(s->cmnd->target == reselection_id &&
+				   s->cmnd->lun == lun) {
+					printk("%d ", s->tag);
+					if(s->tag == hostdata->msgin[2]) {
+						printk(" ***FOUND*** \n");
+						slot = s;
+						goto retry;
+					}
+						
+				}
+				s = s->ITL_back;
+			}
+			printk("\n");
+		} else {
+			if(hostdata->state != NCR_700_HOST_BUSY)
+				printk(KERN_ERR "scsi%d: FATAL, host not busy during valid reselection!\n",
+				       host->host_no);
+			resume_offset = slot->resume_offset;
+			hostdata->cmd = slot->cmnd;
+
+			/* re-patch for this command */
+			script_patch_32_abs(hostdata->script, CommandAddress, 
+					    virt_to_bus(slot->cmnd->cmnd));
+			script_patch_16(hostdata->script,
+					CommandCount, slot->cmnd->cmd_len);
+			script_patch_32_abs(hostdata->script, SGScriptStartAddress,
+					    virt_to_bus(&slot->SG[0].ins));
+
+			/* Note: setting SXFER only works if we're
+			 * still in the MESSAGE phase, so it is vital
+			 * that ACK is still asserted when we process
+			 * the reselection message.  The resume offset
+			 * should therefore always clear ACK */
+			NCR_700_writeb(NCR_700_get_SXFER(hostdata->cmd->device),
+				       host, SXFER_REG);
+			
+		}
+	} else if(dsps == A_RESELECTED_DURING_SELECTION) {
+
+		/* This section is full of debugging code because I've
+		 * never managed to reach it.  I think what happens is
+		 * that, because the 700 runs with selection
+		 * interrupts enabled the whole time that we take a
+		 * selection interrupt before we manage to get to the
+		 * reselected script interrupt */
+
+		__u8 reselection_id = NCR_700_readb(host, SFBR_REG);
+		struct NCR_700_command_slot *slot;
+		
+		/* Take out our own ID */
+		reselection_id &= ~(1<<host->this_id);
+		
+		printk(KERN_INFO "scsi%d: (%d:%d) RESELECTION DURING SELECTION, dsp=%p[%04x] state=%d, count=%d\n",
+		       host->host_no, reselection_id, lun, (void *)dsp, dsp - hostdata->pScript, hostdata->state, hostdata->command_slot_count);
+
+		{
+			/* FIXME: DEBUGGING CODE */
+			__u32 SG = (__u32)bus_to_virt(hostdata->script[A_SGScriptStartAddress_used[0]]);
+			int i;
+
+			for(i=0; i< NCR_700_COMMAND_SLOTS_PER_HOST; i++) {
+				if(SG >= (__u32)(&hostdata->slots[i].SG[0])
+				   && SG <= (__u32)(&hostdata->slots[i].SG[NCR_700_SG_SEGMENTS]))
+					break;
+			}
+			printk(KERN_INFO "IDENTIFIED SG segment as being %p in slot %p, cmd %p, slot->resume_offset=%p\n", (void *)SG, &hostdata->slots[i], hostdata->slots[i].cmnd, (void *)hostdata->slots[i].resume_offset);
+			SCp =  hostdata->slots[i].cmnd;
+		}
+
+		if(SCp != NULL) {
+			slot = (struct NCR_700_command_slot *)SCp->host_scribble;
+			/* change slot from busy to queued to redo command */
+			slot->state = NCR_700_SLOT_QUEUED;
+		}
+		hostdata->cmd = NULL;
+		
+		if(reselection_id == 0) {
+			if(hostdata->reselection_id == 0xff) {
+				printk(KERN_ERR "scsi%d: Invalid reselection during selection!!\n", host->host_no);
+				return 0;
+			} else {
+				printk(KERN_ERR "scsi%d: script reselected and we took a selection interrupt\n",
+				       host->host_no);
+				reselection_id = hostdata->reselection_id;
+			}
+		} else {
+			
+			/* convert to real ID */
+			reselection_id = bitmap_to_number(reselection_id);
+		}
+		hostdata->reselection_id = reselection_id;
+		hostdata->msgin[1] = 0;
+		dma_cache_wback((unsigned long)hostdata->msgin, sizeof(hostdata->msgin));
+		if(hostdata->tag_negotiated & (1<<reselection_id)) {
+			resume_offset = hostdata->pScript + Ent_GetReselectionWithTag;
+		} else {
+			resume_offset = hostdata->pScript + Ent_GetReselectionData;
+		}
+	} else if(dsps == A_COMPLETED_SELECTION_AS_TARGET) {
+		/* we've just disconnected from the bus, do nothing since
+		 * a return here will re-run the queued command slot
+		 * that may have been interrupted by the initial selection */
+		DEBUG((" SELECTION COMPLETED\n"));
+	} else if((dsps & 0xfffff0f0) == A_MSG_IN) { 
+		resume_offset = process_message(host, hostdata, SCp,
+						dsp, dsps);
+	} else if((dsps &  0xfffff000) == 0) {
+		__u8 i = (dsps & 0xf0) >> 4, j = (dsps & 0xf00) >> 8;
+		printk(KERN_ERR "scsi%d: (%d:%d), unhandled script condition %s %s at %04x\n",
+		       host->host_no, pun, lun, NCR_700_condition[i],
+		       NCR_700_phase[j], dsp - hostdata->pScript);
+		if(SCp != NULL) {
+			print_command(SCp->cmnd);
+
+			if(SCp->use_sg) {
+				for(i = 0; i < SCp->use_sg + 1; i++) {
+					printk(KERN_INFO " SG[%d].length = %d, move_insn=%08x, addr %08x\n", i, ((struct scatterlist *)SCp->buffer)[i].length, ((struct NCR_700_command_slot *)SCp->host_scribble)->SG[i].ins, ((struct NCR_700_command_slot *)SCp->host_scribble)->SG[i].pAddr);
+				}
+			}
+		}	       
+		NCR_700_internal_bus_reset(host);
+	} else if((dsps & 0xfffff000) == A_DEBUG_INTERRUPT) {
+		printk(KERN_NOTICE "scsi%d (%d:%d) DEBUG INTERRUPT %d AT %p[%04x], continuing\n",
+		       host->host_no, pun, lun, dsps & 0xfff, (void *)dsp, dsp - hostdata->pScript);
+		resume_offset = dsp;
+	} else {
+		printk(KERN_ERR "scsi%d: (%d:%d), unidentified script interrupt 0x%x at %04x\n",
+		       host->host_no, pun, lun, dsps, dsp - hostdata->pScript);
+		NCR_700_internal_bus_reset(host);
+	}
+	return resume_offset;
+}
+
+/* We run the 53c700 with selection interrupts always enabled.  This
+ * means that the chip may be selected as soon as the bus frees.  On a
+ * busy bus, this can be before the scripts engine finishes its
+ * processing.  Therefore, part of the selection processing has to be
+ * to find out what the scripts engine is doing and complete the
+ * function if necessary (i.e. process the pending disconnect or save
+ * the interrupted initial selection */
+STATIC inline __u32
+process_selection(struct Scsi_Host *host, __u32 dsp)
+{
+	__u8 id = 0;	/* Squash compiler warning */
+	int count = 0;
+	__u32 resume_offset = 0;
+	struct NCR_700_Host_Parameters *hostdata =
+		(struct NCR_700_Host_Parameters *)host->hostdata[0];
+	Scsi_Cmnd *SCp = hostdata->cmd;
+	__u8 sbcl;
+
+	for(count = 0; count < 5; count++) {
+		id = NCR_700_readb(host, SFBR_REG);
+
+		/* Take out our own ID */
+		id &= ~(1<<host->this_id);
+		if(id != 0) 
+			break;
+		udelay(5);
+	}
+	sbcl = NCR_700_readb(host, SBCL_REG);
+	if((sbcl & SBCL_IO) == 0) {
+		/* mark as having been selected rather than reselected */
+		id = 0xff;
+	} else {
+		/* convert to real ID */
+		hostdata->reselection_id = id = bitmap_to_number(id);
+		DEBUG(("scsi%d:  Reselected by %d\n",
+		       host->host_no, id));
+	}
+	if(hostdata->state == NCR_700_HOST_BUSY && SCp != NULL) {
+		struct NCR_700_command_slot *slot =
+			(struct NCR_700_command_slot *)SCp->host_scribble;
+		DEBUG(("  ID %d WARNING: RESELECTION OF BUSY HOST, saving cmd %p, slot %p, addr %x [%04x], resume %x!\n", id, hostdata->cmd, slot, dsp, dsp - hostdata->pScript, resume_offset));
+		
+		switch(dsp - hostdata->pScript) {
+		case Ent_Disconnect1:
+		case Ent_Disconnect2:
+			save_for_reselection(hostdata, SCp, Ent_Disconnect2 + hostdata->pScript);
+			break;
+		case Ent_Disconnect3:
+		case Ent_Disconnect4:
+			save_for_reselection(hostdata, SCp, Ent_Disconnect4 + hostdata->pScript);
+			break;
+		case Ent_Disconnect5:
+		case Ent_Disconnect6:
+			save_for_reselection(hostdata, SCp, Ent_Disconnect6 + hostdata->pScript);
+			break;
+		case Ent_Disconnect7:
+		case Ent_Disconnect8:
+			save_for_reselection(hostdata, SCp, Ent_Disconnect8 + hostdata->pScript);
+			break;
+		case Ent_Finish1:
+		case Ent_Finish2:
+			process_script_interrupt(A_GOOD_STATUS_AFTER_STATUS, dsp, SCp, host, hostdata);
+			break;
+			
+		default:
+			slot->state = NCR_700_SLOT_QUEUED;
+			break;
+			}
+	}
+	hostdata->state = NCR_700_HOST_BUSY;
+	hostdata->cmd = NULL;
+	hostdata->msgin[1] = 0;
+	dma_cache_wback((unsigned long)hostdata->msgin, sizeof(hostdata->msgin));
+
+	if(id == 0xff) {
+		/* Selected as target, Ignore */
+		resume_offset = hostdata->pScript + Ent_SelectedAsTarget;
+	} else if(hostdata->tag_negotiated & (1<<id)) {
+		resume_offset = hostdata->pScript + Ent_GetReselectionWithTag;
+	} else {
+		resume_offset = hostdata->pScript + Ent_GetReselectionData;
+	}
+	return resume_offset;
+}
+
+
+STATIC int
+NCR_700_start_command(Scsi_Cmnd *SCp)
+{
+	struct NCR_700_command_slot *slot =
+		(struct NCR_700_command_slot *)SCp->host_scribble;
+	struct NCR_700_Host_Parameters *hostdata =
+		(struct NCR_700_Host_Parameters *)SCp->host->hostdata[0];
+	unsigned long flags;
+	__u16 count = 1;	/* for IDENTIFY message */
+	
+	save_flags(flags);
+	cli();
+	if(hostdata->state != NCR_700_HOST_FREE) {
+		/* keep this inside the lock to close the race window where
+		 * the running command finishes on another CPU while we don't
+		 * change the state to queued on this one */
+		slot->state = NCR_700_SLOT_QUEUED;
+		restore_flags(flags);
+
+		DEBUG(("scsi%d: host busy, queueing command %p, slot %p\n",
+		       SCp->host->host_no, slot->cmnd, slot));
+		return 0;
+	}
+	hostdata->state = NCR_700_HOST_BUSY;
+	hostdata->cmd = SCp;
+	slot->state = NCR_700_SLOT_BUSY;
+	/* keep interrupts disabled until we have the command correctly
+	 * set up so we cannot take a selection interrupt */
+
+	hostdata->msgout[0] = NCR_700_identify(SCp->cmnd[0] != REQUEST_SENSE,
+					    SCp->lun);
+	/* for INQUIRY or REQUEST_SENSE commands, we cannot be sure
+	 * if the negotiated transfer parameters still hold, so
+	 * always renegotiate them */
+	if(SCp->cmnd[0] == INQUIRY || SCp->cmnd[0] == REQUEST_SENSE) {
+		NCR_700_clear_flag(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC);
+	}
+
+	/* REQUEST_SENSE is asking for contingent I_T_L status.  If a
+	 * contingent allegiance condition exists, the device will
+	 * refuse all tags, so send the request sense as untagged */
+	if((hostdata->tag_negotiated & (1<<SCp->target))
+	   && (slot->tag != NCR_700_NO_TAG && SCp->cmnd[0] != REQUEST_SENSE)) {
+		hostdata->msgout[count++] = A_SIMPLE_TAG_MSG;
+		hostdata->msgout[count++] = slot->tag;
+	}
+
+	if(hostdata->fast &&
+	   NCR_700_is_flag_clear(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC)) {
+		memcpy(&hostdata->msgout[count], NCR_700_SDTR_msg,
+		       sizeof(NCR_700_SDTR_msg));
+		count += sizeof(NCR_700_SDTR_msg);
+		NCR_700_set_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION);
+	}
+
+	dma_cache_wback((unsigned long)hostdata->msgout, count);
+
+	script_patch_16(hostdata->script, MessageCount, count);
+
+
+	script_patch_ID(hostdata->script,
+			Device_ID, 1<<SCp->target);
+
+	script_patch_32_abs(hostdata->script, CommandAddress, 
+			virt_to_bus(SCp->cmnd));
+	script_patch_16(hostdata->script, CommandCount, SCp->cmd_len);
+	/* finally plumb the beginning of the SG list into the script
+	 * */
+	script_patch_32_abs(hostdata->script, SGScriptStartAddress,
+			    virt_to_bus(&slot->SG[0].ins));
+	NCR_700_writeb(CLR_FIFO, SCp->host, DFIFO_REG);
+
+	/* set the synchronous period/offset */
+	if(slot->resume_offset == 0)
+		slot->resume_offset = hostdata->pScript;
+	NCR_700_writeb(NCR_700_get_SXFER(SCp->device),
+	     SCp->host, SXFER_REG);
+	/* allow interrupts here so that if we're selected we can take
+	 * a selection interrupt.  The script start may not be
+	 * effective in this case, but the selection interrupt will
+	 * save our command in that case */
+	NCR_700_writel(slot->temp, SCp->host, TEMP_REG);
+	NCR_700_writel(slot->resume_offset, SCp->host, DSP_REG);
+	restore_flags(flags);
+
+	return 1;
+}
+
+void
+NCR_700_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct Scsi_Host *host = (struct Scsi_Host *)dev_id;
+	struct NCR_700_Host_Parameters *hostdata =
+		(struct NCR_700_Host_Parameters *)host->hostdata[0];
+	__u8 istat;
+	__u32 resume_offset = 0;
+	__u8 pun = 0xff, lun = 0xff;
+	unsigned long flags;
+
+	/* Unfortunately, we have to take the io_request_lock here
+	 * rather than the host lock hostdata->lock because we're
+	 * looking to exclude queuecommand from messing with the
+	 * registers while we're processing the interrupt.  Since
+	 * queuecommand is called holding io_request_lock, and we have
+	 * to take io_request_lock before we call the command
+	 * scsi_done, we would get a deadlock if we took
+	 * hostdata->lock here and in queuecommand (because the order
+	 * of locking in queuecommand: 1) io_request_lock then 2)
+	 * hostdata->lock would be the reverse of taking it in this
+	 * routine */
+	spin_lock_irqsave(&io_request_lock, flags);
+	if((istat = NCR_700_readb(host, ISTAT_REG))
+	      & (SCSI_INT_PENDING | DMA_INT_PENDING)) {
+		__u32 dsps;
+		__u8 sstat0 = 0, dstat = 0;
+		__u32 dsp;
+		Scsi_Cmnd *SCp = hostdata->cmd;
+		enum NCR_700_Host_State state;
+
+		state = hostdata->state;
+		SCp = hostdata->cmd;
+
+		if(istat & SCSI_INT_PENDING) {
+			udelay(10);
+
+			sstat0 = NCR_700_readb(host, SSTAT0_REG);
+		}
+
+		if(istat & DMA_INT_PENDING) {
+			udelay(10);
+
+			dstat = NCR_700_readb(host, DSTAT_REG);
+		}
+
+		dsps = NCR_700_readl(host, DSPS_REG);
+		dsp = NCR_700_readl(host, DSP_REG);
+
+		DEBUG(("scsi%d: istat %02x sstat0 %02x dstat %02x dsp %04x[%08x] dsps 0x%x\n",
+		       host->host_no, istat, sstat0, dstat,
+		       (dsp - (__u32)virt_to_bus(hostdata->script))/4,
+		       dsp, dsps));
+
+		if(SCp != NULL) {
+			pun = SCp->target;
+			lun = SCp->lun;
+		}
+
+		if(sstat0 & SCSI_RESET_DETECTED) {
+			Scsi_Device *SDp;
+			int i;
+
+			hostdata->state = NCR_700_HOST_BUSY;
+
+			printk(KERN_ERR "scsi%d: Bus Reset detected, executing command %p, slot %p, dsp %p[%04x]\n",
+			       host->host_no, SCp, SCp == NULL ? NULL : SCp->host_scribble, (void *)dsp, dsp - hostdata->pScript);
+
+			/* clear all the negotiated parameters */
+			for(SDp = host->host_queue; SDp != NULL; SDp = SDp->next)
+				SDp->hostdata = 0;
+			
+			/* clear all the slots and their pending commands */
+			for(i = 0; i < NCR_700_COMMAND_SLOTS_PER_HOST; i++) {
+				Scsi_Cmnd *SCp;
+				struct NCR_700_command_slot *slot =
+					&hostdata->slots[i];
+
+				if(slot->state == NCR_700_SLOT_FREE)
+					continue;
+				
+				SCp = slot->cmnd;
+				printk(KERN_ERR " failing command because of reset, slot %p, cmnd %p\n",
+				       slot, SCp);
+				free_slot(slot, hostdata);
+				SCp->host_scribble = NULL;
+				NCR_700_set_depth(SCp->device, 0);
+				/* NOTE: deadlock potential here: we
+				 * rely on mid-layer guarantees that
+				 * scsi_done won't try to issue the
+				 * command again otherwise we'll
+				 * deadlock on the
+				 * hostdata->state_lock */
+				SCp->result = DID_RESET << 16;
+				SCp->scsi_done(SCp);
+			}
+			mdelay(25);
+			NCR_700_chip_setup(host);
+
+			hostdata->state = NCR_700_HOST_FREE;
+			hostdata->cmd = NULL;
+			goto out_unlock;
+		} else if(sstat0 & SELECTION_TIMEOUT) {
+			DEBUG(("scsi%d: (%d:%d) selection timeout\n",
+			       host->host_no, pun, lun));
+			NCR_700_scsi_done(hostdata, SCp, DID_NO_CONNECT<<16);
+		} else if(sstat0 & PHASE_MISMATCH) {
+			struct NCR_700_command_slot *slot = (SCp == NULL) ? NULL :
+				(struct NCR_700_command_slot *)SCp->host_scribble;
+
+			if(dsp == Ent_SendMessage + 8 + hostdata->pScript) {
+				/* It wants to reply to some part of
+				 * our message */
+#ifdef NCR_700_DEBUG
+				__u32 temp = NCR_700_readl(host, TEMP_REG);
+				int count = (hostdata->script[Ent_SendMessage/4] & 0xffffff) - ((NCR_700_readl(host, DBC_REG) & 0xffffff) + NCR_700_data_residual(host));
+				printk("scsi%d (%d:%d) PHASE MISMATCH IN SEND MESSAGE %d remain, return %p[%04x], phase %s\n", host->host_no, pun, lun, count, (void *)temp, temp - hostdata->pScript, sbcl_to_string(NCR_700_readb(host, SBCL_REG)));
+#endif
+				resume_offset = hostdata->pScript + Ent_SendMessagePhaseMismatch;
+			} else if(dsp >= virt_to_bus(&slot->SG[0].ins) &&
+				  dsp <= virt_to_bus(&slot->SG[NCR_700_SG_SEGMENTS].ins)) {
+				int data_transfer = NCR_700_readl(host, DBC_REG) & 0xffffff;
+				int SGcount = (dsp - virt_to_bus(&slot->SG[0].ins))/sizeof(struct NCR_700_SG_List);
+				int residual = NCR_700_data_residual(host);
+				int i;
+#ifdef NCR_700_DEBUG
+				printk("scsi%d: (%d:%d) Expected phase mismatch in slot->SG[%d], transferred 0x%x\n",
+				       host->host_no, pun, lun,
+				       SGcount, data_transfer);
+				print_command(SCp->cmnd);
+				if(residual) {
+					printk("scsi%d: (%d:%d) Expected phase mismatch in slot->SG[%d], transferred 0x%x, residual %d\n",
+				       host->host_no, pun, lun,
+				       SGcount, data_transfer, residual);
+				}
+#endif
+				data_transfer += residual;
+
+				if(data_transfer != 0) {
+					int count; 
+					__u32 pAddr;
+
+					SGcount--;
+
+					count = (bS_to_cpu(slot->SG[SGcount].ins) & 0x00ffffff);
+					DEBUG(("DATA TRANSFER MISMATCH, count = %d, transferred %d\n", count, count-data_transfer));
+					slot->SG[SGcount].ins &= bS_to_host(0xff000000);
+					slot->SG[SGcount].ins |= bS_to_host(data_transfer);
+					pAddr = bS_to_cpu(slot->SG[SGcount].pAddr);
+					pAddr += (count - data_transfer);
+					slot->SG[SGcount].pAddr = bS_to_host(pAddr);
+				}
+				/* set the executed moves to nops */
+				for(i=0; i<SGcount; i++) {
+					slot->SG[i].ins = bS_to_host(SCRIPT_NOP);
+					slot->SG[i].pAddr = 0;
+				}
+				dma_cache_wback((unsigned long)slot->SG, sizeof(slot->SG));
+				/* and pretend we disconnected after
+				 * the command phase */
+				resume_offset = hostdata->pScript + Ent_MsgInDuringData;
+			} else {
+				__u8 sbcl = NCR_700_readb(host, SBCL_REG);
+				printk(KERN_ERR "scsi%d: (%d:%d) phase mismatch at %04x, phase %s\n",
+				       host->host_no, pun, lun, dsp - hostdata->pScript, sbcl_to_string(sbcl));
+				NCR_700_internal_bus_reset(host);
+			}
+
+		} else if(sstat0 & SCSI_GROSS_ERROR) {
+			printk(KERN_ERR "scsi%d: (%d:%d) GROSS ERROR\n",
+			       host->host_no, pun, lun);
+			NCR_700_scsi_done(hostdata, SCp, DID_ERROR<<16);
+		} else if(dstat & SCRIPT_INT_RECEIVED) {
+			DEBUG(("scsi%d: (%d:%d) ====>SCRIPT INTERRUPT<====\n",
+			       host->host_no, pun, lun));
+			resume_offset = process_script_interrupt(dsps, dsp, SCp, host, hostdata);
+		} else if(dstat & (ILGL_INST_DETECTED)) {
+			printk(KERN_ERR "scsi%d: (%d:%d) Illegal Instruction detected at 0x%p[0x%x]!!!\n"
+			       "         Please email James.Bottomley@HansenPartnership.com with the details\n",
+			       host->host_no, pun, lun,
+			       (void *)dsp, dsp - hostdata->pScript);
+			NCR_700_scsi_done(hostdata, SCp, DID_ERROR<<16);
+		} else if(dstat & (WATCH_DOG_INTERRUPT|ABORTED)) {
+			printk(KERN_ERR "scsi%d: (%d:%d) serious DMA problem, dstat=%02x\n",
+			       host->host_no, pun, lun, dstat);
+			NCR_700_scsi_done(hostdata, SCp, DID_ERROR<<16);
+		}
+
+		
+		/* NOTE: selection interrupt processing MUST occur
+		 * after script interrupt processing to correctly cope
+		 * with the case where we process a disconnect and
+		 * then get reselected before we process the
+		 * disconnection */
+		if(sstat0 & SELECTED) {
+			/* FIXME: It currently takes at least FOUR
+			 * interrupts to complete a command that
+			 * disconnects: one for the disconnect, one
+			 * for the reselection, one to get the
+			 * reselection data and one to complete the
+			 * command.  If we guess the reselected
+			 * command here and prepare it, we only need
+			 * to get a reselection data interrupt if we
+			 * guessed wrongly.  Since the interrupt
+			 * overhead is much greater than the command
+			 * setup, this would be an efficient
+			 * optimisation particularly as we probably
+			 * only have one outstanding command on a
+			 * target most of the time */
+
+			resume_offset = process_selection(host, dsp);
+
+		}
+
+	}
+
+	if(resume_offset) {
+		if(hostdata->state != NCR_700_HOST_BUSY) {
+			printk(KERN_ERR "scsi%d: Driver error: resume at %p [%04x] with non busy host!\n",
+			       host->host_no, (void *)resume_offset, resume_offset - hostdata->pScript);
+			hostdata->state = NCR_700_HOST_BUSY;
+		}
+
+		DEBUG(("Attempting to resume at %x\n", resume_offset));
+		NCR_700_writeb(CLR_FIFO, host, DFIFO_REG);
+		NCR_700_writel(resume_offset, host, DSP_REG);
+	} 
+	/* There is probably a technical no-no about this: If we're a
+	 * shared interrupt and we got this interrupt because the
+	 * other device needs servicing not us, we're still going to
+	 * check our queued commands here---of course, there shouldn't
+	 * be any outstanding.... */
+	if(hostdata->state == NCR_700_HOST_FREE) {
+		int i;
+
+		for(i = 0; i < NCR_700_COMMAND_SLOTS_PER_HOST; i++) {
+			/* fairness: always run the queue from the last
+			 * position we left off */
+			int j = (i + hostdata->saved_slot_position)
+				% NCR_700_COMMAND_SLOTS_PER_HOST;
+			
+			if(hostdata->slots[j].state != NCR_700_SLOT_QUEUED)
+				continue;
+			if(NCR_700_start_command(hostdata->slots[j].cmnd)) {
+				DEBUG(("scsi%d: Issuing saved command slot %p, cmd %p\t\n",
+				       host->host_no, &hostdata->slots[j],
+				       hostdata->slots[j].cmnd));
+				hostdata->saved_slot_position = j + 1;
+			}
+
+			break;
+		}
+	}
+ out_unlock:
+	spin_unlock_irqrestore(&io_request_lock, flags);
+}
+
+/* FIXME: Need to put some proc information in and plumb it
+ * into the scsi proc system */
+STATIC int
+NCR_700_proc_directory_info(char *proc_buf, char **startp,
+			 off_t offset, int bytes_available,
+			 int host_no, int write)
+{
+	static char buf[4096];	/* 1 page should be sufficient */
+	int len = 0;
+	struct Scsi_Host *host = scsi_hostlist;
+	struct NCR_700_Host_Parameters *hostdata;
+	Scsi_Device *SDp;
+
+	while(host != NULL && host->host_no != host_no)
+		host = host->next;
+
+	if(host == NULL)
+		return 0;
+
+	if(write) {
+		/* FIXME: Clear internal statistics here */
+		return 0;
+	}
+	hostdata = (struct NCR_700_Host_Parameters *)host->hostdata[0];
+	len += sprintf(&buf[len], "Total commands outstanding: %d\n", hostdata->command_slot_count);
+	len += sprintf(&buf[len],"\
+Target	Depth  Active  Next Tag\n\
+======	=====  ======  ========\n");
+	for(SDp = host->host_queue; SDp != NULL; SDp = SDp->next) {
+		len += sprintf(&buf[len]," %2d:%2d   %4d    %4d      %4d\n", SDp->id, SDp->lun, SDp->queue_depth, NCR_700_get_depth(SDp), SDp->current_tag);
+	}
+	if((len -= offset) <= 0)
+		return 0;
+	if(len > bytes_available)
+		len = bytes_available;
+	memcpy(proc_buf, buf + offset, len);
+	return len;
+}
+
+STATIC int
+NCR_700_queuecommand(Scsi_Cmnd *SCp, void (*done)(Scsi_Cmnd *))
+{
+	struct NCR_700_Host_Parameters *hostdata = 
+		(struct NCR_700_Host_Parameters *)SCp->host->hostdata[0];
+	__u32 move_ins;
+	struct NCR_700_command_slot *slot;
+	int hash;
+
+	if(hostdata->command_slot_count >= NCR_700_COMMAND_SLOTS_PER_HOST) {
+		/* We're over our allocation, this should never happen
+		 * since we report the max allocation to the mid layer */
+		printk(KERN_WARNING "scsi%d: Command depth has gone over queue depth\n", SCp->host->host_no);
+		return 1;
+	}
+	if(NCR_700_get_depth(SCp->device) != 0 && !(hostdata->tag_negotiated & (1<<SCp->target))) {
+		DEBUG((KERN_ERR "scsi%d (%d:%d) has non zero depth %d\n",
+		       SCp->host->host_no, SCp->target, SCp->lun,
+		       NCR_700_get_depth(SCp->device)));
+		return 1;
+	}
+	if(NCR_700_get_depth(SCp->device) >= NCR_700_MAX_TAGS) {
+		DEBUG((KERN_ERR "scsi%d (%d:%d) has max tag depth %d\n",
+		       SCp->host->host_no, SCp->target, SCp->lun,
+		       NCR_700_get_depth(SCp->device)));
+		return 1;
+	}
+	NCR_700_set_depth(SCp->device, NCR_700_get_depth(SCp->device) + 1);
+
+	/* begin the command here */
+	/* no need to check for NULL, test for command_slot_cound above
+	 * ensures a slot is free */
+	slot = find_empty_slot(hostdata);
+
+	slot->cmnd = SCp;
+
+	SCp->scsi_done = done;
+	SCp->host_scribble = (unsigned char *)slot;
+	SCp->SCp.ptr = NULL;
+	SCp->SCp.buffer = NULL;
+
+#ifdef NCR_700_DEBUG
+	printk("53c700: scsi%d, command ", SCp->host->host_no);
+	print_command(SCp->cmnd);
+#endif
+
+	if(hostdata->tag_negotiated &(1<<SCp->target)) {
+
+		struct NCR_700_command_slot *old =
+			find_ITL_Nexus(hostdata, SCp->target, SCp->lun);
+#ifdef NCR_700_TAG_DEBUG
+		struct NCR_700_command_slot *found;
+#endif
+		
+		if(old != NULL && old->tag == SCp->device->current_tag) {
+			printk(KERN_WARNING "scsi%d (%d:%d) Tag clock back to current, queueing\n", SCp->host->host_no, SCp->target, SCp->lun);
+			return 1;
+		}
+		slot->tag = SCp->device->current_tag++;
+#ifdef NCR_700_TAG_DEBUG
+		while((found = find_ITLQ_Nexus(hostdata, SCp->target, SCp->lun, slot->tag)) != NULL) {
+			printk("\n\n**ERROR** already using tag %d, but oldest is %d\n", slot->tag, (old == NULL) ? -1 : old->tag);
+			printk("  FOUND = %p, tag = %d, pun = %d, lun = %d\n",
+			       found, found->tag, found->cmnd->target, found->cmnd->lun);
+			slot->tag = SCp->device->current_tag++;
+			printk("   Tag list is: ");
+			while(old != NULL) {
+				if(old->cmnd->target == SCp->target &&
+				   old->cmnd->lun == SCp->lun)
+					printk("%d ", old->tag);
+				old = old->ITL_back;
+			}
+			printk("\n\n");
+		}
+#endif
+		hash = hash_ITLQ(SCp->target, SCp->lun, slot->tag);
+		/* link into the ITLQ hash queues */
+		slot->ITLQ_forw = hostdata->ITLQ_Hash_forw[hash];
+		hostdata->ITLQ_Hash_forw[hash] = slot;
+#ifdef NCR_700_TAG_DEBUG
+		if(slot->ITLQ_forw != NULL && slot->ITLQ_forw->ITLQ_back != NULL) {
+			printk(KERN_ERR "scsi%d (%d:%d) ITLQ_back is not NULL!!!!\n", SCp->host->host_no, SCp->target, SCp->lun);
+		}
+#endif
+		if(slot->ITLQ_forw != NULL)
+			slot->ITLQ_forw->ITLQ_back = slot;
+		else
+			hostdata->ITLQ_Hash_back[hash] = slot;
+		slot->ITLQ_back = NULL;
+	} else {
+		slot->tag = NCR_700_NO_TAG;
+	}
+	/* link into the ITL hash queues */
+	hash = hash_ITL(SCp->target, SCp->lun);
+	slot->ITL_forw = hostdata->ITL_Hash_forw[hash];
+	hostdata->ITL_Hash_forw[hash] = slot;
+#ifdef NCR_700_TAG_DEBUG
+	if(slot->ITL_forw != NULL && slot->ITL_forw->ITL_back != NULL) {
+		printk(KERN_ERR "scsi%d (%d:%d) ITL_back is not NULL!!!!\n",
+		       SCp->host->host_no, SCp->target, SCp->lun);
+	}
+#endif
+	if(slot->ITL_forw != NULL)
+		slot->ITL_forw->ITL_back = slot;
+	else
+		hostdata->ITL_Hash_back[hash] = slot;
+	slot->ITL_back = NULL;
+
+		
+	/* This is f****g ridiculous; every low level HBA driver has
+	 * to determine the direction of the commands, why isn't this
+	 * done inside the scsi_lib !!??? */
+	switch (SCp->cmnd[0]) {
+	case REQUEST_SENSE:
+		/* clear the internal sense magic */
+		SCp->cmnd[6] = 0;
+		/* fall through */
+	case INQUIRY:
+	case MODE_SENSE:
+	case READ_6:
+	case READ_10:
+	case READ_12:
+	case READ_CAPACITY:
+	case READ_BLOCK_LIMITS:
+	case READ_TOC:
+		move_ins = SCRIPT_MOVE_DATA_IN;
+		break;
+	case MODE_SELECT:
+	case WRITE_6:
+	case WRITE_10:
+	case WRITE_12:
+		move_ins = SCRIPT_MOVE_DATA_OUT;
+		break;
+	case TEST_UNIT_READY:
+	case ALLOW_MEDIUM_REMOVAL:
+	case START_STOP:
+		move_ins = 0;
+		break;
+	default:
+		/* OK, get it from the command */
+		switch(SCp->sc_data_direction) {
+		case SCSI_DATA_UNKNOWN:
+		default:
+			printk(KERN_ERR "53c700: Unknown command for data direction ");
+			print_command(SCp->cmnd);
+			
+			move_ins = 0;
+			break;
+		case SCSI_DATA_NONE:
+			move_ins = 0;
+			break;
+		case SCSI_DATA_READ:
+			move_ins = SCRIPT_MOVE_DATA_IN;
+			break;
+		case SCSI_DATA_WRITE:
+			move_ins = SCRIPT_MOVE_DATA_OUT;
+			break;
+		}
+	}
+
+	/* now build the scatter gather list */
+	if(move_ins != 0) {
+		int i;
+
+		for(i = 0; i < (SCp->use_sg ? SCp->use_sg : 1); i++) {
+			void *vPtr;
+			__u32 count;
+
+			if(SCp->use_sg) {
+				vPtr = (((struct scatterlist *)SCp->buffer)[i].address);
+				count = ((struct scatterlist *)SCp->buffer)[i].length;
+			} else {
+				vPtr = SCp->request_buffer;
+				count = SCp->request_bufflen;
+			}
+			slot->SG[i].ins = bS_to_host(move_ins | count);
+			DEBUG((" scatter block %d: move %d[%08x] from 0x%lx\n",
+			       i, count, slot->SG[i].ins, 
+			       virt_to_bus(vPtr)));
+			dma_cache_wback_inv((unsigned long)vPtr, count);
+			slot->SG[i].pAddr = bS_to_host(virt_to_bus(vPtr));
+		}
+		slot->SG[i].ins = bS_to_host(SCRIPT_RETURN);
+		slot->SG[i].pAddr = 0;
+		dma_cache_wback((unsigned long)slot->SG, sizeof(slot->SG));
+		DEBUG((" SETTING %08lx to %x\n",
+		       virt_to_bus(&slot->SG[i].ins), 
+		       slot->SG[i].ins));
+	}
+	slot->resume_offset = 0;
+	NCR_700_start_command(SCp);
+	return 0;
+}
+
+STATIC int
+NCR_700_abort(Scsi_Cmnd * SCp)
+{
+	struct NCR_700_command_slot *slot;
+	struct NCR_700_Host_Parameters *hostdata = 
+		(struct NCR_700_Host_Parameters *)SCp->host->hostdata[0];
+
+	printk(KERN_INFO "scsi%d (%d:%d) New error handler wants to abort command\n\t",
+	       SCp->host->host_no, SCp->target, SCp->lun);
+	print_command(SCp->cmnd);
+
+	slot = find_ITL_Nexus(hostdata, SCp->target, SCp->lun);
+	while(slot != NULL && slot->cmnd != SCp)
+		slot = slot->ITL_back;
+
+	if(slot == NULL)
+		/* no outstanding command to abort */
+		return SUCCESS;
+	if(SCp->cmnd[0] == TEST_UNIT_READY) {
+		/* FIXME: This is because of a problem in the new
+		 * error handler.  When it is in error recovery, it
+		 * will send a TUR to a device it thinks may still be
+		 * showing a problem.  If the TUR isn't responded to,
+		 * it will abort it and mark the device off line.
+		 * Unfortunately, it does no other error recovery, so
+		 * this would leave us with an outstanding command
+		 * occupying a slot.  Rather than allow this to
+		 * happen, we issue a bus reset to force all
+		 * outstanding commands to terminate here. */
+		NCR_700_internal_bus_reset(SCp->host);
+		/* still drop through and return failed */
+	}
+	return FAILED;
+
+}
+
+STATIC int
+NCR_700_bus_reset(Scsi_Cmnd * SCp)
+{
+	printk(KERN_INFO "scsi%d (%d:%d) New error handler wants BUS reset, cmd %p\n\t",
+	       SCp->host->host_no, SCp->target, SCp->lun, SCp);
+	print_command(SCp->cmnd);
+	NCR_700_internal_bus_reset(SCp->host);
+	return SUCCESS;
+}
+
+STATIC int
+NCR_700_dev_reset(Scsi_Cmnd * SCp)
+{
+	printk(KERN_INFO "scsi%d (%d:%d) New error handler wants device reset\n\t",
+	       SCp->host->host_no, SCp->target, SCp->lun);
+	print_command(SCp->cmnd);
+	
+	return FAILED;
+}
+
+STATIC int
+NCR_700_host_reset(Scsi_Cmnd * SCp)
+{
+	printk(KERN_INFO "scsi%d (%d:%d) New error handler wants HOST reset\n\t",
+	       SCp->host->host_no, SCp->target, SCp->lun);
+	print_command(SCp->cmnd);
+
+	NCR_700_internal_bus_reset(SCp->host);
+	NCR_700_chip_reset(SCp->host);
+	return SUCCESS;
+}
+
+EXPORT_SYMBOL(NCR_700_detect);
+EXPORT_SYMBOL(NCR_700_release);
+EXPORT_SYMBOL(NCR_700_intr);
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/53c700.h linux/drivers/scsi/53c700.h
--- v2.4.9/linux/drivers/scsi/53c700.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/53c700.h	Sun Sep  9 10:50:48 2001
@@ -0,0 +1,534 @@
+/* -*- mode: c; c-basic-offset: 8 -*- */
+
+/* Driver for 53c700 and 53c700-66 chips from NCR and Symbios
+ *
+ * Copyright (C) 2001 by James.Bottomley@HansenPartnership.com
+ */
+
+#ifndef _53C700_H
+#define _53C700_H
+
+/* Turn on for general debugging---too verbose for normal use */
+#undef NCR_700_DEBUG
+/* Debug the tag queues, checking hash queue allocation and deallocation
+ * and search for duplicate tags */
+#undef NCR_700_TAG_DEBUG
+
+#ifdef NCR_700_DEBUG
+#define DEBUG(x)	printk x
+#else
+#define DEBUG(x)
+#endif
+
+/* The number of available command slots */
+#define NCR_700_COMMAND_SLOTS_PER_HOST	64
+/* The maximum number of Scatter Gathers we allow */
+#define NCR_700_SG_SEGMENTS		32
+/* The maximum number of luns (make this of the form 2^n) */
+#define NCR_700_MAX_LUNS		32
+#define NCR_700_LUN_MASK		(NCR_700_MAX_LUNS - 1)
+/* Alter this with care: too many tags won't give the elevator a chance to
+ * work; too few will cause the device to operate less efficiently */
+#define NCR_700_MAX_TAGS		16
+/* magic byte identifying an internally generated REQUEST_SENSE command */
+#define NCR_700_INTERNAL_SENSE_MAGIC	0x42
+
+/* WARNING: Leave this in for now: the dependency preprocessor doesn't
+ * pick up file specific flags, so must define here if they are not
+ * set */
+#if !defined(IO_MAPPED) && !defined(MEM_MAPPED)
+#define IO_MAPPED
+#endif
+
+
+struct NCR_700_Host_Parameters;
+
+/* These are the externally used routines */
+struct Scsi_Host *NCR_700_detect(Scsi_Host_Template *, struct NCR_700_Host_Parameters *);
+int NCR_700_release(struct Scsi_Host *host);
+void NCR_700_intr(int, void *, struct pt_regs *);
+
+
+enum NCR_700_Host_State {
+	NCR_700_HOST_BUSY,
+	NCR_700_HOST_FREE,
+};
+
+struct NCR_700_SG_List {
+	/* The following is a script fragment to move the buffer onto the
+	 * bus and then link the next fragment or return */
+	#define	SCRIPT_MOVE_DATA_IN		0x09000000
+	#define	SCRIPT_MOVE_DATA_OUT		0x08000000
+	__u32	ins;
+	__u32	pAddr;
+	#define	SCRIPT_NOP			0x80000000
+	#define	SCRIPT_RETURN			0x90080000
+};
+
+/* We use device->hostdata to store negotiated parameters.  This is
+ * supposed to be a pointer to a device private area, but we cannot
+ * really use it as such since it will never be freed, so just use the
+ * 32 bits to cram the information.  The SYNC negotiation sequence looks
+ * like:
+ * 
+ * If DEV_NEGOTIATED_SYNC not set, tack and SDTR message on to the
+ * initial identify for the device and set DEV_BEGIN_SYNC_NEGOTATION
+ * If we get an SDTR reply, work out the SXFER parameters, squirrel
+ * them away here, clear DEV_BEGIN_SYNC_NEGOTIATION and set
+ * DEV_NEGOTIATED_SYNC.  If we get a REJECT msg, squirrel
+ *
+ *
+ * 0:7	SXFER_REG negotiated value for this device
+ * 8:15 Current queue depth
+ * 16	negotiated SYNC flag
+ * 17 begin SYNC negotiation flag 
+ * 18 device supports tag queueing */
+#define NCR_700_DEV_NEGOTIATED_SYNC	(1<<16)
+#define NCR_700_DEV_BEGIN_SYNC_NEGOTIATION	(1<<17)
+#define NCR_700_DEV_BEGIN_TAG_QUEUEING	(1<<18)
+
+static inline void
+NCR_700_set_SXFER(Scsi_Device *SDp, __u8 sxfer)
+{
+	((__u32)SDp->hostdata) &= 0xffffff00;
+	((__u32)SDp->hostdata) |= sxfer & 0xff;
+}
+static inline __u8 NCR_700_get_SXFER(Scsi_Device *SDp)
+{
+	return (((__u32)SDp->hostdata) & 0xff);
+}
+static inline void
+NCR_700_set_depth(Scsi_Device *SDp, __u8 depth)
+{
+	((__u32)SDp->hostdata) &= 0xffff00ff;
+	((__u32)SDp->hostdata) |= (0xff00 & (depth << 8));
+}
+static inline __u8
+NCR_700_get_depth(Scsi_Device *SDp)
+{
+	return ((((__u32)SDp->hostdata) & 0xff00)>>8);
+}
+static inline int
+NCR_700_is_flag_set(Scsi_Device *SDp, __u32 flag)
+{
+	return (((__u32)SDp->hostdata) & flag) == flag;
+}
+static inline int
+NCR_700_is_flag_clear(Scsi_Device *SDp, __u32 flag)
+{
+	return (((__u32)SDp->hostdata) & flag) == 0;
+}
+static inline void
+NCR_700_set_flag(Scsi_Device *SDp, __u32 flag)
+{
+	((__u32)SDp->hostdata) |= (flag & 0xffff0000);
+}
+static inline void
+NCR_700_clear_flag(Scsi_Device *SDp, __u32 flag)
+{
+	((__u32)SDp->hostdata) &= ~(flag & 0xffff0000);
+}
+
+/* These represent the Nexus hashing functions.  A Nexus in SCSI terms
+ * just means the identification of an outstanding command, by ITL
+ * (Initiator Target Lun) or ITLQ (Initiator Target Lun Tag).  I'm not
+ * very keen on XOR based hashes, so these are based on number theory
+ * instead.  All you need to do is to fix your hash bucket size and
+ * then choose reasonable strides which are coprime with the chosen
+ * bucket size
+ *
+ * Note: this mathematical hash can be made very efficient, if the
+ * compiler is good at optimising: Choose the number of buckets to be
+ * 2^n and the modulo becomes a logical and with (2^n-1).
+ * Additionally, if you chose the coprimes of the form 2^n-2^n the
+ * multiplication can be done by a shift and an addition. */
+#define MAX_ITL_HASH_BUCKETS	16
+#define ITL_HASH_PRIME		7
+
+#define MAX_ITLQ_HASH_BUCKETS	64
+#define ITLQ_PUN_PRIME		7
+#define ITLQ_LUN_PRIME		3
+
+static inline int
+hash_ITL(__u8 pun, __u8 lun)
+{
+	return (pun*ITL_HASH_PRIME + lun) % MAX_ITL_HASH_BUCKETS;
+}
+
+static inline int
+hash_ITLQ(__u8 pun, __u8 lun, __u8 tag)
+{
+	return (pun*ITLQ_PUN_PRIME + lun*ITLQ_LUN_PRIME + tag) % MAX_ITLQ_HASH_BUCKETS;
+}
+
+struct NCR_700_command_slot {
+	#define NCR_700_SLOT_MASK 0xFC
+	#define NCR_700_SLOT_MAGIC 0xb8
+	#define	NCR_700_SLOT_FREE (0|NCR_700_SLOT_MAGIC) /* slot may be used */
+	#define NCR_700_SLOT_BUSY (1|NCR_700_SLOT_MAGIC) /* slot has command active on HA */
+	#define NCR_700_SLOT_QUEUED (2|NCR_700_SLOT_MAGIC) /* slot has command to be made active on HA */
+	__u8	state;
+	#define NCR_700_NO_TAG	0xdead
+	__u16	tag;
+	struct NCR_700_SG_List	SG[NCR_700_SG_SEGMENTS+1];
+	__u32	resume_offset;
+	Scsi_Cmnd	*cmnd;
+	__u32		temp;
+	/* Doubly linked ITL/ITLQ list kept in strict time order
+	 * (latest at the back) */
+	struct NCR_700_command_slot *ITL_forw;
+	struct NCR_700_command_slot *ITL_back;
+	struct NCR_700_command_slot *ITLQ_forw;
+	struct NCR_700_command_slot *ITLQ_back;
+};
+
+struct NCR_700_Host_Parameters {
+	/* These must be filled in by the calling driver */
+	int	clock;			/* board clock speed in MHz */
+	__u32	base;			/* the base for the port (copied to host) */
+	__u8	differential:1;	/* if we are differential */
+#ifdef __hppa__
+	/* This option is for HP only.  Set it if your chip is wired for
+	 * little endian on this platform (which is big endian) */
+	__u8	force_le_on_be:1;
+#endif
+
+	/* NOTHING BELOW HERE NEEDS ALTERING */
+	__u8	fast:1;		/* if we can alter the SCSI bus clock
+                                   speed (so can negiotiate sync) */
+
+	int	sync_clock;	/* The speed of the SYNC core */
+
+	__u32	*script;		/* pointer to script location */
+	__u32	pScript;		/* physical mem addr of script */
+
+	/* This will be the host lock.  Unfortunately, we can't use it
+	 * at the moment because of the necessity of holding the
+	 * io_request_lock */
+	spinlock_t lock;
+	enum NCR_700_Host_State state; /* protected by state lock */
+	Scsi_Cmnd *cmd;
+
+	__u8	msgout[8];
+	__u8	tag_negotiated;
+	__u8	status;
+	__u8	msgin[8];
+	struct NCR_700_command_slot	*slots;
+	int	saved_slot_position;
+	int	command_slot_count; /* protected by state lock */
+	__u8	rev;
+	__u8	reselection_id;
+	/* flags for the host */
+
+	/* ITL list.  ALL outstanding commands are hashed here in strict
+	 * order, latest at the back */
+	struct NCR_700_command_slot *ITL_Hash_forw[MAX_ITL_HASH_BUCKETS];
+	struct NCR_700_command_slot *ITL_Hash_back[MAX_ITL_HASH_BUCKETS];
+
+	/* Only tagged outstanding commands are hashed here (also latest
+	 * at the back) */
+	struct NCR_700_command_slot *ITLQ_Hash_forw[MAX_ITLQ_HASH_BUCKETS];
+	struct NCR_700_command_slot *ITLQ_Hash_back[MAX_ITLQ_HASH_BUCKETS];
+
+	/* Free list, singly linked by ITL_forw elements */
+	struct NCR_700_command_slot *free_list;
+};
+
+/*
+ *	53C700 Register Interface - the offset from the Selected base
+ *	I/O address */
+#ifdef __hppa__
+#define bE	(hostdata->force_le_on_be ? 0 : 3)
+#define	bSWAP	(hostdata->force_le_on_be)
+#elif defined(__BIG_ENDIAN)
+#define bE	3
+#define bSWAP	0
+#elif defined(__LITTLE_ENDIAN)
+#define bE	0
+#define bSWAP	0
+#else
+#error "__BIG_ENDIAN or __LITTLE_ENDIAN must be defined, did you include byteorder.h?"
+#endif
+#define bS_to_cpu(x)	(bSWAP ? le32_to_cpu(x) : (x))
+#define bS_to_host(x)	(bSWAP ? cpu_to_le32(x) : (x))
+
+/* NOTE: These registers are in the LE register space only, the required byte
+ * swapping is done by the NCR_700_{read|write}[b] functions */
+#define	SCNTL0_REG			0x00
+#define		FULL_ARBITRATION	0xc0
+#define 	PARITY			0x08
+#define		ENABLE_PARITY		0x04
+#define 	AUTO_ATN		0x02
+#define	SCNTL1_REG			0x01
+#define 	SLOW_BUS		0x80
+#define		ENABLE_SELECT		0x20
+#define		ASSERT_RST		0x08
+#define		ASSERT_EVEN_PARITY	0x04
+#define	SDID_REG			0x02
+#define	SIEN_REG			0x03
+#define 	PHASE_MM_INT		0x80
+#define 	FUNC_COMP_INT		0x40
+#define 	SEL_TIMEOUT_INT		0x20
+#define 	SELECT_INT		0x10
+#define 	GROSS_ERR_INT		0x08
+#define 	UX_DISC_INT		0x04
+#define 	RST_INT			0x02
+#define 	PAR_ERR_INT		0x01
+#define	SCID_REG			0x04
+#define SXFER_REG			0x05
+#define		ASYNC_OPERATION		0x00
+#define SODL_REG                        0x06
+#define	SOCL_REG			0x07
+#define	SFBR_REG			0x08
+#define	SIDL_REG			0x09
+#define	SBDL_REG			0x0A
+#define	SBCL_REG			0x0B
+/* read bits */
+#define		SBCL_IO			0x01
+/*write bits */
+#define		SYNC_DIV_AS_ASYNC	0x00
+#define		SYNC_DIV_1_0		0x01
+#define		SYNC_DIV_1_5		0x02
+#define		SYNC_DIV_2_0		0x03
+#define	DSTAT_REG			0x0C
+#define		ILGL_INST_DETECTED	0x01
+#define		WATCH_DOG_INTERRUPT	0x02
+#define		SCRIPT_INT_RECEIVED	0x04
+#define		ABORTED			0x10
+#define	SSTAT0_REG			0x0D
+#define		PARITY_ERROR		0x01
+#define		SCSI_RESET_DETECTED	0x02
+#define		UNEXPECTED_DISCONNECT	0x04
+#define		SCSI_GROSS_ERROR	0x08
+#define		SELECTED		0x10
+#define		SELECTION_TIMEOUT	0x20
+#define		FUNCTION_COMPLETE	0x40
+#define		PHASE_MISMATCH 		0x80
+#define	SSTAT1_REG			0x0E
+#define		SIDL_REG_FULL		0x80
+#define		SODR_REG_FULL		0x40
+#define		SODL_REG_FULL		0x20
+#define SSTAT2_REG                      0x0F
+#define CTEST0_REG                      0x14
+#define CTEST1_REG                      0x15
+#define CTEST2_REG                      0x16
+#define CTEST3_REG                      0x17
+#define CTEST4_REG                      0x18
+#define         DISABLE_FIFO            0x00
+#define         SLBE                    0x10
+#define         SFWR                    0x08
+#define         BYTE_LANE0              0x04
+#define         BYTE_LANE1              0x05
+#define         BYTE_LANE2              0x06
+#define         BYTE_LANE3              0x07
+#define         SCSI_ZMODE              0x20
+#define         ZMODE                   0x40
+#define CTEST5_REG                      0x19
+#define         MASTER_CONTROL          0x10
+#define         DMA_DIRECTION           0x08
+#define CTEST7_REG                      0x1B
+#define         DFP                     0x08
+#define         EVP                     0x04
+#define		DIFF			0x01
+#define CTEST6_REG                      0x1A
+#define	TEMP_REG			0x1C
+#define	DFIFO_REG			0x20
+#define		FLUSH_DMA_FIFO		0x80
+#define		CLR_FIFO		0x40
+#define	ISTAT_REG			0x21
+#define		ABORT_OPERATION		0x80
+#define		DMA_INT_PENDING		0x01
+#define		SCSI_INT_PENDING	0x02
+#define		CONNECTED		0x08
+#define CTEST8_REG                      0x22
+#define         LAST_DIS_ENBL           0x01
+#define		SHORTEN_FILTERING	0x04
+#define		ENABLE_ACTIVE_NEGATION	0x10
+#define		GENERATE_RECEIVE_PARITY	0x20
+#define CTEST9_REG                      0x23
+#define	DBC_REG				0x24
+#define	DCMD_REG			0x27
+#define	DNAD_REG			0x28
+#define	DIEN_REG			0x39
+#define 	ABORT_INT		0x10
+#define 	INT_INST_INT		0x04
+#define 	WD_INT			0x02
+#define 	ILGL_INST_INT		0x01
+#define	DCNTL_REG			0x3B
+#define		SOFTWARE_RESET		0x01
+#define 	SCRPTS_16BITS		0x20
+#define		ASYNC_DIV_2_0		0x00
+#define		ASYNC_DIV_1_5		0x01
+#define		ASYNC_DIV_1_0		0x02
+#define		ASYNC_DIV_3_0		0x03
+#define	DMODE_REG			0x34
+#define		BURST_LENGTH_1		0x00
+#define		BURST_LENGTH_2		0x40
+#define		BURST_LENGTH_4		0x80
+#define		BURST_LENGTH_8		0xC0
+#define 	BW16			32 
+#define 	MODE_286		16
+#define 	IO_XFER			8
+#define 	FIXED_ADDR		4
+
+#define DSP_REG                         0x2C
+#define DSPS_REG                        0x30
+
+/* Parameters to begin SDTR negotiations.  Empirically, I find that
+ * the 53c700-66 cannot handle an offset >8, so don't change this  */
+#define NCR_700_MAX_OFFSET	8
+#define NCR_700_MIN_XFERP	1
+#define NCR_700_MIN_PERIOD	25 /* for SDTR message, 100ns */
+
+#define script_patch_32(script, symbol, value) \
+{ \
+	int i; \
+	for(i=0; i< (sizeof(A_##symbol##_used) / sizeof(__u32)); i++) { \
+		__u32 val = bS_to_cpu((script)[A_##symbol##_used[i]]) + value; \
+		(script)[A_##symbol##_used[i]] = bS_to_host(val); \
+		dma_cache_wback((unsigned long)&(script)[A_##symbol##_used[i]], 4); \
+		DEBUG((" script, patching %s at %d to 0x%lx\n", \
+		       #symbol, A_##symbol##_used[i], (value))); \
+	} \
+}
+
+#define script_patch_32_abs(script, symbol, value) \
+{ \
+	int i; \
+	for(i=0; i< (sizeof(A_##symbol##_used) / sizeof(__u32)); i++) { \
+		(script)[A_##symbol##_used[i]] = bS_to_host(value); \
+		dma_cache_wback((unsigned long)&(script)[A_##symbol##_used[i]], 4); \
+		DEBUG((" script, patching %s at %d to 0x%lx\n", \
+		       #symbol, A_##symbol##_used[i], (value))); \
+	} \
+}
+
+/* Used for patching the SCSI ID in the SELECT instruction */
+#define script_patch_ID(script, symbol, value) \
+{ \
+	int i; \
+	for(i=0; i< (sizeof(A_##symbol##_used) / sizeof(__u32)); i++) { \
+		__u32 val = bS_to_cpu((script)[A_##symbol##_used[i]]); \
+		val &= 0xff00ffff; \
+		val |= ((value) & 0xff) << 16; \
+		(script)[A_##symbol##_used[i]] = bS_to_host(val); \
+		dma_cache_wback((unsigned long)&(script)[A_##symbol##_used[i]], 4); \
+		DEBUG((" script, patching ID field %s at %d to 0x%x\n", \
+		       #symbol, A_##symbol##_used[i], val)); \
+	} \
+}
+
+#define script_patch_16(script, symbol, value) \
+{ \
+	int i; \
+	for(i=0; i< (sizeof(A_##symbol##_used) / sizeof(__u32)); i++) { \
+		__u32 val = bS_to_cpu((script)[A_##symbol##_used[i]]); \
+		val &= 0xffff0000; \
+		val |= ((value) & 0xffff); \
+		(script)[A_##symbol##_used[i]] = bS_to_host(val); \
+		dma_cache_wback((unsigned long)&(script)[A_##symbol##_used[i]], 4); \
+		DEBUG((" script, patching ID field %s at %d to 0x%x\n", \
+		       #symbol, A_##symbol##_used[i], val)); \
+	} \
+}
+
+#endif
+
+#ifdef MEM_MAPPED
+static inline __u8
+NCR_700_readb(struct Scsi_Host *host, __u32 reg)
+{
+	const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
+		= (struct NCR_700_Host_Parameters *)host->hostdata[0];
+
+	return readb(host->base + (reg^bE));
+}
+
+static inline __u32
+NCR_700_readl(struct Scsi_Host *host, __u32 reg)
+{
+	__u32 value = readl(host->base + reg);
+	const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
+		= (struct NCR_700_Host_Parameters *)host->hostdata[0];
+#if 1
+	/* sanity check the register */
+	if((reg & 0x3) != 0)
+		BUG();
+#endif
+
+	return bS_to_cpu(value);
+}
+
+static inline void
+NCR_700_writeb(__u8 value, struct Scsi_Host *host, __u32 reg)
+{
+	const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
+		= (struct NCR_700_Host_Parameters *)host->hostdata[0];
+
+	writeb(value, host->base + (reg^bE));
+}
+
+static inline void
+NCR_700_writel(__u32 value, struct Scsi_Host *host, __u32 reg)
+{
+	const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
+		= (struct NCR_700_Host_Parameters *)host->hostdata[0];
+
+#if 1
+	/* sanity check the register */
+	if((reg & 0x3) != 0)
+		BUG();
+#endif
+
+	writel(bS_to_host(value), host->base + reg);
+}
+#elif defined(IO_MAPPED)
+static inline __u8
+NCR_700_readb(struct Scsi_Host *host, __u32 reg)
+{
+	const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
+		= (struct NCR_700_Host_Parameters *)host->hostdata[0];
+
+	return inb(host->base + (reg^bE));
+}
+
+static inline __u32
+NCR_700_readl(struct Scsi_Host *host, __u32 reg)
+{
+	__u32 value = inl(host->base + reg);
+	const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
+		= (struct NCR_700_Host_Parameters *)host->hostdata[0];
+
+#if 1
+	/* sanity check the register */
+	if((reg & 0x3) != 0)
+		BUG();
+#endif
+
+	return bS_to_cpu(value);
+}
+
+static inline void
+NCR_700_writeb(__u8 value, struct Scsi_Host *host, __u32 reg)
+{
+	const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
+		= (struct NCR_700_Host_Parameters *)host->hostdata[0];
+
+	outb(value, host->base + (reg^bE));
+}
+
+static inline void
+NCR_700_writel(__u32 value, struct Scsi_Host *host, __u32 reg)
+{
+	const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
+		= (struct NCR_700_Host_Parameters *)host->hostdata[0];
+
+#if 1
+	/* sanity check the register */
+	if((reg & 0x3) != 0)
+		BUG();
+#endif
+
+	outl(bS_to_host(value), host->base + reg);
+}
+#endif
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/53c700.scr linux/drivers/scsi/53c700.scr
--- v2.4.9/linux/drivers/scsi/53c700.scr	Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/53c700.scr	Sun Sep  9 10:50:48 2001
@@ -0,0 +1,404 @@
+; Script for the NCR (or symbios) 53c700 and 53c700-66 chip
+;
+; Copyright (C) 2001 James.Bottomley@HansenPartnership.com
+;;-----------------------------------------------------------------------------
+;;  
+;;  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+;;
+;;-----------------------------------------------------------------------------
+;
+; This script is designed to be modified for the particular command in
+; operation.  The particular variables pertaining to the commands are:
+;
+ABSOLUTE	Device_ID = 0		; ID of target for command
+ABSOLUTE	MessageCount = 0	; Number of bytes in message
+ABSOLUTE	MessageLocation = 0	; Addr of message
+ABSOLUTE	CommandCount = 0	; Number of bytes in command
+ABSOLUTE	CommandAddress = 0	; Addr of Command
+ABSOLUTE	StatusAddress = 0	; Addr to receive status return
+ABSOLUTE	ReceiveMsgAddress = 0	; Addr to receive msg
+;
+; This is the magic component for handling scatter-gather.  Each of the
+; SG components is preceeded by a script fragment which moves the
+; necessary amount of data and jumps to the next SG segment.  The final
+; SG segment jumps back to .  However, this address is the first SG script
+; segment.
+;
+ABSOLUTE	SGScriptStartAddress = 0
+
+; The following represent status interrupts we use 3 hex digits for
+; this: 0xPRS where 
+
+; P:
+ABSOLUTE	AFTER_SELECTION 	= 0x100
+ABSOLUTE	BEFORE_CMD 		= 0x200
+ABSOLUTE	AFTER_CMD 		= 0x300
+ABSOLUTE	AFTER_STATUS 		= 0x400
+ABSOLUTE	AFTER_DATA_IN		= 0x500
+ABSOLUTE	AFTER_DATA_OUT		= 0x600
+ABSOLUTE	DURING_DATA_IN		= 0x700
+
+; R:
+ABSOLUTE	NOT_MSG_OUT 		= 0x10
+ABSOLUTE	UNEXPECTED_PHASE 	= 0x20
+ABSOLUTE	NOT_MSG_IN 		= 0x30
+ABSOLUTE	UNEXPECTED_MSG		= 0x40
+ABSOLUTE	MSG_IN			= 0x50
+ABSOLUTE	SDTR_MSG_R		= 0x60
+ABSOLUTE	REJECT_MSG_R		= 0x70
+ABSOLUTE	DISCONNECT		= 0x80
+ABSOLUTE	MSG_OUT			= 0x90
+ABSOLUTE	WDTR_MSG_R		= 0xA0
+
+; S:
+ABSOLUTE	GOOD_STATUS 		= 0x1
+
+; Combinations, since the script assembler can't process |
+ABSOLUTE	NOT_MSG_OUT_AFTER_SELECTION = 0x110
+ABSOLUTE	UNEXPECTED_PHASE_BEFORE_CMD = 0x220
+ABSOLUTE	UNEXPECTED_PHASE_AFTER_CMD = 0x320
+ABSOLUTE	NOT_MSG_IN_AFTER_STATUS = 0x430
+ABSOLUTE	GOOD_STATUS_AFTER_STATUS = 0x401
+ABSOLUTE	UNEXPECTED_PHASE_AFTER_DATA_IN = 0x520
+ABSOLUTE	UNEXPECTED_PHASE_AFTER_DATA_OUT = 0x620
+ABSOLUTE	UNEXPECTED_MSG_BEFORE_CMD = 0x240
+ABSOLUTE	MSG_IN_BEFORE_CMD = 0x250
+ABSOLUTE	MSG_IN_AFTER_CMD = 0x350
+ABSOLUTE	SDTR_MSG_BEFORE_CMD = 0x260
+ABSOLUTE	REJECT_MSG_BEFORE_CMD = 0x270
+ABSOLUTE	DISCONNECT_AFTER_CMD = 0x380
+ABSOLUTE	SDTR_MSG_AFTER_CMD = 0x360
+ABSOLUTE	WDTR_MSG_AFTER_CMD = 0x3A0
+ABSOLUTE	DISCONNECT_AFTER_DATA = 0x580
+ABSOLUTE	MSG_IN_AFTER_DATA_IN = 0x550
+ABSOLUTE	MSG_IN_AFTER_DATA_OUT = 0x650
+ABSOLUTE	MSG_OUT_AFTER_DATA_IN = 0x590
+ABSOLUTE	DATA_IN_AFTER_DATA_IN = 0x5a0
+ABSOLUTE	MSG_IN_DURING_DATA_IN = 0x750
+ABSOLUTE	DISCONNECT_DURING_DATA = 0x780
+
+;
+; Other interrupt conditions
+; 
+ABSOLUTE	RESELECTED_DURING_SELECTION = 0x1000
+ABSOLUTE	COMPLETED_SELECTION_AS_TARGET = 0x1001
+ABSOLUTE	RESELECTION_IDENTIFIED = 0x1003
+;
+; Fatal interrupt conditions.  If you add to this, also add to the
+; array of corresponding messages
+;
+ABSOLUTE	FATAL = 0x2000
+ABSOLUTE	FATAL_UNEXPECTED_RESELECTION_MSG = 0x2000
+ABSOLUTE	FATAL_SEND_MSG = 0x2001
+ABSOLUTE	FATAL_NOT_MSG_IN_AFTER_SELECTION = 0x2002
+ABSOLUTE	FATAL_ILLEGAL_MSG_LENGTH = 0x2003
+
+ABSOLUTE	DEBUG_INTERRUPT	= 0x3000
+ABSOLUTE	DEBUG_INTERRUPT1 = 0x3001
+ABSOLUTE	DEBUG_INTERRUPT2 = 0x3002
+ABSOLUTE	DEBUG_INTERRUPT3 = 0x3003
+ABSOLUTE	DEBUG_INTERRUPT4 = 0x3004
+ABSOLUTE	DEBUG_INTERRUPT5 = 0x3005
+ABSOLUTE	DEBUG_INTERRUPT6 = 0x3006
+
+
+;
+; SCSI Messages we interpret in the script
+; 
+ABSOLUTE	EXTENDED_MSG		= 0x01
+ABSOLUTE	SDTR_MSG		= 0x01
+ABSOLUTE	SAVE_DATA_PTRS_MSG	= 0x02
+ABSOLUTE	RESTORE_DATA_PTRS_MSG	= 0x03
+ABSOLUTE	WDTR_MSG		= 0x03
+ABSOLUTE	DISCONNECT_MSG		= 0x04
+ABSOLUTE	REJECT_MSG		= 0x07
+ABSOLUTE	PARITY_ERROR_MSG	= 0x09
+ABSOLUTE	SIMPLE_TAG_MSG		= 0x20
+ABSOLUTE	IDENTIFY_MSG		= 0x80
+ABSOLUTE	IDENTIFY_MSG_MASK	= 0x7F
+ABSOLUTE	TWO_BYTE_MSG		= 0x20
+ABSOLUTE	TWO_BYTE_MSG_MASK	= 0x0F
+
+; This is where the script begins
+
+ENTRY	StartUp
+
+StartUp:
+	SELECT	ATN Device_ID, Reselect
+	JUMP	Finish, WHEN STATUS
+	JUMP	SendIdentifyMsg, IF MSG_OUT
+	INT	NOT_MSG_OUT_AFTER_SELECTION
+
+Reselect:
+	WAIT	RESELECT SelectedAsTarget
+	INT	RESELECTED_DURING_SELECTION, WHEN MSG_IN
+	INT	FATAL_NOT_MSG_IN_AFTER_SELECTION
+
+	ENTRY	GetReselectionData
+GetReselectionData:
+	MOVE	1, ReceiveMsgAddress, WHEN MSG_IN
+	INT	RESELECTION_IDENTIFIED
+
+	ENTRY	GetReselectionWithTag
+GetReselectionWithTag:
+	MOVE	3, ReceiveMsgAddress, WHEN MSG_IN
+	INT	RESELECTION_IDENTIFIED
+	
+	ENTRY	SelectedAsTarget
+SelectedAsTarget:
+; Basically tell the selecting device that there's nothing here
+	SET	TARGET
+	DISCONNECT
+	CLEAR	TARGET
+	INT	COMPLETED_SELECTION_AS_TARGET
+;
+; These are the messaging entries
+;
+; Send a message.  Message count should be correctly patched
+	ENTRY	SendMessage
+SendMessage:
+	MOVE	MessageCount, MessageLocation, WHEN MSG_OUT
+ResumeSendMessage:
+	RETURN,	WHEN NOT MSG_OUT
+	INT	FATAL_SEND_MSG
+
+	ENTRY	SendMessagePhaseMismatch
+SendMessagePhaseMismatch:
+	CLEAR	ACK
+	JUMP	ResumeSendMessage
+;
+; Receive a message.  Need to identify the message to
+; receive it correctly
+	ENTRY	ReceiveMessage
+ReceiveMessage:
+	MOVE	1, ReceiveMsgAddress, WHEN MSG_IN
+;
+; Use this entry if we've just tried to look at the first byte
+; of the message and want to process it further
+ProcessReceiveMessage:
+	JUMP	ReceiveExtendedMessage, IF EXTENDED_MSG
+	RETURN,	IF NOT TWO_BYTE_MSG, AND MASK TWO_BYTE_MSG_MASK
+	CLEAR	ACK
+	MOVE	1, ReceiveMsgAddress + 1, WHEN MSG_IN
+	RETURN
+ReceiveExtendedMessage:
+	CLEAR	ACK
+	MOVE	1, ReceiveMsgAddress + 1, WHEN MSG_IN
+	JUMP	Receive1Byte, IF 0x01
+	JUMP	Receive2Byte, IF 0x02
+	JUMP	Receive3Byte, IF 0x03
+	JUMP	Receive4Byte, IF 0x04
+	JUMP	Receive5Byte, IF 0x05
+	INT	FATAL_ILLEGAL_MSG_LENGTH
+Receive1Byte:
+	CLEAR	ACK
+	MOVE	1, ReceiveMsgAddress + 2, WHEN MSG_IN
+	RETURN
+Receive2Byte:
+	CLEAR	ACK
+	MOVE	2, ReceiveMsgAddress + 2, WHEN MSG_IN
+	RETURN
+Receive3Byte:
+	CLEAR	ACK
+	MOVE	3, ReceiveMsgAddress + 2, WHEN MSG_IN
+	RETURN
+Receive4Byte:
+	CLEAR	ACK
+	MOVE	4, ReceiveMsgAddress + 2, WHEN MSG_IN
+	RETURN
+Receive5Byte:
+	CLEAR	ACK
+	MOVE	5, ReceiveMsgAddress + 2, WHEN MSG_IN
+	RETURN
+;
+; Come here from the message processor to ignore the message
+;
+	ENTRY	IgnoreMessage
+IgnoreMessage:
+	CLEAR	ACK
+	RETURN
+;
+; Come here to send a reply to a message
+;
+	ENTRY	SendMessageWithATN
+SendMessageWithATN:
+	SET	ATN
+	CLEAR	ACK
+	JUMP	SendMessage
+
+SendIdentifyMsg:
+	CALL	SendMessage
+	JUMP	SendCommand
+
+IgnoreMsgBeforeCommand:
+	CLEAR	ACK
+	ENTRY	SendCommand
+SendCommand:
+	JUMP	Finish, WHEN STATUS
+	JUMP	MsgInBeforeCommand, IF MSG_IN
+	INT	UNEXPECTED_PHASE_BEFORE_CMD, IF NOT CMD
+	MOVE	CommandCount, CommandAddress, WHEN CMD
+ResumeSendCommand:
+	JUMP	Finish, WHEN STATUS
+	JUMP	MsgInAfterCmd, IF MSG_IN
+	JUMP	DataIn, IF DATA_IN
+	JUMP	DataOut, IF DATA_OUT
+	INT	UNEXPECTED_PHASE_AFTER_CMD
+
+IgnoreMsgDuringData:
+	CLEAR	ACK
+	; fall through to MsgInDuringData
+
+Entry MsgInDuringData
+MsgInDuringData:
+;
+; Could be we have nothing more to transfer
+;
+	JUMP	Finish, WHEN STATUS
+	MOVE	1, ReceiveMsgAddress, WHEN MSG_IN
+	JUMP	DisconnectDuringDataIn, IF DISCONNECT_MSG
+	JUMP	IgnoreMsgDuringData, IF SAVE_DATA_PTRS_MSG
+	JUMP	IgnoreMsgDuringData, IF RESTORE_DATA_PTRS_MSG
+	INT	MSG_IN_DURING_DATA_IN
+
+MsgInAfterCmd:
+	MOVE	1, ReceiveMsgAddress, WHEN MSG_IN
+	JUMP	DisconnectAfterCmd, IF DISCONNECT_MSG
+	JUMP	IgnoreMsgInAfterCmd, IF SAVE_DATA_PTRS_MSG
+	JUMP	IgnoreMsgInAfterCmd, IF RESTORE_DATA_PTRS_MSG
+	CALL	ProcessReceiveMessage
+	INT	MSG_IN_AFTER_CMD
+	CLEAR	ACK
+	JUMP	ResumeSendCommand
+
+IgnoreMsgInAfterCmd:
+	CLEAR	ACK
+	JUMP	ResumeSendCommand
+
+DisconnectAfterCmd:
+	CLEAR	ACK
+	WAIT	DISCONNECT
+	ENTRY	Disconnect1
+Disconnect1:
+	INT	DISCONNECT_AFTER_CMD
+	ENTRY	Disconnect2
+Disconnect2:
+; We return here after a reselection
+	CLEAR	ACK
+	JUMP	ResumeSendCommand
+
+MsgInBeforeCommand:
+	MOVE	1, ReceiveMsgAddress, WHEN MSG_IN
+	JUMP	IgnoreMsgBeforeCommand, IF SAVE_DATA_PTRS_MSG
+	JUMP	IgnoreMsgBeforeCommand, IF RESTORE_DATA_PTRS_MSG
+	CALL	ProcessReceiveMessage
+	INT	MSG_IN_BEFORE_CMD
+	CLEAR	ACK
+	JUMP	SendCommand
+
+DataIn:
+	CALL	SGScriptStartAddress
+ResumeDataIn:
+	JUMP	Finish, WHEN STATUS
+	JUMP	MsgInAfterDataIn, IF MSG_IN
+	JUMP	DataInAfterDataIn, if DATA_IN
+	INT	MSG_OUT_AFTER_DATA_IN, if MSG_OUT
+	INT	UNEXPECTED_PHASE_AFTER_DATA_IN
+
+DataInAfterDataIn:
+	INT	DATA_IN_AFTER_DATA_IN
+	JUMP	ResumeDataIn
+
+DataOut:
+	CALL	SGScriptStartAddress
+ResumeDataOut:
+	JUMP	Finish, WHEN STATUS
+	JUMP	MsgInAfterDataOut, IF MSG_IN
+	INT	UNEXPECTED_PHASE_AFTER_DATA_OUT
+
+MsgInAfterDataIn:
+	MOVE	1, ReceiveMsgAddress, WHEN MSG_IN
+	JUMP	DisconnectAfterDataIn, IF DISCONNECT_MSG
+	JUMP	IgnoreMsgAfterData, IF SAVE_DATA_PTRS_MSG
+	JUMP	IgnoreMsgAfterData, IF RESTORE_DATA_PTRS_MSG
+	CALL	ProcessReceiveMessage
+	INT	MSG_IN_AFTER_DATA_IN
+	CLEAR	ACK
+	JUMP	ResumeDataIn
+
+DisconnectDuringDataIn:
+	CLEAR	ACK
+	WAIT	DISCONNECT
+	ENTRY	Disconnect3
+Disconnect3:
+	INT	DISCONNECT_DURING_DATA
+	ENTRY	Disconnect4
+Disconnect4:
+; we return here after a reselection
+	CLEAR	ACK
+	JUMP	ResumeSendCommand
+
+
+DisconnectAfterDataIn:
+	CLEAR	ACK
+	WAIT	DISCONNECT
+	ENTRY	Disconnect5
+Disconnect5:
+	INT	DISCONNECT_AFTER_DATA
+	ENTRY	Disconnect6
+Disconnect6:
+; we return here after a reselection
+	CLEAR	ACK
+	JUMP	ResumeDataIn
+
+MsgInAfterDataOut:
+	MOVE	1, ReceiveMsgAddress, WHEN MSG_IN
+	JUMP	DisconnectAfterDataOut, if DISCONNECT_MSG
+	JUMP	IgnoreMsgAfterData, IF SAVE_DATA_PTRS_MSG
+	JUMP	IgnoreMsgAfterData, IF RESTORE_DATA_PTRS_MSG
+	CALL	ProcessReceiveMessage
+	INT	MSG_IN_AFTER_DATA_OUT
+	CLEAR	ACK
+	JUMP	ResumeDataOut
+
+IgnoreMsgAfterData:
+	CLEAR	ACK
+; Data in and out do the same thing on resume, so pick one
+	JUMP	ResumeDataIn
+
+DisconnectAfterDataOut:
+	CLEAR	ACK
+	WAIT	DISCONNECT
+	ENTRY	Disconnect7
+Disconnect7:
+	INT	DISCONNECT_AFTER_DATA
+	ENTRY	Disconnect8
+Disconnect8:
+; we return here after a reselection
+	CLEAR	ACK
+	JUMP	ResumeDataOut
+
+Finish:
+	MOVE	1, StatusAddress, WHEN STATUS
+	INT	NOT_MSG_IN_AFTER_STATUS, WHEN NOT MSG_IN
+	CALL	ReceiveMessage
+	CLEAR	ACK
+	WAIT	DISCONNECT
+	ENTRY	Finish1
+Finish1:
+	INT	GOOD_STATUS_AFTER_STATUS
+	ENTRY	Finish2
+Finish2:
+
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/Config.in linux/drivers/scsi/Config.in
--- v2.4.9/linux/drivers/scsi/Config.in	Wed Jul 25 17:10:22 2001
+++ linux/drivers/scsi/Config.in	Sun Sep  9 10:52:35 2001
@@ -33,7 +33,7 @@
 comment 'SCSI low-level drivers'
 
 if [ "$CONFIG_SGI_IP22" = "y" ]; then
-   dep_tristate 'SGI WD93C93 SCSI Driver' CONFIG_SCSI_SGIWD93 $CONFIG_SCSI
+   dep_tristate 'SGI WD93C93 SCSI Driver' CONFIG_SGIWD93_SCSI $CONFIG_SCSI
 fi
 if [ "$CONFIG_DECSTATION" = "y" ]; then
    if [ "$CONFIG_TC" = "y" ]; then
@@ -59,6 +59,7 @@
       bool '  Collect statistics to report in /proc' CONFIG_AIC7XXX_OLD_PROC_STATS
    fi
 fi
+dep_tristate 'Adaptec I2O RAID support ' CONFIG_SCSI_DPT_I2O $CONFIG_SCSI
 dep_tristate 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS $CONFIG_SCSI
 dep_tristate 'Always IN2000 SCSI support' CONFIG_SCSI_IN2000 $CONFIG_SCSI
 dep_tristate 'AM53/79C974 PCI SCSI support' CONFIG_SCSI_AM53C974 $CONFIG_SCSI $CONFIG_PCI
@@ -85,7 +86,7 @@
 if [ "$CONFIG_MCA" = "y" ]; then
    dep_tristate 'Future Domain MCS-600/700 SCSI support' CONFIG_SCSI_FD_MCS $CONFIG_SCSI
 fi
-dep_tristate 'GDT SCSI Disk Array Controller support' CONFIG_SCSI_GDTH $CONFIG_SCSI
+dep_tristate 'Intel/ICP (former GDT SCSI Disk Array) RAID Controller support' CONFIG_SCSI_GDTH $CONFIG_SCSI
 dep_tristate 'Generic NCR5380/53c400 SCSI support' CONFIG_SCSI_GENERIC_NCR5380 $CONFIG_SCSI
 if [ "$CONFIG_SCSI_GENERIC_NCR5380" != "n" ]; then
    bool '  Enable NCR53c400 extensions' CONFIG_SCSI_GENERIC_NCR53C400
@@ -114,6 +115,10 @@
    fi
 fi
 dep_tristate 'NCR53c406a SCSI support' CONFIG_SCSI_NCR53C406A $CONFIG_SCSI
+dep_tristate 'NCR Dual 700 MCA SCSI support' CONFIG_SCSI_NCR_D700 $CONFIG_SCSI $CONFIG_MCA
+if [ "$CONFIG_PARISC" = "y" ]; then
+   dep_tristate 'HP LASI SCSI support for 53c700' CONFIG_SCSI_LASI70 $CONFIG_SCSI
+fi
 dep_tristate 'NCR53c7,8xx SCSI support'  CONFIG_SCSI_NCR53C7xx $CONFIG_SCSI $CONFIG_PCI
 if [ "$CONFIG_SCSI_NCR53C7xx" != "n" ]; then
    bool '  always negotiate synchronous transfers' CONFIG_SCSI_NCR53C7xx_sync
@@ -151,6 +156,9 @@
 if [ "$CONFIG_PCI" = "y" ]; then
    dep_tristate 'Qlogic ISP SCSI support' CONFIG_SCSI_QLOGIC_ISP $CONFIG_SCSI
    dep_tristate 'Qlogic ISP FC SCSI support' CONFIG_SCSI_QLOGIC_FC $CONFIG_SCSI
+   if [ "$CONFIG_SCSI_QLOGIC_FC" != "n" ]; then
+      bool '   Include loadable firmware in driver' CONFIG_SCSI_QLOGIC_FC_FIRMWARE
+   fi
    dep_tristate 'Qlogic QLA 1280 SCSI support' CONFIG_SCSI_QLOGIC_1280 $CONFIG_SCSI
 fi
 if [ "$CONFIG_X86" = "y" ]; then
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/Makefile linux/drivers/scsi/Makefile
--- v2.4.9/linux/drivers/scsi/Makefile	Fri May  4 15:16:28 2001
+++ linux/drivers/scsi/Makefile	Sun Sep  9 10:52:35 2001
@@ -31,7 +31,7 @@
   endif
 endif
 
-export-objs	:= scsi_syms.o
+export-objs	:= scsi_syms.o 53c700.o 53c700-mem.o
 
 CFLAGS_aha152x.o =   -DAHA152X_STAT -DAUTOCONF
 CFLAGS_gdth.o    = # -DDEBUG_GDTH=2 -D__SERIAL__ -D__COM2__ -DGDTH_STATISTICS
@@ -47,6 +47,7 @@
 obj-$(CONFIG_A2091_SCSI)	+= a2091.o	wd33c93.o
 obj-$(CONFIG_GVP11_SCSI)	+= gvp11.o	wd33c93.o
 obj-$(CONFIG_MVME147_SCSI)	+= mvme147.o	wd33c93.o
+obj-$(CONFIG_SGIWD93_SCSI)	+= sgiwd93.o	wd33c93.o
 obj-$(CONFIG_CYBERSTORM_SCSI)	+= NCR53C9x.o	cyberstorm.o
 obj-$(CONFIG_CYBERSTORMII_SCSI)	+= NCR53C9x.o	cyberstormII.o
 obj-$(CONFIG_BLZ2060_SCSI)	+= NCR53C9x.o	blz2060.o
@@ -65,6 +66,7 @@
 obj-$(CONFIG_SCSI_PCI2220I)	+= pci2220i.o
 obj-$(CONFIG_SCSI_PSI240I)	+= psi240i.o
 obj-$(CONFIG_SCSI_BUSLOGIC)	+= BusLogic.o
+obj-$(CONFIG_SCSI_DPT_I2O)	+= dpt_i2o.o
 obj-$(CONFIG_SCSI_U14_34F)	+= u14-34f.o
 obj-$(CONFIG_SCSI_ULTRASTOR)	+= ultrastor.o
 obj-$(CONFIG_SCSI_AHA152X)	+= aha152x.o
@@ -80,6 +82,7 @@
 obj-$(CONFIG_SCSI_IN2000)	+= in2000.o
 obj-$(CONFIG_SCSI_GENERIC_NCR5380) += g_NCR5380.o
 obj-$(CONFIG_SCSI_NCR53C406A)	+= NCR53c406a.o
+obj-$(CONFIG_SCSI_NCR_D700)	+= NCR_D700.o 53c700.o
 obj-$(CONFIG_SCSI_SYM53C416)	+= sym53c416.o
 obj-$(CONFIG_SCSI_QLOGIC_FAS)	+= qlogicfas.o
 obj-$(CONFIG_SCSI_QLOGIC_ISP)	+= qlogicisp.o 
@@ -121,6 +124,8 @@
 obj-$(CONFIG_SUN3X_ESP)		+= NCR53C9x.o	sun3x_esp.o
 obj-$(CONFIG_SCSI_DEBUG)	+= scsi_debug.o
 obj-$(CONFIG_SCSI_FCAL)		+= fcal.o
+obj-$(CONFIG_SCSI_CPQFCTS)	+= cpqfc.o
+obj-$(CONFIG_SCSI_LASI700)	+= lasi700.o 53c700-mem.o
 
 ifeq ($(CONFIG_ARCH_ACORN),y)
 mod-subdirs	+= ../acorn/scsi
@@ -193,3 +198,22 @@
 sim710_u.h: sim710_d.h
 
 sim710.o : sim710_d.h
+
+53c700_d.h: 53c700.scr script_asm.pl
+	$(PERL) -s script_asm.pl -ncr7x0_family < 53c700.scr
+	rm -f scriptu.h
+	mv script.h 53c700_d.h
+
+53c700.o: 53c700_d.h
+
+53c700-mem.o: 53c700_d.h
+
+53c700-mem.c: 53c700.c
+	echo "/* WARNING: GENERATED FILE (from $<), DO NOT MODIFY */" > $@
+	echo "#define MEM_MAPPED" >> $@
+	cat $< >> $@
+
+cpqfc.o: cpqfcTSinit.o cpqfcTScontrol.o cpqfcTSi2c.o cpqfcTSworker.o \
+	cpqfcTStrigger.o
+	$(LD) -r -o cpqfc.o cpqfcTSinit.o cpqfcTScontrol.o \
+	cpqfcTSi2c.o cpqfcTSworker.o cpqfcTStrigger.o
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/NCR_D700.c linux/drivers/scsi/NCR_D700.c
--- v2.4.9/linux/drivers/scsi/NCR_D700.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/NCR_D700.c	Sun Sep  9 11:58:36 2001
@@ -0,0 +1,326 @@
+/* -*- mode: c; c-basic-offset: 8 -*- */
+
+/* NCR Dual 700 MCA SCSI Driver
+ *
+ * Copyright (C) 2001 by James.Bottomley@HansenPartnership.com
+**-----------------------------------------------------------------------------
+**  
+**  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+**
+**-----------------------------------------------------------------------------
+ */
+
+/* Notes:
+ *
+ * Most of the work is done in the chip specific module, 53c700.o
+ *
+ * TODO List:
+ *
+ * 1. Extract the SCSI ID from the voyager CMOS table (necessary to
+ *    support multi-host environments.
+ *
+ * */
+
+
+/* CHANGELOG 
+ *
+ * Version 2.1
+ *
+ * Modularise the driver into a Board piece (this file) and a chip
+ * piece 53c700.[ch] and 53c700.scr, added module options.  You can
+ * now specify the scsi id by the parameters
+ *
+ * NCR_D700=slot:<n> [siop:<n>] id:<n> ....
+ *
+ * They need to be comma separated if compiled into the kernel
+ *
+ * Version 2.0
+ *
+ * Initial implementation of TCQ (Tag Command Queueing).  TCQ is full
+ * featured and uses the clock algorithm to keep track of outstanding
+ * tags and guard against individual tag starvation.  Also fixed a bug
+ * in all of the 1.x versions where the D700_data_residue() function
+ * was returning results off by 32 bytes (and thus causing the same 32
+ * bytes to be written twice corrupting the data block).  It turns out
+ * the 53c700 only has a 6 bit DBC and DFIFO registers not 7 bit ones
+ * like the 53c710 (The 710 is the only data manual still available,
+ * which I'd been using to program the 700).
+ *
+ * Version 1.2
+ *
+ * Much improved message handling engine
+ *
+ * Version 1.1
+ *
+ * Add code to handle selection reasonably correctly.  By the time we
+ * get the selection interrupt, we've already responded, but drop off the
+ * bus and hope the selector will go away.
+ *
+ * Version 1.0:
+ *
+ *   Initial release.  Fully functional except for procfs and tag
+ * command queueing.  Has only been tested on cards with 53c700-66
+ * chips and only single ended. Features are
+ *
+ * 1. Synchronous data transfers to offset 8 (limit of 700-66) and
+ *    100ns (10MHz) limit of SCSI-2
+ *
+ * 2. Disconnection and reselection
+ *
+ * Testing:
+ * 
+ *  I've only really tested this with the 700-66 chip, but have done
+ * soak tests in multi-device environments to verify that
+ * disconnections and reselections are being processed correctly.
+ * */
+
+#define NCR_D700_VERSION "2.1"
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/spinlock.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/mca.h>
+#include <asm/dma.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/byteorder.h>
+#include <linux/blk.h>
+#include <linux/module.h>
+
+
+#include "scsi.h"
+#include "hosts.h"
+#include "constants.h"
+
+#include "53c700.h"
+#include "NCR_D700.h"
+
+#ifndef CONFIG_MCA
+#error "NCR_D700 driver only compiles for MCA"
+#endif
+
+#ifdef NCR_D700_DEBUG
+#define STATIC
+#else
+#define STATIC static
+#endif
+
+char *NCR_D700;			/* command line from insmod */
+
+MODULE_AUTHOR("James Bottomley");
+MODULE_DESCRIPTION("NCR Dual700 SCSI Driver");
+MODULE_LICENSE("GPL");
+MODULE_PARM(NCR_D700, "s");
+
+static __u8 __initdata id_array[2*(MCA_MAX_SLOT_NR + 1)] =
+	{ [0 ... 2*(MCA_MAX_SLOT_NR + 1)-1] = 7 };
+
+#ifdef MODULE
+#define ARG_SEP ' '
+#else
+#define ARG_SEP ','
+#endif
+
+static int __init
+param_setup(char *string)
+{
+	char *pos = string, *next;
+	int slot = -1, siop = -1;
+
+	while(pos != NULL && (next = strchr(pos, ':')) != NULL) {
+		int val = (int)simple_strtoul(++next, NULL, 0);
+
+		if(!strncmp(pos, "slot:", 5))
+			slot = val;
+		else if(!strncmp(pos, "siop:", 5))
+			siop = val;
+		else if(!strncmp(pos, "id:", 3)) {
+			if(slot == -1) {
+				printk(KERN_WARNING "NCR D700: Must specify slot for id parameter\n");
+			} else if(slot > MCA_MAX_SLOT_NR) {
+				printk(KERN_WARNING "NCR D700: Illegal slot %d for id %d\n", slot, val);
+			} else {
+				if(siop != 0 && siop != 1) {
+					id_array[slot*2] = val;
+					id_array[slot*2 + 1] =val;
+				} else {
+					id_array[slot*2 + siop] = val;
+				}
+			}
+		}
+		if((pos = strchr(pos, ARG_SEP)) != NULL)
+			pos++;
+	}
+	return 1;
+}
+
+#ifndef MODULE
+__setup("NCR_D700=", param_setup);
+#endif
+
+/* Detect a D700 card.  Note, because of the set up---the chips are
+ * essentially connectecd to the MCA bus independently, it is easier
+ * to set them up as two separate host adapters, rather than one
+ * adapter with two channels */
+STATIC int __init
+D700_detect(Scsi_Host_Template *tpnt)
+{
+	int slot = 0;
+	int found = 0;
+	int differential;
+	int banner = 1;
+
+	if(!MCA_bus)
+		return 0;
+
+#ifdef MODULE
+	if(NCR_D700)
+		param_setup(NCR_D700);
+#endif
+
+	for(slot = 0; (slot = mca_find_adapter(NCR_D700_MCA_ID, slot)) != MCA_NOTFOUND; slot++) {
+		int irq, i;
+		int pos3j, pos3k, pos3a, pos3b, pos4;
+		__u32 base_addr, offset_addr;
+		struct Scsi_Host *host = NULL;
+
+		/* enable board interrupt */
+		pos4 = mca_read_pos(slot, 4);
+		pos4 |= 0x4;
+		mca_write_pos(slot, 4, pos4);
+
+		mca_write_pos(slot, 6, 9);
+		pos3j = mca_read_pos(slot, 3);
+		mca_write_pos(slot, 6, 10);
+		pos3k = mca_read_pos(slot, 3);
+		mca_write_pos(slot, 6, 0);
+		pos3a = mca_read_pos(slot, 3);
+		mca_write_pos(slot, 6, 1);
+		pos3b = mca_read_pos(slot, 3);
+
+		base_addr = ((pos3j << 8) | pos3k) & 0xfffffff0;
+		offset_addr = ((pos3a << 8) | pos3b) & 0xffffff70;
+
+		irq = (pos4 & 0x3) + 11;
+		if(irq >= 13)
+			irq++;
+		if(banner) {
+			printk(KERN_NOTICE "NCR D700: Driver Version " NCR_D700_VERSION "\n"
+			       "NCR D700:  Copyright (c) 2001 by James.Bottomley@HansenPartnership.com\n"
+			       "NCR D700:\n");
+			banner = 0;
+		}
+		printk(KERN_NOTICE "NCR D700: found in slot %d  irq = %d  I/O base = 0x%x\n", slot, irq, offset_addr);
+
+		tpnt->proc_name = "NCR_D700";
+
+		/*outb(BOARD_RESET, base_addr);*/
+
+		/* clear any pending interrupts */
+		(void)inb(base_addr + 0x08);
+		/* get modctl, used later for setting diff bits */
+		switch(differential = (inb(base_addr + 0x08) >> 6)) {
+		case 0x00:
+			/* only SIOP1 differential */
+			differential = 0x02;
+			break;
+		case 0x01:
+			/* Both SIOPs differential */
+			differential = 0x03;
+			break;
+		case 0x03:
+			/* No SIOPs differential */
+			differential = 0x00;
+			break;
+		default:
+			printk(KERN_ERR "D700: UNEXPECTED DIFFERENTIAL RESULT 0x%02x\n",
+			       differential);
+			differential = 0x00;
+			break;
+		}
+
+		/* plumb in both 700 chips */
+		for(i=0; i<2; i++) {
+			__u32 region = offset_addr | (0x80 * i);
+			struct NCR_700_Host_Parameters *hostdata =
+				kmalloc(sizeof(struct NCR_700_Host_Parameters),
+					GFP_KERNEL);
+			if(hostdata == NULL) {
+				printk(KERN_ERR "NCR D700: Failed to allocate host data for channel %d, detatching\n", i);
+				continue;
+			}
+			memset(hostdata, 0, sizeof(struct NCR_700_Host_Parameters));
+			if(request_region(region, 64, "NCR_D700") == NULL) {
+				printk(KERN_ERR "NCR D700: Failed to reserve IO region 0x%x\n", region);
+				kfree(hostdata);
+				continue;
+			}
+
+			/* Fill in the three required pieces of hostdata */
+			hostdata->base = region;
+			hostdata->differential = (((1<<i) & differential) != 0);
+			hostdata->clock = NCR_D700_CLOCK_MHZ;
+			/* and register the chip */
+			if((host = NCR_700_detect(tpnt, hostdata)) == NULL) {
+				kfree(hostdata);
+				release_region(host->base, 64);
+				continue;
+			}
+			host->irq = irq;
+			/* FIXME: Read this from SUS */
+			host->this_id = id_array[slot * 2 + i];
+			printk(KERN_NOTICE "NCR D700: SIOP%d, SCSI id is %d\n",
+			       i, host->this_id);
+			if(request_irq(irq, NCR_700_intr, SA_SHIRQ, "NCR_D700", host)) {
+				printk(KERN_ERR "NCR D700, channel %d: irq problem, detatching\n", i);
+				scsi_unregister(host);
+				NCR_700_release(host);
+				continue;
+			}
+			found++;
+		}
+	}
+
+	return found;
+}
+
+
+STATIC int
+D700_release(struct Scsi_Host *host)
+{
+	struct D700_Host_Parameters *hostdata = 
+		(struct D700_Host_Parameters *)host->hostdata[0];
+
+	NCR_700_release(host);
+	kfree(hostdata);
+	free_irq(host->irq, host);
+	release_region(host->base, 64);
+	return 1;
+}
+
+
+static Scsi_Host_Template driver_template = NCR_D700_SCSI;
+
+#include "scsi_module.c"
+
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/NCR_D700.h linux/drivers/scsi/NCR_D700.h
--- v2.4.9/linux/drivers/scsi/NCR_D700.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/NCR_D700.h	Sun Sep  9 11:58:36 2001
@@ -0,0 +1,45 @@
+/* -*- mode: c; c-basic-offset: 8 -*- */
+
+/* NCR Dual 700 MCA SCSI Driver
+ *
+ * Copyright (C) 2001 by James.Bottomley@HansenPartnership.com
+ */
+
+#ifndef _NCR_D700_H
+#define _NCR_D700_H
+
+/* Don't turn on debugging messages */
+#undef NCR_D700_DEBUG
+
+/* The MCA identifier */
+#define NCR_D700_MCA_ID		0x0092
+
+static int D700_detect(Scsi_Host_Template *);
+static int D700_release(struct Scsi_Host *host);
+
+
+/* Host template.  Note the name and proc_name are optional, all the
+ * remaining parameters shown below must be filled in.  The 53c700
+ * routine NCR_700_detect will fill in all of the missing routines */
+#define NCR_D700_SCSI {						\
+	name:				"NCR Dual 700 MCA",	\
+	proc_name:			"NCR_D700",		\
+	detect: 			D700_detect,		\
+	release:			D700_release,		\
+	this_id:			7,			\
+}
+
+
+/* Defines for the Board registers */
+#define	BOARD_RESET		0x80	/* board level reset */
+#define ADD_PARENB		0x04	/* Address Parity Enabled */
+#define DAT_PARENB		0x01	/* Data Parity Enabled */
+#define SFBK_ENB		0x10	/* SFDBK Interrupt Enabled */
+#define LED0GREEN		0x20	/* Led 0 (red 0; green 1) */
+#define LED1GREEN		0x40	/* Led 1 (red 0; green 1) */
+#define LED0RED			0xDF	/* Led 0 (red 0; green 1) */
+#define LED1RED			0xBF	/* Led 1 (red 0; green 1) */
+
+#define NCR_D700_CLOCK_MHZ	50
+
+#endif
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/README.53c700 linux/drivers/scsi/README.53c700
--- v2.4.9/linux/drivers/scsi/README.53c700	Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/README.53c700	Sun Sep  9 11:58:36 2001
@@ -0,0 +1,17 @@
+This driver supports the 53c700 and 53c700-66 chips only.  It is full
+featured and does sync (-66 only), disconnects and tag command
+queueing.
+
+Since the 53c700 must be interfaced to a bus, you need to wrapper the
+card detector around this driver.  For an example, see the
+NCR_D700.[ch] files.
+
+The comments in the 53c700.[ch] files tell you which parts you need to
+fill in to get the driver working.
+
+The driver is currently I/O mapped only, but it should be easy enough
+to memory map (just make the port reads #defines with MEM_MAPPED for
+memory mapping or nothing for I/O mapping, specify an extra rule for
+53c700-mem.o with the -DMEM_MAPPED flag and make your driver use it,
+that way the make rules will generate the correct version).
+
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/README.dpti linux/drivers/scsi/README.dpti
--- v2.4.9/linux/drivers/scsi/README.dpti	Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/README.dpti	Sun Sep  9 10:52:35 2001
@@ -0,0 +1,83 @@
+ /* TERMS AND CONDITIONS OF USE
+ * 
+ * Redistribution and use in source form, with or without modification, are
+ * permitted provided that redistributions of source code must retain the
+ * above copyright notice, this list of conditions and the following disclaimer.
+ * 
+ * This software is provided `as is' by Adaptec and
+ * any express or implied warranties, including, but not limited to, the
+ * implied warranties of merchantability and fitness for a particular purpose,
+ * are disclaimed. In no event shall Adaptec be
+ * liable for any direct, indirect, incidental, special, exemplary or
+ * consequential damages (including, but not limited to, procurement of
+ * substitute goods or services; loss of use, data, or profits; or business
+ * interruptions) however caused and on any theory of liability, whether in
+ * contract, strict liability, or tort (including negligence or otherwise)
+ * arising in any way out of the use of this driver software, even if advised
+ * of the possibility of such damage.
+ * 
+ ****************************************************************
+ * This driver supports the Adaptec I2O RAID and DPT SmartRAID V I2O boards.
+ *
+ * CREDITS:
+ * The original linux driver was ported to Linux by Karen White while at 
+ * Dell Computer.  It was ported from Bob Pasteur's (of DPT) original 
+ * non-Linux driver.  Mark Salyzyn and Bob Pasteur consulted on the original
+ * driver. 
+ * 
+ * 2.0 version of the driver by Deanna Bonds and Mark Salyzyn.
+ *
+ * HISTORY:
+ * The driver was originally ported to linux version 2.0.34 
+ *
+ * V2.0 Rewrite of driver.  Re-architectured based on i2o subsystem.
+ *   This was the first full GPL version since the last version used
+ *   i2osig headers which were not GPL.  Developer Testing version.
+ * V2.1 Internal testing
+ * V2.2 First released version
+ *
+ * V2.3 
+ *   Changes:
+ *      Added Raptor Support
+ *      Fixed bug causing system to hang under extreme load with 
+ *         management utilities running (removed GFP_DMA from kmalloc flags)
+ *
+ *
+ * V2.4 First version ready to be submitted to be embedded in the kernel
+ *   Changes: 
+ *      Implemented suggestions from Alan Cox
+ *      Added calculation of resid for sg layer
+ *      Better error handling
+ *         Added checking underflow condtions 
+ *         Added DATAPROTECT checking
+ *         Changed error return codes
+ *         Fixed pointer bug in bus reset routine
+ *      Enabled hba reset from ioctls (allows a FW flash to reboot and use the new
+ *         FW without having to reboot)
+ *      Changed proc output
+ *
+ * TODO:
+ *      Add 64 bit Scatter Gather when compiled on 64 bit architectures
+ *      Add sparse lun scanning 
+ *      Add code that checks if a device that had been taken offline is
+ *         now online (at the FW level) when test unit ready or inquiry 
+ *         command from scsi-core
+ *      Add proc read interface
+ *         busrescan command
+ *         rescan command
+ *      Add code to rescan routine that notifies scsi-core about new devices
+ *      Add support for C-PCI (hotplug stuff)
+ *      Add ioctl passthru error recovery
+ *
+ * NOTES:
+ * The DPT card optimizes the order of processing commands.  Consequently,
+ * a command may take up to 6 minutes to complete after it has been sent
+ * to the board.  
+ *
+ * The files dpti_ioctl.h dptsig.h osd_defs.h osd_util.h sys_info.h are part of the
+ * interface files for Adaptecs managment routines.  These define the structures used
+ * in the ioctls.  They are written to be portable.  They are hard to read, but I need
+ * to use them 'as is' or I can miss changes in the interface.
+ *
+ */
+
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/aha1542.c linux/drivers/scsi/aha1542.c
--- v2.4.9/linux/drivers/scsi/aha1542.c	Tue May  1 16:05:00 2001
+++ linux/drivers/scsi/aha1542.c	Fri Sep  7 09:28:37 2001
@@ -433,7 +433,7 @@
 	void (*my_done) (Scsi_Cmnd *) = NULL;
 	int errstatus, mbi, mbo, mbistatus;
 	int number_serviced;
-	unsigned int flags;
+	unsigned long flags;
 	struct Scsi_Host *shost;
 	Scsi_Cmnd *SCtmp;
 	int flag;
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/dec_esp.c linux/drivers/scsi/dec_esp.c
--- v2.4.9/linux/drivers/scsi/dec_esp.c	Wed Jul 25 17:10:23 2001
+++ linux/drivers/scsi/dec_esp.c	Sun Sep  9 10:52:35 2001
@@ -9,6 +9,14 @@
  * Copyright (C) 1997 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
  *
  * jazz_esp is based on David S. Miller's ESP driver and cyber_esp
+ *
+ * 20000819 - Small PMAZ-AA fixes by Florian Lohoff <flo@rfc822.org>
+ *            Be warned the PMAZ-AA works currently as a single card.
+ *            Dont try to put multiple cards in one machine - They are
+ *            both detected but it may crash under high load garbling your
+ *            data.
+ * 20001005	- Initialization fixes for 2.4.0-test9
+ * 			  Florian Lohoff <flo@rfc822.org>
  */
 
 #include <linux/kernel.h>
@@ -45,8 +53,6 @@
  * starting point. #define this an be prepared for tons
  * of warnings and errors :)
  */
-#undef PMAZ_A
-
 static int  dma_bytes_sent(struct NCR_ESP *esp, int fifo_count);
 static void dma_drain(struct NCR_ESP *esp);
 static int  dma_can_transfer(struct NCR_ESP *esp, Scsi_Cmnd * sp);
@@ -62,7 +68,6 @@
 static void dma_mmu_get_scsi_sgl(struct NCR_ESP *esp, Scsi_Cmnd * sp);
 static void dma_advance_sg(Scsi_Cmnd * sp);
 
-#ifdef PMAZ_A
 static void pmaz_dma_drain(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);
@@ -70,10 +75,6 @@
 static void pmaz_dma_ints_on(struct NCR_ESP *esp);
 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);
-
-volatile int *scsi_pmaz_dma_ptr_tc;
-#endif
 
 #define TC_ESP_RAM_SIZE 0x20000
 #define ESP_TGT_DMA_SIZE ((TC_ESP_RAM_SIZE/7) & ~(sizeof(int)-1))
@@ -83,9 +84,6 @@
 #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;
 
@@ -105,20 +103,21 @@
 
 static void scsi_dma_int(int, void *, struct pt_regs *);
 
+static Scsi_Host_Template driver_template = SCSI_DEC_ESP;
+
+#include "scsi_module.c"
+
 /***************************************************************** Detection */
 int dec_esp_detect(Scsi_Host_Template * tpnt)
 {
 	struct NCR_ESP *esp;
 	struct ConfigDev *esp_dev;
-#ifdef PMAZ_A
-	int slot, i;
+	int slot;
 	unsigned long mem_start;
-	volatile unsigned char *buffer;
-#endif
 
 	if (IOASIC) {
-	esp_dev = 0;
-	esp = esp_allocate(tpnt, (void *) esp_dev);
+		esp_dev = 0;
+		esp = esp_allocate(tpnt, (void *) esp_dev);
 	
 		scsi_dma_ptr = (unsigned long *) (system_base + IOCTL + SCSI_DMA_P);
 		scsi_next_ptr = (unsigned long *) (system_base + IOCTL + SCSI_DMA_BP);
@@ -127,86 +126,89 @@
 		scsi_sdr0 = (unsigned long *) (system_base + IOCTL + SCSI_SDR0);
 		scsi_sdr1 = (unsigned long *) (system_base + IOCTL + SCSI_SDR1);
 
-	/* Do command transfer with programmed I/O */
-	esp->do_pio_cmds = 1;
+		/* Do command transfer with programmed I/O */
+		esp->do_pio_cmds = 1;
 	
-	/* 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 = &dma_init_read;
-	esp->dma_init_write = &dma_init_write;
-	esp->dma_ints_off = &dma_ints_off;
-	esp->dma_ints_on = &dma_ints_on;
-	esp->dma_irq_p = &dma_irq_p;
-	esp->dma_ports_p = &dma_ports_p;
-	esp->dma_setup = &dma_setup;
+		/* 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 = &dma_init_read;
+		esp->dma_init_write = &dma_init_write;
+		esp->dma_ints_off = &dma_ints_off;
+		esp->dma_ints_on = &dma_ints_on;
+		esp->dma_irq_p = &dma_irq_p;
+		esp->dma_ports_p = &dma_ports_p;
+		esp->dma_setup = &dma_setup;
 
-	/* Optional functions */
-	esp->dma_barrier = 0;
+		/* Optional functions */
+		esp->dma_barrier = 0;
 		esp->dma_drain = &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;
-	
-	/* virtual DMA functions */
-	esp->dma_mmu_get_scsi_one = &dma_mmu_get_scsi_one;
-	esp->dma_mmu_get_scsi_sgl = &dma_mmu_get_scsi_sgl;
+		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;
+		
+		/* virtual DMA functions */
+		esp->dma_mmu_get_scsi_one = &dma_mmu_get_scsi_one;
+		esp->dma_mmu_get_scsi_sgl = &dma_mmu_get_scsi_sgl;
 		esp->dma_mmu_release_scsi_one = 0;
 		esp->dma_mmu_release_scsi_sgl = 0;
-	esp->dma_advance_sg = &dma_advance_sg;
+		esp->dma_advance_sg = &dma_advance_sg;
 
 
-	/* SCSI chip speed */
+		/* SCSI chip speed */
 		esp->cfreq = 25000000;
 
-	/*
-	 * we don't give the address of DMA channel, but the number
-	 * of DMA channel, so we can use the jazz DMA functions
-	 *
-	 */
-	esp->dregs = JAZZ_SCSI_DMA;
+		/*
+		 * we don't give the address of DMA channel, but the number
+		 * of DMA channel, so we can use the jazz DMA functions
+		 *
+		 */
+		esp->dregs = JAZZ_SCSI_DMA;
 	
-	/* ESP register base */
+		/* ESP register base */
 		esp->eregs = (struct ESP_regs *) (system_base + SCSI);
 	
-	/* Set the command buffer */
+		/* Set the command buffer */
 		esp->esp_command = (volatile unsigned char *) cmd_buffer;
 	
-	/* get virtual dma address for command buffer */
+		/* get virtual dma address for command buffer */
 		esp->esp_command_dvma = (__u32) KSEG1ADDR((volatile unsigned char *) cmd_buffer);
 	
 		esp->irq = SCSI_INT;
+
+		esp->scsi_id = 7;
+		
+		/* Check for differential SCSI-bus */
+		esp->diff = 0;
+
+		esp_initialize(esp);
+
 		if (request_irq(esp->irq, esp_intr, SA_INTERRUPT, 
 				"NCR 53C94 SCSI", NULL))
 			goto err_dealloc;
 		if (request_irq(SCSI_DMA_INT, scsi_dma_int, SA_INTERRUPT, 
 				"JUNKIO SCSI DMA", NULL))
 			goto err_free_irq;
-			
-
-	esp->scsi_id = 7;
-		
-	/* Check for differential SCSI-bus */
-	esp->diff = 0;
-
-	esp_initialize(esp);
-	
+ 			
 	}
 
-#ifdef PMAZ_A	
 	if (TURBOCHANNEL) {
-		while ((slot = search_tc_card("PMAZ_AA")) >= 0) {
+		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);
 
+			mem_start = get_tc_base_addr(slot);
+
+			/* Store base addr into esp struct */
+			esp->slot = mem_start;
+
 			esp->dregs = 0;
 			esp->eregs = (struct ESP_regs *) (mem_start + DEC_SCSI_SREG);
 			esp->do_pio_cmds = 1;
@@ -217,16 +219,6 @@
 			/* 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);
@@ -260,18 +252,17 @@
 			esp->dma_mmu_release_scsi_sgl = 0;
 			esp->dma_advance_sg = 0;
 
-			if (request_irq(esp->irq, esp_intr, SA_INTERRUPT, 
-					 "PMAZ_AA", NULL)) {
-				esp_deallocate(esp);
-				release_tc_card(slot);
-				continue;
-			}
+ 			if (request_irq(esp->irq, esp_intr, SA_INTERRUPT, 
+ 					 "PMAZ_AA", NULL)) {
+ 				esp_deallocate(esp);
+ 				release_tc_card(slot);
+ 				continue;
+ 			}
 			esp->scsi_id = 7;
 			esp->diff = 0;
 			esp_initialize(esp);
 		}
 	}
-#endif
 
 	if(nesps) {
 		printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps, esps_in_use);
@@ -476,30 +467,35 @@
 	sp->SCp.ptr = (char *) ((unsigned long) sp->SCp.buffer->dvma_address);
 }
 
-#ifdef PMAZ_A
-
 static void pmaz_dma_drain(struct NCR_ESP *esp)
 {
 	memcpy((void *) (KSEG0ADDR(esp_virt_buffer)),
-		(void *) scsi_pmaz_dma_ptrs_tc[scsi_cur_buff], scsi_current_length);
+		(void *) ( esp->slot + DEC_SCSI_SRAM + ESP_TGT_DMA_SIZE),
+		scsi_current_length);
 }
 
 static void pmaz_dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length)
 {
+	volatile int *dmareg = (volatile int *) (esp->slot + DEC_SCSI_DMAREG);
 
 	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]);
+	*dmareg = TC_ESP_DMA_ADDR(esp->slot + DEC_SCSI_SRAM + ESP_TGT_DMA_SIZE);
+
 	esp_virt_buffer = vaddress;
 	scsi_current_length = length;
 }
 
 static void pmaz_dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length)
 {
-	memcpy((void *)scsi_pmaz_dma_ptrs_tc[scsi_cur_buff], KSEG0ADDR((void *) vaddress), length);
+	volatile int *dmareg = (volatile int *) ( esp->slot + DEC_SCSI_DMAREG );
+
+	memcpy((void *) (esp->slot + DEC_SCSI_SRAM + ESP_TGT_DMA_SIZE),
+			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]);
+	*dmareg = TC_ESP_DMAR_WRITE | 
+		TC_ESP_DMA_ADDR(esp->slot + DEC_SCSI_SRAM + ESP_TGT_DMA_SIZE);
 
 }
 
@@ -524,18 +520,9 @@
 	}
 }
 
-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));
 }
 
-#endif
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/dpt/dpt_osdutil.h linux/drivers/scsi/dpt/dpt_osdutil.h
--- v2.4.9/linux/drivers/scsi/dpt/dpt_osdutil.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/dpt/dpt_osdutil.h	Fri Sep  7 09:28:38 2001
@@ -0,0 +1,358 @@
+/*	BSDI osd_util.h,v 1.8 1998/06/03 19:14:58 karels Exp	*/
+
+/*
+ * Copyright (c) 1996-1999 Distributed Processing Technology Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source form, with or without modification, are
+ * permitted provided that redistributions of source code must retain the
+ * above copyright notice, this list of conditions and the following disclaimer.
+ *
+ * This software is provided `as is' by Distributed Processing Technology and
+ * any express or implied warranties, including, but not limited to, the
+ * implied warranties of merchantability and fitness for a particular purpose,
+ * are disclaimed. In no event shall Distributed Processing Technology be
+ * liable for any direct, indirect, incidental, special, exemplary or
+ * consequential damages (including, but not limited to, procurement of
+ * substitute goods or services; loss of use, data, or profits; or business
+ * interruptions) however caused and on any theory of liability, whether in
+ * contract, strict liability, or tort (including negligence or otherwise)
+ * arising in any way out of the use of this driver software, even if advised
+ * of the possibility of such damage.
+ *
+ */
+
+#ifndef         __OSD_UTIL_H
+#define         __OSD_UTIL_H
+
+/*File - OSD_UTIL.H
+ ****************************************************************************
+ *
+ *Description:
+ *
+ *      This file contains defines and function prototypes that are
+ *operating system dependent.  The resources defined in this file
+ *are not specific to any particular application.
+ *
+ *Copyright Distributed Processing Technology, Corp.
+ *        140 Candace Dr.
+ *        Maitland, Fl. 32751   USA
+ *        Phone: (407) 830-5522  Fax: (407) 260-5366
+ *        All Rights Reserved
+ *
+ *Author:       Doug Anderson
+ *Date:         1/7/94
+ *
+ *Editors:
+ *
+ *Remarks:
+ *
+ *
+ *****************************************************************************/
+
+
+/*Definitions - Defines & Constants ----------------------------------------- */
+
+/*----------------------------- */
+/* Operating system selections: */
+/*----------------------------- */
+
+/*#define               _DPT_MSDOS      */
+/*#define               _DPT_WIN_3X     */
+/*#define               _DPT_WIN_4X     */
+/*#define               _DPT_WIN_NT     */
+/*#define               _DPT_NETWARE    */
+/*#define               _DPT_OS2        */
+/*#define               _DPT_SCO        */
+/*#define               _DPT_UNIXWARE   */
+/*#define               _DPT_SOLARIS    */
+/*#define               _DPT_NEXTSTEP   */
+/*#define               _DPT_BANYAN     */
+
+/*-------------------------------- */
+/* Include the OS specific defines */
+/*-------------------------------- */
+
+/*#define       OS_SELECTION    From Above List */
+/*#define       SEMAPHORE_T     ??? */
+/*#define       DLL_HANDLE_T    ??? */
+
+#if (defined(KERNEL) && (defined(__FreeBSD__) || defined(__bsdi__)))
+# include        "i386/isa/dpt_osd_defs.h"
+#else
+# include        "osd_defs.h"
+#endif
+
+#ifndef DPT_UNALIGNED
+   #define      DPT_UNALIGNED
+#endif
+
+#ifndef DPT_EXPORT
+   #define      DPT_EXPORT
+#endif
+
+#ifndef DPT_IMPORT
+   #define      DPT_IMPORT
+#endif
+
+#ifndef DPT_RUNTIME_IMPORT
+   #define      DPT_RUNTIME_IMPORT  DPT_IMPORT
+#endif
+
+/*--------------------- */
+/* OS dependent defines */
+/*--------------------- */
+
+#if defined (_DPT_MSDOS) || defined (_DPT_WIN_3X)
+   #define      _DPT_16_BIT
+#else
+   #define      _DPT_32_BIT
+#endif
+
+#if defined (_DPT_SCO) || defined (_DPT_UNIXWARE) || defined (_DPT_SOLARIS) || defined (_DPT_AIX) || defined (SNI_MIPS) || defined (_DPT_BSDI) || defined (_DPT_FREE_BSD) || defined(_DPT_LINUX)
+   #define      _DPT_UNIX
+#endif
+
+#if defined (_DPT_WIN_3x) || defined (_DPT_WIN_4X) || defined (_DPT_WIN_NT) \
+	    || defined (_DPT_OS2)
+   #define      _DPT_DLL_SUPPORT
+#endif
+
+#if !defined (_DPT_MSDOS) && !defined (_DPT_WIN_3X) && !defined (_DPT_NETWARE)
+   #define      _DPT_PREEMPTIVE
+#endif
+
+#if !defined (_DPT_MSDOS) && !defined (_DPT_WIN_3X)
+   #define      _DPT_MULTI_THREADED
+#endif
+
+#if !defined (_DPT_MSDOS)
+   #define      _DPT_MULTI_TASKING
+#endif
+
+  /* These exist for platforms that   */
+  /* chunk when accessing mis-aligned */
+  /* data                             */
+#if defined (SNI_MIPS) || defined (_DPT_SOLARIS)
+   #if defined (_DPT_BIG_ENDIAN)
+	#if !defined (_DPT_STRICT_ALIGN)
+            #define _DPT_STRICT_ALIGN
+	#endif
+   #endif
+#endif
+
+  /* Determine if in C or C++ mode */
+#ifdef  __cplusplus
+   #define      _DPT_CPP
+#else
+   #define      _DPT_C
+#endif
+
+/*-------------------------------------------------------------------*/
+/* Under Solaris the compiler refuses to accept code like:           */
+/*   { {"DPT"}, 0, NULL .... },                                      */
+/* and complains about the {"DPT"} part by saying "cannot use { }    */
+/* to initialize char*".                                             */
+/*                                                                   */
+/* By defining these ugly macros we can get around this and also     */
+/* not have to copy and #ifdef large sections of code.  I know that  */
+/* these macros are *really* ugly, but they should help reduce       */
+/* maintenance in the long run.                                      */
+/*                                                                   */
+/*-------------------------------------------------------------------*/
+#if !defined (DPTSQO)
+   #if defined (_DPT_SOLARIS)
+      #define DPTSQO
+      #define DPTSQC
+   #else
+      #define DPTSQO {
+      #define DPTSQC }
+   #endif  /* solaris */
+#endif  /* DPTSQO */
+
+
+/*---------------------- */
+/* OS dependent typedefs */
+/*---------------------- */
+
+#if defined (_DPT_MSDOS) || defined (_DPT_SCO)
+   #define BYTE unsigned char
+   #define WORD unsigned short
+#endif
+
+#ifndef _DPT_TYPEDEFS
+   #define _DPT_TYPEDEFS
+   typedef unsigned char   uCHAR;
+   typedef unsigned short  uSHORT;
+   typedef unsigned int    uINT;
+   typedef unsigned long   uLONG;
+
+   typedef union {
+	 uCHAR        u8[4];
+	 uSHORT       u16[2];
+	 uLONG        u32;
+   } access_U;
+#endif
+
+#if !defined (NULL)
+   #define      NULL    0
+#endif
+
+
+/*Prototypes - function ----------------------------------------------------- */
+
+#ifdef  __cplusplus
+   extern "C" {         /* Declare all these functions as "C" functions */
+#endif
+
+/*------------------------ */
+/* Byte reversal functions */
+/*------------------------ */
+
+  /* Reverses the byte ordering of a 2 byte variable */
+#if (!defined(osdSwap2))
+ uSHORT       osdSwap2(DPT_UNALIGNED uSHORT *);
+#endif  // !osdSwap2
+
+  /* Reverses the byte ordering of a 4 byte variable and shifts left 8 bits */
+#if (!defined(osdSwap3))
+ uLONG        osdSwap3(DPT_UNALIGNED uLONG *);
+#endif  // !osdSwap3
+
+
+#ifdef  _DPT_NETWARE
+   #include "novpass.h" /* For DPT_Bswapl() prototype */
+	/* Inline the byte swap */
+   #ifdef __cplusplus
+	 inline uLONG osdSwap4(uLONG *inLong) {
+	 return *inLong = DPT_Bswapl(*inLong);
+	 }
+   #else
+	 #define osdSwap4(inLong)       DPT_Bswapl(inLong)
+   #endif  // cplusplus
+#else
+	/* Reverses the byte ordering of a 4 byte variable */
+# if (!defined(osdSwap4))
+   uLONG        osdSwap4(DPT_UNALIGNED uLONG *);
+# endif  // !osdSwap4
+
+  /* The following functions ALWAYS swap regardless of the *
+   * presence of DPT_BIG_ENDIAN                            */
+
+   uSHORT       trueSwap2(DPT_UNALIGNED uSHORT *);
+   uLONG        trueSwap4(DPT_UNALIGNED uLONG *);
+
+#endif  // netware
+
+
+/*-------------------------------------*
+ * Network order swap functions        *
+ *                                     *
+ * These functions/macros will be used *
+ * by the structure insert()/extract() *
+ * functions.                          *
+ *
+ * We will enclose all structure       *
+ * portability modifications inside    *
+ * #ifdefs.  When we are ready, we     *
+ * will #define DPT_PORTABLE to begin  *
+ * using the modifications.            *
+ *-------------------------------------*/
+uLONG	netSwap4(uLONG val);
+
+#if defined (_DPT_BIG_ENDIAN)
+
+// for big-endian we need to swap
+
+#ifndef NET_SWAP_2
+#define NET_SWAP_2(x) (((x) >> 8) | ((x) << 8))
+#endif  // NET_SWAP_2
+
+#ifndef NET_SWAP_4
+#define NET_SWAP_4(x) netSwap4((x))
+#endif  // NET_SWAP_4
+
+#else
+
+// for little-endian we don't need to do anything
+
+#ifndef NET_SWAP_2
+#define NET_SWAP_2(x) (x)
+#endif  // NET_SWAP_2
+
+#ifndef NET_SWAP_4
+#define NET_SWAP_4(x) (x)
+#endif  // NET_SWAP_4
+
+#endif  // big endian
+
+
+
+/*----------------------------------- */
+/* Run-time loadable module functions */
+/*----------------------------------- */
+
+  /* Loads the specified run-time loadable DLL */
+DLL_HANDLE_T    osdLoadModule(uCHAR *);
+  /* Unloads the specified run-time loadable DLL */
+uSHORT          osdUnloadModule(DLL_HANDLE_T);
+  /* Returns a pointer to a function inside a run-time loadable DLL */
+void *          osdGetFnAddr(DLL_HANDLE_T,uCHAR *);
+
+/*--------------------------------------- */
+/* Mutually exclusive semaphore functions */
+/*--------------------------------------- */
+
+  /* Create a named semaphore */
+SEMAPHORE_T     osdCreateNamedSemaphore(char *);
+  /* Create a mutually exlusive semaphore */
+SEMAPHORE_T     osdCreateSemaphore(void);
+	/* create an event semaphore */
+SEMAPHORE_T              osdCreateEventSemaphore(void);
+	/* create a named event semaphore */
+SEMAPHORE_T             osdCreateNamedEventSemaphore(char *);
+
+  /* Destroy the specified mutually exclusive semaphore object */
+uSHORT          osdDestroySemaphore(SEMAPHORE_T);
+  /* Request access to the specified mutually exclusive semaphore */
+uLONG           osdRequestSemaphore(SEMAPHORE_T,uLONG);
+  /* Release access to the specified mutually exclusive semaphore */
+uSHORT          osdReleaseSemaphore(SEMAPHORE_T);
+	/* wait for a event to happen */
+uLONG                            osdWaitForEventSemaphore(SEMAPHORE_T, uLONG);
+	/* signal an event */
+uLONG                            osdSignalEventSemaphore(SEMAPHORE_T);
+	/* reset the event */
+uLONG                            osdResetEventSemaphore(SEMAPHORE_T);
+
+/*----------------- */
+/* Thread functions */
+/*----------------- */
+
+  /* Releases control to the task switcher in non-preemptive */
+  /* multitasking operating systems. */
+void            osdSwitchThreads(void);
+
+  /* Starts a thread function */
+uLONG   osdStartThread(void *,void *);
+
+/* what is my thread id */
+uLONG osdGetThreadID(void);
+
+/* wakes up the specifed thread */
+void osdWakeThread(uLONG);
+
+/* osd sleep for x miliseconds */
+void osdSleep(uLONG);
+
+#define DPT_THREAD_PRIORITY_LOWEST 0x00
+#define DPT_THREAD_PRIORITY_NORMAL 0x01
+#define DPT_THREAD_PRIORITY_HIGHEST 0x02
+
+uCHAR osdSetThreadPriority(uLONG tid, uCHAR priority);
+
+#ifdef __cplusplus
+   }    /* end the xtern "C" declaration */
+#endif
+
+#endif  /* osd_util_h */
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/dpt/dpti_i2o.h linux/drivers/scsi/dpt/dpti_i2o.h
--- v2.4.9/linux/drivers/scsi/dpt/dpti_i2o.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/dpt/dpti_i2o.h	Fri Sep  7 09:28:38 2001
@@ -0,0 +1,464 @@
+#ifndef _SCSI_I2O_H
+#define _SCSI_I2O_H
+
+/* I2O kernel space accessible structures/APIs
+ *
+ * (c) Copyright 1999, 2000 Red Hat Software
+ *
+ * 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 header file defined the I2O APIs/structures for use by
+ * the I2O kernel modules.
+ *
+ */
+
+#ifdef __KERNEL__       /* This file to be included by kernel only */
+
+#include <linux/i2o-dev.h>
+
+#include <asm/semaphore.h> /* Needed for MUTEX init macros */
+#include <linux/config.h>
+#include <linux/notifier.h>
+#include <asm/atomic.h>
+
+
+/*
+ *	Tunable parameters first
+ */
+
+/* How many different OSM's are we allowing */ 
+#define MAX_I2O_MODULES		64
+
+#define I2O_EVT_CAPABILITY_OTHER		0x01
+#define I2O_EVT_CAPABILITY_CHANGED		0x02
+
+#define I2O_EVT_SENSOR_STATE_CHANGED		0x01
+
+//#ifdef __KERNEL__   /* ioctl stuff only thing exported to users */
+
+#define I2O_MAX_MANAGERS	4
+
+#include <asm/semaphore.h> /* Needed for MUTEX init macros */
+
+/*
+ *	I2O Interface Objects
+ */
+
+#include <linux/config.h>
+#include <linux/notifier.h>
+#include <asm/atomic.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
+
+#define DECLARE_MUTEX(name) struct semaphore name=MUTEX
+
+typedef struct wait_queue *adpt_wait_queue_head_t;
+#define ADPT_DECLARE_WAIT_QUEUE_HEAD(wait) adpt_wait_queue_head_t wait = NULL
+typedef struct wait_queue adpt_wait_queue_t;
+#else
+
+#include <linux/wait.h>
+typedef wait_queue_head_t adpt_wait_queue_head_t;
+#define ADPT_DECLARE_WAIT_QUEUE_HEAD(wait) DECLARE_WAIT_QUEUE_HEAD(wait)
+typedef wait_queue_t adpt_wait_queue_t;
+
+#endif
+/*
+ * message structures
+ */
+
+struct i2o_message
+{
+	u8	version_offset;
+	u8	flags;
+	u16	size;
+	u32	target_tid:12;
+	u32	init_tid:12;
+	u32	function:8;	
+	u32	initiator_context;
+	/* List follows */
+};
+
+struct adpt_device;
+struct _adpt_hba;
+struct i2o_device
+{
+	struct i2o_device *next;	/* Chain */
+	struct i2o_device *prev;
+
+	char dev_name[8];		/* linux /dev name if available */
+	i2o_lct_entry lct_data;/* Device LCT information */
+	u32 flags;		
+	struct proc_dir_entry* proc_entry;	/* /proc dir */
+	struct adpt_device *owner;
+	struct _adpt_hba *controller;	/* Controlling IOP */
+};
+
+/*
+ *	Each I2O controller has one of these objects
+ */
+ 
+struct i2o_controller
+{
+	char name[16];
+	int unit;
+	int type;
+	int enabled;
+
+	struct notifier_block *event_notifer;	/* Events */
+	atomic_t users;
+	struct i2o_device *devices;		/* I2O device chain */
+	struct i2o_controller *next;		/* Controller chain */
+
+};
+
+/*
+ * I2O System table entry
+ */
+struct i2o_sys_tbl_entry
+{
+	u16	org_id;
+	u16	reserved1;
+	u32	iop_id:12;
+	u32	reserved2:20;
+	u16	seg_num:12;
+	u16 	i2o_version:4;
+	u8 	iop_state;
+	u8 	msg_type;
+	u16	frame_size;
+	u16	reserved3;
+	u32	last_changed;
+	u32	iop_capabilities;
+	u32	inbound_low;
+	u32	inbound_high;
+};
+
+struct i2o_sys_tbl
+{
+	u8 	num_entries;
+	u8 	version;
+	u16 	reserved1;
+	u32	change_ind;
+	u32	reserved2;
+	u32	reserved3;
+	struct i2o_sys_tbl_entry iops[0];
+};	
+
+/*
+ *	I2O classes / subclasses
+ */
+
+/*  Class ID and Code Assignments
+ *  (LCT.ClassID.Version field)
+ */
+#define    I2O_CLASS_VERSION_10                        0x00
+#define    I2O_CLASS_VERSION_11                        0x01
+
+/*  Class code names
+ *  (from v1.5 Table 6-1 Class Code Assignments.)
+ */
+ 
+#define    I2O_CLASS_EXECUTIVE                         0x000
+#define    I2O_CLASS_DDM                               0x001
+#define    I2O_CLASS_RANDOM_BLOCK_STORAGE              0x010
+#define    I2O_CLASS_SEQUENTIAL_STORAGE                0x011
+#define    I2O_CLASS_LAN                               0x020
+#define    I2O_CLASS_WAN                               0x030
+#define    I2O_CLASS_FIBRE_CHANNEL_PORT                0x040
+#define    I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL          0x041
+#define    I2O_CLASS_SCSI_PERIPHERAL                   0x051
+#define    I2O_CLASS_ATE_PORT                          0x060
+#define    I2O_CLASS_ATE_PERIPHERAL                    0x061
+#define    I2O_CLASS_FLOPPY_CONTROLLER                 0x070
+#define    I2O_CLASS_FLOPPY_DEVICE                     0x071
+#define    I2O_CLASS_BUS_ADAPTER_PORT                  0x080
+#define    I2O_CLASS_PEER_TRANSPORT_AGENT              0x090
+#define    I2O_CLASS_PEER_TRANSPORT                    0x091
+
+/*  Rest of 0x092 - 0x09f reserved for peer-to-peer classes
+ */
+ 
+#define    I2O_CLASS_MATCH_ANYCLASS                    0xffffffff
+
+/*  Subclasses
+ */
+
+#define    I2O_SUBCLASS_i960                           0x001
+#define    I2O_SUBCLASS_HDM                            0x020
+#define    I2O_SUBCLASS_ISM                            0x021
+ 
+/* Operation functions */
+
+#define I2O_PARAMS_FIELD_GET	0x0001
+#define I2O_PARAMS_LIST_GET	0x0002
+#define I2O_PARAMS_MORE_GET	0x0003
+#define I2O_PARAMS_SIZE_GET	0x0004
+#define I2O_PARAMS_TABLE_GET	0x0005
+#define I2O_PARAMS_FIELD_SET	0x0006
+#define I2O_PARAMS_LIST_SET	0x0007
+#define I2O_PARAMS_ROW_ADD	0x0008
+#define I2O_PARAMS_ROW_DELETE	0x0009
+#define I2O_PARAMS_TABLE_CLEAR	0x000A
+
+/*
+ *	I2O serial number conventions / formats
+ *	(circa v1.5)
+ */
+
+#define    I2O_SNFORMAT_UNKNOWN                        0
+#define    I2O_SNFORMAT_BINARY                         1
+#define    I2O_SNFORMAT_ASCII                          2
+#define    I2O_SNFORMAT_UNICODE                        3
+#define    I2O_SNFORMAT_LAN48_MAC                      4
+#define    I2O_SNFORMAT_WAN                            5
+
+/* Plus new in v2.0 (Yellowstone pdf doc)
+ */
+
+#define    I2O_SNFORMAT_LAN64_MAC                      6
+#define    I2O_SNFORMAT_DDM                            7
+#define    I2O_SNFORMAT_IEEE_REG64                     8
+#define    I2O_SNFORMAT_IEEE_REG128                    9
+#define    I2O_SNFORMAT_UNKNOWN2                       0xff
+
+/* Transaction Reply Lists (TRL) Control Word structure */
+
+#define TRL_SINGLE_FIXED_LENGTH		0x00
+#define TRL_SINGLE_VARIABLE_LENGTH	0x40
+#define TRL_MULTIPLE_FIXED_LENGTH	0x80
+
+/*
+ *	Messaging API values
+ */
+ 
+#define	I2O_CMD_ADAPTER_ASSIGN		0xB3
+#define	I2O_CMD_ADAPTER_READ		0xB2
+#define	I2O_CMD_ADAPTER_RELEASE		0xB5
+#define	I2O_CMD_BIOS_INFO_SET		0xA5
+#define	I2O_CMD_BOOT_DEVICE_SET		0xA7
+#define	I2O_CMD_CONFIG_VALIDATE		0xBB
+#define	I2O_CMD_CONN_SETUP		0xCA
+#define	I2O_CMD_DDM_DESTROY		0xB1
+#define	I2O_CMD_DDM_ENABLE		0xD5
+#define	I2O_CMD_DDM_QUIESCE		0xC7
+#define	I2O_CMD_DDM_RESET		0xD9
+#define	I2O_CMD_DDM_SUSPEND		0xAF
+#define	I2O_CMD_DEVICE_ASSIGN		0xB7
+#define	I2O_CMD_DEVICE_RELEASE		0xB9
+#define	I2O_CMD_HRT_GET			0xA8
+#define	I2O_CMD_ADAPTER_CLEAR		0xBE
+#define	I2O_CMD_ADAPTER_CONNECT		0xC9
+#define	I2O_CMD_ADAPTER_RESET		0xBD
+#define	I2O_CMD_LCT_NOTIFY		0xA2
+#define	I2O_CMD_OUTBOUND_INIT		0xA1
+#define	I2O_CMD_PATH_ENABLE		0xD3
+#define	I2O_CMD_PATH_QUIESCE		0xC5
+#define	I2O_CMD_PATH_RESET		0xD7
+#define	I2O_CMD_STATIC_MF_CREATE	0xDD
+#define	I2O_CMD_STATIC_MF_RELEASE	0xDF
+#define	I2O_CMD_STATUS_GET		0xA0
+#define	I2O_CMD_SW_DOWNLOAD		0xA9
+#define	I2O_CMD_SW_UPLOAD		0xAB
+#define	I2O_CMD_SW_REMOVE		0xAD
+#define	I2O_CMD_SYS_ENABLE		0xD1
+#define	I2O_CMD_SYS_MODIFY		0xC1
+#define	I2O_CMD_SYS_QUIESCE		0xC3
+#define	I2O_CMD_SYS_TAB_SET		0xA3
+
+#define I2O_CMD_UTIL_NOP		0x00
+#define I2O_CMD_UTIL_ABORT		0x01
+#define I2O_CMD_UTIL_CLAIM		0x09
+#define I2O_CMD_UTIL_RELEASE		0x0B
+#define I2O_CMD_UTIL_PARAMS_GET		0x06
+#define I2O_CMD_UTIL_PARAMS_SET		0x05
+#define I2O_CMD_UTIL_EVT_REGISTER	0x13
+#define I2O_CMD_UTIL_EVT_ACK		0x14
+#define I2O_CMD_UTIL_CONFIG_DIALOG	0x10
+#define I2O_CMD_UTIL_DEVICE_RESERVE	0x0D
+#define I2O_CMD_UTIL_DEVICE_RELEASE	0x0F
+#define I2O_CMD_UTIL_LOCK		0x17
+#define I2O_CMD_UTIL_LOCK_RELEASE	0x19
+#define I2O_CMD_UTIL_REPLY_FAULT_NOTIFY	0x15
+
+#define I2O_CMD_SCSI_EXEC		0x81
+#define I2O_CMD_SCSI_ABORT		0x83
+#define I2O_CMD_SCSI_BUSRESET		0x27
+
+#define I2O_CMD_BLOCK_READ		0x30
+#define I2O_CMD_BLOCK_WRITE		0x31
+#define I2O_CMD_BLOCK_CFLUSH		0x37
+#define I2O_CMD_BLOCK_MLOCK		0x49
+#define I2O_CMD_BLOCK_MUNLOCK		0x4B
+#define I2O_CMD_BLOCK_MMOUNT		0x41
+#define I2O_CMD_BLOCK_MEJECT		0x43
+
+#define I2O_PRIVATE_MSG			0xFF
+
+/*
+ *	Init Outbound Q status 
+ */
+ 
+#define I2O_CMD_OUTBOUND_INIT_IN_PROGRESS	0x01
+#define I2O_CMD_OUTBOUND_INIT_REJECTED		0x02
+#define I2O_CMD_OUTBOUND_INIT_FAILED		0x03
+#define I2O_CMD_OUTBOUND_INIT_COMPLETE		0x04
+
+/*
+ *	I2O Get Status State values 
+ */
+
+#define	ADAPTER_STATE_INITIALIZING		0x01
+#define	ADAPTER_STATE_RESET			0x02
+#define	ADAPTER_STATE_HOLD			0x04
+#define ADAPTER_STATE_READY			0x05
+#define	ADAPTER_STATE_OPERATIONAL		0x08
+#define	ADAPTER_STATE_FAILED			0x10
+#define	ADAPTER_STATE_FAULTED			0x11
+	
+/* I2O API function return values */
+
+#define I2O_RTN_NO_ERROR			0
+#define I2O_RTN_NOT_INIT			1
+#define I2O_RTN_FREE_Q_EMPTY			2
+#define I2O_RTN_TCB_ERROR			3
+#define I2O_RTN_TRANSACTION_ERROR		4
+#define I2O_RTN_ADAPTER_ALREADY_INIT		5
+#define I2O_RTN_MALLOC_ERROR			6
+#define I2O_RTN_ADPTR_NOT_REGISTERED		7
+#define I2O_RTN_MSG_REPLY_TIMEOUT		8
+#define I2O_RTN_NO_STATUS			9
+#define I2O_RTN_NO_FIRM_VER			10
+#define	I2O_RTN_NO_LINK_SPEED			11
+
+/* Reply message status defines for all messages */
+
+#define I2O_REPLY_STATUS_SUCCESS                    	0x00
+#define I2O_REPLY_STATUS_ABORT_DIRTY                	0x01
+#define I2O_REPLY_STATUS_ABORT_NO_DATA_TRANSFER     	0x02
+#define	I2O_REPLY_STATUS_ABORT_PARTIAL_TRANSFER		0x03
+#define	I2O_REPLY_STATUS_ERROR_DIRTY			0x04
+#define	I2O_REPLY_STATUS_ERROR_NO_DATA_TRANSFER		0x05
+#define	I2O_REPLY_STATUS_ERROR_PARTIAL_TRANSFER		0x06
+#define	I2O_REPLY_STATUS_PROCESS_ABORT_DIRTY		0x08
+#define	I2O_REPLY_STATUS_PROCESS_ABORT_NO_DATA_TRANSFER	0x09
+#define	I2O_REPLY_STATUS_PROCESS_ABORT_PARTIAL_TRANSFER	0x0A
+#define	I2O_REPLY_STATUS_TRANSACTION_ERROR		0x0B
+#define	I2O_REPLY_STATUS_PROGRESS_REPORT		0x80
+
+/* Status codes and Error Information for Parameter functions */
+
+#define I2O_PARAMS_STATUS_SUCCESS		0x00
+#define I2O_PARAMS_STATUS_BAD_KEY_ABORT		0x01
+#define I2O_PARAMS_STATUS_BAD_KEY_CONTINUE   	0x02
+#define I2O_PARAMS_STATUS_BUFFER_FULL		0x03
+#define I2O_PARAMS_STATUS_BUFFER_TOO_SMALL	0x04
+#define I2O_PARAMS_STATUS_FIELD_UNREADABLE	0x05
+#define I2O_PARAMS_STATUS_FIELD_UNWRITEABLE	0x06
+#define I2O_PARAMS_STATUS_INSUFFICIENT_FIELDS	0x07
+#define I2O_PARAMS_STATUS_INVALID_GROUP_ID	0x08
+#define I2O_PARAMS_STATUS_INVALID_OPERATION	0x09
+#define I2O_PARAMS_STATUS_NO_KEY_FIELD		0x0A
+#define I2O_PARAMS_STATUS_NO_SUCH_FIELD		0x0B
+#define I2O_PARAMS_STATUS_NON_DYNAMIC_GROUP	0x0C
+#define I2O_PARAMS_STATUS_OPERATION_ERROR	0x0D
+#define I2O_PARAMS_STATUS_SCALAR_ERROR		0x0E
+#define I2O_PARAMS_STATUS_TABLE_ERROR		0x0F
+#define I2O_PARAMS_STATUS_WRONG_GROUP_TYPE	0x10
+
+/* DetailedStatusCode defines for Executive, DDM, Util and Transaction error
+ * messages: Table 3-2 Detailed Status Codes.*/
+
+#define I2O_DSC_SUCCESS                        0x0000
+#define I2O_DSC_BAD_KEY                        0x0002
+#define I2O_DSC_TCL_ERROR                      0x0003
+#define I2O_DSC_REPLY_BUFFER_FULL              0x0004
+#define I2O_DSC_NO_SUCH_PAGE                   0x0005
+#define I2O_DSC_INSUFFICIENT_RESOURCE_SOFT     0x0006
+#define I2O_DSC_INSUFFICIENT_RESOURCE_HARD     0x0007
+#define I2O_DSC_CHAIN_BUFFER_TOO_LARGE         0x0009
+#define I2O_DSC_UNSUPPORTED_FUNCTION           0x000A
+#define I2O_DSC_DEVICE_LOCKED                  0x000B
+#define I2O_DSC_DEVICE_RESET                   0x000C
+#define I2O_DSC_INAPPROPRIATE_FUNCTION         0x000D
+#define I2O_DSC_INVALID_INITIATOR_ADDRESS      0x000E
+#define I2O_DSC_INVALID_MESSAGE_FLAGS          0x000F
+#define I2O_DSC_INVALID_OFFSET                 0x0010
+#define I2O_DSC_INVALID_PARAMETER              0x0011
+#define I2O_DSC_INVALID_REQUEST                0x0012
+#define I2O_DSC_INVALID_TARGET_ADDRESS         0x0013
+#define I2O_DSC_MESSAGE_TOO_LARGE              0x0014
+#define I2O_DSC_MESSAGE_TOO_SMALL              0x0015
+#define I2O_DSC_MISSING_PARAMETER              0x0016
+#define I2O_DSC_TIMEOUT                        0x0017
+#define I2O_DSC_UNKNOWN_ERROR                  0x0018
+#define I2O_DSC_UNKNOWN_FUNCTION               0x0019
+#define I2O_DSC_UNSUPPORTED_VERSION            0x001A
+#define I2O_DSC_DEVICE_BUSY                    0x001B
+#define I2O_DSC_DEVICE_NOT_AVAILABLE           0x001C
+
+/* Device Claim Types */
+#define	I2O_CLAIM_PRIMARY					0x01000000
+#define	I2O_CLAIM_MANAGEMENT					0x02000000
+#define	I2O_CLAIM_AUTHORIZED					0x03000000
+#define	I2O_CLAIM_SECONDARY					0x04000000
+ 
+/* Message header defines for VersionOffset */
+#define I2OVER15	0x0001
+#define I2OVER20	0x0002
+/* Default is 1.5, FIXME: Need support for both 1.5 and 2.0 */
+#define I2OVERSION	I2OVER15
+#define SGL_OFFSET_0    I2OVERSION
+#define SGL_OFFSET_4    (0x0040 | I2OVERSION)
+#define SGL_OFFSET_5    (0x0050 | I2OVERSION)
+#define SGL_OFFSET_6    (0x0060 | I2OVERSION)
+#define SGL_OFFSET_7    (0x0070 | I2OVERSION)
+#define SGL_OFFSET_8    (0x0080 | I2OVERSION)
+#define SGL_OFFSET_9    (0x0090 | I2OVERSION)
+#define SGL_OFFSET_10   (0x00A0 | I2OVERSION)
+#define SGL_OFFSET_12   (0x00C0 | I2OVERSION)
+
+#define TRL_OFFSET_5    (0x0050 | I2OVERSION)
+#define TRL_OFFSET_6    (0x0060 | I2OVERSION)
+
+ /* msg header defines for MsgFlags */
+#define MSG_STATIC	0x0100
+#define MSG_64BIT_CNTXT	0x0200
+#define MSG_MULTI_TRANS	0x1000
+#define MSG_FAIL	0x2000
+#define MSG_LAST	0x4000
+#define MSG_REPLY	0x8000
+
+ /* minimum size msg */
+#define THREE_WORD_MSG_SIZE	0x00030000
+#define FOUR_WORD_MSG_SIZE	0x00040000
+#define FIVE_WORD_MSG_SIZE	0x00050000
+#define SIX_WORD_MSG_SIZE	0x00060000
+#define SEVEN_WORD_MSG_SIZE	0x00070000
+#define EIGHT_WORD_MSG_SIZE	0x00080000
+#define NINE_WORD_MSG_SIZE	0x00090000
+#define TEN_WORD_MSG_SIZE	0x000A0000
+#define I2O_MESSAGE_SIZE(x)	((x)<<16)
+
+
+/* Special TID Assignments */
+
+#define ADAPTER_TID		0
+#define HOST_TID		1
+
+#define MSG_FRAME_SIZE		128
+#define NMBR_MSG_FRAMES		128
+
+#define MSG_POOL_SIZE		16384
+
+#define I2O_POST_WAIT_OK	0
+#define I2O_POST_WAIT_TIMEOUT	-ETIMEDOUT
+
+
+#endif /* __KERNEL__ */
+
+#endif /* _SCSI_I2O_H */
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/dpt/dpti_ioctl.h linux/drivers/scsi/dpt/dpti_ioctl.h
--- v2.4.9/linux/drivers/scsi/dpt/dpti_ioctl.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/dpt/dpti_ioctl.h	Fri Sep  7 09:28:38 2001
@@ -0,0 +1,139 @@
+/***************************************************************************
+                          dpti_ioctl.h  -  description
+                             -------------------
+    begin                : Thu Sep 7 2000
+    copyright            : (C) 2001 by Adaptec
+    email                : deanna_bonds@adaptec.com
+
+    See README.dpti for history, notes, license info, and credits
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 file is generated from  osd_unix.h                                 *
+ * *************************************************************************/
+
+#ifndef _dpti_ioctl_h
+#define _dpti_ioctl_h
+
+// IOCTL interface commands
+
+#ifndef _IOWR
+# define _IOWR(x,y,z)	(((x)<<8)|y)
+#endif
+#ifndef _IOW
+# define _IOW(x,y,z)	(((x)<<8)|y)
+#endif
+#ifndef _IOR
+# define _IOR(x,y,z)	(((x)<<8)|y)
+#endif
+#ifndef _IO
+# define _IO(x,y)	(((x)<<8)|y)
+#endif
+/* EATA PassThrough Command	*/
+#define EATAUSRCMD      _IOWR('D',65,EATA_CP)
+/* Set Debug Level If Enabled	*/
+#define DPT_DEBUG       _IOW('D',66,int)
+/* Get Signature Structure	*/
+#define DPT_SIGNATURE   _IOR('D',67,dpt_sig_S)
+#if defined __bsdi__
+#define DPT_SIGNATURE_PACKED   _IOR('D',67,dpt_sig_S_Packed)
+#endif
+/* Get Number Of DPT Adapters	*/
+#define DPT_NUMCTRLS    _IOR('D',68,int)
+/* Get Adapter Info Structure	*/
+#define DPT_CTRLINFO    _IOR('D',69,CtrlInfo)
+/* Get Statistics If Enabled	*/
+#define DPT_STATINFO    _IO('D',70)
+/* Clear Stats If Enabled	*/
+#define DPT_CLRSTAT     _IO('D',71)
+/* Get System Info Structure	*/
+#define DPT_SYSINFO     _IOR('D',72,sysInfo_S)
+/* Set Timeout Value		*/
+#define DPT_TIMEOUT     _IO('D',73)
+/* Get config Data  		*/
+#define DPT_CONFIG      _IO('D',74)
+/* Get Blink LED Code	        */
+#define DPT_BLINKLED    _IOR('D',75,int)
+/* Get Statistical information (if available) */
+#define DPT_STATS_INFO        _IOR('D',80,STATS_DATA)
+/* Clear the statistical information          */
+#define DPT_STATS_CLEAR       _IO('D',81)
+/* Get Performance metrics */
+#define DPT_PERF_INFO        _IOR('D',82,dpt_perf_t)
+/* Send an I2O command */
+#define I2OUSRCMD	_IO('D',76)
+/* Inform driver to re-acquire LCT information */
+#define I2ORESCANCMD	_IO('D',77)
+/* Inform driver to reset adapter */
+#define I2ORESETCMD	_IO('D',78)
+/* See if the target is mounted */
+#define DPT_TARGET_BUSY	_IOR('D',79, TARGET_BUSY_T)
+
+
+  /* Structure Returned From Get Controller Info                             */
+
+typedef struct {
+	uCHAR    state;            /* Operational state               */
+	uCHAR    id;               /* Host adapter SCSI id            */
+	int      vect;             /* Interrupt vector number         */
+	int      base;             /* Base I/O address                */
+	int      njobs;            /* # of jobs sent to HA            */
+	int      qdepth;           /* Controller queue depth.         */
+	int      wakebase;         /* mpx wakeup base index.          */
+	uLONG    SGsize;           /* Scatter/Gather list size.       */
+	unsigned heads;            /* heads for drives on cntlr.      */
+	unsigned sectors;          /* sectors for drives on cntlr.    */
+	uCHAR    do_drive32;       /* Flag for Above 16 MB Ability    */
+	uCHAR    BusQuiet;         /* SCSI Bus Quiet Flag             */
+	char     idPAL[4];         /* 4 Bytes Of The ID Pal           */
+	uCHAR    primary;          /* 1 For Primary, 0 For Secondary  */
+	uCHAR    eataVersion;      /* EATA Version                    */
+	uLONG    cpLength;         /* EATA Command Packet Length      */
+	uLONG    spLength;         /* EATA Status Packet Length       */
+	uCHAR    drqNum;           /* DRQ Index (0,5,6,7)             */ 
+	uCHAR    flag1;            /* EATA Flags 1 (Byte 9)           */
+	uCHAR    flag2;            /* EATA Flags 2 (Byte 30)          */
+} CtrlInfo;
+
+typedef struct {
+	uSHORT length;		// Remaining length of this
+	uSHORT drvrHBAnum;	// Relative HBA # used by the driver
+	uLONG baseAddr;		// Base I/O address
+	uSHORT blinkState;	// Blink LED state (0=Not in blink LED)
+	uCHAR pciBusNum;	// PCI Bus # (Optional)
+	uCHAR pciDeviceNum;	// PCI Device # (Optional)
+	uSHORT hbaFlags;	// Miscellaneous HBA flags
+	uSHORT Interrupt;	// Interrupt set for this device.
+#   if (defined(_DPT_ARC))
+	uLONG baseLength;
+	ADAPTER_OBJECT *AdapterObject;
+	LARGE_INTEGER DmaLogicalAddress;
+	PVOID DmaVirtualAddress;
+	LARGE_INTEGER ReplyLogicalAddress;
+	PVOID ReplyVirtualAddress;
+#   else
+	uLONG reserved1;	// Reserved for future expansion
+	uLONG reserved2;	// Reserved for future expansion
+	uLONG reserved3;	// Reserved for future expansion
+#   endif
+} drvrHBAinfo_S;
+
+typedef struct TARGET_BUSY
+{
+  uLONG channel;
+  uLONG id;
+  uLONG lun;
+  uLONG isBusy;
+} TARGET_BUSY_T;
+
+#endif
+
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/dpt/dptsig.h linux/drivers/scsi/dpt/dptsig.h
--- v2.4.9/linux/drivers/scsi/dpt/dptsig.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/dpt/dptsig.h	Fri Sep  7 09:28:38 2001
@@ -0,0 +1,339 @@
+/*	BSDI dptsig.h,v 1.7 1998/06/03 19:15:00 karels Exp	*/
+
+/*
+ * Copyright (c) 1996-1999 Distributed Processing Technology Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source form, with or without modification, are
+ * permitted provided that redistributions of source code must retain the
+ * above copyright notice, this list of conditions and the following disclaimer.
+ *
+ * This software is provided `as is' by Distributed Processing Technology and
+ * any express or implied warranties, including, but not limited to, the
+ * implied warranties of merchantability and fitness for a particular purpose,
+ * are disclaimed. In no event shall Distributed Processing Technology be
+ * liable for any direct, indirect, incidental, special, exemplary or
+ * consequential damages (including, but not limited to, procurement of
+ * substitute goods or services; loss of use, data, or profits; or business
+ * interruptions) however caused and on any theory of liability, whether in
+ * contract, strict liability, or tort (including negligence or otherwise)
+ * arising in any way out of the use of this driver software, even if advised
+ * of the possibility of such damage.
+ *
+ */
+
+#ifndef __DPTSIG_H_
+#define __DPTSIG_H_
+#ifdef _SINIX_ADDON
+#include "dpt.h"
+#endif
+/* DPT SIGNATURE SPEC AND HEADER FILE                           */
+/* Signature Version 1 (sorry no 'A')                           */
+
+/* to make sure we are talking the same size under all OS's     */
+typedef unsigned char sigBYTE;
+typedef unsigned short sigWORD;
+#if (defined(_MULTI_DATAMODEL) && defined(sun) && !defined(_ILP32))
+typedef uint32_t sigLONG;
+#else
+typedef unsigned long sigLONG;
+#endif
+
+/*
+ * use sigWORDLittleEndian for:
+ *  dsCapabilities
+ *  dsDeviceSupp
+ *  dsAdapterSupp
+ *  dsApplication
+ * use sigLONGLittleEndian for:
+ *      dsOS
+ * so that the sig can be standardised to Little Endian
+ */
+#if (defined(_DPT_BIG_ENDIAN))
+# define sigWORDLittleEndian(x) ((((x)&0xFF)<<8)|(((x)>>8)&0xFF))
+# define sigLONGLittleEndian(x) \
+        ((((x)&0xFF)<<24) |             \
+         (((x)&0xFF00)<<8) |    \
+         (((x)&0xFF0000L)>>8) | \
+         (((x)&0xFF000000L)>>24))
+#else
+# define sigWORDLittleEndian(x) (x)
+# define sigLONGLittleEndian(x) (x)
+#endif
+
+/* must make sure the structure is not word or double-word aligned      */
+/* ---------------------------------------------------------------      */
+/* Borland will ignore the following pragma:                            */
+/* Word alignment is OFF by default.  If in the, IDE make               */
+/* sure that Options | Compiler | Code Generation | Word Alignment      */
+/* is not checked.  If using BCC, do not use the -a option.             */
+
+#ifndef NO_PACK
+#if defined (_DPT_AIX)
+#pragma options align=packed
+#else
+#pragma pack(1)
+#endif  /* aix */
+#endif
+/* For the Macintosh */
+#if STRUCTALIGNMENTSUPPORTED
+#pragma options align=mac68k
+#endif
+
+
+/* Current Signature Version - sigBYTE dsSigVersion; */
+/* ------------------------------------------------------------------ */
+#define SIG_VERSION 1
+
+/* Processor Family - sigBYTE dsProcessorFamily;  DISTINCT VALUES */
+/* ------------------------------------------------------------------ */
+/* What type of processor the file is meant to run on. */
+/* This will let us know whether to read sigWORDs as high/low or low/high. */
+#define PROC_INTEL      0x00    /* Intel 80x86 */
+#define PROC_MOTOROLA   0x01    /* Motorola 68K */
+#define PROC_MIPS4000   0x02    /* MIPS RISC 4000 */
+#define PROC_ALPHA      0x03    /* DEC Alpha */
+#define PROC_POWERPC    0x04    /* IBM Power PC */
+#define PROC_i960       0x05    /* Intel i960 */
+#define PROC_ULTRASPARC 0x06    /* SPARC processor */
+
+/* Specific Minimim Processor - sigBYTE dsProcessor;    FLAG BITS */
+/* ------------------------------------------------------------------ */
+/* Different bit definitions dependent on processor_family */
+
+/* PROC_INTEL: */
+#define PROC_8086       0x01    /* Intel 8086 */
+#define PROC_286        0x02    /* Intel 80286 */
+#define PROC_386        0x04    /* Intel 80386 */
+#define PROC_486        0x08    /* Intel 80486 */
+#define PROC_PENTIUM    0x10    /* Intel 586 aka P5 aka Pentium */
+#define PROC_SEXIUM	0x20	/* Intel 686 aka P6 aka Pentium Pro or MMX */
+
+/* PROC_i960: */
+#define PROC_960RX      0x01    /* Intel 80960RC/RD */
+#define PROC_960HX      0x02    /* Intel 80960HA/HD/HT */
+
+/* PROC_MOTOROLA: */
+#define PROC_68000      0x01    /* Motorola 68000 */
+#define PROC_68010	0x02	/* Motorola 68010 */
+#define PROC_68020      0x04    /* Motorola 68020 */
+#define PROC_68030      0x08    /* Motorola 68030 */
+#define PROC_68040      0x10    /* Motorola 68040 */
+
+/* PROC_POWERPC */
+#define PROC_PPC601		0x01	/* PowerPC 601 */
+#define PROC_PPC603		0x02	/* PowerPC 603 */
+#define PROC_PPC604		0x04	/* PowerPC 604 */
+
+/* PROC_MIPS4000: */
+#define PROC_R4000      0x01    /* MIPS R4000 */
+
+/* Filetype - sigBYTE dsFiletype;       DISTINCT VALUES */
+/* ------------------------------------------------------------------ */
+#define FT_EXECUTABLE   0       /* Executable Program */
+#define FT_SCRIPT       1       /* Script/Batch File??? */
+#define FT_HBADRVR      2       /* HBA Driver */
+#define FT_OTHERDRVR    3       /* Other Driver */
+#define FT_IFS          4       /* Installable Filesystem Driver */
+#define FT_ENGINE       5       /* DPT Engine */
+#define FT_COMPDRVR     6       /* Compressed Driver Disk */
+#define FT_LANGUAGE     7       /* Foreign Language file */
+#define FT_FIRMWARE     8       /* Downloadable or actual Firmware */
+#define FT_COMMMODL     9       /* Communications Module */
+#define FT_INT13        10      /* INT 13 style HBA Driver */
+#define FT_HELPFILE     11      /* Help file */
+#define FT_LOGGER       12      /* Event Logger */
+#define FT_INSTALL      13      /* An Install Program */
+#define FT_LIBRARY      14      /* Storage Manager Real-Mode Calls */
+#define FT_RESOURCE 	15 	/* Storage Manager Resource File */
+#define FT_MODEM_DB  	16  	/* Storage Manager Modem Database */
+
+/* Filetype flags - sigBYTE dsFiletypeFlags;    FLAG BITS */
+/* ------------------------------------------------------------------ */
+#define FTF_DLL         0x01    /* Dynamic Link Library */
+#define FTF_NLM         0x02    /* Netware Loadable Module */
+#define FTF_OVERLAYS    0x04    /* Uses overlays */
+#define FTF_DEBUG       0x08    /* Debug version */
+#define FTF_TSR         0x10    /* TSR */
+#define FTF_SYS         0x20    /* DOS Loadable driver */
+#define FTF_PROTECTED   0x40    /* Runs in protected mode */
+#define FTF_APP_SPEC    0x80    /* Application Specific */
+#define FTF_ROM		(FTF_SYS|FTF_TSR)	/* Special Case */
+
+/* OEM - sigBYTE dsOEM;         DISTINCT VALUES */
+/* ------------------------------------------------------------------ */
+#define OEM_DPT         0       /* DPT */
+#define OEM_ATT         1       /* ATT */
+#define OEM_NEC         2       /* NEC */
+#define OEM_ALPHA       3       /* Alphatronix */
+#define OEM_AST         4       /* AST */
+#define OEM_OLIVETTI    5       /* Olivetti */
+#define OEM_SNI         6       /* Siemens/Nixdorf */
+#define OEM_SUN         7       /* SUN Microsystems */
+
+/* Operating System  - sigLONG dsOS;    FLAG BITS */
+/* ------------------------------------------------------------------ */
+#define OS_DOS          0x00000001 /* PC/MS-DOS				*/
+#define OS_WINDOWS      0x00000002 /* Microsoft Windows 3.x		*/
+#define OS_WINDOWS_NT   0x00000004 /* Microsoft Windows NT		*/
+#define OS_OS2M         0x00000008 /* OS/2 1.2.x,MS 1.3.0,IBM 1.3.x - Monolithic */
+#define OS_OS2L         0x00000010 /* Microsoft OS/2 1.301 - LADDR	*/
+#define OS_OS22x        0x00000020 /* IBM OS/2 2.x			*/
+#define OS_NW286        0x00000040 /* Novell NetWare 286		*/
+#define OS_NW386        0x00000080 /* Novell NetWare 386		*/
+#define OS_GEN_UNIX     0x00000100 /* Generic Unix			*/
+#define OS_SCO_UNIX     0x00000200 /* SCO Unix				*/
+#define OS_ATT_UNIX     0x00000400 /* ATT Unix				*/
+#define OS_UNIXWARE     0x00000800 /* USL Unix				*/
+#define OS_INT_UNIX     0x00001000 /* Interactive Unix			*/
+#define OS_SOLARIS      0x00002000 /* SunSoft Solaris			*/
+#define OS_QNX          0x00004000 /* QNX for Tom Moch			*/
+#define OS_NEXTSTEP     0x00008000 /* NeXTSTEP/OPENSTEP/MACH		*/
+#define OS_BANYAN       0x00010000 /* Banyan Vines			*/
+#define OS_OLIVETTI_UNIX 0x00020000/* Olivetti Unix			*/
+#define OS_MAC_OS	0x00040000 /* Mac OS				*/
+#define OS_WINDOWS_95	0x00080000 /* Microsoft Windows '95		*/
+#define OS_NW4x		0x00100000 /* Novell Netware 4.x		*/
+#define OS_BSDI_UNIX	0x00200000 /* BSDi Unix BSD/OS 2.0 and up	*/
+#define OS_AIX_UNIX     0x00400000 /* AIX Unix				*/
+#define OS_FREE_BSD	0x00800000 /* FreeBSD Unix			*/
+#define OS_LINUX	0x01000000 /* Linux				*/
+#define OS_DGUX_UNIX	0x02000000 /* Data General Unix			*/
+#define OS_SINIX_N      0x04000000 /* SNI SINIX-N			*/
+#define OS_PLAN9	0x08000000 /* ATT Plan 9			*/
+#define OS_TSX		0x10000000 /* SNH TSX-32			*/
+
+#define OS_OTHER        0x80000000 /* Other				*/
+
+/* Capabilities - sigWORD dsCapabilities;        FLAG BITS */
+/* ------------------------------------------------------------------ */
+#define CAP_RAID0       0x0001  /* RAID-0 */
+#define CAP_RAID1       0x0002  /* RAID-1 */
+#define CAP_RAID3       0x0004  /* RAID-3 */
+#define CAP_RAID5       0x0008  /* RAID-5 */
+#define CAP_SPAN        0x0010  /* Spanning */
+#define CAP_PASS        0x0020  /* Provides passthrough */
+#define CAP_OVERLAP     0x0040  /* Passthrough supports overlapped commands */
+#define CAP_ASPI        0x0080  /* Supports ASPI Command Requests */
+#define CAP_ABOVE16MB   0x0100  /* ISA Driver supports greater than 16MB */
+#define CAP_EXTEND      0x8000  /* Extended info appears after description */
+#ifdef SNI_MIPS
+#define CAP_CACHEMODE   0x1000  /* dpt_force_cache is set in driver */
+#endif
+
+/* Devices Supported - sigWORD dsDeviceSupp;    FLAG BITS */
+/* ------------------------------------------------------------------ */
+#define DEV_DASD        0x0001  /* DASD (hard drives) */
+#define DEV_TAPE        0x0002  /* Tape drives */
+#define DEV_PRINTER     0x0004  /* Printers */
+#define DEV_PROC        0x0008  /* Processors */
+#define DEV_WORM        0x0010  /* WORM drives */
+#define DEV_CDROM       0x0020  /* CD-ROM drives */
+#define DEV_SCANNER     0x0040  /* Scanners */
+#define DEV_OPTICAL     0x0080  /* Optical Drives */
+#define DEV_JUKEBOX     0x0100  /* Jukebox */
+#define DEV_COMM        0x0200  /* Communications Devices */
+#define DEV_OTHER       0x0400  /* Other Devices */
+#define DEV_ALL         0xFFFF  /* All SCSI Devices */
+
+/* Adapters Families Supported - sigWORD dsAdapterSupp; FLAG BITS */
+/* ------------------------------------------------------------------ */
+#define ADF_2001        0x0001  /* PM2001           */
+#define ADF_2012A       0x0002  /* PM2012A          */
+#define ADF_PLUS_ISA    0x0004  /* PM2011,PM2021    */
+#define ADF_PLUS_EISA   0x0008  /* PM2012B,PM2022   */
+#define ADF_SC3_ISA	0x0010  /* PM2021           */
+#define ADF_SC3_EISA	0x0020  /* PM2022,PM2122, etc */
+#define ADF_SC3_PCI	0x0040  /* SmartCache III PCI */
+#define ADF_SC4_ISA	0x0080  /* SmartCache IV ISA */
+#define ADF_SC4_EISA	0x0100  /* SmartCache IV EISA */
+#define ADF_SC4_PCI	0x0200	/* SmartCache IV PCI */
+#define ADF_SC5_PCI	0x0400	/* Fifth Generation I2O products */
+/*
+ *	Combinations of products
+ */
+#define ADF_ALL_2000	(ADF_2001|ADF_2012A)
+#define ADF_ALL_PLUS	(ADF_PLUS_ISA|ADF_PLUS_EISA)
+#define ADF_ALL_SC3	(ADF_SC3_ISA|ADF_SC3_EISA|ADF_SC3_PCI)
+#define ADF_ALL_SC4	(ADF_SC4_ISA|ADF_SC4_EISA|ADF_SC4_PCI)
+#define ADF_ALL_SC5	(ADF_SC5_PCI)
+/* All EATA Cacheing Products */
+#define ADF_ALL_CACHE	(ADF_ALL_PLUS|ADF_ALL_SC3|ADF_ALL_SC4)
+/* All EATA Bus Mastering Products */
+#define ADF_ALL_MASTER	(ADF_2012A|ADF_ALL_CACHE)
+/* All EATA Adapter Products */
+#define ADF_ALL_EATA	(ADF_2001|ADF_ALL_MASTER)
+#define ADF_ALL		ADF_ALL_EATA
+
+/* Application - sigWORD dsApplication;         FLAG BITS */
+/* ------------------------------------------------------------------ */
+#define APP_DPTMGR      0x0001  /* DPT Storage Manager */
+#define APP_ENGINE      0x0002  /* DPT Engine */
+#define APP_SYTOS       0x0004  /* Sytron Sytos Plus */
+#define APP_CHEYENNE    0x0008  /* Cheyenne ARCServe + ARCSolo */
+#define APP_MSCDEX      0x0010  /* Microsoft CD-ROM extensions */
+#define APP_NOVABACK    0x0020  /* NovaStor Novaback */
+#define APP_AIM         0x0040  /* Archive Information Manager */
+
+/* Requirements - sigBYTE dsRequirements;         FLAG BITS             */
+/* ------------------------------------------------------------------   */
+#define REQ_SMARTROM    0x01    /* Requires SmartROM to be present      */
+#define REQ_DPTDDL      0x02    /* Requires DPTDDL.SYS to be loaded     */
+#define REQ_HBA_DRIVER  0x04    /* Requires an HBA driver to be loaded  */
+#define REQ_ASPI_TRAN   0x08    /* Requires an ASPI Transport Modules   */
+#define REQ_ENGINE      0x10    /* Requires a DPT Engine to be loaded   */
+#define REQ_COMM_ENG    0x20    /* Requires a DPT Communications Engine */
+
+/*
+ * You may adjust dsDescription_size with an override to a value less than
+ * 50 so that the structure allocates less real space.
+ */
+#if (!defined(dsDescription_size))
+# define dsDescription_size 50
+#endif
+
+typedef struct dpt_sig {
+    char    dsSignature[6];      /* ALWAYS "dPtSiG" */
+    sigBYTE dsSigVersion;        /* signature version (currently 1) */
+    sigBYTE dsProcessorFamily;   /* what type of processor */
+    sigBYTE dsProcessor;         /* precise processor */
+    sigBYTE dsFiletype;          /* type of file */
+    sigBYTE dsFiletypeFlags;     /* flags to specify load type, etc. */
+    sigBYTE dsOEM;               /* OEM file was created for */
+    sigLONG dsOS;                /* which Operating systems */
+    sigWORD dsCapabilities;      /* RAID levels, etc. */
+    sigWORD dsDeviceSupp;        /* Types of SCSI devices supported */
+    sigWORD dsAdapterSupp;       /* DPT adapter families supported */
+    sigWORD dsApplication;       /* applications file is for */
+    sigBYTE dsRequirements;      /* Other driver dependencies */
+    sigBYTE dsVersion;           /* 1 */
+    sigBYTE dsRevision;          /* 'J' */
+    sigBYTE dsSubRevision;       /* '9'   ' ' if N/A */
+    sigBYTE dsMonth;             /* creation month */
+    sigBYTE dsDay;               /* creation day */
+    sigBYTE dsYear;              /* creation year since 1980 (1993=13) */
+    /* description (NULL terminated) */
+    char  dsDescription[dsDescription_size];
+} dpt_sig_S;
+/* 32 bytes minimum - with no description.  Put NULL at description[0] */
+/* 81 bytes maximum - with 49 character description plus NULL. */
+
+/* This line added at Roycroft's request */
+/* Microsoft's NT compiler gets confused if you do a pack and don't */
+/* restore it. */
+
+#ifndef NO_UNPACK
+#if defined (_DPT_AIX)
+#pragma options align=reset
+#elif defined (UNPACK_FOUR)
+#pragma pack(4)
+#else
+#pragma pack()
+#endif  /* aix */
+#endif
+/* For the Macintosh */
+#if STRUCTALIGNMENTSUPPORTED
+#pragma options align=reset
+#endif
+
+#endif
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/dpt/osd_defs.h linux/drivers/scsi/dpt/osd_defs.h
--- v2.4.9/linux/drivers/scsi/dpt/osd_defs.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/dpt/osd_defs.h	Fri Sep  7 09:28:38 2001
@@ -0,0 +1,79 @@
+/*	BSDI osd_defs.h,v 1.4 1998/06/03 19:14:58 karels Exp	*/
+/*
+ * Copyright (c) 1996-1999 Distributed Processing Technology Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source form, with or without modification, are
+ * permitted provided that redistributions of source code must retain the
+ * above copyright notice, this list of conditions and the following disclaimer.
+ *
+ * This software is provided `as is' by Distributed Processing Technology and
+ * any express or implied warranties, including, but not limited to, the
+ * implied warranties of merchantability and fitness for a particular purpose,
+ * are disclaimed. In no event shall Distributed Processing Technology be
+ * liable for any direct, indirect, incidental, special, exemplary or
+ * consequential damages (including, but not limited to, procurement of
+ * substitute goods or services; loss of use, data, or profits; or business
+ * interruptions) however caused and on any theory of liability, whether in
+ * contract, strict liability, or tort (including negligence or otherwise)
+ * arising in any way out of the use of this driver software, even if advised
+ * of the possibility of such damage.
+ *
+ */
+
+#ifndef		_OSD_DEFS_H
+#define		_OSD_DEFS_H
+
+/*File - OSD_DEFS.H
+ ****************************************************************************
+ *
+ *Description:
+ *
+ *	This file contains the OS dependent defines.  This file is included
+ *in osd_util.h and provides the OS specific defines for that file.
+ *
+ *Copyright Distributed Processing Technology, Corp.
+ *	  140 Candace Dr.
+ *	  Maitland, Fl.	32751   USA
+ *	  Phone: (407) 830-5522  Fax: (407) 260-5366
+ *	  All Rights Reserved
+ *
+ *Author:	Doug Anderson
+ *Date:		1/31/94
+ *
+ *Editors:
+ *
+ *Remarks:
+ *
+ *
+ *****************************************************************************/
+
+
+/*Definitions - Defines & Constants ----------------------------------------- */
+
+  /* Define the operating system */
+#if (defined(__linux__))
+# define _DPT_LINUX
+#elif (defined(__bsdi__))
+# define _DPT_BSDI
+#elif (defined(__FreeBSD__))
+# define _DPT_FREE_BSD
+#else
+# define _DPT_SCO
+#endif
+
+#if defined (ZIL_CURSES)
+#define		_DPT_CURSES
+#else
+#define         _DPT_MOTIF
+#endif
+
+  /* Redefine 'far' to nothing - no far pointer type required in UNIX */
+#define		far
+
+  /* Define the mutually exclusive semaphore type */
+#define		SEMAPHORE_T	unsigned int *
+  /* Define a handle to a DLL */
+#define		DLL_HANDLE_T	unsigned int *
+
+#endif
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/dpt/osd_util.h linux/drivers/scsi/dpt/osd_util.h
--- v2.4.9/linux/drivers/scsi/dpt/osd_util.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/dpt/osd_util.h	Fri Sep  7 09:28:38 2001
@@ -0,0 +1,358 @@
+/*	BSDI osd_util.h,v 1.8 1998/06/03 19:14:58 karels Exp	*/
+
+/*
+ * Copyright (c) 1996-1999 Distributed Processing Technology Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source form, with or without modification, are
+ * permitted provided that redistributions of source code must retain the
+ * above copyright notice, this list of conditions and the following disclaimer.
+ *
+ * This software is provided `as is' by Distributed Processing Technology and
+ * any express or implied warranties, including, but not limited to, the
+ * implied warranties of merchantability and fitness for a particular purpose,
+ * are disclaimed. In no event shall Distributed Processing Technology be
+ * liable for any direct, indirect, incidental, special, exemplary or
+ * consequential damages (including, but not limited to, procurement of
+ * substitute goods or services; loss of use, data, or profits; or business
+ * interruptions) however caused and on any theory of liability, whether in
+ * contract, strict liability, or tort (including negligence or otherwise)
+ * arising in any way out of the use of this driver software, even if advised
+ * of the possibility of such damage.
+ *
+ */
+
+#ifndef         __OSD_UTIL_H
+#define         __OSD_UTIL_H
+
+/*File - OSD_UTIL.H
+ ****************************************************************************
+ *
+ *Description:
+ *
+ *      This file contains defines and function prototypes that are
+ *operating system dependent.  The resources defined in this file
+ *are not specific to any particular application.
+ *
+ *Copyright Distributed Processing Technology, Corp.
+ *        140 Candace Dr.
+ *        Maitland, Fl. 32751   USA
+ *        Phone: (407) 830-5522  Fax: (407) 260-5366
+ *        All Rights Reserved
+ *
+ *Author:       Doug Anderson
+ *Date:         1/7/94
+ *
+ *Editors:
+ *
+ *Remarks:
+ *
+ *
+ *****************************************************************************/
+
+
+/*Definitions - Defines & Constants ----------------------------------------- */
+
+/*----------------------------- */
+/* Operating system selections: */
+/*----------------------------- */
+
+/*#define               _DPT_MSDOS      */
+/*#define               _DPT_WIN_3X     */
+/*#define               _DPT_WIN_4X     */
+/*#define               _DPT_WIN_NT     */
+/*#define               _DPT_NETWARE    */
+/*#define               _DPT_OS2        */
+/*#define               _DPT_SCO        */
+/*#define               _DPT_UNIXWARE   */
+/*#define               _DPT_SOLARIS    */
+/*#define               _DPT_NEXTSTEP   */
+/*#define               _DPT_BANYAN     */
+
+/*-------------------------------- */
+/* Include the OS specific defines */
+/*-------------------------------- */
+
+/*#define       OS_SELECTION    From Above List */
+/*#define       SEMAPHORE_T     ??? */
+/*#define       DLL_HANDLE_T    ??? */
+
+#if (defined(KERNEL) && (defined(__FreeBSD__) || defined(__bsdi__)))
+# include        "i386/isa/dpt_osd_defs.h"
+#else
+# include        "osd_defs.h"
+#endif
+
+#ifndef DPT_UNALIGNED
+   #define      DPT_UNALIGNED
+#endif
+
+#ifndef DPT_EXPORT
+   #define      DPT_EXPORT
+#endif
+
+#ifndef DPT_IMPORT
+   #define      DPT_IMPORT
+#endif
+
+#ifndef DPT_RUNTIME_IMPORT
+   #define      DPT_RUNTIME_IMPORT  DPT_IMPORT
+#endif
+
+/*--------------------- */
+/* OS dependent defines */
+/*--------------------- */
+
+#if defined (_DPT_MSDOS) || defined (_DPT_WIN_3X)
+   #define      _DPT_16_BIT
+#else
+   #define      _DPT_32_BIT
+#endif
+
+#if defined (_DPT_SCO) || defined (_DPT_UNIXWARE) || defined (_DPT_SOLARIS) || defined (_DPT_AIX) || defined (SNI_MIPS) || defined (_DPT_BSDI) || defined (_DPT_FREE_BSD) || defined(_DPT_LINUX)
+   #define      _DPT_UNIX
+#endif
+
+#if defined (_DPT_WIN_3x) || defined (_DPT_WIN_4X) || defined (_DPT_WIN_NT) \
+	    || defined (_DPT_OS2)
+   #define      _DPT_DLL_SUPPORT
+#endif
+
+#if !defined (_DPT_MSDOS) && !defined (_DPT_WIN_3X) && !defined (_DPT_NETWARE)
+   #define      _DPT_PREEMPTIVE
+#endif
+
+#if !defined (_DPT_MSDOS) && !defined (_DPT_WIN_3X)
+   #define      _DPT_MULTI_THREADED
+#endif
+
+#if !defined (_DPT_MSDOS)
+   #define      _DPT_MULTI_TASKING
+#endif
+
+  /* These exist for platforms that   */
+  /* chunk when accessing mis-aligned */
+  /* data                             */
+#if defined (SNI_MIPS) || defined (_DPT_SOLARIS)
+   #if defined (_DPT_BIG_ENDIAN)
+	#if !defined (_DPT_STRICT_ALIGN)
+            #define _DPT_STRICT_ALIGN
+	#endif
+   #endif
+#endif
+
+  /* Determine if in C or C++ mode */
+#ifdef  __cplusplus
+   #define      _DPT_CPP
+#else
+   #define      _DPT_C
+#endif
+
+/*-------------------------------------------------------------------*/
+/* Under Solaris the compiler refuses to accept code like:           */
+/*   { {"DPT"}, 0, NULL .... },                                      */
+/* and complains about the {"DPT"} part by saying "cannot use { }    */
+/* to initialize char*".                                             */
+/*                                                                   */
+/* By defining these ugly macros we can get around this and also     */
+/* not have to copy and #ifdef large sections of code.  I know that  */
+/* these macros are *really* ugly, but they should help reduce       */
+/* maintenance in the long run.                                      */
+/*                                                                   */
+/*-------------------------------------------------------------------*/
+#if !defined (DPTSQO)
+   #if defined (_DPT_SOLARIS)
+      #define DPTSQO
+      #define DPTSQC
+   #else
+      #define DPTSQO {
+      #define DPTSQC }
+   #endif  /* solaris */
+#endif  /* DPTSQO */
+
+
+/*---------------------- */
+/* OS dependent typedefs */
+/*---------------------- */
+
+#if defined (_DPT_MSDOS) || defined (_DPT_SCO)
+   #define BYTE unsigned char
+   #define WORD unsigned short
+#endif
+
+#ifndef _DPT_TYPEDEFS
+   #define _DPT_TYPEDEFS
+   typedef unsigned char   uCHAR;
+   typedef unsigned short  uSHORT;
+   typedef unsigned int    uINT;
+   typedef unsigned long   uLONG;
+
+   typedef union {
+	 uCHAR        u8[4];
+	 uSHORT       u16[2];
+	 uLONG        u32;
+   } access_U;
+#endif
+
+#if !defined (NULL)
+   #define      NULL    0
+#endif
+
+
+/*Prototypes - function ----------------------------------------------------- */
+
+#ifdef  __cplusplus
+   extern "C" {         /* Declare all these functions as "C" functions */
+#endif
+
+/*------------------------ */
+/* Byte reversal functions */
+/*------------------------ */
+
+  /* Reverses the byte ordering of a 2 byte variable */
+#if (!defined(osdSwap2))
+ uSHORT       osdSwap2(DPT_UNALIGNED uSHORT *);
+#endif  // !osdSwap2
+
+  /* Reverses the byte ordering of a 4 byte variable and shifts left 8 bits */
+#if (!defined(osdSwap3))
+ uLONG        osdSwap3(DPT_UNALIGNED uLONG *);
+#endif  // !osdSwap3
+
+
+#ifdef  _DPT_NETWARE
+   #include "novpass.h" /* For DPT_Bswapl() prototype */
+	/* Inline the byte swap */
+   #ifdef __cplusplus
+	 inline uLONG osdSwap4(uLONG *inLong) {
+	 return *inLong = DPT_Bswapl(*inLong);
+	 }
+   #else
+	 #define osdSwap4(inLong)       DPT_Bswapl(inLong)
+   #endif  // cplusplus
+#else
+	/* Reverses the byte ordering of a 4 byte variable */
+# if (!defined(osdSwap4))
+   uLONG        osdSwap4(DPT_UNALIGNED uLONG *);
+# endif  // !osdSwap4
+
+  /* The following functions ALWAYS swap regardless of the *
+   * presence of DPT_BIG_ENDIAN                            */
+
+   uSHORT       trueSwap2(DPT_UNALIGNED uSHORT *);
+   uLONG        trueSwap4(DPT_UNALIGNED uLONG *);
+
+#endif  // netware
+
+
+/*-------------------------------------*
+ * Network order swap functions        *
+ *                                     *
+ * These functions/macros will be used *
+ * by the structure insert()/extract() *
+ * functions.                          *
+ *
+ * We will enclose all structure       *
+ * portability modifications inside    *
+ * #ifdefs.  When we are ready, we     *
+ * will #define DPT_PORTABLE to begin  *
+ * using the modifications.            *
+ *-------------------------------------*/
+uLONG	netSwap4(uLONG val);
+
+#if defined (_DPT_BIG_ENDIAN)
+
+// for big-endian we need to swap
+
+#ifndef NET_SWAP_2
+#define NET_SWAP_2(x) (((x) >> 8) | ((x) << 8))
+#endif  // NET_SWAP_2
+
+#ifndef NET_SWAP_4
+#define NET_SWAP_4(x) netSwap4((x))
+#endif  // NET_SWAP_4
+
+#else
+
+// for little-endian we don't need to do anything
+
+#ifndef NET_SWAP_2
+#define NET_SWAP_2(x) (x)
+#endif  // NET_SWAP_2
+
+#ifndef NET_SWAP_4
+#define NET_SWAP_4(x) (x)
+#endif  // NET_SWAP_4
+
+#endif  // big endian
+
+
+
+/*----------------------------------- */
+/* Run-time loadable module functions */
+/*----------------------------------- */
+
+  /* Loads the specified run-time loadable DLL */
+DLL_HANDLE_T    osdLoadModule(uCHAR *);
+  /* Unloads the specified run-time loadable DLL */
+uSHORT          osdUnloadModule(DLL_HANDLE_T);
+  /* Returns a pointer to a function inside a run-time loadable DLL */
+void *          osdGetFnAddr(DLL_HANDLE_T,uCHAR *);
+
+/*--------------------------------------- */
+/* Mutually exclusive semaphore functions */
+/*--------------------------------------- */
+
+  /* Create a named semaphore */
+SEMAPHORE_T     osdCreateNamedSemaphore(char *);
+  /* Create a mutually exlusive semaphore */
+SEMAPHORE_T     osdCreateSemaphore(void);
+	/* create an event semaphore */
+SEMAPHORE_T              osdCreateEventSemaphore(void);
+	/* create a named event semaphore */
+SEMAPHORE_T             osdCreateNamedEventSemaphore(char *);
+
+  /* Destroy the specified mutually exclusive semaphore object */
+uSHORT          osdDestroySemaphore(SEMAPHORE_T);
+  /* Request access to the specified mutually exclusive semaphore */
+uLONG           osdRequestSemaphore(SEMAPHORE_T,uLONG);
+  /* Release access to the specified mutually exclusive semaphore */
+uSHORT          osdReleaseSemaphore(SEMAPHORE_T);
+	/* wait for a event to happen */
+uLONG                            osdWaitForEventSemaphore(SEMAPHORE_T, uLONG);
+	/* signal an event */
+uLONG                            osdSignalEventSemaphore(SEMAPHORE_T);
+	/* reset the event */
+uLONG                            osdResetEventSemaphore(SEMAPHORE_T);
+
+/*----------------- */
+/* Thread functions */
+/*----------------- */
+
+  /* Releases control to the task switcher in non-preemptive */
+  /* multitasking operating systems. */
+void            osdSwitchThreads(void);
+
+  /* Starts a thread function */
+uLONG   osdStartThread(void *,void *);
+
+/* what is my thread id */
+uLONG osdGetThreadID(void);
+
+/* wakes up the specifed thread */
+void osdWakeThread(uLONG);
+
+/* osd sleep for x miliseconds */
+void osdSleep(uLONG);
+
+#define DPT_THREAD_PRIORITY_LOWEST 0x00
+#define DPT_THREAD_PRIORITY_NORMAL 0x01
+#define DPT_THREAD_PRIORITY_HIGHEST 0x02
+
+uCHAR osdSetThreadPriority(uLONG tid, uCHAR priority);
+
+#ifdef __cplusplus
+   }    /* end the xtern "C" declaration */
+#endif
+
+#endif  /* osd_util_h */
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/dpt/sys_info.h linux/drivers/scsi/dpt/sys_info.h
--- v2.4.9/linux/drivers/scsi/dpt/sys_info.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/dpt/sys_info.h	Fri Sep  7 09:28:38 2001
@@ -0,0 +1,417 @@
+/*	BSDI sys_info.h,v 1.6 1998/06/03 19:14:59 karels Exp	*/
+
+/*
+ * Copyright (c) 1996-1999 Distributed Processing Technology Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source form, with or without modification, are
+ * permitted provided that redistributions of source code must retain the
+ * above copyright notice, this list of conditions and the following disclaimer.
+ *
+ * This software is provided `as is' by Distributed Processing Technology and
+ * any express or implied warranties, including, but not limited to, the
+ * implied warranties of merchantability and fitness for a particular purpose,
+ * are disclaimed. In no event shall Distributed Processing Technology be
+ * liable for any direct, indirect, incidental, special, exemplary or
+ * consequential damages (including, but not limited to, procurement of
+ * substitute goods or services; loss of use, data, or profits; or business
+ * interruptions) however caused and on any theory of liability, whether in
+ * contract, strict liability, or tort (including negligence or otherwise)
+ * arising in any way out of the use of this driver software, even if advised
+ * of the possibility of such damage.
+ *
+ */
+
+#ifndef         __SYS_INFO_H
+#define         __SYS_INFO_H
+
+/*File - SYS_INFO.H
+ ****************************************************************************
+ *
+ *Description:
+ *
+ *      This file contains structure definitions for the OS dependent
+ *layer system information buffers.
+ *
+ *Copyright Distributed Processing Technology, Corp.
+ *        140 Candace Dr.
+ *        Maitland, Fl. 32751   USA
+ *        Phone: (407) 830-5522  Fax: (407) 260-5366
+ *        All Rights Reserved
+ *
+ *Author:       Don Kemper
+ *Date:         5/10/94
+ *
+ *Editors:
+ *
+ *Remarks:
+ *
+ *
+ *****************************************************************************/
+
+
+/*Include Files ------------------------------------------------------------- */
+
+#include        "osd_util.h"
+
+#ifndef NO_PACK
+#if defined (_DPT_AIX)
+#pragma options align=packed
+#else
+#pragma pack(1)
+#endif  /* aix */
+#endif  // no unpack
+
+
+/*struct - driveParam_S - start
+ *===========================================================================
+ *
+ *Description:
+ *
+ *      This structure defines the drive parameters seen during
+ *booting.
+ *
+ *---------------------------------------------------------------------------*/
+
+#ifdef  __cplusplus
+   struct driveParam_S {
+#else
+   typedef struct  {
+#endif
+
+   uSHORT       cylinders;      /* Upto 1024 */
+   uCHAR        heads;          /* Upto 255 */
+   uCHAR        sectors;        /* Upto 63 */
+
+#ifdef  __cplusplus
+
+//---------- Portability Additions ----------- in sp_sinfo.cpp
+#ifdef DPT_PORTABLE
+	uSHORT		netInsert(dptBuffer_S *buffer);
+	uSHORT		netExtract(dptBuffer_S *buffer);
+#endif // DPT PORTABLE
+//--------------------------------------------
+
+   };
+#else
+   } driveParam_S;
+#endif
+/*driveParam_S - end */
+
+
+/*struct - sysInfo_S - start
+ *===========================================================================
+ *
+ *Description:
+ *
+ *      This structure defines the command system information that
+ *should be returned by every OS dependent layer.
+ *
+ *---------------------------------------------------------------------------*/
+
+/*flags - bit definitions */
+#define SI_CMOS_Valid           0x0001
+#define SI_NumDrivesValid       0x0002
+#define SI_ProcessorValid       0x0004
+#define SI_MemorySizeValid      0x0008
+#define SI_DriveParamsValid     0x0010
+#define SI_SmartROMverValid     0x0020
+#define SI_OSversionValid       0x0040
+#define SI_OSspecificValid      0x0080  /* 1 if OS structure returned */
+#define SI_BusTypeValid         0x0100
+
+#define SI_ALL_VALID            0x0FFF  /* All Std SysInfo is valid */
+#define SI_NO_SmartROM          0x8000
+
+/*busType - definitions */
+#define SI_ISA_BUS      0x00
+#define SI_MCA_BUS      0x01
+#define SI_EISA_BUS     0x02
+#define SI_PCI_BUS      0x04
+
+#ifdef  __cplusplus
+   struct sysInfo_S {
+#else
+   typedef struct  {
+#endif
+
+   uCHAR        drive0CMOS;             /* CMOS Drive 0 Type */
+   uCHAR        drive1CMOS;             /* CMOS Drive 1 Type */
+   uCHAR        numDrives;              /* 0040:0075 contents */
+   uCHAR        processorFamily;        /* Same as DPTSIG's definition */
+   uCHAR        processorType;          /* Same as DPTSIG's definition */
+   uCHAR        smartROMMajorVersion;
+   uCHAR        smartROMMinorVersion;   /* SmartROM version */
+   uCHAR        smartROMRevision;
+   uSHORT       flags;                  /* See bit definitions above */
+   uSHORT       conventionalMemSize;    /* in KB */
+   uLONG        extendedMemSize;        /* in KB */
+   uLONG        osType;                 /* Same as DPTSIG's definition */
+   uCHAR        osMajorVersion;
+   uCHAR        osMinorVersion;         /* The OS version */
+   uCHAR        osRevision;
+#ifdef _SINIX_ADDON
+   uCHAR        busType;                /* See defininitions above */
+   uSHORT       osSubRevision;
+   uCHAR        pad[2];                 /* For alignment */
+#else
+   uCHAR        osSubRevision;
+   uCHAR        busType;                /* See defininitions above */
+   uCHAR        pad[3];                 /* For alignment */
+#endif
+   driveParam_S drives[16];             /* SmartROM Logical Drives */
+
+#ifdef  __cplusplus
+
+//---------- Portability Additions ----------- in sp_sinfo.cpp
+#ifdef DPT_PORTABLE
+	uSHORT		netInsert(dptBuffer_S *buffer);
+	uSHORT		netExtract(dptBuffer_S *buffer);
+#endif // DPT PORTABLE
+//--------------------------------------------
+
+   };
+#else
+   } sysInfo_S;
+#endif
+/*sysInfo_S - end */
+
+
+/*struct - DOS_Info_S - start
+ *===========================================================================
+ *
+ *Description:
+ *
+ *      This structure defines the system information specific to a
+ *DOS workstation.
+ *
+ *---------------------------------------------------------------------------*/
+
+/*flags - bit definitions */
+#define DI_DOS_HIGH             0x01    /* DOS is loaded high */
+#define DI_DPMI_VALID           0x02    /* DPMI version is valid */
+
+#ifdef  __cplusplus
+   struct DOS_Info_S {
+#else
+   typedef struct {
+#endif
+
+   uCHAR        flags;          /* See bit definitions above */
+   uSHORT       driverLocation; /* SmartROM BIOS address */
+   uSHORT       DOS_version;
+   uSHORT       DPMI_version;
+
+#ifdef  __cplusplus
+
+//---------- Portability Additions ----------- in sp_sinfo.cpp
+#ifdef DPT_PORTABLE
+	uSHORT		netInsert(dptBuffer_S *buffer);
+	uSHORT		netExtract(dptBuffer_S *buffer);
+#endif // DPT PORTABLE
+//--------------------------------------------
+
+   };
+#else
+   } DOS_Info_S;
+#endif
+/*DOS_Info_S - end */
+
+
+/*struct - Netware_Info_S - start
+ *===========================================================================
+ *
+ *Description:
+ *
+ *      This structure defines the system information specific to a
+ *Netware machine.
+ *
+ *---------------------------------------------------------------------------*/
+
+#ifdef  __cplusplus
+   struct Netware_Info_S {
+#else
+   typedef struct {
+#endif
+
+   uCHAR        driverName[13];         /* ie PM12NW31.DSK */
+   uCHAR        serverName[48];
+   uCHAR        netwareVersion;         /* The Netware OS version */
+   uCHAR        netwareSubVersion;
+   uCHAR        netwareRevision;
+   uSHORT       maxConnections;         /* Probably  250 or 1000 */
+   uSHORT       connectionsInUse;
+   uSHORT       maxVolumes;
+   uCHAR        unused;
+   uCHAR        SFTlevel;
+   uCHAR        TTSlevel;
+
+   uCHAR        clibMajorVersion;       /* The CLIB.NLM version */
+   uCHAR        clibMinorVersion;
+   uCHAR        clibRevision;
+
+#ifdef  __cplusplus
+
+//---------- Portability Additions ----------- in sp_sinfo.cpp
+#ifdef DPT_PORTABLE
+	uSHORT		netInsert(dptBuffer_S *buffer);
+	uSHORT		netExtract(dptBuffer_S *buffer);
+#endif // DPT PORTABLE
+//--------------------------------------------
+
+   };
+#else
+   } Netware_Info_S;
+#endif
+/*Netware_Info_S - end */
+
+
+/*struct - OS2_Info_S - start
+ *===========================================================================
+ *
+ *Description:
+ *
+ *      This structure defines the system information specific to an
+ *OS/2 machine.
+ *
+ *---------------------------------------------------------------------------*/
+
+#ifdef  __cplusplus
+   struct OS2_Info_S {
+#else
+   typedef struct {
+#endif
+
+   uCHAR        something;
+
+#ifdef  __cplusplus
+
+//---------- Portability Additions ----------- in sp_sinfo.cpp
+#ifdef DPT_PORTABLE
+	uSHORT		netInsert(dptBuffer_S *buffer);
+	uSHORT		netExtract(dptBuffer_S *buffer);
+#endif // DPT PORTABLE
+//--------------------------------------------
+
+   };
+#else
+   } OS2_Info_S;
+#endif
+/*OS2_Info_S - end */
+
+
+/*struct - WinNT_Info_S - start
+ *===========================================================================
+ *
+ *Description:
+ *
+ *      This structure defines the system information specific to a
+ *Windows NT machine.
+ *
+ *---------------------------------------------------------------------------*/
+
+#ifdef  __cplusplus
+   struct WinNT_Info_S {
+#else
+   typedef struct {
+#endif
+
+   uCHAR        something;
+
+#ifdef  __cplusplus
+
+//---------- Portability Additions ----------- in sp_sinfo.cpp
+#ifdef DPT_PORTABLE
+	uSHORT		netInsert(dptBuffer_S *buffer);
+	uSHORT		netExtract(dptBuffer_S *buffer);
+#endif // DPT PORTABLE
+//--------------------------------------------
+
+   };
+#else
+   } WinNT_Info_S;
+#endif
+/*WinNT_Info_S - end */
+
+
+/*struct - SCO_Info_S - start
+ *===========================================================================
+ *
+ *Description:
+ *
+ *      This structure defines the system information specific to an
+ *SCO UNIX machine.
+ *
+ *---------------------------------------------------------------------------*/
+
+#ifdef  __cplusplus
+   struct SCO_Info_S {
+#else
+   typedef struct {
+#endif
+
+   uCHAR        something;
+
+#ifdef  __cplusplus
+
+//---------- Portability Additions ----------- in sp_sinfo.cpp
+#ifdef DPT_PORTABLE
+	uSHORT		netInsert(dptBuffer_S *buffer);
+	uSHORT		netExtract(dptBuffer_S *buffer);
+#endif // DPT PORTABLE
+//--------------------------------------------
+
+   };
+#else
+   } SCO_Info_S;
+#endif
+/*SCO_Info_S - end */
+
+
+/*struct - USL_Info_S - start
+ *===========================================================================
+ *
+ *Description:
+ *
+ *      This structure defines the system information specific to a
+ *USL UNIX machine.
+ *
+ *---------------------------------------------------------------------------*/
+
+#ifdef  __cplusplus
+   struct USL_Info_S {
+#else
+   typedef struct {
+#endif
+
+   uCHAR        something;
+
+#ifdef  __cplusplus
+
+//---------- Portability Additions ----------- in sp_sinfo.cpp
+#ifdef DPT_PORTABLE
+	uSHORT		netInsert(dptBuffer_S *buffer);
+	uSHORT		netExtract(dptBuffer_S *buffer);
+#endif // DPT PORTABLE
+//--------------------------------------------
+
+   };
+#else
+   } USL_Info_S;
+#endif
+/*USL_Info_S - end */
+
+
+  /* Restore default structure packing */
+#ifndef NO_UNPACK
+#if defined (_DPT_AIX)
+#pragma options align=reset
+#elif defined (UNPACK_FOUR)
+#pragma pack(4)
+#else
+#pragma pack()
+#endif  /* aix */
+#endif  // no unpack
+
+#endif  // __SYS_INFO_H
+
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/dpt_i2o.c linux/drivers/scsi/dpt_i2o.c
--- v2.4.9/linux/drivers/scsi/dpt_i2o.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/dpt_i2o.c	Sun Sep  9 10:52:35 2001
@@ -0,0 +1,3326 @@
+/***************************************************************************
+                          dpti.c  -  description
+                             -------------------
+    begin                : Thu Sep 7 2000
+    copyright            : (C) 2000 by Adaptec
+    email                : deanna_bonds@adaptec.com
+
+    			   July 30, 2001 First version being submitted
+			   for inclusion in the kernel.  V2.4
+
+    See README.dpti for history, notes, license info, and credits
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 DEBUG 1
+//#define UARTDELAY 1
+
+// On the real kernel ADDR32 should always be zero for 2.4. GFP_HIGH allocates
+// high pages. Keep the macro around because of the broken unmerged ia64 tree
+
+#define ADDR32 (0)
+
+#include <linux/version.h>
+#include <linux/module.h>
+
+MODULE_AUTHOR("Deanna Bonds, with _lots_ of help from Mark Salyzyn");
+MODULE_DESCRIPTION("Adaptec I2O RAID Driver");
+
+////////////////////////////////////////////////////////////////
+
+#include <linux/ioctl.h>	/* For SCSI-Passthrough */
+#include <asm/uaccess.h>
+
+#include <linux/stat.h>
+#include <linux/slab.h>		/* for kmalloc() */
+#include <linux/config.h>	/* for CONFIG_PCI */
+#include <linux/pci.h>		/* for PCI support */
+#include <linux/proc_fs.h>
+#include <linux/blk.h>
+#include <linux/delay.h>	/* for udelay */
+#include <linux/tqueue.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>	/* for printk */
+#include <linux/sched.h>
+#include <linux/reboot.h>
+#include <linux/smp_lock.h>
+
+#include <linux/timer.h>
+#include <linux/string.h>
+#include <linux/ioport.h>
+#include <linux/stat.h>
+
+#include <asm/processor.h>	/* for boot_cpu_data */
+#include <asm/pgtable.h>
+#include <asm/io.h>		/* for virt_to_bus, etc. */
+
+#include "scsi.h"
+#include "hosts.h"
+#include "sd.h"
+
+#include "dpt/dptsig.h"
+#include "dpti.h"
+
+/*============================================================================
+ * Create a binary signature - this is read by dptsig
+ * Needed for our management apps
+ *============================================================================
+ */
+static dpt_sig_S DPTI_sig = {
+	{'d', 'P', 't', 'S', 'i', 'G'}, SIG_VERSION,
+#ifdef __i386__
+	PROC_INTEL, PROC_386 | PROC_486 | PROC_PENTIUM | PROC_SEXIUM,
+#elif defined __ia64__
+	PROC_INTEL, PROC_IA64,
+#elif define __sparc__
+	PROC_ULTRASPARC,
+#elif defined(__alpha__)
+	PROC_ALPHA ,
+#else
+	(-1),
+#endif
+	 FT_HBADRVR, 0, OEM_DPT, OS_LINUX, CAP_OVERLAP, DEV_ALL,
+	ADF_ALL_SC5, 0, 0, DPT_VERSION, DPT_REVISION, DPT_SUBREVISION,
+	DPT_MONTH, DPT_DAY, DPT_YEAR, "Adaptec Linux I2O RAID Driver"
+};
+
+
+
+
+/*============================================================================
+ * Globals
+ *============================================================================
+ */
+
+DECLARE_MUTEX(adpt_configuration_lock);
+
+static struct i2o_sys_tbl *sys_tbl = NULL;
+static int sys_tbl_ind = 0;
+static int sys_tbl_len = 0;
+
+static adpt_hba* hbas[DPTI_MAX_HBA];
+static adpt_hba* hba_chain = NULL;
+static int hba_count = 0;
+
+// Debug flags to be put into the HBA flags field when initialized
+// Make sure to enable DEBUG_PRINT for these flags to work
+static unsigned long DebugFlags = HBA_FLAGS_DBG_SCAN_B | HBA_FLAGS_DBG_FLAGS_MASK;
+
+static struct file_operations adpt_fops = {
+	ioctl: adpt_ioctl,
+	open: adpt_open,
+	release: adpt_close
+};
+
+#ifdef REBOOT_NOTIFIER
+static struct notifier_block adpt_reboot_notifier =
+{
+	 adpt_reboot_event,
+	 NULL,
+	 0
+};
+#endif
+
+/* Structures and definitions for synchronous message posting.
+ * See adpt_i2o_post_wait() for description
+ * */
+struct adpt_i2o_post_wait_data
+{
+	int status;
+	u32 id;
+	adpt_wait_queue_head_t *wq;
+	struct adpt_i2o_post_wait_data *next;
+};
+
+static struct adpt_i2o_post_wait_data *adpt_post_wait_queue = NULL;
+static u32 adpt_post_wait_id = 0;
+static spinlock_t adpt_post_wait_lock = SPIN_LOCK_UNLOCKED;
+
+
+/*============================================================================
+ * 				Functions
+ *============================================================================
+ */
+
+static u8 adpt_read_blink_led(adpt_hba* host)
+{
+	if(host->FwDebugBLEDflag_P != 0) {
+		if( readb(host->FwDebugBLEDflag_P) == 0xbc ){
+			return readb(host->FwDebugBLEDvalue_P);
+		}
+	}
+	return 0;
+}
+
+/*============================================================================
+ * Scsi host template interface functions
+ *============================================================================
+ */
+
+static int adpt_detect(Scsi_Host_Template* sht)
+{
+	struct pci_dev *pDev = NULL;
+	adpt_hba* pHba;
+
+	adpt_init();
+	sht->use_new_eh_code = 1;
+
+	PINFO("Detecting Adaptec I2O RAID controllers...\n");
+
+        /* search for all Adatpec I2O RAID cards */
+	while ((pDev = pci_find_device( PCI_DPT_VENDOR_ID, PCI_ANY_ID, pDev))) {
+		if(pDev->device == PCI_DPT_DEVICE_ID ||
+		   pDev->device == PCI_DPT_RAPTOR_DEVICE_ID){
+			if(adpt_install_hba(sht, pDev) ){
+				PERROR("Could not Init an I2O RAID device\n");
+				PERROR("Will not try to detect others.\n");
+				return hba_count-1;
+			}
+		}
+	}
+
+	/* In INIT state, Activate IOPs */
+	for (pHba = hba_chain; pHba; pHba = pHba->next) {
+		// Activate does get status , init outbound, and get hrt
+		if (adpt_i2o_activate_hba(pHba) < 0) {
+			adpt_i2o_delete_hba(pHba);
+		}
+	}
+
+
+	/* Active IOPs in HOLD state */
+
+rebuild_sys_tab:
+	if (hba_chain == NULL) 
+		return 0;
+
+	/*
+	 * If build_sys_table fails, we kill everything and bail
+	 * as we can't init the IOPs w/o a system table
+	 */	
+	if (adpt_i2o_build_sys_table() < 0) {
+		adpt_i2o_sys_shutdown();
+		return 0;
+	}
+
+	PDEBUG("HBA's in HOLD state\n");
+
+	/* If IOP don't get online, we need to rebuild the System table */
+	for (pHba = hba_chain; pHba; pHba = pHba->next) {
+		if (adpt_i2o_online_hba(pHba) < 0) {
+			adpt_i2o_delete_hba(pHba);	
+			goto rebuild_sys_tab;
+		}
+	}
+
+	/* Active IOPs now in OPERATIONAL state */
+	PDEBUG("HBA's in OPERATIONAL state\n");
+
+	printk(KERN_INFO"dpti: If you have a lot of devices this could take a few minutes.\n");
+	for (pHba = hba_chain; pHba; pHba = pHba->next) {
+		printk(KERN_INFO"%s: Reading the hardware resource table.\n", pHba->name);
+		if (adpt_i2o_lct_get(pHba) < 0){
+			adpt_i2o_delete_hba(pHba);
+			continue;
+		}
+
+		if (adpt_i2o_parse_lct(pHba) < 0){
+			adpt_i2o_delete_hba(pHba);
+			continue;
+		}
+		adpt_inquiry(pHba);
+	}
+
+	for (pHba = hba_chain; pHba; pHba = pHba->next) {
+		if( adpt_scsi_register(pHba,sht) < 0){
+			adpt_i2o_delete_hba(pHba);
+			continue;
+		}
+		pHba->initialized = TRUE;
+		pHba->state &= ~DPTI_STATE_RESET;
+	}
+
+	// Register our control device node
+	// nodes will need to be created in /dev to access this
+	// the nodes can not be created from within the driver
+	if (hba_count && register_chrdev(DPTI_I2O_MAJOR, DPT_DRIVER, &adpt_fops)) {
+		adpt_i2o_sys_shutdown();
+		return 0;
+	}
+	return hba_count;
+}
+
+
+/*
+ * scsi_unregister will be called AFTER we return. 
+ */
+static int adpt_release(struct Scsi_Host *host)
+{
+	adpt_hba* pHba = (adpt_hba*) host->hostdata[0];
+//	adpt_i2o_quiesce_hba(pHba);
+	adpt_i2o_delete_hba(pHba);
+	return 0;
+}
+
+
+static void adpt_inquiry(adpt_hba* pHba)
+{
+	u32 msg[14]; 
+	u32 *mptr;
+	u32 *lenptr;
+	int direction;
+	int scsidir;
+	u32 len;
+	u32 reqlen;
+	u8* buf;
+	u8  scb[16];
+	s32 rcode;
+
+	memset(msg, 0, sizeof(msg));
+	buf = (u8*)kmalloc(80,GFP_KERNEL|ADDR32);
+	if(!buf){
+		printk(KERN_ERR"%s: Could not allocate buffer\n",pHba->name);
+		return;
+	}
+	memset((void*)buf, 0, 36);
+	
+	len = 36;
+	direction = 0x00000000;	
+	scsidir  =0x40000000;	// DATA IN  (iop<--dev)
+
+	reqlen = 14;		// SINGLE SGE
+	/* Stick the headers on */
+	msg[0] = reqlen<<16 | SGL_OFFSET_12;
+	msg[1] = (0xff<<24|HOST_TID<<12|ADAPTER_TID);
+	msg[2] = 0;
+	msg[3]  = 0;
+	// Adaptec/DPT Private stuff 
+	msg[4] = I2O_CMD_SCSI_EXEC|DPT_ORGANIZATION_ID<<16;
+	msg[5] = ADAPTER_TID | 1<<16 /* Interpret*/;
+	/* Direction, disconnect ok | sense data | simple queue , CDBLen */
+	// I2O_SCB_FLAG_ENABLE_DISCONNECT | 
+	// I2O_SCB_FLAG_SIMPLE_QUEUE_TAG | 
+	// I2O_SCB_FLAG_SENSE_DATA_IN_MESSAGE;
+	msg[6] = scsidir|0x20a00000| 6 /* cmd len*/;
+
+	mptr=msg+7;
+
+	memset(scb, 0, sizeof(scb));
+	// Write SCSI command into the message - always 16 byte block 
+	scb[0] = INQUIRY;
+	scb[1] = 0;
+	scb[2] = 0;
+	scb[3] = 0;
+	scb[4] = 36;
+	scb[5] = 0;
+	// Don't care about the rest of scb
+
+	memcpy(mptr, scb, sizeof(scb));
+	mptr+=4;
+	lenptr=mptr++;		/* Remember me - fill in when we know */
+
+	/* Now fill in the SGList and command */
+	*lenptr = len;
+	*mptr++ = 0xD0000000|direction|len;
+	*mptr++ = virt_to_bus(buf);
+
+	// Send it on it's way
+	rcode = adpt_i2o_post_wait(pHba, msg, reqlen<<2, 120);
+	if (rcode != 0) {
+		sprintf(pHba->detail, "Adaptec I2O RAID");
+		printk(KERN_INFO "%s: Inquiry Error (%d)\n",pHba->name,rcode);
+	} else {
+		memset(pHba->detail, 0, sizeof(pHba->detail));
+		memcpy(&(pHba->detail), "Vendor: Adaptec ", 16);
+		memcpy(&(pHba->detail[16]), " Model: ", 8);
+		memcpy(&(pHba->detail[24]), (u8*) &buf[16], 16);
+		memcpy(&(pHba->detail[40]), " FW: ", 4);
+		memcpy(&(pHba->detail[44]), (u8*) &buf[32], 4);
+		pHba->detail[48] = '\0';	/* precautionary */
+	}
+	kfree(buf);
+	adpt_i2o_status_get(pHba);
+	return ;
+}
+
+
+static void adpt_select_queue_depths(struct Scsi_Host *host, Scsi_Device * devicelist)
+{
+	Scsi_Device *device;	/* scsi layer per device information */
+	adpt_hba* pHba;
+
+	pHba = (adpt_hba *) host->hostdata[0];
+
+	for (device = devicelist; device != NULL; device = device->next) {
+		if (device->host != host) {
+			continue;
+		}
+		if (host->can_queue) {
+			device->queue_depth =  host->can_queue - 1;
+		} else {
+			device->queue_depth = 1;
+		}
+	}
+}
+
+static int adpt_queue(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
+{
+	adpt_hba* pHba = NULL;
+	struct adpt_device* pDev = NULL;	/* dpt per device information */
+	ulong timeout = jiffies + (TMOUT_SCSI*HZ);
+
+	cmd->scsi_done = done;
+	/*
+	 * SCSI REQUEST_SENSE commands will be executed automatically by the 
+	 * Host Adapter for any errors, so they should not be executed 
+	 * explicitly unless the Sense Data is zero indicating that no error 
+	 * occurred.
+	 */
+
+	if ((cmd->cmnd[0] == REQUEST_SENSE) && (cmd->sense_buffer[0] != 0)) {
+		cmd->result = (DID_OK << 16);
+		cmd->scsi_done(cmd);
+		return 0;
+	}
+
+	pHba = (adpt_hba*)cmd->host->hostdata[0];
+	if (!pHba) {
+		return FAILED;
+	}
+
+	rmb();
+	/*
+	 * TODO: I need to block here if I am processing ioctl cmds
+	 * but if the outstanding cmds all finish before the ioctl,
+	 * the scsi-core will not know to start sending cmds to me again.
+	 * I need to a way to restart the scsi-cores queues or should I block
+	 * calling scsi_done on the outstanding cmds instead
+	 * for now we don't set the IOCTL state
+	 */
+	if(((pHba->state) & DPTI_STATE_IOCTL) || ((pHba->state) & DPTI_STATE_RESET)) {
+		pHba->host->last_reset = jiffies;
+		pHba->host->resetting = 1;
+		return 1;
+	}
+
+	if(cmd->eh_state != SCSI_STATE_QUEUED){
+		// If we are not doing error recovery
+		mod_timer(&cmd->eh_timeout, timeout);
+	}
+
+	// TODO if the cmd->device if offline then I may need to issue a bus rescan
+	// followed by a get_lct to see if the device is there anymore
+	if((pDev = (struct adpt_device*) (cmd->device->hostdata)) == NULL) {
+		/*
+		 * First command request for this device.  Set up a pointer
+		 * to the device structure.  This should be a TEST_UNIT_READY
+		 * command from scan_scsis_single.
+		 */
+		if ((pDev = adpt_find_device(pHba, (u32)cmd->channel, (u32)cmd->target, (u32)cmd-> lun)) == NULL) {
+			// TODO: if any luns are at this bus, scsi id then fake a TEST_UNIT_READY and INQUIRY response 
+			// with type 7F (for all luns less than the max for this bus,id) so the lun scan will continue.
+			cmd->result = (DID_NO_CONNECT << 16);
+			cmd->scsi_done(cmd);
+			return 0;
+		}
+		(struct adpt_device*)(cmd->device->hostdata) = pDev;
+	}
+	pDev->pScsi_dev = cmd->device;
+
+	/*
+	 * If we are being called from when the device is being reset, 
+	 * delay processing of the command until later.
+	 */
+	if (pDev->state & DPTI_DEV_RESET ) {
+		return FAILED;
+	}
+	return adpt_scsi_to_i2o(pHba, cmd, pDev);
+}
+
+static int adpt_bios_param(Disk* disk, kdev_t dev, int geom[])
+{
+	int heads=-1;
+	int sectors=-1;
+	int cylinders=-1;
+
+	// *** First lets set the default geometry ****
+	
+	// If the capacity is less than ox2000
+	if (disk->capacity < 0x2000 ) {	// floppy
+		heads = 18;
+		sectors = 2;
+	} 
+	// else if between 0x2000 and 0x20000
+	else if (disk->capacity < 0x20000) {
+		heads = 64;
+		sectors = 32;
+	}
+	// else if between 0x20000 and 0x40000
+	else if (disk->capacity < 0x40000) {
+		heads = 65;
+		sectors = 63;
+	}
+	// else if between 0x4000 and 0x80000
+	else if (disk->capacity < 0x80000) {
+		heads = 128;
+		sectors = 63;
+	}
+	// else if greater than 0x80000
+	else {
+		heads = 255;
+		sectors = 63;
+	}
+	cylinders = disk->capacity / (heads * sectors);
+
+	// Special case if CDROM
+	if(disk->device->type == 5) {  // CDROM
+		heads = 252;
+		sectors = 63;
+		cylinders = 1111;
+	}
+
+	geom[0] = heads;
+	geom[1] = sectors;
+	geom[2] = cylinders;
+	
+	PDEBUG("adpt_bios_param: exit\n");
+	return 0;
+}
+
+
+static const char *adpt_info(struct Scsi_Host *host)
+{
+	adpt_hba* pHba;
+
+	pHba = (adpt_hba *) host->hostdata[0];
+	return (char *) (pHba->detail);
+}
+
+static int adpt_proc_info(char *buffer, char **start, off_t offset,
+		  int length, int hostno, int inout)
+{
+	struct adpt_device* d;
+	int id;
+	int chan;
+	int len = 0;
+	int begin = 0;
+	int pos = 0;
+	adpt_hba* pHba;
+	struct Scsi_Host *host;
+	int unit;
+
+	*start = buffer;
+	if (inout == TRUE) {
+		/*
+		 * The user has done a write and wants us to take the
+		 * data in the buffer and do something with it.
+		 * proc_scsiwrite calls us with inout = 1
+		 *
+		 * Read data from buffer (writing to us) - NOT SUPPORTED
+		 */
+		return -EINVAL;
+	}
+
+	/*
+	 * inout = 0 means the user has done a read and wants information
+	 * returned, so we write information about the cards into the buffer
+	 * proc_scsiread() calls us with inout = 0
+	 */
+
+	// Find HBA (host bus adapter) we are looking for
+	down(&adpt_configuration_lock);
+	for (pHba = hba_chain; pHba; pHba = pHba->next) {
+		if (pHba->host->host_no == hostno) {
+			break;	/* found adapter */
+		}
+	}
+	up(&adpt_configuration_lock);
+	if (pHba == NULL) {
+		return 0;
+	}
+	host = pHba->host;
+
+	len  = sprintf(buffer    , "Adaptec I2O RAID Driver Version: %s\n\n", DPT_I2O_VERSION);
+	len += sprintf(buffer+len, "%s\n", pHba->detail);
+	len += sprintf(buffer+len, "SCSI Host=scsi%d  Control Node=/dev/%s  irq=%d\n", 
+			pHba->host->host_no, pHba->name, host->irq);
+	len += sprintf(buffer+len, "\tpost fifo size  = %d\n\treply fifo size = %d\n\tsg table size   = %d\n\n",
+			host->can_queue, (int) pHba->reply_fifo_size , host->sg_tablesize);
+
+	pos = begin + len;
+
+	/* CHECKPOINT */
+	if(pos > offset + length) {
+		goto stop_output;
+	}
+	if(pos <= offset) {
+		/*
+		 * If we haven't even written to where we last left
+		 * off (the last time we were called), reset the 
+		 * beginning pointer.
+		 */
+		len = 0;
+		begin = pos;
+	}
+	len +=  sprintf(buffer+len, "Devices:\n");
+	for(chan = 0; chan < MAX_CHANNEL; chan++) {
+		for(id = 0; id < MAX_ID; id++) {
+			d = pHba->channel[chan].device[id];
+			while(d){
+				len += sprintf(buffer+len,"\t%-24.24s", d->pScsi_dev->vendor);
+				len += sprintf(buffer+len," Rev: %-8.8s\n", d->pScsi_dev->rev);
+				pos = begin + len;
+
+
+				/* CHECKPOINT */
+				if(pos > offset + length) {
+					goto stop_output;
+				}
+				if(pos <= offset) {
+					len = 0;
+					begin = pos;
+				}
+
+				unit = d->pI2o_dev->lct_data.tid;
+				len += sprintf(buffer+len, "\tTID=%d, (Channel=%d, Target=%d, Lun=%d)  (%s)\n\n",
+					       unit, (int)d->scsi_channel, (int)d->scsi_id, (int)d->scsi_lun,
+					       d->pScsi_dev->online? "online":"offline"); 
+				pos = begin + len;
+
+				/* CHECKPOINT */
+				if(pos > offset + length) {
+					goto stop_output;
+				}
+				if(pos <= offset) {
+					len = 0;
+					begin = pos;
+				}
+
+				d = d->next_lun;
+			}
+		}
+	}
+
+	/*
+	 * begin is where we last checked our position with regards to offset
+	 * begin is always less than offset.  len is relative to begin.  It
+	 * is the number of bytes written past begin
+	 *
+	 */
+stop_output:
+	/* stop the output and calculate the correct length */
+	*(buffer + len) = '\0';
+
+	*start = buffer + (offset - begin);	/* Start of wanted data */
+	len -= (offset - begin);
+	if(len > length) {
+		len = length;
+	} else if(len < 0){
+		len = 0;
+		**start = '\0';
+	}
+	return len;
+}
+
+
+/*===========================================================================
+ * Error Handling routines
+ *===========================================================================
+ */
+
+static int adpt_abort(Scsi_Cmnd * cmd)
+{
+	adpt_hba* pHba = NULL;	/* host bus adapter structure */
+	struct adpt_device* dptdevice;	/* dpt per device information */
+	u32 msg[5];
+	int rcode;
+
+	if(cmd->serial_number == 0){
+		return FAILED;
+	}
+	pHba = (adpt_hba*) cmd->host->hostdata[0];
+	printk(KERN_INFO"%s: Trying to Abort cmd=%ld\n",pHba->name, cmd->serial_number);
+	if ((dptdevice = (void*) (cmd->device->hostdata)) == NULL) {
+		printk(KERN_ERR "%s: Unable to abort: No device in cmnd\n",pHba->name);
+		return FAILED;
+	}
+
+	memset(msg, 0, sizeof(msg));
+	msg[0] = FIVE_WORD_MSG_SIZE|SGL_OFFSET_0;
+	msg[1] = I2O_CMD_SCSI_ABORT<<24|HOST_TID<<12|dptdevice->tid;
+	msg[2] = 0;
+	msg[3]= 0; 
+	msg[4] = (u32)cmd;
+	if( (rcode = adpt_i2o_post_wait(pHba, msg, sizeof(msg), FOREVER)) != 0){
+		if(rcode == -EOPNOTSUPP ){
+			printk(KERN_INFO"%s: Abort cmd not supported\n",pHba->name);
+			return FAILED;
+		}
+		printk(KERN_INFO"%s: Abort cmd=%ld failed.\n",pHba->name, cmd->serial_number);
+		return FAILED;
+	} 
+	printk(KERN_INFO"%s: Abort cmd=%ld complete.\n",pHba->name, cmd->serial_number);
+	return SUCCESS;
+}
+
+
+#define I2O_DEVICE_RESET 0x27
+// This is the same for BLK and SCSI devices
+// NOTE this is wrong in the i2o.h definitions
+// This is not currently supported by our adapter but we issue it anyway
+static int adpt_device_reset(Scsi_Cmnd* cmd)
+{
+	adpt_hba* pHba;
+	u32 msg[4];
+	u32 rcode;
+	int old_state;
+	struct adpt_device* d = (void*) cmd->device->hostdata;
+
+	pHba = (void*) cmd->host->hostdata[0];
+	printk(KERN_INFO"%s: Trying to reset device\n",pHba->name);
+	if (!d) {
+		printk(KERN_INFO"%s: Reset Device: Device Not found\n",pHba->name);
+		return FAILED;
+	}
+	memset(msg, 0, sizeof(msg));
+	msg[0] = FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
+	msg[1] = (I2O_DEVICE_RESET<<24|HOST_TID<<12|d->tid);
+	msg[2] = 0;
+	msg[3] = 0;
+
+	old_state = d->state;
+	d->state |= DPTI_DEV_RESET;
+	if( (rcode = adpt_i2o_post_wait(pHba, (void*)msg,sizeof(msg), FOREVER)) ){
+		d->state = old_state;
+		if(rcode == -EOPNOTSUPP ){
+			printk(KERN_INFO"%s: Device reset not supported\n",pHba->name);
+			return FAILED;
+		}
+		printk(KERN_INFO"%s: Device reset failed\n",pHba->name);
+		return FAILED;
+	} else {
+		d->state = old_state;
+		printk(KERN_INFO"%s: Device reset successful\n",pHba->name);
+		return SUCCESS;
+	}
+}
+
+
+#define I2O_HBA_BUS_RESET 0x87
+// This version of bus reset is called by the eh_error handler
+static int adpt_bus_reset(Scsi_Cmnd* cmd)
+{
+	adpt_hba* pHba;
+	u32 msg[4];
+
+	pHba = (adpt_hba*)cmd->host->hostdata[0];
+	memset(msg, 0, sizeof(msg));
+	printk(KERN_WARNING"%s: Bus reset: SCSI Bus %d: tid: %d\n",pHba->name, cmd->channel,pHba->channel[cmd->channel].tid );
+	msg[0] = FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
+	msg[1] = (I2O_HBA_BUS_RESET<<24|HOST_TID<<12|pHba->channel[cmd->channel].tid);
+	msg[2] = 0;
+	msg[3] = 0;
+	if(adpt_i2o_post_wait(pHba, (void*)msg,sizeof(msg), FOREVER) ){
+		printk(KERN_WARNING"%s: Bus reset failed.\n",pHba->name);
+		return FAILED;
+	} else {
+		printk(KERN_WARNING"%s: Bus reset success.\n",pHba->name);
+		return SUCCESS;
+	}
+}
+
+// This version of reset is called by the eh_error_handler
+static int adpt_reset(Scsi_Cmnd* cmd)
+{
+	adpt_hba* pHba;
+	int rcode;
+	pHba = (adpt_hba*)cmd->host->hostdata[0];
+	printk(KERN_WARNING"%s: Hba Reset: scsi id %d: tid: %d\n",pHba->name,cmd->channel,pHba->channel[cmd->channel].tid );
+	rcode =  adpt_hba_reset(pHba);
+	if(rcode == 0){
+		printk(KERN_WARNING"%s: HBA reset complete\n",pHba->name);
+		return SUCCESS;
+	} else {
+		printk(KERN_WARNING"%s: HBA reset failed (%x)\n",pHba->name, rcode);
+		return FAILED;
+	}
+}
+
+// This version of reset is called by the ioctls and indirectly from eh_error_handler via adpt_reset
+static int adpt_hba_reset(adpt_hba* pHba)
+{
+	int rcode;
+
+	pHba->state |= DPTI_STATE_RESET;
+
+	// Activate does get status , init outbound, and get hrt
+	if ((rcode=adpt_i2o_activate_hba(pHba)) < 0) {
+		printk(KERN_ERR "%s: Could not activate\n", pHba->name);
+		adpt_i2o_delete_hba(pHba);
+		return rcode;
+	}
+
+	if ((rcode=adpt_i2o_build_sys_table()) < 0) {
+		adpt_i2o_delete_hba(pHba);
+		return rcode;
+	}
+	PDEBUG("%s: in HOLD state\n",pHba->name);
+
+	if ((rcode=adpt_i2o_online_hba(pHba)) < 0) {
+		adpt_i2o_delete_hba(pHba);	
+		return rcode;
+	}
+	PDEBUG("%s: in OPERATIONAL state\n",pHba->name);
+
+	if ((rcode=adpt_i2o_lct_get(pHba)) < 0){
+		adpt_i2o_delete_hba(pHba);
+		return rcode;
+	}
+
+	if ((rcode=adpt_i2o_reparse_lct(pHba)) < 0){
+		adpt_i2o_delete_hba(pHba);
+		return rcode;
+	}
+	pHba->state &= ~DPTI_STATE_RESET;
+
+	adpt_fail_posted_scbs(pHba);
+	return 0;	/* return success */
+}
+
+/*===========================================================================
+ * 
+ *===========================================================================
+ */
+
+
+static void adpt_i2o_sys_shutdown(void)
+{
+	adpt_hba *pHba, *pNext;
+	struct adpt_i2o_post_wait_data *p1, *p2;
+
+	 printk(KERN_INFO"Shutting down Adaptec I2O controllers.\n");
+	 printk(KERN_INFO"   This could take a few minutes if there are many devices attached\n");
+	/* Delete all IOPs from the controller chain */
+	/* They should have already been released by the
+	 * scsi-core
+	 */
+	for (pHba = hba_chain; pHba; pHba = pNext) {
+		pNext = pHba->next;
+		adpt_i2o_delete_hba(pHba);
+	}
+
+	/* Remove any timedout entries from the wait queue.  */
+	p2 = NULL;
+//	spin_lock_irqsave(&adpt_post_wait_lock, flags);
+	/* Nothing should be outstanding at this point so just
+	 * free them 
+	 */
+	for(p1 = adpt_post_wait_queue; p1; p2 = p1, p1 = p2->next) {
+		kfree(p1);
+	}
+//	spin_unlock_irqrestore(&adpt_post_wait_lock, flags);
+	adpt_post_wait_queue = 0;
+
+	 printk(KERN_INFO "Adaptec I2O controllers down.\n");
+}
+
+/*
+ * reboot/shutdown notification.
+ *
+ * - Quiesce each IOP in the system
+ *
+ */
+
+#ifdef REBOOT_NOTIFIER
+static int adpt_reboot_event(struct notifier_block *n, ulong code, void *p)
+{
+
+	 if(code != SYS_RESTART && code != SYS_HALT && code != SYS_POWER_OFF)
+		  return NOTIFY_DONE;
+
+	 adpt_i2o_sys_shutdown();
+
+	 return NOTIFY_DONE;
+}
+#endif
+
+
+static int adpt_install_hba(Scsi_Host_Template* sht, struct pci_dev* pDev) 
+{
+
+	adpt_hba* pHba = NULL;
+	adpt_hba* p = NULL;
+	ulong base_addr0_phys = 0;
+	ulong base_addr1_phys = 0;
+	u32 hba_map0_area_size = 0;
+	u32 hba_map1_area_size = 0;
+	ulong base_addr_virt = 0;
+	ulong msg_addr_virt = 0;
+
+	int raptorFlag = FALSE;
+	int i;
+
+	if(pci_enable_device(pDev)) {
+		return -EINVAL;
+	}
+	pci_set_master(pDev);
+
+	base_addr0_phys = pci_resource_start(pDev,0);
+	hba_map0_area_size = pci_resource_len(pDev,0);
+
+	// Check if standard PCI card or single BAR Raptor
+	if(pDev->device == PCI_DPT_DEVICE_ID){
+		if(pDev->subsystem_device >=0xc032 && pDev->subsystem_device <= 0xc03b){
+			// Raptor card with this device id needs 4M
+			hba_map0_area_size = 0x400000;
+		} else { // Not Raptor - it is a PCI card
+			if(hba_map0_area_size > 0x100000 ){ 
+				hba_map0_area_size = 0x100000;
+			}
+		}
+	} else {// Raptor split BAR config
+		// Use BAR1 in this configuration
+		base_addr1_phys = pci_resource_start(pDev,1);
+		hba_map1_area_size = pci_resource_len(pDev,1);
+		raptorFlag = TRUE;
+	}
+
+
+	base_addr_virt = (ulong)ioremap(base_addr0_phys,hba_map0_area_size);
+	if(base_addr_virt == 0) {
+		PERROR("dpti: adpt_config_hba: io remap failed\n");
+		return -EINVAL;
+	}
+
+        if(raptorFlag == TRUE) {
+		msg_addr_virt = (ulong)ioremap(base_addr1_phys, hba_map1_area_size );
+		if(msg_addr_virt == 0) {
+			PERROR("dpti: adpt_config_hba: io remap failed on BAR1\n");
+			iounmap((void*)base_addr_virt);
+			return -EINVAL;
+		}
+	} else {
+		msg_addr_virt = base_addr_virt;
+	}
+	
+	// Allocate and zero the data structure
+	pHba = kmalloc(sizeof(adpt_hba), GFP_KERNEL);
+	if( pHba == NULL) {
+		if(msg_addr_virt != base_addr_virt){
+			iounmap((void*)msg_addr_virt);
+		}
+		iounmap((void*)base_addr_virt);
+		return -ENOMEM;
+	}
+	memset(pHba, 0, sizeof(adpt_hba));
+
+	down(&adpt_configuration_lock);
+	for(i=0;i<DPTI_MAX_HBA;i++) {
+		if(hbas[i]==NULL) {
+			hbas[i]=pHba;
+			break;
+		}
+	}
+
+	if(hba_chain != NULL){
+		for(p = hba_chain; p->next; p = p->next);
+		p->next = pHba;
+	} else {
+		hba_chain = pHba;
+	}
+	pHba->next = NULL;
+	pHba->unit = hba_count;
+	sprintf(pHba->name, "dpti%d", i);
+	hba_count++;
+	
+	up(&adpt_configuration_lock);
+
+	pHba->pDev = pDev;
+	pHba->base_addr_phys = base_addr0_phys;
+
+	// Set up the Virtual Base Address of the I2O Device
+	pHba->base_addr_virt = base_addr_virt;
+	pHba->msg_addr_virt = msg_addr_virt;  
+	pHba->irq_mask = (ulong)(base_addr_virt+0x30);
+	pHba->post_port = (ulong)(base_addr_virt+0x40);
+	pHba->reply_port = (ulong)(base_addr_virt+0x44);
+
+	pHba->hrt = NULL;
+	pHba->lct = NULL;
+	pHba->lct_size = 0;
+	pHba->status_block = NULL;
+	pHba->post_count = 0;
+	pHba->state = DPTI_STATE_RESET;
+	pHba->pDev = pDev;
+	pHba->devices = NULL;
+
+	// Initializing the spinlocks
+	spin_lock_init(&pHba->state_lock);
+
+	if(raptorFlag == 0){
+		printk(KERN_INFO"Adaptec I2O RAID controller %d at %lx size=%x irq=%d\n", 
+			hba_count-1, base_addr_virt, hba_map0_area_size, pDev->irq);
+	} else {
+		printk(KERN_INFO"Adaptec I2O RAID controller %d irq=%d\n",hba_count-1, pDev->irq);
+		printk(KERN_INFO"     BAR0 %lx - size= %x\n",base_addr_virt,hba_map0_area_size);
+		printk(KERN_INFO"     BAR1 %lx - size= %x\n",msg_addr_virt,hba_map1_area_size);
+	}
+
+	if (request_irq (pDev->irq, adpt_isr, SA_SHIRQ, pHba->name, pHba)) {
+		printk(KERN_ERR"%s: Couldn't register IRQ %d\n", pHba->name, pDev->irq);
+		adpt_i2o_delete_hba(pHba);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+
+static void adpt_i2o_delete_hba(adpt_hba* pHba)
+{
+	adpt_hba* p1;
+	adpt_hba* p2;
+	struct i2o_device* d;
+	struct i2o_device* next;
+	int i;
+	int j;
+	struct adpt_device* pDev;
+	struct adpt_device* pNext;
+
+
+	down(&adpt_configuration_lock);
+	// scsi_unregister calls our adpt_release which
+	// does a quiese
+	if(pHba->host){
+		free_irq(pHba->host->irq, pHba);
+	}
+	for(i=0;i<DPTI_MAX_HBA;i++) {
+		if(hbas[i]==pHba) {
+			hbas[i] = NULL;
+		}
+	}
+	p2 = NULL;
+	for( p1 = hba_chain; p1; p2 = p1,p1=p1->next){
+		if(p1 == pHba) {
+			if(p2) {
+				p2->next = p1->next;
+			} else {
+				hba_chain = p1->next;
+			}
+			break;
+		}
+	}
+
+	hba_count--;
+	up(&adpt_configuration_lock);
+
+	iounmap((void*)pHba->base_addr_virt);
+	if(pHba->msg_addr_virt != pHba->base_addr_virt){
+		iounmap((void*)pHba->msg_addr_virt);
+	}
+	if(pHba->hrt) {
+		kfree(pHba->hrt);
+	}
+	if(pHba->lct){
+		kfree(pHba->lct);
+	}
+	if(pHba->status_block) {
+		kfree(pHba->status_block);
+	}
+	if(pHba->reply_pool){
+		kfree(pHba->reply_pool);
+	}
+
+	for(d = pHba->devices; d ; d = next){
+		next = d->next;
+		kfree(d);
+	}
+	for(i = 0 ; i < pHba->top_scsi_channel ; i++){
+		for(j = 0; j < MAX_ID; j++){
+			if(pHba->channel[i].device[j] != NULL){
+				for(pDev = pHba->channel[i].device[j]; pDev; pDev = pNext){
+					pNext = pDev->next_lun;
+					kfree(pDev);
+				}
+			}
+		}
+	}
+	kfree(pHba);
+
+	if(hba_count <= 0){
+		unregister_chrdev(DPTI_I2O_MAJOR, DPT_DRIVER);   
+	}
+}
+
+
+static int adpt_init(void)
+{
+	int i;
+
+	printk(KERN_INFO"Loading Adaptec I2O RAID: Version " DPT_I2O_VERSION "\n");
+	for (i = 0; i < DPTI_MAX_HBA; i++) {
+		hbas[i] = NULL;
+	}
+#ifdef REBOOT_NOTIFIER
+	register_reboot_notifier(&adpt_reboot_notifier);
+#endif
+
+	return 0;
+}
+
+
+static struct adpt_device* adpt_find_device(adpt_hba* pHba, u32 chan, u32 id, u32 lun)
+{
+	struct adpt_device* d;
+
+	if(chan < 0 || chan >= MAX_CHANNEL)
+		return NULL;
+	
+	if( pHba->channel[chan].device == NULL){
+		printk(KERN_DEBUG"Adaptec I2O RAID: Trying to find device before they are allocated\n");
+		return NULL;
+	}
+
+	d = pHba->channel[chan].device[id];
+	if(!d || d->tid == 0) {
+		return NULL;
+	}
+
+	/* If it is the only lun at that address then this should match*/
+	if(d->scsi_lun == lun){
+		return d;
+	}
+
+	/* else we need to look through all the luns */
+	for(d=d->next_lun ; d ; d = d->next_lun){
+		if(d->scsi_lun == lun){
+			return d;
+		}
+	}
+	return NULL;
+}
+
+
+static int adpt_i2o_post_wait(adpt_hba* pHba, u32* msg, int len, int timeout)
+{
+	// I used my own version of the WAIT_QUEUE_HEAD
+	// to handle some version differences
+	// When embedded in the kernel this could go back to the vanilla one
+	ADPT_DECLARE_WAIT_QUEUE_HEAD(adpt_wq_i2o_post);
+	int status = 0;
+	ulong flags = 0;
+	struct adpt_i2o_post_wait_data *p1, *p2;
+	struct adpt_i2o_post_wait_data *wait_data =
+		kmalloc(sizeof(struct adpt_i2o_post_wait_data),GFP_KERNEL);
+	adpt_wait_queue_t wait;
+
+	if(!wait_data){
+		return -ENOMEM;
+	}
+	/*
+	 * The spin locking is needed to keep anyone from playing
+	 * with the queue pointers and id while we do the same
+	 */
+	spin_lock_irqsave(&adpt_post_wait_lock, flags);
+       // TODO we need a MORE unique way of getting ids
+       // to support async LCT get
+	wait_data->next = adpt_post_wait_queue;
+	adpt_post_wait_queue = wait_data;
+	adpt_post_wait_id = (++adpt_post_wait_id & 0x7fff);
+	wait_data->id =  adpt_post_wait_id;
+	spin_unlock_irqrestore(&adpt_post_wait_lock, flags);
+
+	wait_data->wq = &adpt_wq_i2o_post;
+	wait_data->status = -ETIMEDOUT;
+
+	// this code is taken from kernel/sched.c:interruptible_sleep_on_timeout
+	wait.task = current;
+	init_waitqueue_entry(&wait, current);
+	wq_write_lock_irqsave(&adpt_wq_i2o_post.lock,flags);
+	__add_wait_queue(&adpt_wq_i2o_post, &wait);
+	wq_write_unlock(&adpt_wq_i2o_post.lock);
+
+	msg[2] |= 0x80000000 | ((u32)wait_data->id);
+	timeout *= HZ;
+	if((status = adpt_i2o_post_this(pHba, msg, len)) == 0){
+		if(!timeout){
+			current->state = TASK_INTERRUPTIBLE;
+			spin_unlock_irq(&io_request_lock);
+			schedule();
+			spin_lock_irq(&io_request_lock);
+		} else {
+			current->state = TASK_INTERRUPTIBLE;
+			spin_unlock_irq(&io_request_lock);
+			schedule_timeout(timeout*HZ);
+			spin_lock_irq(&io_request_lock);
+		}
+	}
+	wq_write_lock_irq(&adpt_wq_i2o_post.lock);
+	__remove_wait_queue(&adpt_wq_i2o_post, &wait);
+	wq_write_unlock_irqrestore(&adpt_wq_i2o_post.lock,flags);
+
+	if(status == -ETIMEDOUT){
+		printk(KERN_INFO"dpti%d: POST WAIT TIMEOUT\n",pHba->unit);
+		// We will have to free the wait_data memory during shutdown
+		return status;
+	}
+
+	/* Remove the entry from the queue.  */
+	p2 = NULL;
+	spin_lock_irqsave(&adpt_post_wait_lock, flags);
+	for(p1 = adpt_post_wait_queue; p1; p2 = p1, p1 = p1->next) {
+		if(p1 == wait_data) {
+			if(p1->status == I2O_DETAIL_STATUS_UNSUPPORTED_FUNCTION ) {
+				status = -EOPNOTSUPP;
+			}
+			if(p2) {
+				p2->next = p1->next;
+			} else {
+				adpt_post_wait_queue = p1->next;
+			}
+			break;
+		}
+	}
+	spin_unlock_irqrestore(&adpt_post_wait_lock, flags);
+
+	kfree(wait_data);
+
+	return status;
+}
+
+
+static s32 adpt_i2o_post_this(adpt_hba* pHba, u32* data, int len)
+{
+
+	u32 m = EMPTY_QUEUE;
+	u32 *msg;
+	ulong timeout = jiffies + 30*HZ;
+	do {
+		rmb();
+		m = readl(pHba->post_port);
+		if (m != EMPTY_QUEUE) {
+			break;
+		}
+		if(time_after(jiffies,timeout)){
+			printk(KERN_WARNING"dpti%d: Timeout waiting for message frame!\n", pHba->unit);
+			return -ETIMEDOUT;
+		}
+	} while(m == EMPTY_QUEUE);
+		
+	msg = (u32*) (pHba->msg_addr_virt + m);
+	memcpy_toio(msg, data, len);
+	wmb();
+
+	//post message
+	writel(m, pHba->post_port);
+	wmb();
+
+	return 0;
+}
+
+
+static void adpt_i2o_post_wait_complete(u32 context, int status)
+{
+	struct adpt_i2o_post_wait_data *p1 = NULL;
+	/*
+	 * We need to search through the adpt_post_wait
+	 * queue to see if the given message is still
+	 * outstanding.  If not, it means that the IOP
+	 * took longer to respond to the message than we
+	 * had allowed and timer has already expired.
+	 * Not much we can do about that except log
+	 * it for debug purposes, increase timeout, and recompile
+	 *
+	 * Lock needed to keep anyone from moving queue pointers
+	 * around while we're looking through them.
+	 */
+
+	context &= 0x7fff;
+
+	spin_lock(&adpt_post_wait_lock);
+	for(p1 = adpt_post_wait_queue; p1; p1 = p1->next) {
+		if(p1->id == context) {
+			p1->status = status;
+			spin_unlock(&adpt_post_wait_lock);
+			wake_up_interruptible(p1->wq);
+			return;
+		}
+	}
+	spin_unlock(&adpt_post_wait_lock);
+        // If this happens we loose commands that probably really completed
+	printk(KERN_DEBUG"dpti: Could Not find task %d in wait queue\n",context);
+	printk(KERN_DEBUG"      Tasks in wait queue:\n");
+	for(p1 = adpt_post_wait_queue; p1; p1 = p1->next) {
+		printk(KERN_DEBUG"           %d\n",p1->id);
+	}
+	return;
+}
+
+static s32 adpt_i2o_reset_hba(adpt_hba* pHba)			
+{
+	u32 msg[8];
+	u8* status;
+	u32 m = EMPTY_QUEUE ;
+	ulong timeout = jiffies + (TMOUT_IOPRESET*HZ);
+
+	if(pHba->initialized  == FALSE) {	// First time reset should be quick
+		timeout = jiffies + (25*HZ);
+	} else {
+		adpt_i2o_quiesce_hba(pHba);
+	}
+
+	do {
+		rmb();
+		m = readl(pHba->post_port);
+		if (m != EMPTY_QUEUE) {
+			break;
+		}
+		if(time_after(jiffies,timeout)){
+			printk(KERN_WARNING"Timeout waiting for message!\n");
+			return -ETIMEDOUT;
+		}
+	} while (m == EMPTY_QUEUE);
+
+	status = (u8*)kmalloc(4, GFP_KERNEL|ADDR32);
+	if(status == NULL) {
+		adpt_send_nop(pHba, m);
+		printk(KERN_ERR"IOP reset failed - no free memory.\n");
+		return -ENOMEM;
+	}
+	memset(status,0,4);
+
+	msg[0]=EIGHT_WORD_MSG_SIZE|SGL_OFFSET_0;
+	msg[1]=I2O_CMD_ADAPTER_RESET<<24|HOST_TID<<12|ADAPTER_TID;
+	msg[2]=0;
+	msg[3]=0;
+	msg[4]=0;
+	msg[5]=0;
+	msg[6]=virt_to_bus(status);
+	msg[7]=0;     
+
+	memcpy_toio(pHba->msg_addr_virt+m, msg, sizeof(msg));
+	wmb();
+	writel(m, pHba->post_port);
+	wmb();
+
+	while(*status == 0){
+		if(time_after(jiffies,timeout)){
+			printk(KERN_WARNING"%s: IOP Reset Timeout\n",pHba->name);
+			kfree(status);
+			return -ETIMEDOUT;
+		}
+		rmb();
+	}
+
+	if(*status == 0x01 /*I2O_EXEC_IOP_RESET_IN_PROGRESS*/) {
+		PDEBUG("%s: Reset in progress...\n", pHba->name);
+		// Here we wait for message frame to become available
+		// indicated that reset has finished
+		do {
+			rmb();
+			m = readl(pHba->post_port);
+			if (m != EMPTY_QUEUE) {
+				break;
+			}
+			if(time_after(jiffies,timeout)){
+				printk(KERN_ERR "%s:Timeout waiting for IOP Reset.\n",pHba->name);
+				return -ETIMEDOUT;
+			}
+		} while (m == EMPTY_QUEUE);
+		// Flush the offset
+		adpt_send_nop(pHba, m);
+	}
+	adpt_i2o_status_get(pHba);
+	if(*status == 0x02 ||
+			pHba->status_block->iop_state != ADAPTER_STATE_RESET) {
+		printk(KERN_WARNING"%s: Reset reject, trying to clear\n",
+				pHba->name);
+	} else {
+		PDEBUG("%s: Reset completed.\n", pHba->name);
+	}
+
+	kfree(status);
+#ifdef UARTDELAY
+	// This delay is to allow someone attached to the card through the debug UART to 
+	// set up the dump levels that they want before the rest of the initialization sequence
+	adpt_delay(20000);
+#endif
+	return 0;
+}
+
+
+static int adpt_i2o_parse_lct(adpt_hba* pHba)
+{
+	int i;
+	int max;
+	int tid;
+	struct i2o_device *d;
+	i2o_lct *lct = pHba->lct;
+	u8 bus_no = 0;
+	s16 scsi_id;
+	s16 scsi_lun;
+	u32 buf[10]; // larger than 7, or 8 ...
+	struct adpt_device* pDev; 
+	
+	if (lct == NULL) {
+		printk(KERN_ERR "%s: LCT is empty???\n",pHba->name);
+		return -1;
+	}
+	
+	max = lct->table_size;	
+	max -= 3;
+	max /= 9;
+
+	for(i=0;i<max;i++) {
+		if( lct->lct_entry[i].user_tid != 0xfff){
+			/*
+			 * If we have hidden devices, we need to inform the upper layers about
+			 * the possible maximum id reference to handle device access when
+			 * an array is disassembled. This code has no other purpose but to
+			 * allow us future access to devices that are currently hidden
+			 * behind arrays, hotspares or have not been configured (JBOD mode).
+			 */
+			if( lct->lct_entry[i].class_id != I2O_CLASS_RANDOM_BLOCK_STORAGE &&
+			    lct->lct_entry[i].class_id != I2O_CLASS_SCSI_PERIPHERAL &&
+			    lct->lct_entry[i].class_id != I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL ){
+			    	continue;
+			}
+			tid = lct->lct_entry[i].tid;
+			// I2O_DPT_DEVICE_INFO_GROUP_NO;
+			if(adpt_i2o_query_scalar(pHba, tid, 0x8000, -1, buf, 32)<0) {
+				continue;
+			}
+			bus_no = buf[0]>>16;
+			scsi_id = buf[1];
+			scsi_lun = (buf[2]>>8 )&0xff;
+			if(bus_no >= MAX_CHANNEL) {	// Something wrong skip it
+				printk(KERN_WARNING"%s: Channel number %d out of range \n", pHba->name, bus_no);
+				continue;
+			}
+			if(scsi_id > MAX_ID){
+				printk(KERN_WARNING"%s: SCSI ID %d out of range \n", pHba->name, bus_no);
+				continue;
+			}
+			if(bus_no > pHba->top_scsi_channel){
+				pHba->top_scsi_channel = bus_no;
+			}
+			if(scsi_id > pHba->top_scsi_id){
+				pHba->top_scsi_id = scsi_id;
+			}
+			if(scsi_lun > pHba->top_scsi_lun){
+				pHba->top_scsi_lun = scsi_lun;
+			}
+			continue;
+		}
+		d = (struct i2o_device *)kmalloc(sizeof(struct i2o_device), GFP_KERNEL);
+		if(d==NULL)
+		{
+			printk(KERN_CRIT"%s: Out of memory for I2O device data.\n",pHba->name);
+			return -ENOMEM;
+		}
+		
+		d->controller = (void*)pHba;
+		d->next = NULL;
+
+		memcpy(&d->lct_data, &lct->lct_entry[i], sizeof(i2o_lct_entry));
+
+		d->flags = 0;
+		tid = d->lct_data.tid;
+		adpt_i2o_report_hba_unit(pHba, d);
+		adpt_i2o_install_device(pHba, d);
+	}
+	bus_no = 0;
+	for(d = pHba->devices; d ; d = d->next) {
+		if(d->lct_data.class_id  == I2O_CLASS_BUS_ADAPTER_PORT ||
+		   d->lct_data.class_id  == I2O_CLASS_FIBRE_CHANNEL_PORT){
+			tid = d->lct_data.tid;
+			// TODO get the bus_no from hrt-but for now they are in order
+			//bus_no = 
+			if(bus_no > pHba->top_scsi_channel){
+				pHba->top_scsi_channel = bus_no;
+			}
+			pHba->channel[bus_no].type = d->lct_data.class_id;
+			pHba->channel[bus_no].tid = tid;
+			if(adpt_i2o_query_scalar(pHba, tid, 0x0200, -1, buf, 28)>=0)
+			{
+				pHba->channel[bus_no].scsi_id = buf[1];
+				PDEBUG("Bus %d - SCSI ID %d.\n", bus_no, buf[1]);
+			}
+			// TODO remove - this is just until we get from hrt
+			bus_no++;
+			if(bus_no >= MAX_CHANNEL) {	// Something wrong skip it
+				printk(KERN_WARNING"%s: Channel number %d out of range - LCT\n", pHba->name, bus_no);
+				break;
+			}
+		}
+	}
+
+	// Setup adpt_device table
+	for(d = pHba->devices; d ; d = d->next) {
+		if(d->lct_data.class_id  == I2O_CLASS_RANDOM_BLOCK_STORAGE ||
+		   d->lct_data.class_id  == I2O_CLASS_SCSI_PERIPHERAL ||
+		   d->lct_data.class_id  == I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL ){
+
+			tid = d->lct_data.tid;
+			scsi_id = -1;
+			// I2O_DPT_DEVICE_INFO_GROUP_NO;
+			if(adpt_i2o_query_scalar(pHba, tid, 0x8000, -1, buf, 32)>=0) {
+				bus_no = buf[0]>>16;
+				scsi_id = buf[1];
+				scsi_lun = (buf[2]>>8 )&0xff;
+				if(bus_no >= MAX_CHANNEL) {	// Something wrong skip it
+					continue;
+				}
+				if(scsi_id > MAX_ID){
+					continue;
+				}
+				if( pHba->channel[bus_no].device[scsi_id] == NULL){
+					pDev =  kmalloc(sizeof(struct adpt_device),GFP_KERNEL);
+					if(pDev == NULL) {
+						return -ENOMEM;
+					}
+					pHba->channel[bus_no].device[scsi_id] = pDev;
+					memset(pDev,0,sizeof(struct adpt_device));
+				} else {
+					for( pDev = pHba->channel[bus_no].device[scsi_id];	
+							pDev->next_lun; pDev = pDev->next_lun){
+					}
+					pDev->next_lun = kmalloc(sizeof(struct adpt_device),GFP_KERNEL);
+					if(pDev == NULL) {
+						return -ENOMEM;
+					}
+					memset(pDev->next_lun,0,sizeof(struct adpt_device));
+					pDev = pDev->next_lun;
+				}
+				pDev->tid = tid;
+				pDev->scsi_channel = bus_no;
+				pDev->scsi_id = scsi_id;
+				pDev->scsi_lun = scsi_lun;
+				pDev->pI2o_dev = d;
+				d->owner = pDev;
+				pDev->type = (buf[0])&0xff;
+				pDev->flags = (buf[0]>>8)&0xff;
+				if(scsi_id > pHba->top_scsi_id){
+					pHba->top_scsi_id = scsi_id;
+				}
+				if(scsi_lun > pHba->top_scsi_lun){
+					pHba->top_scsi_lun = scsi_lun;
+				}
+			}
+			if(scsi_id == -1){
+				printk(KERN_WARNING"Could not find SCSI ID for %s\n",
+						d->lct_data.identity_tag);
+			}
+		}
+	}
+	return 0;
+}
+
+
+/*
+ *	Each I2O controller has a chain of devices on it - these match
+ *	the useful parts of the LCT of the board.
+ */
+ 
+static int adpt_i2o_install_device(adpt_hba* pHba, struct i2o_device *d)
+{
+	down(&adpt_configuration_lock);
+	d->controller=pHba;
+	d->owner=NULL;
+	d->next=pHba->devices;
+	d->prev=NULL;
+	if (pHba->devices != NULL){
+		pHba->devices->prev=d;
+	}
+	pHba->devices=d;
+	*d->dev_name = 0;
+
+	up(&adpt_configuration_lock);
+	return 0;
+}
+
+static int adpt_open(struct inode *inode, struct file *file)
+{
+	int minor;
+	adpt_hba* pHba;
+
+	//TODO check for root access
+	//
+	minor = MINOR(inode->i_rdev);
+	if (minor >= hba_count) {
+		return -ENXIO;
+	}
+	down(&adpt_configuration_lock);
+	for (pHba = hba_chain; pHba; pHba = pHba->next) {
+		if (pHba->unit == minor) {
+			break;	/* found adapter */
+		}
+	}
+	if (pHba == NULL) {
+		up(&adpt_configuration_lock);
+		return -ENXIO;
+	}
+
+//	if(pHba->in_use){
+	//	up(&adpt_configuration_lock);
+//		return -EBUSY;
+//	}
+
+	pHba->in_use = 1;
+	up(&adpt_configuration_lock);
+
+	return 0;
+}
+
+static int adpt_close(struct inode *inode, struct file *file)
+{
+	int minor;
+	adpt_hba* pHba;
+
+	minor = MINOR(inode->i_rdev);
+	if (minor >= hba_count) {
+		return -ENXIO;
+	}
+	down(&adpt_configuration_lock);
+	for (pHba = hba_chain; pHba; pHba = pHba->next) {
+		if (pHba->unit == minor) {
+			break;	/* found adapter */
+		}
+	}
+	up(&adpt_configuration_lock);
+	if (pHba == NULL) {
+		return -ENXIO;
+	}
+
+	pHba->in_use = 0;
+
+	return 0;
+}
+
+
+static int adpt_i2o_passthru(adpt_hba* pHba, u32* arg)
+{
+	u32 msg[MAX_MESSAGE_SIZE];
+	u32* reply = NULL;
+	u32 size = 0;
+	u32 reply_size = 0;
+	u32* user_msg = (u32*)arg;
+	u32* user_reply = NULL;
+	ulong sg_list[pHba->sg_tablesize];
+	u32 sg_offset = 0;
+	u32 sg_count = 0;
+	int sg_index = 0;
+	u32 i = 0;
+	u32 rcode = 0;
+	ulong p = 0;
+	ulong flags = 0;
+
+	memset(&msg, 0, MAX_MESSAGE_SIZE*4);
+	// get user msg size in u32s 
+	if(get_user(size, &user_msg[0])){
+		return -EFAULT;
+	}
+	size = size>>16;
+
+	user_reply = &user_msg[size];
+	if(size > MAX_MESSAGE_SIZE){
+		return -EFAULT;
+	}
+	size *= 4; // Convert to bytes
+
+	/* Copy in the user's I2O command */
+	if(copy_from_user((void*)msg, (void*)user_msg, size)) {
+		return -EFAULT;
+	}
+	get_user(reply_size, &user_reply[0]);
+	reply_size = reply_size>>16;
+	if(reply_size > REPLY_FRAME_SIZE){
+		reply_size = REPLY_FRAME_SIZE;
+	}
+	reply_size *= 4;
+	reply = kmalloc(REPLY_FRAME_SIZE*4, GFP_KERNEL);
+	if(reply == NULL) {
+		printk(KERN_WARNING"%s: Could not allocate reply buffer\n",pHba->name);
+		return -ENOMEM;
+	}
+	memset(reply,0,REPLY_FRAME_SIZE*4);
+	sg_offset = (msg[0]>>4)&0xf;
+	msg[2] = 0x40000000; // IOCTL context
+	msg[3] = (u32)reply;
+	memset(sg_list,0, sizeof(sg_list[0])*pHba->sg_tablesize);
+	if(sg_offset) {
+		// TODO 64bit fix
+		struct sg_simple_element *sg =  (struct sg_simple_element*) (msg+sg_offset);
+		sg_count = (size - sg_offset*4) / sizeof(struct sg_simple_element);
+		if (sg_count > pHba->sg_tablesize){
+			printk(KERN_DEBUG"%s:IOCTL SG List too large (%u)\n", pHba->name,sg_count);
+			kfree (reply);
+			return -EINVAL;
+		}
+
+		for(i = 0; i < sg_count; i++) {
+			int sg_size;
+
+			if (!(sg[i].flag_count & 0x10000000 /*I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT*/)) {
+				printk(KERN_DEBUG"%s:Bad SG element %d - not simple (%x)\n",pHba->name,i,  sg[i].flag_count);
+				rcode = -EINVAL;
+				goto cleanup;
+			}
+			sg_size = sg[i].flag_count & 0xffffff;      
+			/* Allocate memory for the transfer */
+			p = (ulong)kmalloc(sg_size, GFP_KERNEL|ADDR32);
+			if(p == 0) {
+				printk(KERN_DEBUG"%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
+						pHba->name,sg_size,i,sg_count);
+				rcode = -ENOMEM;
+				goto cleanup;
+			}
+			sg_list[sg_index++] = p; // sglist indexed with input frame, not our internal frame.
+			/* Copy in the user's SG buffer if necessary */
+			if(sg[i].flag_count & 0x04000000 /*I2O_SGL_FLAGS_DIR*/) {
+				// TODO 64bit fix
+				if (copy_from_user((void*)p,(void*)sg[i].addr_bus, sg_size)) {
+					printk(KERN_DEBUG"%s: Could not copy SG buf %d FROM user\n",pHba->name,i);
+					rcode = -EFAULT;
+					goto cleanup;
+				}
+			}
+			//TODO 64bit fix
+			sg[i].addr_bus = (u32)virt_to_bus((void*)p);
+		}
+	}
+
+	do {
+		spin_lock_irqsave(&io_request_lock, flags);
+		// This state stops any new commands from enterring the
+		// controller while processing the ioctl
+//		pHba->state |= DPTI_STATE_IOCTL;
+//		We can't set this now - The scsi subsystem sets host_blocked and
+//		the queue empties and stops.  We need a way to restart the queue
+		rcode = adpt_i2o_post_wait(pHba, msg, size, FOREVER);
+//		pHba->state &= ~DPTI_STATE_IOCTL;
+		spin_unlock_irqrestore(&io_request_lock, flags);
+	} while(rcode == -ETIMEDOUT);  
+
+	if(rcode){
+		goto cleanup;
+	}
+
+	if(sg_offset) {
+	/* Copy back the Scatter Gather buffers back to user space */
+		u32 j;
+		// TODO 64bit fix
+		struct sg_simple_element* sg;
+		int sg_size;
+
+		// re-acquire the original message to handle correctly the sg copy operation
+		memset(&msg, 0, MAX_MESSAGE_SIZE*4); 
+		// get user msg size in u32s 
+		if(get_user(size, &user_msg[0])){
+			rcode = -EFAULT; 
+			goto cleanup; 
+		}
+		size = size>>16;
+		size *= 4;
+		/* Copy in the user's I2O command */
+		if (copy_from_user ((void*)msg, (void*)user_msg, size)) {
+			rcode = -EFAULT;
+			goto cleanup;
+		}
+		sg_count = (size - sg_offset*4) / sizeof(struct sg_simple_element);
+
+		// TODO 64bit fix
+		sg 	 = (struct sg_simple_element*)(msg + sg_offset);
+		for (j = 0; j < sg_count; j++) {
+			/* Copy out the SG list to user's buffer if necessary */
+			if(! (sg[j].flag_count & 0x4000000 /*I2O_SGL_FLAGS_DIR*/)) {
+				sg_size = sg[j].flag_count & 0xffffff; 
+				// TODO 64bit fix
+				if (copy_to_user((void*)sg[j].addr_bus,(void*)sg_list[j], sg_size)) {
+					printk(KERN_WARNING"%s: Could not copy %lx TO user %x\n",pHba->name, sg_list[j], sg[j].addr_bus);
+					rcode = -EFAULT;
+					goto cleanup;
+				}
+			}
+		}
+	} 
+
+	/* Copy back the reply to user space */
+	if (reply_size) {
+		// we wrote our own values for context - now restore the user supplied ones
+		if(copy_from_user(reply+2, user_msg+2, sizeof(u32)*2)) {
+			printk(KERN_WARNING"%s: Could not copy message context FROM user\n",pHba->name);
+			rcode = -EFAULT;
+		}
+		if(copy_to_user(user_reply, reply, reply_size)) {
+			printk(KERN_WARNING"%s: Could not copy reply TO user\n",pHba->name);
+			rcode = -EFAULT;
+		}
+	}
+
+
+cleanup:
+	kfree (reply);
+	while(sg_index) {
+		if(sg_list[--sg_index]) {
+			kfree((void*)(sg_list[sg_index]));
+		}
+	}
+	return rcode;
+}
+
+
+/*
+ * This routine returns information about the system.  This does not effect
+ * any logic and if the info is wrong - it doesn't matter.
+ */
+
+/* Get all the info we can not get from kernel services */
+static int adpt_system_info(void *buffer)
+{
+	sysInfo_S si;
+
+	memset(&si, 0, sizeof(si));
+
+	si.osType = OS_LINUX;
+	si.osMajorVersion = (u8) (LINUX_VERSION_CODE >> 16);
+	si.osMinorVersion = (u8) (LINUX_VERSION_CODE >> 8 & 0x0ff);
+	si.osRevision =     (u8) (LINUX_VERSION_CODE & 0x0ff);
+	si.busType = SI_PCI_BUS;
+	si.processorFamily = DPTI_sig.dsProcessorFamily;
+
+#if defined __i386__ 
+	adpt_i386_info(&si);
+#elif defined __ia64__
+	adpt_ia64_info(&si);
+#elif define __sparc__
+	adpt_sparc_info(&si);
+#elif defined __alpha__ 
+	adpt_alpha_info(&si);
+#else
+	si.processorType = 0xff ;
+#endif
+	if(copy_to_user(buffer, &si, sizeof(si))){
+		printk(KERN_WARNING"dpti: Could not copy buffer TO user\n");
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+#if defined __ia64__ 
+static void adpt_ia64_info(sysInfo_S* si)
+{
+	// This is all the info we need for now
+	// We will add more info as our new
+	// managmenent utility requires it
+	si->processorType = PROC_IA64;
+}
+#endif
+
+
+#if defined __sparc__ 
+static void adpt_sparc_info(sysInfo_S* si)
+{
+	// This is all the info we need for now
+	// We will add more info as our new
+	// managmenent utility requires it
+	si->processorType = PROC_ULTRASPARC;
+}
+#endif
+
+#if defined __alpha__ 
+static void adpt_sparc_info(sysInfo_S* si)
+{
+	// This is all the info we need for now
+	// We will add more info as our new
+	// managmenent utility requires it
+	si->processorType = PROC_ALPHA;
+}
+#endif
+
+#if defined __i386__
+
+static void adpt_i386_info(sysInfo_S* si)
+{
+	// This is all the info we need for now
+	// We will add more info as our new
+	// managmenent utility requires it
+	switch (boot_cpu_data.x86) {
+	case CPU_386:
+		si->processorType = PROC_386;
+		break;
+	case CPU_486:
+		si->processorType = PROC_486;
+		break;
+	case CPU_586:
+		si->processorType = PROC_PENTIUM;
+		break;
+	default:  // Just in case 
+		si->processorType = PROC_PENTIUM;
+		break;
+	}
+}
+
+#endif
+
+
+static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd,
+	      ulong arg)
+{
+	int minor;
+	int error = 0;
+	adpt_hba* pHba;
+	ulong flags;
+
+	minor = MINOR(inode->i_rdev);
+	if (minor >= DPTI_MAX_HBA){
+		return -ENXIO;
+	}
+	down(&adpt_configuration_lock);
+	for (pHba = hba_chain; pHba; pHba = pHba->next) {
+		if (pHba->unit == minor) {
+			break;	/* found adapter */
+		}
+	}
+	up(&adpt_configuration_lock);
+	if(pHba == NULL){
+		return -ENXIO;
+	}
+
+	while((volatile u32) pHba->state & DPTI_STATE_RESET ) {
+		set_task_state(current,TASK_UNINTERRUPTIBLE);
+		schedule_timeout(2);
+
+	}
+
+	switch (cmd) {
+	// TODO: handle 3 cases
+	case DPT_SIGNATURE:
+		if (copy_to_user((char*)arg, &DPTI_sig, sizeof(DPTI_sig))) {
+			return -EFAULT;
+		}
+		break;
+	case I2OUSRCMD:
+		return	adpt_i2o_passthru(pHba,(u32*)arg);
+		break;
+
+	case DPT_CTRLINFO:{
+		drvrHBAinfo_S HbaInfo;
+
+#define FLG_OSD_PCI_VALID 0x0001
+#define FLG_OSD_DMA	  0x0002
+#define FLG_OSD_I2O	  0x0004
+		memset(&HbaInfo, 0, sizeof(HbaInfo));
+		HbaInfo.drvrHBAnum = pHba->unit;
+		HbaInfo.baseAddr = (ulong) pHba->base_addr_phys;
+		HbaInfo.blinkState = adpt_read_blink_led(pHba);
+		HbaInfo.pciBusNum =  pHba->pDev->bus->number;
+		HbaInfo.pciDeviceNum=PCI_SLOT(pHba->pDev->devfn); 
+		HbaInfo.Interrupt = pHba->pDev->irq; 
+		HbaInfo.hbaFlags = FLG_OSD_PCI_VALID | FLG_OSD_DMA | FLG_OSD_I2O;
+		if(copy_to_user((void *) arg, &HbaInfo, sizeof(HbaInfo))){
+			printk(KERN_WARNING"%s: Could not copy HbaInfo TO user\n",pHba->name);
+			return -EFAULT;
+		}
+		break;
+		}
+	case DPT_SYSINFO:
+		return adpt_system_info((void*)arg);
+		break;
+	case DPT_BLINKLED:{
+		u32 value;
+		value = (u32)adpt_read_blink_led(pHba);
+		if (copy_to_user((char*)arg, &value, sizeof(value))) {
+			return -EFAULT;
+		}
+		break;
+		}
+	case I2ORESETCMD:
+		spin_lock_irqsave(&io_request_lock, flags);
+		adpt_hba_reset(pHba);
+		spin_unlock_irqrestore(&io_request_lock, flags);
+		break;
+	case I2ORESCANCMD:
+		adpt_rescan(pHba);
+		break;
+	case DPT_TARGET_BUSY & 0xFFFF:
+	case DPT_TARGET_BUSY:
+	{
+		TARGET_BUSY_T busy;
+		struct adpt_device* d;
+
+		if (copy_from_user((void*)&busy, (void*)arg, sizeof(TARGET_BUSY_T))) {
+			return -EFAULT;
+		}
+
+		d = adpt_find_device(pHba, busy.channel, busy.id, busy.lun);
+		if(d == NULL){
+			return -ENODEV;
+		}
+		busy.isBusy = ((d->pScsi_dev) && (0 != d->pScsi_dev->access_count)) ? 1 : 0;
+		if (copy_to_user ((char*)arg, &busy, sizeof(busy))) {
+			return -EFAULT;
+		}
+		break;
+	}
+	default:
+		return -EINVAL;
+	}
+
+	return error;
+}
+
+
+static void adpt_isr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	Scsi_Cmnd* cmd;
+	adpt_hba* pHba=NULL;
+	u32 m;
+	ulong reply;
+	u32 status=0;
+	u32 context;
+	ulong flags = 0;
+
+	pHba = dev_id;
+	if (pHba == NULL ){
+		printk(KERN_WARNING"adpt_isr: NULL dev_id\n");
+		return;
+	}
+	spin_lock_irqsave(&io_request_lock, flags);
+	while( readl(pHba->irq_mask) & I2O_INTERRUPT_PENDING_B) {
+		m = readl(pHba->reply_port);
+		if(m == EMPTY_QUEUE){
+			// Try twice then give up
+			rmb();
+			m = readl(pHba->reply_port);
+			if(m == EMPTY_QUEUE){ 
+				// This really should not happen
+				printk(KERN_ERR"dpti: Could not get reply frame\n");
+				spin_unlock_irqrestore(&io_request_lock,flags);
+				return;
+			}
+		}
+		reply = (ulong)bus_to_virt(m);
+
+		if (readl(reply) & MSG_FAIL) {
+			u32 old_m = readl(reply+28); 
+			ulong msg;
+			u32 old_context;
+			PDEBUG("%s: Failed message\n",pHba->name);
+			if(old_m >= 0x100000){
+				printk(KERN_ERR"%s: Bad preserved MFA (%x)- dropping frame\n",pHba->name,old_m);
+				writel(m,pHba->reply_port);
+				continue;
+			}
+			// Transaction context is 0 in failed reply frame
+			msg = (ulong)(pHba->msg_addr_virt + old_m);
+			old_context = readl(msg+12);
+			writel(old_context, reply+12);
+			adpt_send_nop(pHba, old_m);
+		} 
+		context = readl(reply+8);
+		if(context & 0x40000000){ // IOCTL
+			ulong p = (ulong)(readl(reply+12));
+			if( p != 0) {
+				memcpy((void*)p, (void*)reply, REPLY_FRAME_SIZE * 4);
+			}
+			// All IOCTLs will also be post wait
+		}
+		if(context & 0x80000000){ // Post wait message
+			status = readl(reply+16);
+			if(status  >> 24){
+				status &=  0xffff; /* Get detail status */
+			} else {
+				status = I2O_POST_WAIT_OK;
+			}
+			if(!(context & 0x40000000)) {
+				cmd = (Scsi_Cmnd*) readl(reply+12); 
+				if(cmd != NULL) {
+					printk(KERN_WARNING"%s: Apparent SCSI cmd in Post Wait Context - cmd=%p context=%x\n", pHba->name, cmd, context);
+				}
+			}
+			adpt_i2o_post_wait_complete(context, status);
+		} else { // SCSI message
+			cmd = (Scsi_Cmnd*) readl(reply+12); 
+			if(cmd != NULL){
+				if(cmd->serial_number != 0) { // If not timedout
+					adpt_i2o_to_scsi(reply, cmd);
+				}
+			}
+		}
+		writel(m, pHba->reply_port);
+		wmb();
+		rmb();
+	}
+	spin_unlock_irqrestore(&io_request_lock, flags);
+	return;
+
+}
+
+static s32 adpt_scsi_to_i2o(adpt_hba* pHba, Scsi_Cmnd* cmd, struct adpt_device* d)
+{
+	int i;
+	u32 msg[MAX_MESSAGE_SIZE];
+	u32* mptr;
+	u32 *lenptr;
+	int direction;
+	int scsidir;
+	u32 len;
+	u32 reqlen;
+	s32 rcode;
+
+	memset(msg, 0 , sizeof(msg));
+	len = cmd->request_bufflen;
+	direction = 0x00000000;	
+	
+	scsidir = 0x00000000;			// DATA NO XFER
+	if(len) {
+		/*
+		 * Set SCBFlags to indicate if data is being transferred
+		 * in or out, or no data transfer
+		 * Note:  Do not have to verify index is less than 0 since
+		 * cmd->cmnd[0] is an unsigned char
+		 */
+		switch(cmd->sc_data_direction){
+		case SCSI_DATA_READ:
+			scsidir  =0x40000000;	// DATA IN  (iop<--dev)
+			break;
+		case SCSI_DATA_WRITE:
+			direction=0x04000000;	// SGL OUT
+			scsidir  =0x80000000;	// DATA OUT (iop-->dev)
+			break;
+		case SCSI_DATA_NONE:
+			break;
+		case SCSI_DATA_UNKNOWN:
+			scsidir  =0x40000000;	// DATA IN  (iop<--dev)
+			// Assume In - and continue;
+			break;
+		default:
+			printk(KERN_WARNING"%s: scsi opcode 0x%x not supported.\n",
+			     pHba->name, cmd->cmnd[0]);
+			cmd->result = (DID_OK <<16) | (INITIATOR_ERROR << 8);
+			cmd->scsi_done(cmd);
+			return 	0;
+		}
+	}
+	// msg[0] is set later
+	// I2O_CMD_SCSI_EXEC
+	msg[1] = ((0xff<<24)|(HOST_TID<<12)|d->tid);
+	msg[2] = 0;
+	msg[3] = (u32)cmd;	/* We want the SCSI control block back */
+	// Our cards use the transaction context as the tag for queueing
+	// Adaptec/DPT Private stuff 
+	msg[4] = I2O_CMD_SCSI_EXEC|(DPT_ORGANIZATION_ID<<16);
+	msg[5] = d->tid;
+	/* Direction, disconnect ok | sense data | simple queue , CDBLen */
+	// I2O_SCB_FLAG_ENABLE_DISCONNECT | 
+	// I2O_SCB_FLAG_SIMPLE_QUEUE_TAG | 
+	// I2O_SCB_FLAG_SENSE_DATA_IN_MESSAGE;
+	msg[6] = scsidir|0x20a00000|cmd->cmd_len;
+
+	mptr=msg+7;
+
+	// Write SCSI command into the message - always 16 byte block 
+	memset(mptr, 0,  16);
+	memcpy(mptr, cmd->cmnd, cmd->cmd_len);
+	mptr+=4;
+	lenptr=mptr++;		/* Remember me - fill in when we know */
+	reqlen = 14;		// SINGLE SGE
+	/* Now fill in the SGList and command */
+	if(cmd->use_sg) {
+		struct scatterlist *sg = (struct scatterlist *)cmd->request_buffer;
+		len = 0;
+		for(i = 0 ; i < cmd->use_sg; i++) {
+			*mptr++ = direction|0x10000000|sg->length;
+			len+=sg->length;
+			*mptr++ = virt_to_bus(sg->address);
+			sg++;
+		}
+		/* Make this an end of list */
+		mptr[-2] = direction|0xD0000000|(sg-1)->length;
+		reqlen = mptr - msg;
+		*lenptr = len;
+		
+		if(cmd->underflow && len != cmd->underflow){
+			printk(KERN_WARNING"Cmd len %08X Cmd underflow %08X\n",
+				len, cmd->underflow);
+		}
+	} else {
+		*lenptr = len = cmd->request_bufflen;
+		if(len == 0) {
+			reqlen = 12;
+		} else {
+			*mptr++ = 0xD0000000|direction|cmd->request_bufflen;
+			*mptr++ = virt_to_bus(cmd->request_buffer);
+		}
+	}
+	
+	/* Stick the headers on */
+	msg[0] = reqlen<<16 | ((reqlen > 12) ? SGL_OFFSET_12 : SGL_OFFSET_0);
+	
+	// Send it on it's way
+	rcode = adpt_i2o_post_this(pHba, msg, reqlen<<2);
+	if (rcode == 0) {
+		return 0;
+	}
+	return rcode;
+}
+
+
+static s32 adpt_scsi_register(adpt_hba* pHba,Scsi_Host_Template * sht)
+{
+	struct Scsi_Host *host = NULL;
+
+	host = scsi_register(sht, sizeof(adpt_hba*));
+	if (host == NULL) {
+		printk ("%s: scsi_register returned NULL\n",pHba->name);
+		return -1;
+	}
+	(adpt_hba*)(host->hostdata[0]) = pHba;
+	pHba->host = host;
+
+	host->irq = pHba->pDev->irq;;
+	/* no IO ports, so don't have to set host->io_port and 
+	 * host->n_io_port
+	 */
+	host->io_port = 0;
+	host->n_io_port = 0;
+				/* see comments in hosts.h */
+	host->max_id = 16;
+	host->max_lun = 256;
+	host->max_channel = pHba->top_scsi_channel + 1;
+	host->cmd_per_lun = 256;
+	host->unique_id = (uint) pHba;
+	host->sg_tablesize = pHba->sg_tablesize;
+	host->can_queue = pHba->post_fifo_size;
+	host->select_queue_depths = adpt_select_queue_depths;
+
+	return 0;
+}
+
+
+static s32 adpt_i2o_to_scsi(ulong reply, Scsi_Cmnd* cmd)
+{
+	adpt_hba* pHba;
+	u32 hba_status;
+	u32 dev_status;
+	u32 reply_flags = readl(reply) & 0xff00; // Leave it shifted up 8 bits 
+	// I know this would look cleaner if I just read bytes
+	// but the model I have been using for all the rest of the
+	// io is in 4 byte words - so I keep that model
+	u16 detailed_status = readl(reply+16) &0xffff;
+	dev_status = (detailed_status & 0xff);
+	hba_status = detailed_status >> 8;
+
+	// calculate resid for sg 
+	cmd->resid = cmd->request_bufflen - readl(reply+5);
+
+	pHba = (adpt_hba*) cmd->host->hostdata[0];
+
+	cmd->sense_buffer[0] = '\0';  // initialize sense valid flag to false
+
+	if(!(reply_flags & MSG_FAIL)) {
+		switch(detailed_status & I2O_SCSI_DSC_MASK) {
+		case I2O_SCSI_DSC_SUCCESS:
+			cmd->result = (DID_OK << 16);
+			// handle underflow
+			if(readl(reply+5) < cmd->underflow ) {
+				cmd->result = (DID_ERROR <<16);
+				printk(KERN_WARNING"%s: SCSI CMD underflow\n",pHba->name);
+			}
+			break;
+		case I2O_SCSI_DSC_REQUEST_ABORTED:
+			cmd->result = (DID_ABORT << 16);
+			break;
+		case I2O_SCSI_DSC_PATH_INVALID:
+		case I2O_SCSI_DSC_DEVICE_NOT_PRESENT:
+		case I2O_SCSI_DSC_SELECTION_TIMEOUT:
+		case I2O_SCSI_DSC_COMMAND_TIMEOUT:
+		case I2O_SCSI_DSC_NO_ADAPTER:
+		case I2O_SCSI_DSC_RESOURCE_UNAVAILABLE:
+			printk(KERN_WARNING"%s: SCSI Timeout-Device (%d,%d,%d) hba status=0x%x, dev status=0x%x, cmd=0x%x\n",
+				pHba->name, (u32)cmd->channel, (u32)cmd->target, (u32)cmd->lun, hba_status, dev_status, cmd->cmnd[0]);
+			cmd->result = (DID_TIME_OUT << 16);
+			break;
+		case I2O_SCSI_DSC_ADAPTER_BUSY:
+		case I2O_SCSI_DSC_BUS_BUSY:
+			cmd->result = (DID_BUS_BUSY << 16);
+			break;
+		case I2O_SCSI_DSC_SCSI_BUS_RESET:
+		case I2O_SCSI_DSC_BDR_MESSAGE_SENT:
+			cmd->result = (DID_RESET << 16);
+			break;
+		case I2O_SCSI_DSC_PARITY_ERROR_FAILURE:
+			printk(KERN_WARNING"%s: SCSI CMD parity error\n",pHba->name);
+			cmd->result = (DID_PARITY << 16);
+			break;
+		case I2O_SCSI_DSC_UNABLE_TO_ABORT:
+		case I2O_SCSI_DSC_COMPLETE_WITH_ERROR:
+		case I2O_SCSI_DSC_UNABLE_TO_TERMINATE:
+		case I2O_SCSI_DSC_MR_MESSAGE_RECEIVED:
+		case I2O_SCSI_DSC_AUTOSENSE_FAILED:
+		case I2O_SCSI_DSC_DATA_OVERRUN:
+		case I2O_SCSI_DSC_UNEXPECTED_BUS_FREE:
+		case I2O_SCSI_DSC_SEQUENCE_FAILURE:
+		case I2O_SCSI_DSC_REQUEST_LENGTH_ERROR:
+		case I2O_SCSI_DSC_PROVIDE_FAILURE:
+		case I2O_SCSI_DSC_REQUEST_TERMINATED:
+		case I2O_SCSI_DSC_IDE_MESSAGE_SENT:
+		case I2O_SCSI_DSC_UNACKNOWLEDGED_EVENT:
+		case I2O_SCSI_DSC_MESSAGE_RECEIVED:
+		case I2O_SCSI_DSC_INVALID_CDB:
+		case I2O_SCSI_DSC_LUN_INVALID:
+		case I2O_SCSI_DSC_SCSI_TID_INVALID:
+		case I2O_SCSI_DSC_FUNCTION_UNAVAILABLE:
+		case I2O_SCSI_DSC_NO_NEXUS:
+		case I2O_SCSI_DSC_CDB_RECEIVED:
+		case I2O_SCSI_DSC_LUN_ALREADY_ENABLED:
+		case I2O_SCSI_DSC_QUEUE_FROZEN:
+		case I2O_SCSI_DSC_REQUEST_INVALID:
+		default:
+			printk(KERN_WARNING"%s: SCSI error %0x-Device(%d,%d,%d) hba_status=0x%x, dev_status=0x%x, cmd=0x%x\n",
+				pHba->name, detailed_status & I2O_SCSI_DSC_MASK, (u32)cmd->channel, (u32)cmd->target, (u32)cmd-> lun,
+			       hba_status, dev_status, cmd->cmnd[0]);
+			cmd->result = (DID_ERROR << 16);
+			break;
+		}
+
+		// copy over the request sense data if it was a check
+		// condition status
+		if(dev_status == 0x02 /*CHECK_CONDITION*/) {
+			u32 len = sizeof(cmd->sense_buffer);
+			len = (len > 40) ?  40 : len;
+			// Copy over the sense data
+			memcpy(cmd->sense_buffer, (void*)(reply+28) , len);
+			if(cmd->sense_buffer[0] == 0x70 /* class 7 */ && 
+			   cmd->sense_buffer[2] == DATA_PROTECT ){
+				/* This is to handle an array failed */
+				cmd->result = (DID_TIME_OUT << 16);
+				printk(KERN_WARNING"%s: SCSI Data Protect-Device (%d,%d,%d) hba_status=0x%x, dev_status=0x%x, cmd=0x%x\n",
+					pHba->name, (u32)cmd->channel, (u32)cmd->target, (u32)cmd->lun, 
+					hba_status, dev_status, cmd->cmnd[0]);
+
+			}
+		}
+	} else {
+		/* In this condtion we could not talk to the tid
+		 * the card rejected it.  We should signal a retry
+		 * for a limitted number of retries.
+		 */
+		cmd->result = (DID_TIME_OUT << 16);
+		printk(KERN_WARNING"%s: I2O MSG_FAIL - Device (%d,%d,%d) tid=%d, cmd=0x%x\n",
+			pHba->name, (u32)cmd->channel, (u32)cmd->target, (u32)cmd-> lun,
+			((struct adpt_device*)(cmd->device->hostdata))->tid, cmd->cmnd[0]);
+	}
+
+	cmd->result |= (dev_status);
+
+	if(cmd->scsi_done != NULL){
+		cmd->scsi_done(cmd);
+	} 
+	return cmd->result;
+}
+
+
+static s32 adpt_rescan(adpt_hba* pHba)
+{
+	s32 rcode;
+	ulong flags;
+
+	spin_lock_irqsave(&io_request_lock, flags);
+	if ((rcode=adpt_i2o_lct_get(pHba)) < 0){
+		spin_unlock_irqrestore(&io_request_lock, flags);
+		return rcode;
+	}
+
+	if ((rcode=adpt_i2o_reparse_lct(pHba)) < 0){
+		spin_unlock_irqrestore(&io_request_lock, flags);
+		return rcode;
+	}
+	spin_unlock_irqrestore(&io_request_lock, flags);
+	return 0;
+}
+
+
+static s32 adpt_i2o_reparse_lct(adpt_hba* pHba)
+{
+	int i;
+	int max;
+	int tid;
+	struct i2o_device *d;
+	i2o_lct *lct = pHba->lct;
+	u8 bus_no = 0;
+	s16 scsi_id;
+	s16 scsi_lun;
+	u32 buf[10]; // at least 8 u32's
+	struct adpt_device* pDev = NULL;
+	struct i2o_device* pI2o_dev = NULL;
+	
+	if (lct == NULL) {
+		printk(KERN_ERR "%s: LCT is empty???\n",pHba->name);
+		return -1;
+	}
+	
+	max = lct->table_size;	
+	max -= 3;
+	max /= 9;
+
+	// Mark each drive as unscanned
+	for (d = pHba->devices; d; d = d->next) {
+		pDev =(struct adpt_device*) d->owner;
+		if(!pDev){
+			continue;
+		}
+		pDev->state |= DPTI_DEV_UNSCANNED;
+	}
+
+	printk(KERN_INFO "%s: LCT has %d entries.\n", pHba->name,max);
+	
+	for(i=0;i<max;i++) {
+		if( lct->lct_entry[i].user_tid != 0xfff){
+			continue;
+		}
+
+		if( lct->lct_entry[i].class_id == I2O_CLASS_RANDOM_BLOCK_STORAGE ||
+		    lct->lct_entry[i].class_id == I2O_CLASS_SCSI_PERIPHERAL ||
+		    lct->lct_entry[i].class_id == I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL ){
+			tid = lct->lct_entry[i].tid;
+			if(adpt_i2o_query_scalar(pHba, tid, 0x8000, -1, buf, 32)<0) {
+				printk(KERN_ERR"%s: Could not query device\n",pHba->name);
+				continue;
+			}
+			bus_no = buf[0]>>16;
+			scsi_id = buf[1];
+			scsi_lun = (buf[2]>>8 )&0xff;
+			pDev = pHba->channel[bus_no].device[scsi_id];
+			/* da lun */
+			while(pDev) {
+				if(pDev->scsi_lun == scsi_lun) {
+					break;
+				}
+				pDev = pDev->next_lun;
+			}
+			if(!pDev ) { // Something new add it
+				d = (struct i2o_device *)kmalloc(sizeof(struct i2o_device), GFP_KERNEL);
+				if(d==NULL)
+				{
+					printk(KERN_CRIT "Out of memory for I2O device data.\n");
+					return -ENOMEM;
+				}
+				
+				d->controller = (void*)pHba;
+				d->next = NULL;
+
+				memcpy(&d->lct_data, &lct->lct_entry[i], sizeof(i2o_lct_entry));
+
+				d->flags = 0;
+				adpt_i2o_report_hba_unit(pHba, d);
+				adpt_i2o_install_device(pHba, d);
+	
+				if(bus_no >= MAX_CHANNEL) {	// Something wrong skip it
+					printk(KERN_WARNING"%s: Channel number %d out of range \n", pHba->name, bus_no);
+					continue;
+				}
+				pDev = pHba->channel[bus_no].device[scsi_id];	
+				if( pDev == NULL){
+					pDev =  kmalloc(sizeof(struct adpt_device),GFP_KERNEL);
+					if(pDev == NULL) {
+						return -ENOMEM;
+					}
+					pHba->channel[bus_no].device[scsi_id] = pDev;
+				} else {
+					while (pDev->next_lun) {
+						pDev = pDev->next_lun;
+					}
+					pDev = pDev->next_lun = kmalloc(sizeof(struct adpt_device),GFP_KERNEL);
+					if(pDev == NULL) {
+						return -ENOMEM;
+					}
+				}
+				memset(pDev,0,sizeof(struct adpt_device));
+				pDev->tid = d->lct_data.tid;
+				pDev->scsi_channel = bus_no;
+				pDev->scsi_id = scsi_id;
+				pDev->scsi_lun = scsi_lun;
+				pDev->pI2o_dev = d;
+				d->owner = pDev;
+				pDev->type = (buf[0])&0xff;
+				pDev->flags = (buf[0]>>8)&0xff;
+				// Too late, SCSI system has made up it's mind, but what the hey ...
+				if(scsi_id > pHba->top_scsi_id){
+					pHba->top_scsi_id = scsi_id;
+				}
+				if(scsi_lun > pHba->top_scsi_lun){
+					pHba->top_scsi_lun = scsi_lun;
+				}
+				continue;
+			} // end of new i2o device
+
+			// We found an old device - check it
+			while(pDev) {
+				if(pDev->scsi_lun == scsi_lun) {
+					if(pDev->pScsi_dev->online == FALSE) {
+						printk(KERN_WARNING"%s: Setting device (%d,%d,%d) back online\n",
+								pHba->name,bus_no,scsi_id,scsi_lun);
+						if (pDev->pScsi_dev) {
+							pDev->pScsi_dev->online = TRUE;
+						}
+					}
+					d = pDev->pI2o_dev;
+					if(d->lct_data.tid != tid) { // something changed
+						pDev->tid = tid;
+						memcpy(&d->lct_data, &lct->lct_entry[i], sizeof(i2o_lct_entry));
+						if (pDev->pScsi_dev) {
+							pDev->pScsi_dev->changed = TRUE;
+							pDev->pScsi_dev->removable = TRUE;
+						}
+					}
+					// Found it - mark it scanned
+					pDev->state = DPTI_DEV_ONLINE;
+					break;
+				}
+				pDev = pDev->next_lun;
+			}
+		}
+	}
+	for (pI2o_dev = pHba->devices; pI2o_dev; pI2o_dev = pI2o_dev->next) {
+		pDev =(struct adpt_device*) pI2o_dev->owner;
+		if(!pDev){
+			continue;
+		}
+		// Drive offline drives that previously existed but could not be found
+		// in the LCT table
+		if (pDev->state & DPTI_DEV_UNSCANNED){
+			pDev->state = DPTI_DEV_OFFLINE;
+			printk(KERN_WARNING"%s: Device (%d,%d,%d) offline\n",pHba->name,pDev->scsi_channel,pDev->scsi_id,pDev->scsi_lun);
+			if (pDev->pScsi_dev) {
+				pDev->pScsi_dev->online = FALSE;
+				if (pDev->pScsi_dev->access_count) {
+					// A drive that was mounted is no longer there... bad!
+					SCSI_LOG_ERROR_RECOVERY(1, printk ("%s:Rescan: Previously "
+								 "mounted drive not found!\n",pHba->name));
+					printk(KERN_WARNING"%s:Mounted drive taken offline\n",pHba->name);
+				}
+			}
+		}
+	}
+	return 0;
+}
+
+static void adpt_fail_posted_scbs(adpt_hba* pHba)
+{
+	Scsi_Cmnd* 	cmd = NULL;
+	Scsi_Device* 	d = NULL;
+
+	if( pHba->host->host_queue != NULL ) {
+		d = pHba->host->host_queue;
+		if(!d){
+			return;
+		}
+		while( d->next != NULL ){
+			for(cmd = d->device_queue; cmd ; cmd = cmd->next){
+				if(cmd->serial_number == 0){
+					continue;
+				}
+				cmd->result = (DID_OK << 16) | (QUEUE_FULL <<1);
+				cmd->scsi_done(cmd);
+			}
+			d = d->next;
+		}
+	}
+}
+
+
+/*============================================================================
+ *  Routines from i2o subsystem
+ *============================================================================
+ */
+
+
+
+/*
+ *	Bring an I2O controller into HOLD state. See the spec.
+ */
+static int adpt_i2o_activate_hba(adpt_hba* pHba)
+{
+	int rcode;
+
+	if(pHba->initialized ) {
+		if (adpt_i2o_status_get(pHba) < 0) {
+			if((rcode = adpt_i2o_reset_hba(pHba) != 0)){
+				printk(KERN_WARNING"%s: Could NOT reset.\n", pHba->name);
+				return rcode;
+			}
+			if (adpt_i2o_status_get(pHba) < 0) {
+				printk(KERN_INFO "HBA not responding.\n");
+				return -1;
+			}
+		}
+
+		if(pHba->status_block->iop_state == ADAPTER_STATE_FAULTED) {
+			printk(KERN_CRIT "%s: hardware fault\n", pHba->name);
+			return -1;
+		}
+
+		if (pHba->status_block->iop_state == ADAPTER_STATE_READY ||
+		    pHba->status_block->iop_state == ADAPTER_STATE_OPERATIONAL ||
+		    pHba->status_block->iop_state == ADAPTER_STATE_HOLD ||
+		    pHba->status_block->iop_state == ADAPTER_STATE_FAILED) {
+			adpt_i2o_reset_hba(pHba);			
+			if (adpt_i2o_status_get(pHba) < 0 || pHba->status_block->iop_state != ADAPTER_STATE_RESET) {
+				printk(KERN_ERR "%s: Failed to initialize.\n", pHba->name);
+				return -1;
+			}
+		}
+	} else {
+		if((rcode = adpt_i2o_reset_hba(pHba) != 0)){
+			printk(KERN_WARNING"%s: Could NOT reset.\n", pHba->name);
+			return rcode;
+		}
+
+	}
+
+	if (adpt_i2o_init_outbound_q(pHba) < 0) {
+		return -1;
+	}
+
+	/* In HOLD state */
+	
+	if (adpt_i2o_hrt_get(pHba) < 0) {
+		return -1;
+	}
+
+	return 0;
+}
+
+/*
+ *	Bring a controller online into OPERATIONAL state. 
+ */
+ 
+static int adpt_i2o_online_hba(adpt_hba* pHba)
+{
+	if (adpt_i2o_systab_send(pHba) < 0) {
+		adpt_i2o_delete_hba(pHba);
+		return -1;
+	}
+	/* In READY state */
+
+	if (adpt_i2o_enable_hba(pHba) < 0) {
+		adpt_i2o_delete_hba(pHba);
+		return -1;
+	}
+
+	/* In OPERATIONAL state  */
+	return 0;
+}
+
+static s32 adpt_send_nop(adpt_hba*pHba,u32 m)
+{
+	u32 *msg;
+	ulong timeout = jiffies + 5*HZ;
+
+	while(m == EMPTY_QUEUE){
+		rmb();
+		m = readl(pHba->post_port);
+		if(m != EMPTY_QUEUE){
+			break;
+		}
+		if(time_after(jiffies,timeout)){
+			printk(KERN_ERR "%s: Timeout waiting for message frame!\n",pHba->name);
+			return 2;
+		}
+	}
+	msg = (u32*)(pHba->msg_addr_virt + m);
+	writel( THREE_WORD_MSG_SIZE | SGL_OFFSET_0,&msg[0]);
+	writel( I2O_CMD_UTIL_NOP << 24 | HOST_TID << 12 | 0,&msg[1]);
+	writel( 0,&msg[2]);
+	wmb();
+
+	writel(m, pHba->post_port);
+	wmb();
+	return 0;
+}
+
+static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba)
+{
+	u8 *status;
+	u32 *msg = NULL;
+	int i;
+	ulong timeout = jiffies + TMOUT_INITOUTBOUND*HZ;
+	u32* ptr;
+	u32 outbound_frame;  // This had to be a 32 bit address
+	u32 m;
+
+	do {
+		rmb();
+		m = readl(pHba->post_port);
+		if (m != EMPTY_QUEUE) {
+			break;
+		}
+
+		if(time_after(jiffies,timeout)){
+			printk(KERN_WARNING"%s: Timeout waiting for message frame\n",pHba->name);
+			return -ETIMEDOUT;
+		}
+	} while(m == EMPTY_QUEUE);
+
+	msg=(u32 *)(pHba->msg_addr_virt+m);
+
+	status = kmalloc(4,GFP_KERNEL|ADDR32);
+	if (status==NULL) {
+		adpt_send_nop(pHba, m);
+		printk(KERN_WARNING"%s: IOP reset failed - no free memory.\n",
+			pHba->name);
+		return -ENOMEM;
+	}
+	memset(status, 0, 4);
+
+	writel(EIGHT_WORD_MSG_SIZE| SGL_OFFSET_6, &msg[0]);
+	writel(I2O_CMD_OUTBOUND_INIT<<24 | HOST_TID<<12 | ADAPTER_TID, &msg[1]);
+	writel(0, &msg[2]);
+	writel(0x0106, &msg[3]);	/* Transaction context */
+	writel(4096, &msg[4]);		/* Host page frame size */
+	writel((REPLY_FRAME_SIZE)<<16|0x80, &msg[5]);	/* Outbound msg frame size and Initcode */
+	writel(0xD0000004, &msg[6]);		/* Simple SG LE, EOB */
+	writel(virt_to_bus(status), &msg[7]);
+
+	writel(m, pHba->post_port);
+	wmb();
+
+	// Wait for the reply status to come back
+	do {
+		if (*status) {
+			if (*status != 0x01 /*I2O_EXEC_OUTBOUND_INIT_IN_PROGRESS*/) {
+				break;
+			}
+		}
+		rmb();
+		if(time_after(jiffies,timeout)){
+			printk(KERN_WARNING"%s: Timeout Initializing\n",pHba->name);
+			kfree((void*)status);
+			return -ETIMEDOUT;
+		}
+	} while (1);
+
+	// If the command was successful, fill the fifo with our reply
+	// message packets
+	if(*status != 0x04 /*I2O_EXEC_OUTBOUND_INIT_COMPLETE*/) {
+		kfree((void*)status);
+		return -2;
+	}
+	kfree((void*)status);
+
+	if(pHba->reply_pool != NULL){
+		kfree(pHba->reply_pool);
+	}
+
+	pHba->reply_pool = (u32*)kmalloc(pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4, GFP_KERNEL|ADDR32);
+	if(!pHba->reply_pool){
+		printk(KERN_ERR"%s: Could not allocate reply pool\n",pHba->name);
+		return -1;
+	}
+	memset(pHba->reply_pool, 0 , pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4);
+
+	ptr = pHba->reply_pool;
+	for(i = 0; i < pHba->reply_fifo_size; i++) {
+		outbound_frame = (u32)virt_to_bus(ptr);
+		writel(outbound_frame, pHba->reply_port);
+		wmb();
+		ptr +=  REPLY_FRAME_SIZE;
+	}
+	adpt_i2o_status_get(pHba);
+	return 0;
+}
+
+
+/*
+ * I2O System Table.  Contains information about
+ * all the IOPs in the system.  Used to inform IOPs
+ * about each other's existence.
+ *
+ * sys_tbl_ver is the CurrentChangeIndicator that is
+ * used by IOPs to track changes.
+ */
+
+
+
+static s32 adpt_i2o_status_get(adpt_hba* pHba)
+{
+	ulong timeout;
+	u32 m;
+	u32 *msg;
+	u8 *status_block=NULL;
+	ulong status_block_bus;
+
+	if(pHba->status_block == NULL) {
+		pHba->status_block = (i2o_status_block*)
+			kmalloc(sizeof(i2o_status_block),GFP_KERNEL|ADDR32);
+		if(pHba->status_block == NULL) {
+			printk(KERN_ERR
+			"dpti%d: Get Status Block failed; Out of memory. \n", 
+			pHba->unit);
+			return -ENOMEM;
+		}
+	}
+	memset(pHba->status_block, 0, sizeof(i2o_status_block));
+	status_block = (u8*)(pHba->status_block);
+	status_block_bus = virt_to_bus(pHba->status_block);
+	timeout = jiffies+TMOUT_GETSTATUS*HZ;
+	do {
+		rmb();
+		m = readl(pHba->post_port);
+		if (m != EMPTY_QUEUE) {
+			break;
+		}
+		if(time_after(jiffies,timeout)){
+			printk(KERN_ERR "%s: Timeout waiting for message !\n",
+					pHba->name);
+			return -ETIMEDOUT;
+		}
+	} while(m==EMPTY_QUEUE);
+
+	
+	msg=(u32*)(pHba->msg_addr_virt+m);
+
+	writel(NINE_WORD_MSG_SIZE|SGL_OFFSET_0, &msg[0]);
+	writel(I2O_CMD_STATUS_GET<<24|HOST_TID<<12|ADAPTER_TID, &msg[1]);
+	writel(1, &msg[2]);
+	writel(0, &msg[3]);
+	writel(0, &msg[4]);
+	writel(0, &msg[5]);
+	writel(((u32)status_block_bus)&0xffffffff, &msg[6]);
+	writel(0, &msg[7]);
+	writel(sizeof(i2o_status_block), &msg[8]); // 88 bytes
+
+	//post message
+	writel(m, pHba->post_port);
+	wmb();
+
+	while(status_block[87]!=0xff){
+		if(time_after(jiffies,timeout)){
+			printk(KERN_ERR"dpti%d: Get status timeout.\n",
+				pHba->unit);
+			return -ETIMEDOUT;
+		}
+		rmb();
+	}
+
+	// Set up our number of outbound and inbound messages
+	pHba->post_fifo_size = pHba->status_block->max_inbound_frames;
+	if (pHba->post_fifo_size > MAX_TO_IOP_MESSAGES) {
+		pHba->post_fifo_size = MAX_TO_IOP_MESSAGES;
+	}
+
+	pHba->reply_fifo_size = pHba->status_block->max_outbound_frames;
+	if (pHba->reply_fifo_size > MAX_FROM_IOP_MESSAGES) {
+		pHba->reply_fifo_size = MAX_FROM_IOP_MESSAGES;
+	}
+
+	// Calculate the Scatter Gather list size
+	pHba->sg_tablesize = (pHba->status_block->inbound_frame_size * 4 -40)/ sizeof(struct sg_simple_element);
+	if (pHba->sg_tablesize > SG_LIST_ELEMENTS) {
+		pHba->sg_tablesize = SG_LIST_ELEMENTS;
+	}
+
+
+#ifdef DEBUG
+	printk("dpti%d: State = ",pHba->unit);
+	switch(pHba->status_block->iop_state) {
+		case 0x01:
+			printk("INIT\n");
+			break;
+		case 0x02:
+			printk("RESET\n");
+			break;
+		case 0x04:
+			printk("HOLD\n");
+			break;
+		case 0x05:
+			printk("READY\n");
+			break;
+		case 0x08:
+			printk("OPERATIONAL\n");
+			break;
+		case 0x10:
+			printk("FAILED\n");
+			break;
+		case 0x11:
+			printk("FAULTED\n");
+			break;
+		default:
+			printk("%x (unknown!!)\n",pHba->status_block->iop_state);
+	}
+#endif
+	return 0;
+}
+
+/*
+ * Get the IOP's Logical Configuration Table
+ */
+static int adpt_i2o_lct_get(adpt_hba* pHba)
+{
+	u32 msg[8];
+	int ret;
+	u32 buf[16];
+
+	if ((pHba->lct_size == 0) || (pHba->lct == NULL)){
+		pHba->lct_size = pHba->status_block->expected_lct_size;
+	}
+	do {
+		if (pHba->lct == NULL) {
+			pHba->lct = kmalloc(pHba->lct_size, GFP_KERNEL|ADDR32);
+			if(pHba->lct == NULL) {
+				printk(KERN_CRIT "%s: Lct Get failed. Out of memory.\n",
+					pHba->name);
+				return -ENOMEM;
+			}
+		}
+		memset(pHba->lct, 0, pHba->lct_size);
+
+		msg[0] = EIGHT_WORD_MSG_SIZE|SGL_OFFSET_6;
+		msg[1] = I2O_CMD_LCT_NOTIFY<<24 | HOST_TID<<12 | ADAPTER_TID;
+		msg[2] = 0;
+		msg[3] = 0;
+		msg[4] = 0xFFFFFFFF;	/* All devices */
+		msg[5] = 0x00000000;	/* Report now */
+		msg[6] = 0xD0000000|pHba->lct_size;
+		msg[7] = virt_to_bus(pHba->lct);
+
+		if ((ret=adpt_i2o_post_wait(pHba, msg, sizeof(msg), 360))) {
+			printk(KERN_ERR "%s: LCT Get failed (status=%#10x.\n", 
+				pHba->name, ret);	
+			printk(KERN_ERR"Adaptec: Error Reading Hardware.\n");
+			return ret;
+		}
+
+		if ((pHba->lct->table_size << 2) > pHba->lct_size) {
+			pHba->lct_size = pHba->lct->table_size << 2;
+			kfree(pHba->lct);
+			pHba->lct = NULL;
+		}
+	} while (pHba->lct == NULL);
+
+	PDEBUG("%s: Hardware resource table read.\n", pHba->name);
+
+
+	// I2O_DPT_EXEC_IOP_BUFFERS_GROUP_NO;
+	if(adpt_i2o_query_scalar(pHba, 0 , 0x8000, -1, buf, sizeof(buf))>=0) {
+		pHba->FwDebugBufferSize = buf[1];
+		pHba->FwDebugBuffer_P    = pHba->base_addr_virt + buf[0];
+		pHba->FwDebugFlags_P     = pHba->FwDebugBuffer_P + FW_DEBUG_FLAGS_OFFSET;
+		pHba->FwDebugBLEDvalue_P = pHba->FwDebugBuffer_P + FW_DEBUG_BLED_OFFSET;
+		pHba->FwDebugBLEDflag_P  = pHba->FwDebugBLEDvalue_P + 1;
+		pHba->FwDebugStrLength_P = pHba->FwDebugBuffer_P + FW_DEBUG_STR_LENGTH_OFFSET;
+		pHba->FwDebugBuffer_P += buf[2]; 
+		pHba->FwDebugFlags = 0;
+	}
+
+	return 0;
+}
+
+static int adpt_i2o_build_sys_table(void)
+{
+	adpt_hba* pHba = NULL;
+	int count = 0;
+
+	sys_tbl_len = sizeof(struct i2o_sys_tbl) +	// Header + IOPs
+				(hba_count) * sizeof(struct i2o_sys_tbl_entry);
+
+	if(sys_tbl)
+		kfree(sys_tbl);
+
+	sys_tbl = kmalloc(sys_tbl_len, GFP_KERNEL|ADDR32);
+	if(!sys_tbl) {
+		printk(KERN_WARNING "SysTab Set failed. Out of memory.\n");	
+		return -ENOMEM;
+	}
+	memset(sys_tbl, 0, sys_tbl_len);
+
+	sys_tbl->num_entries = hba_count;
+	sys_tbl->version = I2OVERSION;
+	sys_tbl->change_ind = sys_tbl_ind++;
+
+	for(pHba = hba_chain; pHba; pHba = pHba->next) {
+		// Get updated Status Block so we have the latest information
+		if (adpt_i2o_status_get(pHba)) {
+			sys_tbl->num_entries--;
+			continue; // try next one	
+		}
+
+		sys_tbl->iops[count].org_id = pHba->status_block->org_id;
+		sys_tbl->iops[count].iop_id = pHba->unit + 2;
+		sys_tbl->iops[count].seg_num = 0;
+		sys_tbl->iops[count].i2o_version = pHba->status_block->i2o_version;
+		sys_tbl->iops[count].iop_state = pHba->status_block->iop_state;
+		sys_tbl->iops[count].msg_type = pHba->status_block->msg_type;
+		sys_tbl->iops[count].frame_size = pHba->status_block->inbound_frame_size;
+		sys_tbl->iops[count].last_changed = sys_tbl_ind - 1; // ??
+		sys_tbl->iops[count].iop_capabilities = pHba->status_block->iop_capabilities;
+		sys_tbl->iops[count].inbound_low = (u32)virt_to_bus((void*)pHba->post_port);
+		sys_tbl->iops[count].inbound_high = (u32)((u64)virt_to_bus((void*)pHba->post_port)>>32);
+
+		count++;
+	}
+
+#ifdef DEBUG
+{
+	u32 *table = (u32*)sys_tbl;
+	printk(KERN_DEBUG"sys_tbl_len=%d in 32bit words\n",(sys_tbl_len >>2));
+	for(count = 0; count < (sys_tbl_len >>2); count++) {
+		printk(KERN_INFO "sys_tbl[%d] = %0#10x\n", 
+			count, table[count]);
+	}
+}
+#endif
+
+	return 0;
+}
+
+
+/*
+ *	 Dump the information block associated with a given unit (TID)
+ */
+ 
+static void adpt_i2o_report_hba_unit(adpt_hba* pHba, struct i2o_device *d)
+{
+	char buf[64];
+	int unit = d->lct_data.tid;
+
+	printk(KERN_INFO "TID %3.3d ", unit);
+
+	if(adpt_i2o_query_scalar(pHba, unit, 0xF100, 3, buf, 16)>=0)
+	{
+		buf[16]=0;
+		printk(" Vendor: %-12.12s", buf);
+	}
+	if(adpt_i2o_query_scalar(pHba, unit, 0xF100, 4, buf, 16)>=0)
+	{
+		buf[16]=0;
+		printk(" Device: %-12.12s", buf);
+	}
+	if(adpt_i2o_query_scalar(pHba, unit, 0xF100, 6, buf, 8)>=0)
+	{
+		buf[8]=0;
+		printk(" Rev: %-12.12s\n", buf);
+	}
+#ifdef DEBUG
+	 printk(KERN_INFO "\tClass: %.21s\n", adpt_i2o_get_class_name(d->lct_data.class_id));
+	 printk(KERN_INFO "\tSubclass: 0x%04X\n", d->lct_data.sub_class);
+	 printk(KERN_INFO "\tFlags: ");
+
+	 if(d->lct_data.device_flags&(1<<0))
+		  printk("C");	     // ConfigDialog requested
+	 if(d->lct_data.device_flags&(1<<1))
+		  printk("U");	     // Multi-user capable
+	 if(!(d->lct_data.device_flags&(1<<4)))
+		  printk("P");	     // Peer service enabled!
+	 if(!(d->lct_data.device_flags&(1<<5)))
+		  printk("M");	     // Mgmt service enabled!
+	 printk("\n");
+#endif
+}
+
+#ifdef DEBUG
+/*
+ *	Do i2o class name lookup
+ */
+static const char *adpt_i2o_get_class_name(int class)
+{
+	int idx = 16;
+	static char *i2o_class_name[] = {
+		"Executive",
+		"Device Driver Module",
+		"Block Device",
+		"Tape Device",
+		"LAN Interface",
+		"WAN Interface",
+		"Fibre Channel Port",
+		"Fibre Channel Device",
+		"SCSI Device",
+		"ATE Port",
+		"ATE Device",
+		"Floppy Controller",
+		"Floppy Device",
+		"Secondary Bus Port",
+		"Peer Transport Agent",
+		"Peer Transport",
+		"Unknown"
+	};
+	
+	switch(class&0xFFF) {
+	case I2O_CLASS_EXECUTIVE:
+		idx = 0; break;
+	case I2O_CLASS_DDM:
+		idx = 1; break;
+	case I2O_CLASS_RANDOM_BLOCK_STORAGE:
+		idx = 2; break;
+	case I2O_CLASS_SEQUENTIAL_STORAGE:
+		idx = 3; break;
+	case I2O_CLASS_LAN:
+		idx = 4; break;
+	case I2O_CLASS_WAN:
+		idx = 5; break;
+	case I2O_CLASS_FIBRE_CHANNEL_PORT:
+		idx = 6; break;
+	case I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL:
+		idx = 7; break;
+	case I2O_CLASS_SCSI_PERIPHERAL:
+		idx = 8; break;
+	case I2O_CLASS_ATE_PORT:
+		idx = 9; break;
+	case I2O_CLASS_ATE_PERIPHERAL:
+		idx = 10; break;
+	case I2O_CLASS_FLOPPY_CONTROLLER:
+		idx = 11; break;
+	case I2O_CLASS_FLOPPY_DEVICE:
+		idx = 12; break;
+	case I2O_CLASS_BUS_ADAPTER_PORT:
+		idx = 13; break;
+	case I2O_CLASS_PEER_TRANSPORT_AGENT:
+		idx = 14; break;
+	case I2O_CLASS_PEER_TRANSPORT:
+		idx = 15; break;
+	}
+	return i2o_class_name[idx];
+}
+#endif
+
+
+static s32 adpt_i2o_hrt_get(adpt_hba* pHba)
+{
+	u32 msg[6];
+	int ret, size = sizeof(i2o_hrt);
+
+	do {
+		if (pHba->hrt == NULL) {
+			pHba->hrt=kmalloc(size, GFP_KERNEL|ADDR32);
+			if (pHba->hrt == NULL) {
+				printk(KERN_CRIT "%s: Hrt Get failed; Out of memory.\n", pHba->name);
+				return -ENOMEM;
+			}
+		}
+
+		msg[0]= SIX_WORD_MSG_SIZE| SGL_OFFSET_4;
+		msg[1]= I2O_CMD_HRT_GET<<24 | HOST_TID<<12 | ADAPTER_TID;
+		msg[2]= 0;
+		msg[3]= 0;
+		msg[4]= (0xD0000000 | size);    /* Simple transaction */
+		msg[5]= virt_to_bus(pHba->hrt);   /* Dump it here */
+
+		if ((ret = adpt_i2o_post_wait(pHba, msg, sizeof(msg),20))) {
+			printk(KERN_ERR "%s: Unable to get HRT (status=%#10x)\n", pHba->name, ret);
+			return ret;
+		}
+
+		if (pHba->hrt->num_entries * pHba->hrt->entry_len << 2 > size) {
+			size = pHba->hrt->num_entries * pHba->hrt->entry_len << 2;
+			kfree(pHba->hrt);
+			pHba->hrt = NULL;
+		}
+	} while(pHba->hrt == NULL);
+	return 0;
+}                                                                                                                                       
+
+/*
+ *	 Query one scalar group value or a whole scalar group.
+ */		    	
+static int adpt_i2o_query_scalar(adpt_hba* pHba, int tid, 
+			int group, int field, void *buf, int buflen)
+{
+	u16 opblk[] = { 1, 0, I2O_PARAMS_FIELD_GET, group, 1, field };
+	u8  resblk[8+buflen]; /* 8 bytes for header */
+	int size;
+
+	if (field == -1)  		/* whole group */
+			opblk[4] = -1;
+
+	size = adpt_i2o_issue_params(I2O_CMD_UTIL_PARAMS_GET, pHba, tid, 
+		opblk, sizeof(opblk), resblk, sizeof(resblk));
+			
+	memcpy(buf, resblk+8, buflen);  /* cut off header */
+
+	if (size < 0)
+		return size;	
+
+	return buflen;
+}
+
+
+/*	Issue UTIL_PARAMS_GET or UTIL_PARAMS_SET
+ *
+ *	This function can be used for all UtilParamsGet/Set operations.
+ *	The OperationBlock is given in opblk-buffer, 
+ *	and results are returned in resblk-buffer.
+ *	Note that the minimum sized resblk is 8 bytes and contains
+ *	ResultCount, ErrorInfoSize, BlockStatus and BlockSize.
+ */
+static int adpt_i2o_issue_params(int cmd, adpt_hba* pHba, int tid, 
+		  void *opblk, int oplen, void *resblk, int reslen)
+{
+	u32 msg[9]; 
+	u32 *res = (u32 *)resblk;
+	int wait_status;
+
+	msg[0] = NINE_WORD_MSG_SIZE | SGL_OFFSET_5;
+	msg[1] = cmd << 24 | HOST_TID << 12 | tid; 
+	msg[2] = 0;
+	msg[3] = 0;
+	msg[4] = 0;
+	msg[5] = 0x54000000 | oplen;	/* OperationBlock */
+	msg[6] = virt_to_bus(opblk);
+	msg[7] = 0xD0000000 | reslen;	/* ResultBlock */
+	msg[8] = virt_to_bus(resblk);
+
+	if ((wait_status = adpt_i2o_post_wait(pHba, msg, sizeof(msg), 20))) {
+   		return wait_status; 	/* -DetailedStatus */
+	}
+
+	if (res[1]&0x00FF0000) { 	/* BlockStatus != SUCCESS */
+		printk(KERN_WARNING "%s: %s - Error:\n  ErrorInfoSize = 0x%02x, "
+			"BlockStatus = 0x%02x, BlockSize = 0x%04x\n",
+			pHba->name,
+			(cmd == I2O_CMD_UTIL_PARAMS_SET) ? "PARAMS_SET"
+							 : "PARAMS_GET",   
+			res[1]>>24, (res[1]>>16)&0xFF, res[1]&0xFFFF);
+		return -((res[1] >> 16) & 0xFF); /* -BlockStatus */
+	}
+
+	 return 4 + ((res[1] & 0x0000FFFF) << 2); /* bytes used in resblk */ 
+}
+
+
+static s32 adpt_i2o_quiesce_hba(adpt_hba* pHba)
+{
+	u32 msg[4];
+	int ret;
+
+	adpt_i2o_status_get(pHba);
+
+	/* SysQuiesce discarded if IOP not in READY or OPERATIONAL state */
+
+	if((pHba->status_block->iop_state != ADAPTER_STATE_READY) &&
+   	   (pHba->status_block->iop_state != ADAPTER_STATE_OPERATIONAL)){
+		return 0;
+	}
+
+	msg[0] = FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
+	msg[1] = I2O_CMD_SYS_QUIESCE<<24|HOST_TID<<12|ADAPTER_TID;
+	msg[2] = 0;
+	msg[3] = 0;
+
+	if((ret = adpt_i2o_post_wait(pHba, msg, sizeof(msg), 240))) {
+		printk(KERN_INFO"dpti%d: Unable to quiesce (status=%#x).\n",
+				pHba->unit, -ret);
+	} else {
+		printk(KERN_INFO"dpti%d: Quiesced.\n",pHba->unit);
+	}
+
+	adpt_i2o_status_get(pHba);
+	return ret;
+}
+
+
+/* 
+ * Enable IOP. Allows the IOP to resume external operations.
+ */
+static int adpt_i2o_enable_hba(adpt_hba* pHba)
+{
+	u32 msg[4];
+	int ret;
+	
+	adpt_i2o_status_get(pHba);
+	if(!pHba->status_block){
+		return -ENOMEM;
+	}
+	/* Enable only allowed on READY state */
+	if(pHba->status_block->iop_state == ADAPTER_STATE_OPERATIONAL)
+		return 0;
+
+	if(pHba->status_block->iop_state != ADAPTER_STATE_READY)
+		return -EINVAL;
+
+	msg[0]=FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
+	msg[1]=I2O_CMD_SYS_ENABLE<<24|HOST_TID<<12|ADAPTER_TID;
+	msg[2]= 0;
+	msg[3]= 0;
+
+	if ((ret = adpt_i2o_post_wait(pHba, msg, sizeof(msg), 240))) {
+		printk(KERN_WARNING"%s: Could not enable (status=%#10x).\n", 
+			pHba->name, ret);
+	} else {
+		PDEBUG("%s: Enabled.\n", pHba->name);
+	}
+
+	adpt_i2o_status_get(pHba);
+	return ret;
+}
+
+
+static int adpt_i2o_systab_send(adpt_hba* pHba)
+{
+	 u32 msg[12];
+	 int ret;
+
+	msg[0] = I2O_MESSAGE_SIZE(12) | SGL_OFFSET_6;
+	msg[1] = I2O_CMD_SYS_TAB_SET<<24 | HOST_TID<<12 | ADAPTER_TID;
+	msg[2] = 0;
+	msg[3] = 0;
+	msg[4] = (0<<16) | ((pHba->unit+2) << 12); /* Host 0 IOP ID (unit + 2) */
+	msg[5] = 0;				   /* Segment 0 */
+
+	/* 
+	 * Provide three SGL-elements:
+	 * System table (SysTab), Private memory space declaration and 
+	 * Private i/o space declaration  
+	 */
+	msg[6] = 0x54000000 | sys_tbl_len;
+	msg[7] = virt_to_phys(sys_tbl);
+	msg[8] = 0x54000000 | 0;
+	msg[9] = 0;
+	msg[10] = 0xD4000000 | 0;
+	msg[11] = 0;
+
+	if ((ret=adpt_i2o_post_wait(pHba, msg, sizeof(msg), 120))) {
+		printk(KERN_INFO "%s: Unable to set SysTab (status=%#10x).\n", 
+			pHba->name, ret);
+	}
+#ifdef DEBUG
+	else {
+		PINFO("%s: SysTab set.\n", pHba->name);
+	}
+#endif
+
+	return ret;	
+ }
+
+
+/*============================================================================
+ *
+ *============================================================================
+ */
+
+
+#ifdef UARTDELAY 
+
+static static void adpt_delay(int millisec)
+{
+	int i;
+	for (i = 0; i < millisec; i++) {
+		udelay(1000);	/* delay for one millisecond */
+	}
+}
+
+#endif
+
+static Scsi_Host_Template driver_template = DPT_I2O;
+#include "scsi_module.c"
+EXPORT_NO_SYMBOLS;
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/dpti.h linux/drivers/scsi/dpti.h
--- v2.4.9/linux/drivers/scsi/dpti.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/dpti.h	Fri Sep  7 09:28:38 2001
@@ -0,0 +1,403 @@
+/***************************************************************************
+                          dpti.h  -  description
+                             -------------------
+    begin                : Thu Sep 7 2000
+    copyright            : (C) 2001 by Adaptec
+    email                : deanna_bonds@adaptec.com
+
+    See README.dpti for history, notes, license info, and credits
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#ifndef _DPT_H
+#define _DPT_H
+
+#ifndef LINUX_VERSION_CODE
+#include <linux/version.h>
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,00)
+#define MAX_TO_IOP_MESSAGES   (210)
+#else
+#define MAX_TO_IOP_MESSAGES   (255)
+#endif
+#define MAX_FROM_IOP_MESSAGES (255)
+
+
+/*
+ * SCSI interface function Prototypes
+ */
+
+static int adpt_proc_info(char *buffer, char **start, off_t offset,
+		  int length, int inode, int inout);
+static int adpt_detect(Scsi_Host_Template * sht);
+static int adpt_queue(Scsi_Cmnd * cmd, void (*cmdcomplete) (Scsi_Cmnd *));
+static int adpt_abort(Scsi_Cmnd * cmd);
+static int adpt_reset(Scsi_Cmnd* cmd);
+static int adpt_release(struct Scsi_Host *host);
+
+static const char *adpt_info(struct Scsi_Host *pSHost);
+static int adpt_bios_param(Disk * disk, kdev_t dev, int geom[]);
+
+static int adpt_bus_reset(Scsi_Cmnd* cmd);
+static int adpt_device_reset(Scsi_Cmnd* cmd);
+
+
+/*
+ * Scsi_Host_Template (see hosts.h) 
+ */
+
+#define DPT_DRIVER_NAME	"Adaptec I2O RAID"
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,00)
+#define DPT_I2O { \
+	proc_info: adpt_proc_info,					\
+	detect: adpt_detect,						\
+	release: adpt_release,						\
+	info: adpt_info,						\
+	queuecommand: adpt_queue,					\
+	eh_abort_handler: adpt_abort,					\
+	eh_device_reset_handler: adpt_device_reset,			\
+	eh_bus_reset_handler: adpt_bus_reset,				\
+	eh_host_reset_handler: adpt_reset,				\
+	bios_param: adpt_bios_param,					\
+	can_queue: MAX_TO_IOP_MESSAGES ,/* max simultaneous cmds      */\
+	this_id: 7,			/* scsi id of host adapter    */\
+	sg_tablesize: 0,		/* max scatter-gather cmds    */\
+	cmd_per_lun: 256,		/* cmds per lun (linked cmds) */\
+	use_clustering: ENABLE_CLUSTERING,				\
+	use_new_eh_code: 1						\
+}
+
+#else				/* KERNEL_VERSION > 2.2.16 */
+
+#define DPT_I2O { \
+	proc_info: adpt_proc_info,					\
+	detect: adpt_detect,						\
+	release: adpt_release,						\
+	info: adpt_info,						\
+	queuecommand: adpt_queue,					\
+	eh_abort_handler: adpt_abort,					\
+	eh_device_reset_handler: adpt_device_reset,			\
+	eh_bus_reset_handler: adpt_bus_reset,				\
+	eh_host_reset_handler: adpt_reset,				\
+	bios_param: adpt_bios_param,					\
+	can_queue: MAX_TO_IOP_MESSAGES,	/* max simultaneous cmds      */\
+	this_id: 7,			/* scsi id of host adapter    */\
+	sg_tablesize: 0,		/* max scatter-gather cmds    */\
+	cmd_per_lun: 256,		/* cmds per lun (linked cmds) */\
+	use_clustering: ENABLE_CLUSTERING,				\
+	use_new_eh_code: 1,						\
+	proc_name: "dpt_i2o"	/* this is the name of our proc node*/	\
+}
+#endif
+
+#ifndef HOSTS_C
+
+#include "dpt/sys_info.h"
+#include <linux/wait.h>
+#include "dpt/dpti_i2o.h"
+#include "dpt/dpti_ioctl.h"
+
+#define DPT_I2O_VERSION "2.4 Build 5"
+#define DPT_VERSION     2
+#define DPT_REVISION    '4'
+#define DPT_SUBREVISION '5'
+#define DPT_BETA	""
+#define DPT_MONTH      8 
+#define DPT_DAY        7
+#define DPT_YEAR        (2001-1980)
+
+#define DPT_DRIVER	"dpt_i2o"
+#define DPTI_I2O_MAJOR	(151)
+#define DPT_ORGANIZATION_ID (0x1B)        /* For Private Messages */
+#define DPTI_MAX_HBA	(16)
+#define MAX_CHANNEL     (5)	// Maximum Channel # Supported
+#define MAX_ID        	(128)	// Maximum Target ID Supported
+
+/* Sizes in 4 byte words */
+#define REPLY_FRAME_SIZE  (17)
+#define MAX_MESSAGE_SIZE  (128)
+#define SG_LIST_ELEMENTS  (56)
+
+#define EMPTY_QUEUE           0xffffffff
+#define I2O_INTERRUPT_PENDING_B   (0x08)
+
+#define PCI_DPT_VENDOR_ID         (0x1044)	// DPT PCI Vendor ID
+#define PCI_DPT_DEVICE_ID         (0xA501)	// DPT PCI I2O Device ID
+#define PCI_DPT_RAPTOR_DEVICE_ID  (0xA511)	
+
+//#define REBOOT_NOTIFIER 1
+/* Debugging macro from Linux Device Drivers - Rubini */
+#undef PDEBUG
+#ifdef DEBUG
+//TODO add debug level switch
+#  define PDEBUG(fmt, args...)  printk(KERN_DEBUG "dpti: " fmt, ##args)
+#  define PDEBUGV(fmt, args...) printk(KERN_DEBUG "dpti: " fmt, ##args)
+#else
+# define PDEBUG(fmt, args...) /* not debugging: nothing */
+# define PDEBUGV(fmt, args...) /* not debugging: nothing */
+#endif
+
+#define PERROR(fmt, args...) printk(KERN_ERR fmt, ##args)
+#define PWARN(fmt, args...) printk(KERN_WARNING fmt, ##args)
+#define PINFO(fmt, args...) printk(KERN_INFO fmt, ##args)
+#define PCRIT(fmt, args...) printk(KERN_CRIT fmt, ##args)
+
+#define SHUTDOWN_SIGS	(sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGTERM))
+
+// Command timeouts
+#define FOREVER			(0)
+#define TMOUT_INQUIRY 		(20)
+#define TMOUT_FLUSH		(360/45)
+#define TMOUT_ABORT		(30)
+#define TMOUT_SCSI		(300)
+#define TMOUT_IOPRESET		(360)
+#define TMOUT_GETSTATUS		(15)
+#define TMOUT_INITOUTBOUND	(15)
+#define TMOUT_LCT		(360)
+
+
+#define I2O_SCSI_DEVICE_DSC_MASK                0x00FF
+
+#define I2O_DETAIL_STATUS_UNSUPPORTED_FUNCTION  0x000A
+
+#define I2O_SCSI_DSC_MASK                   0xFF00
+#define I2O_SCSI_DSC_SUCCESS                0x0000
+#define I2O_SCSI_DSC_REQUEST_ABORTED        0x0200
+#define I2O_SCSI_DSC_UNABLE_TO_ABORT        0x0300
+#define I2O_SCSI_DSC_COMPLETE_WITH_ERROR    0x0400
+#define I2O_SCSI_DSC_ADAPTER_BUSY           0x0500
+#define I2O_SCSI_DSC_REQUEST_INVALID        0x0600
+#define I2O_SCSI_DSC_PATH_INVALID           0x0700
+#define I2O_SCSI_DSC_DEVICE_NOT_PRESENT     0x0800
+#define I2O_SCSI_DSC_UNABLE_TO_TERMINATE    0x0900
+#define I2O_SCSI_DSC_SELECTION_TIMEOUT      0x0A00
+#define I2O_SCSI_DSC_COMMAND_TIMEOUT        0x0B00
+#define I2O_SCSI_DSC_MR_MESSAGE_RECEIVED    0x0D00
+#define I2O_SCSI_DSC_SCSI_BUS_RESET         0x0E00
+#define I2O_SCSI_DSC_PARITY_ERROR_FAILURE   0x0F00
+#define I2O_SCSI_DSC_AUTOSENSE_FAILED       0x1000
+#define I2O_SCSI_DSC_NO_ADAPTER             0x1100
+#define I2O_SCSI_DSC_DATA_OVERRUN           0x1200
+#define I2O_SCSI_DSC_UNEXPECTED_BUS_FREE    0x1300
+#define I2O_SCSI_DSC_SEQUENCE_FAILURE       0x1400
+#define I2O_SCSI_DSC_REQUEST_LENGTH_ERROR   0x1500
+#define I2O_SCSI_DSC_PROVIDE_FAILURE        0x1600
+#define I2O_SCSI_DSC_BDR_MESSAGE_SENT       0x1700
+#define I2O_SCSI_DSC_REQUEST_TERMINATED     0x1800
+#define I2O_SCSI_DSC_IDE_MESSAGE_SENT       0x3300
+#define I2O_SCSI_DSC_RESOURCE_UNAVAILABLE   0x3400
+#define I2O_SCSI_DSC_UNACKNOWLEDGED_EVENT   0x3500
+#define I2O_SCSI_DSC_MESSAGE_RECEIVED       0x3600
+#define I2O_SCSI_DSC_INVALID_CDB            0x3700
+#define I2O_SCSI_DSC_LUN_INVALID            0x3800
+#define I2O_SCSI_DSC_SCSI_TID_INVALID       0x3900
+#define I2O_SCSI_DSC_FUNCTION_UNAVAILABLE   0x3A00
+#define I2O_SCSI_DSC_NO_NEXUS               0x3B00
+#define I2O_SCSI_DSC_SCSI_IID_INVALID       0x3C00
+#define I2O_SCSI_DSC_CDB_RECEIVED           0x3D00
+#define I2O_SCSI_DSC_LUN_ALREADY_ENABLED    0x3E00
+#define I2O_SCSI_DSC_BUS_BUSY               0x3F00
+#define I2O_SCSI_DSC_QUEUE_FROZEN           0x4000
+
+
+#ifndef TRUE
+#define TRUE                  1
+#define FALSE                 0
+#endif
+
+#define HBA_FLAGS_INSTALLED_B       0x00000001	// Adapter Was Installed
+#define HBA_FLAGS_BLINKLED_B        0x00000002	// Adapter In Blink LED State
+#define HBA_FLAGS_IN_RESET	0x00000040	/* in reset */
+#define HBA_HOSTRESET_FAILED	0x00000080	/* adpt_resethost failed */
+
+
+// Device state flags
+#define DPTI_DEV_ONLINE    0x00
+#define DPTI_DEV_UNSCANNED 0x01
+#define DPTI_DEV_RESET	   0x02
+#define DPTI_DEV_OFFLINE   0x04
+
+
+struct adpt_device {
+	struct adpt_device* next_lun;
+	u32	flags;
+	u32	type;
+	u32	capacity;
+	u32	block_size;
+	u8	scsi_channel;
+	u8	scsi_id;
+	u8 	scsi_lun;
+	u8	state;
+	u16	tid;
+	struct i2o_device* pI2o_dev;
+	Scsi_Device *pScsi_dev;
+};
+
+struct adpt_channel {
+	struct adpt_device* device[MAX_ID];	/* used as an array of 128 scsi ids */
+	u8	scsi_id;
+	u8	type;
+	u16	tid;
+	u32	state;
+	struct i2o_device* pI2o_dev;
+};
+
+// HBA state flags
+#define DPTI_STATE_RESET	(0x01)
+#define DPTI_STATE_IOCTL	(0x02)
+
+typedef struct _adpt_hba {
+	struct _adpt_hba *next;
+	struct pci_dev *pDev;
+	struct Scsi_Host *host;
+	u32 state;
+	spinlock_t state_lock;
+	int unit;
+	int host_no;		/* SCSI host number */
+	u8 initialized;
+	u8 in_use;		/* is the management node open*/
+
+	char name[32];
+	char detail[55];
+
+	ulong base_addr_virt;
+	ulong msg_addr_virt;
+	ulong base_addr_phys;
+	ulong  post_port;
+	ulong  reply_port;
+	ulong  irq_mask;
+	u16  post_count;
+	u32  post_fifo_size;
+	u32  reply_fifo_size;
+	u32* reply_pool;
+	u32  sg_tablesize;	// Scatter/Gather List Size.       
+	u8  top_scsi_channel;
+	u8  top_scsi_id;
+	u8  top_scsi_lun;
+
+	i2o_status_block* status_block;
+	i2o_hrt* hrt;
+	i2o_lct* lct;
+	uint lct_size;
+	struct i2o_device* devices;
+	struct adpt_channel channel[MAX_CHANNEL];
+	struct proc_dir_entry* proc_entry;	/* /proc dir */
+
+	ulong FwDebugBuffer_P;	// Virtual Address Of FW Debug Buffer
+	u32   FwDebugBufferSize;	// FW Debug Buffer Size In Bytes
+	ulong FwDebugStrLength_P;	// Virtual Addr Of FW Debug String Len
+	ulong FwDebugFlags_P;	// Virtual Address Of FW Debug Flags 
+	ulong FwDebugBLEDflag_P;	// Virtual Addr Of FW Debug BLED
+	ulong FwDebugBLEDvalue_P;	// Virtual Addr Of FW Debug BLED
+	u32 FwDebugFlags;
+} adpt_hba;
+
+struct sg_simple_element {
+   u32  flag_count;
+   u32 addr_bus;
+}; 
+
+/*
+ * Function Prototypes
+ */
+
+static void adpt_i2o_sys_shutdown(void);
+static int adpt_init(void);
+static int adpt_i2o_build_sys_table(void);
+static void adpt_isr(int irq, void *dev_id, struct pt_regs *regs);
+#ifdef REBOOT_NOTIFIER
+static int adpt_reboot_event(struct notifier_block *n, ulong code, void *p);
+#endif
+
+static void adpt_i2o_report_hba_unit(adpt_hba* pHba, struct i2o_device *d);
+static int adpt_i2o_query_scalar(adpt_hba* pHba, int tid, 
+			int group, int field, void *buf, int buflen);
+#ifdef DEBUG
+static const char *adpt_i2o_get_class_name(int class);
+#endif
+static int adpt_i2o_issue_params(int cmd, adpt_hba* pHba, int tid, 
+		  void *opblk, int oplen, void *resblk, int reslen);
+static int adpt_i2o_post_wait(adpt_hba* pHba, u32* msg, int len, int timeout);
+static int adpt_i2o_lct_get(adpt_hba* pHba);
+static int adpt_i2o_parse_lct(adpt_hba* pHba);
+static int adpt_i2o_activate_hba(adpt_hba* pHba);
+static int adpt_i2o_enable_hba(adpt_hba* pHba);
+static int adpt_i2o_install_device(adpt_hba* pHba, struct i2o_device *d);
+static s32 adpt_i2o_post_this(adpt_hba* pHba, u32* data, int len);
+static s32 adpt_i2o_quiesce_hba(adpt_hba* pHba);
+static s32 adpt_i2o_status_get(adpt_hba* pHba);
+static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba);
+static s32 adpt_i2o_hrt_get(adpt_hba* pHba);
+static s32 adpt_scsi_to_i2o(adpt_hba* pHba, Scsi_Cmnd* cmd, struct adpt_device* dptdevice);
+static s32 adpt_i2o_to_scsi(ulong reply, Scsi_Cmnd* cmd);
+static s32 adpt_scsi_register(adpt_hba* pHba,Scsi_Host_Template * sht);
+static s32 adpt_hba_reset(adpt_hba* pHba);
+static s32 adpt_i2o_reset_hba(adpt_hba* pHba);
+static s32 adpt_rescan(adpt_hba* pHba);
+static s32 adpt_i2o_reparse_lct(adpt_hba* pHba);
+static s32 adpt_send_nop(adpt_hba*pHba,u32 m);
+static void adpt_i2o_delete_hba(adpt_hba* pHba);
+static void adpt_select_queue_depths(struct Scsi_Host *host, Scsi_Device * devicelist);
+static void adpt_inquiry(adpt_hba* pHba);
+static void adpt_fail_posted_scbs(adpt_hba* pHba);
+static struct adpt_device* adpt_find_device(adpt_hba* pHba, u32 chan, u32 id, u32 lun);
+static int adpt_install_hba(Scsi_Host_Template* sht, struct pci_dev* pDev) ;
+static int adpt_i2o_online_hba(adpt_hba* pHba);
+static void adpt_i2o_post_wait_complete(u32, int);
+static int adpt_i2o_systab_send(adpt_hba* pHba);
+
+static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg);
+static int adpt_open(struct inode *inode, struct file *file);
+static int adpt_close(struct inode *inode, struct file *file);
+
+
+#ifdef UARTDELAY
+static void adpt_delay(int millisec);
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
+static struct pci_dev* adpt_pci_find_device(uint vendor, struct pci_dev* from);
+#endif
+
+#if defined __ia64__ 
+static void adpt_ia64_info(sysInfo_S* si);
+#endif
+#if defined __sparc__ 
+static void adpt_sparc_info(sysInfo_S* si);
+#endif
+#if defined __alpha__ 
+static void adpt_sparc_info(sysInfo_S* si);
+#endif
+#if defined __i386__
+static void adpt_i386_info(sysInfo_S* si);
+#endif
+
+#define PRINT_BUFFER_SIZE     512
+
+#define HBA_FLAGS_DBG_FLAGS_MASK         0xffff0000	// Mask for debug flags
+#define HBA_FLAGS_DBG_KERNEL_PRINT_B     0x00010000	// Kernel Debugger Print
+#define HBA_FLAGS_DBG_FW_PRINT_B         0x00020000	// Firmware Debugger Print
+#define HBA_FLAGS_DBG_FUNCTION_ENTRY_B   0x00040000	// Function Entry Point
+#define HBA_FLAGS_DBG_FUNCTION_EXIT_B    0x00080000	// Function Exit
+#define HBA_FLAGS_DBG_ERROR_B            0x00100000	// Error Conditions
+#define HBA_FLAGS_DBG_INIT_B             0x00200000	// Init Prints
+#define HBA_FLAGS_DBG_OS_COMMANDS_B      0x00400000	// OS Command Info
+#define HBA_FLAGS_DBG_SCAN_B             0x00800000	// Device Scan
+
+#define FW_DEBUG_STR_LENGTH_OFFSET 0
+#define FW_DEBUG_FLAGS_OFFSET      4
+#define FW_DEBUG_BLED_OFFSET       8
+
+#define FW_DEBUG_FLAGS_NO_HEADERS_B    0x01
+#endif				/* !HOSTS_C */
+#endif				/* _DPT_H */
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/gdth.c linux/drivers/scsi/gdth.c
--- v2.4.9/linux/drivers/scsi/gdth.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/scsi/gdth.c	Fri Sep  7 09:28:37 2001
@@ -1,8 +1,10 @@
 /************************************************************************
- * GDT ISA/EISA/PCI Disk Array Controller driver for Linux              *
+ * Linux driver for                                                     *  
+ * ICP vortex GmbH:    GDT ISA/EISA/PCI Disk Array Controllers          *
+ * Intel Corporation:  Storage RAID Controllers                         *
  *                                                                      *
  * gdth.c                                                               *
- * Copyright (C) 1995-01 ICP vortex Computersysteme GmbH, Achim Leubner *
+ * Copyright (C) 1995-01 ICP vortex, an Intel company,  Achim Leubner   *
  *                                                                      *
  * <achim@vortex.de>                                                    *
  *                                                                      *
@@ -20,9 +22,36 @@
  * along with this kernel; if not, write to the Free Software           *
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.            *
  *                                                                      *
- * Tested with Linux 1.2.13, ..., 2.2.18, ..., 2.4.2                    *
+ * Tested with Linux 1.2.13, ..., 2.2.19, ..., 2.4.7                    *
  *                                                                      *
  * $Log: gdth.c,v $
+ * Revision 1.57  2001/08/21 11:16:35  achim
+ * Bugfix free_irq()
+ *
+ * Revision 1.56  2001/08/09 11:19:39  achim
+ * Scsi_Host_Template changes
+ *
+ * Revision 1.55  2001/08/09 10:11:28  achim
+ * Command HOST_UNFREEZE_IO before cache service init.
+ *
+ * Revision 1.54  2001/07/20 13:48:12  achim
+ * Expand: gdth_analyse_hdrive() removed
+ *
+ * Revision 1.53  2001/07/17 09:52:49  achim
+ * Small OEM related change
+ *
+ * Revision 1.52  2001/06/19 15:06:20  achim
+ * New host command GDT_UNFREEZE_IO added
+ *
+ * Revision 1.51  2001/05/22 06:42:37  achim
+ * PCI: Subdevice ID added
+ *
+ * Revision 1.50  2001/05/17 13:42:16  achim
+ * Support for Intel Storage RAID Controllers added
+ *
+ * Revision 1.50  2001/05/17 12:12:34  achim
+ * Support for Intel Storage RAID Controllers added
+ *
  * Revision 1.49  2001/03/15 15:07:17  achim
  * New __setup interface for boot command line options added
  *
@@ -203,7 +232,7 @@
  * Initial revision
  *
  ************************************************************************/
-#ident "$Id: gdth.c,v 1.49 2001/03/15 15:07:17 achim Exp $" 
+#ident "$Id: gdth.c,v 1.57 2001/08/21 11:16:35 achim Exp $" 
 
 /* All GDT Disk Array Controllers are fully supported by this driver.
  * This includes the PCI/EISA/ISA SCSI Disk Array Controllers and the
@@ -291,9 +320,6 @@
 #else
 #include <linux/bios32.h>
 #endif
-#if LINUX_VERSION_CODE >= 0x020126
-#include <linux/init.h>
-#endif
 
 #include <asm/dma.h>
 #include <asm/system.h>
@@ -344,6 +370,8 @@
 static int gdth_search_eisa(ushort eisa_adr);
 static int gdth_search_isa(ulong32 bios_adr);
 static int gdth_search_pci(gdth_pci_str *pcistr);
+static void gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt, 
+                            ushort vendor, ushort dev);
 static void gdth_sort_pci(gdth_pci_str *pcistr, int cnt);
 static int gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha);
 static int gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha);
@@ -588,8 +616,10 @@
 /* __initfunc, __initdata macros */
 #if LINUX_VERSION_CODE >= 0x020322
 #define GDTH_INITFUNC(type, func)       type __init func 
+#include <linux/init.h>
 #elif LINUX_VERSION_CODE >= 0x020126
 #define GDTH_INITFUNC(type, func)       __initfunc(type func)
+#include <linux/init.h>
 #else
 #define GDTH_INITFUNC(type, func)       type func
 #define __initdata
@@ -753,8 +783,28 @@
 
 GDTH_INITFUNC(static int, gdth_search_pci(gdth_pci_str *pcistr))
 {
+    ushort device, cnt;
+    
+    TRACE(("gdth_search_pci()\n"));
+
+    cnt = 0;
+    for (device = 0; device <= PCI_DEVICE_ID_VORTEX_GDT6555; ++device)
+        gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_VORTEX, device);
+    for (device = PCI_DEVICE_ID_VORTEX_GDT6x17RP; 
+         device <= PCI_DEVICE_ID_VORTEX_GDTMAXRP; ++device)
+        gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_VORTEX, device);
+    gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_VORTEX, 
+                    PCI_DEVICE_ID_VORTEX_GDTNEWRX);
+    gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_INTEL,
+                    PCI_DEVICE_ID_INTEL_SRC);
+    return cnt;
+}
+
+
+GDTH_INITFUNC(static void, gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt,
+                                           ushort vendor, ushort device))
+{
     ulong base0, base1, base2;
-    ushort device_id, cnt;
 #if LINUX_VERSION_CODE >= 0x2015C
     struct pci_dev *pdev;
 #else
@@ -762,147 +812,150 @@
     ushort idx;
 #endif
     
-    TRACE(("gdth_search_pci()\n"));
+    TRACE(("gdth_search_dev() cnt %d vendor %x device %x\n",
+          *cnt, vendor, device));
 
-    cnt = 0;
-    for (device_id = 0; device_id <= PCI_DEVICE_ID_VORTEX_GDTMAXRP; 
-         ++device_id) {
-        if (device_id > PCI_DEVICE_ID_VORTEX_GDT6555 &&
-            device_id < PCI_DEVICE_ID_VORTEX_GDT6x17RP)
-            continue;
 #if LINUX_VERSION_CODE >= 0x20363
-        pdev = NULL;
-        while ((pdev = pci_find_device(PCI_VENDOR_ID_VORTEX,device_id,pdev)) 
-               != NULL) {
-            if (pci_enable_device(pdev))
+    pdev = NULL;
+    while ((pdev = pci_find_device(vendor, device, pdev)) 
+           != NULL) {
+        if (pci_enable_device(pdev))
+            continue;
+        if (*cnt >= MAXHA)
+            return;
+        /* GDT PCI controller found, resources are already in pdev */
+        pcistr[*cnt].pdev = pdev;
+        pcistr[*cnt].vendor_id = vendor;
+        pcistr[*cnt].device_id = device;
+        pcistr[*cnt].subdevice_id = pdev->subsystem_device;
+        pcistr[*cnt].bus = pdev->bus->number;
+        pcistr[*cnt].device_fn = pdev->devfn;
+        pcistr[*cnt].irq = pdev->irq;
+        base0 = pci_resource_flags(pdev, 0);
+        base1 = pci_resource_flags(pdev, 1);
+        base2 = pci_resource_flags(pdev, 2);
+        if (device <= PCI_DEVICE_ID_VORTEX_GDT6000B ||   /* GDT6000/B */
+            device >= PCI_DEVICE_ID_VORTEX_GDT6x17RP) {  /* MPR */
+            if (!(base0 & IORESOURCE_MEM)) 
                 continue;
-            if (cnt >= MAXHA)
-                return cnt;
-            /* GDT PCI controller found, resources are already in pdev */
-            pcistr[cnt].pdev = pdev;
-            pcistr[cnt].device_id = device_id;
-            pcistr[cnt].bus = pdev->bus->number;
-            pcistr[cnt].device_fn = pdev->devfn;
-            pcistr[cnt].irq = pdev->irq;
-            base0 = pci_resource_flags(pdev, 0);
-            base1 = pci_resource_flags(pdev, 1);
-            base2 = pci_resource_flags(pdev, 2);
-            if (device_id <= PCI_DEVICE_ID_VORTEX_GDT6000B ||   /* GDT6000/B */
-                device_id >= PCI_DEVICE_ID_VORTEX_GDT6x17RP) {  /* MPR */
-                if (!(base0 & IORESOURCE_MEM)) 
-                    continue;
-                pcistr[cnt].dpmem = pci_resource_start(pdev, 0);
-            } else {                                  /* GDT6110, GDT6120, .. */
-                if (!(base0 & IORESOURCE_MEM) ||
-                    !(base2 & IORESOURCE_MEM) ||
-                    !(base1 & IORESOURCE_IO)) 
-                    continue;
-                pcistr[cnt].dpmem = pci_resource_start(pdev, 2);
-                pcistr[cnt].io_mm = pci_resource_start(pdev, 0);
-                pcistr[cnt].io    = pci_resource_start(pdev, 1);
-            }
-            TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%lx\n",
-                    pcistr[cnt].bus, PCI_SLOT(pcistr[cnt].device_fn), 
-                    pcistr[cnt].irq, pcistr[cnt].dpmem));
-            cnt++;
-        }       
+            pcistr[*cnt].dpmem = pci_resource_start(pdev, 0);
+        } else {                                  /* GDT6110, GDT6120, .. */
+            if (!(base0 & IORESOURCE_MEM) ||
+                !(base2 & IORESOURCE_MEM) ||
+                !(base1 & IORESOURCE_IO)) 
+                continue;
+            pcistr[*cnt].dpmem = pci_resource_start(pdev, 2);
+            pcistr[*cnt].io_mm = pci_resource_start(pdev, 0);
+            pcistr[*cnt].io    = pci_resource_start(pdev, 1);
+        }
+        TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%lx\n",
+                pcistr[*cnt].bus, PCI_SLOT(pcistr[*cnt].device_fn), 
+                pcistr[*cnt].irq, pcistr[*cnt].dpmem));
+        (*cnt)++;
+    }       
 #elif LINUX_VERSION_CODE >= 0x2015C
-        pdev = NULL;
-        while ((pdev = pci_find_device(PCI_VENDOR_ID_VORTEX,device_id,pdev)) 
-               != NULL) {
-            if (cnt >= MAXHA)
-                return cnt;
-            /* GDT PCI controller found, resources are already in pdev */
-            pcistr[cnt].pdev = pdev;
-            pcistr[cnt].device_id = device_id;
-            pcistr[cnt].bus = pdev->bus->number;
-            pcistr[cnt].device_fn = pdev->devfn;
-            pcistr[cnt].irq = pdev->irq;
-            base0 = pdev->base_address[0];
-            base1 = pdev->base_address[1];
-            base2 = pdev->base_address[2];
-            if (device_id <= PCI_DEVICE_ID_VORTEX_GDT6000B ||   /* GDT6000/B */
-                device_id >= PCI_DEVICE_ID_VORTEX_GDT6x17RP) {  /* MPR */
-                if ((base0 & PCI_BASE_ADDRESS_SPACE) != 
-                    PCI_BASE_ADDRESS_SPACE_MEMORY)
-                    continue;
-                pcistr[cnt].dpmem = base0 & PCI_BASE_ADDRESS_MEM_MASK;
-            } else {                                  /* GDT6110, GDT6120, .. */
-                if ((base0 & PCI_BASE_ADDRESS_SPACE) !=
-                    PCI_BASE_ADDRESS_SPACE_MEMORY ||
-                    (base2 & PCI_BASE_ADDRESS_SPACE) !=
-                    PCI_BASE_ADDRESS_SPACE_MEMORY ||
-                    (base1 & PCI_BASE_ADDRESS_SPACE) !=
-                    PCI_BASE_ADDRESS_SPACE_IO)
-                    continue;
-                pcistr[cnt].dpmem = base2 & PCI_BASE_ADDRESS_MEM_MASK;
-                pcistr[cnt].io_mm = base0 & PCI_BASE_ADDRESS_MEM_MASK;
-                pcistr[cnt].io    = base1 & PCI_BASE_ADDRESS_IO_MASK;
-            }
-            TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%lx\n",
-                    pcistr[cnt].bus, PCI_SLOT(pcistr[cnt].device_fn), 
-                    pcistr[cnt].irq, pcistr[cnt].dpmem));
-            cnt++;
-        }       
+    pdev = NULL;
+    while ((pdev = pci_find_device(vendor, device, pdev)) 
+           != NULL) {
+        if (*cnt >= MAXHA)
+            return;
+        /* GDT PCI controller found, resources are already in pdev */
+        pcistr[*cnt].pdev = pdev;
+        pcistr[*cnt].vendor_id = vendor;
+        pcistr[*cnt].device_id = device;
+        pcistr[*cnt].bus = pdev->bus->number;
+        pcistr[*cnt].device_fn = pdev->devfn;
+        pcibios_read_config_word(pcistr[*cnt].bus, pcistr[*cnt].device_fn,
+                                 PCI_SUBSYSTEM_ID, &pcistr[*cnt].subdevice_id);
+        pcistr[*cnt].irq = pdev->irq;
+        base0 = pdev->base_address[0];
+        base1 = pdev->base_address[1];
+        base2 = pdev->base_address[2];
+        if (device <= PCI_DEVICE_ID_VORTEX_GDT6000B ||   /* GDT6000/B */
+            device >= PCI_DEVICE_ID_VORTEX_GDT6x17RP) {  /* MPR */
+            if ((base0 & PCI_BASE_ADDRESS_SPACE) != 
+                PCI_BASE_ADDRESS_SPACE_MEMORY)
+                continue;
+            pcistr[*cnt].dpmem = base0 & PCI_BASE_ADDRESS_MEM_MASK;
+        } else {                                  /* GDT6110, GDT6120, .. */
+            if ((base0 & PCI_BASE_ADDRESS_SPACE) !=
+                PCI_BASE_ADDRESS_SPACE_MEMORY ||
+                (base2 & PCI_BASE_ADDRESS_SPACE) !=
+                PCI_BASE_ADDRESS_SPACE_MEMORY ||
+                (base1 & PCI_BASE_ADDRESS_SPACE) !=
+                PCI_BASE_ADDRESS_SPACE_IO)
+                continue;
+            pcistr[*cnt].dpmem = base2 & PCI_BASE_ADDRESS_MEM_MASK;
+            pcistr[*cnt].io_mm = base0 & PCI_BASE_ADDRESS_MEM_MASK;
+            pcistr[*cnt].io    = base1 & PCI_BASE_ADDRESS_IO_MASK;
+        }
+        TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%lx\n",
+                pcistr[*cnt].bus, PCI_SLOT(pcistr[*cnt].device_fn), 
+                pcistr[*cnt].irq, pcistr[*cnt].dpmem));
+        (*cnt)++;
+    }       
 #else   
-        idx = 0;
-        while (!pcibios_find_device(PCI_VENDOR_ID_VORTEX,device_id,idx++,
-                                    &pcistr[cnt].bus,&pcistr[cnt].device_fn)) {
-            if (cnt >= MAXHA)
-                return cnt;
-            /* GDT PCI ctr. found, now read resources from config space */
+    idx = 0;
+    while (!pcibios_find_device(vendor, device, idx++,
+                                &pcistr[*cnt].bus,&pcistr[*cnt].device_fn)) {
+        if (*cnt >= MAXHA)
+            return;
+        /* GDT PCI ctr. found, now read resources from config space */
 #if LINUX_VERSION_CODE >= 0x010300
 #define GDTH_BASEP      (int *)
 #else
 #define GDTH_BASEP
 #endif
-            if ((error = pcibios_read_config_dword(pcistr[cnt].bus,
-                                                   pcistr[cnt].device_fn,
-                                                   PCI_BASE_ADDRESS_0,
-                                                   GDTH_BASEP&base0)) ||
-                (error = pcibios_read_config_dword(pcistr[cnt].bus,
-                                                   pcistr[cnt].device_fn,
-                                                   PCI_BASE_ADDRESS_1,
-                                                   GDTH_BASEP&base1)) ||
-                (error = pcibios_read_config_dword(pcistr[cnt].bus,
-                                                   pcistr[cnt].device_fn,
-                                                   PCI_BASE_ADDRESS_2,
-                                                   GDTH_BASEP&base2)) ||
-                (error = pcibios_read_config_byte(pcistr[cnt].bus,
-                                                  pcistr[cnt].device_fn,
-                                                  PCI_INTERRUPT_LINE,
-                                                  &pcistr[cnt].irq))) {
-                printk("GDT-PCI: error %d reading configuration space", error);
+        if ((error = pcibios_read_config_dword(pcistr[*cnt].bus,
+                                               pcistr[*cnt].device_fn,
+                                               PCI_BASE_ADDRESS_0,
+                                               GDTH_BASEP&base0)) ||
+            (error = pcibios_read_config_dword(pcistr[*cnt].bus,
+                                               pcistr[*cnt].device_fn,
+                                               PCI_BASE_ADDRESS_1,
+                                               GDTH_BASEP&base1)) ||
+            (error = pcibios_read_config_dword(pcistr[*cnt].bus,
+                                               pcistr[*cnt].device_fn,
+                                               PCI_BASE_ADDRESS_2,
+                                               GDTH_BASEP&base2)) ||
+            (error = pcibios_read_config_word(pcistr[*cnt].bus,
+                                              pcistr[*cnt].device_fn,
+                                              PCI_SUBSYSTEM_ID,
+                                              &pcistr[*cnt].subdevice_id)) ||
+            (error = pcibios_read_config_byte(pcistr[*cnt].bus,
+                                              pcistr[*cnt].device_fn,
+                                              PCI_INTERRUPT_LINE,
+                                              &pcistr[*cnt].irq))) {
+            printk("GDT-PCI: error %d reading configuration space", error);
+            continue;
+        }
+        pcistr[*cnt].vendor_id = vendor;
+        pcistr[*cnt].device_id = device;
+        if (device <= PCI_DEVICE_ID_VORTEX_GDT6000B ||   /* GDT6000/B */
+            device >= PCI_DEVICE_ID_VORTEX_GDT6x17RP) {  /* MPR */
+            if ((base0 & PCI_BASE_ADDRESS_SPACE) !=
+                PCI_BASE_ADDRESS_SPACE_MEMORY)
                 continue;
-            }
-            pcistr[cnt].device_id = device_id;
-            if (device_id <= PCI_DEVICE_ID_VORTEX_GDT6000B ||   /* GDT6000/B */
-                device_id >= PCI_DEVICE_ID_VORTEX_GDT6x17RP) {  /* MPR */
-                if ((base0 & PCI_BASE_ADDRESS_SPACE) !=
-                    PCI_BASE_ADDRESS_SPACE_MEMORY)
-                    continue;
-                pcistr[cnt].dpmem = base0 & PCI_BASE_ADDRESS_MEM_MASK;
-            } else {                                    /* GDT6110, GDT6120, .. */
-                if ((base0 & PCI_BASE_ADDRESS_SPACE) !=
-                    PCI_BASE_ADDRESS_SPACE_MEMORY ||
-                    (base2 & PCI_BASE_ADDRESS_SPACE) !=
-                    PCI_BASE_ADDRESS_SPACE_MEMORY ||
-                    (base1 & PCI_BASE_ADDRESS_SPACE) !=
-                    PCI_BASE_ADDRESS_SPACE_IO)
-                    continue;
-                pcistr[cnt].dpmem = base2 & PCI_BASE_ADDRESS_MEM_MASK;
-                pcistr[cnt].io_mm = base0 & PCI_BASE_ADDRESS_MEM_MASK;
-                pcistr[cnt].io    = base1 & PCI_BASE_ADDRESS_IO_MASK;
-            }
-            TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%lx\n",
-                    pcistr[cnt].bus, PCI_SLOT(pcistr[cnt].device_fn), 
-                    pcistr[cnt].irq, pcistr[cnt].dpmem));
-            cnt++;
+            pcistr[*cnt].dpmem = base0 & PCI_BASE_ADDRESS_MEM_MASK;
+        } else {                                    /* GDT6110, GDT6120, .. */
+            if ((base0 & PCI_BASE_ADDRESS_SPACE) !=
+                PCI_BASE_ADDRESS_SPACE_MEMORY ||
+                (base2 & PCI_BASE_ADDRESS_SPACE) !=
+                PCI_BASE_ADDRESS_SPACE_MEMORY ||
+                (base1 & PCI_BASE_ADDRESS_SPACE) !=
+                PCI_BASE_ADDRESS_SPACE_IO)
+                continue;
+            pcistr[*cnt].dpmem = base2 & PCI_BASE_ADDRESS_MEM_MASK;
+            pcistr[*cnt].io_mm = base0 & PCI_BASE_ADDRESS_MEM_MASK;
+            pcistr[*cnt].io    = base1 & PCI_BASE_ADDRESS_IO_MASK;
         }
+        TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%lx\n",
+                pcistr[*cnt].bus, PCI_SLOT(pcistr[*cnt].device_fn), 
+                pcistr[*cnt].irq, pcistr[*cnt].dpmem));
+        (*cnt)++;
+    }
 #endif
-    }   
-    return cnt;
-}
+}   
 
 
 GDTH_INITFUNC(static void, gdth_sort_pci(gdth_pci_str *pcistr, int cnt))
@@ -982,6 +1035,7 @@
 
     /* detect IRQ */ 
     if ((id = inl(eisa_adr+ID0REG)) == GDT3_ID) {
+        ha->oem_id = OEM_ID_ICP;
         ha->type = GDT_EISA;
         ha->stype = id;
         outl(1,eisa_adr+MAILBOXREG+8);
@@ -1025,6 +1079,7 @@
         if (eisacf > 4)                         /* level triggered */
             eisacf -= 4;
         ha->irq = gdth_irq_tab[eisacf];
+        ha->oem_id = OEM_ID_ICP;
         ha->type = GDT_EISA;
         ha->stype = id;
     }
@@ -1101,6 +1156,7 @@
         return 0;
     }
 
+    ha->oem_id = OEM_ID_ICP;
     ha->type = GDT_ISA;
     ha->ic_all_size = sizeof(dp2_ptr->u);
     ha->stype= GDT2_ID;
@@ -1144,9 +1200,14 @@
 
     TRACE(("gdth_init_pci()\n"));
 
+    if (pcistr->vendor_id == PCI_VENDOR_ID_INTEL)
+        ha->oem_id = OEM_ID_INTEL;
+    else
+        ha->oem_id = OEM_ID_ICP;
     ha->brd_phys = (pcistr->bus << 8) | (pcistr->device_fn & 0xf8);
-    ha->stype    = (ulong32)pcistr->device_id;
-    ha->irq      = pcistr->irq;
+    ha->stype = (ulong32)pcistr->device_id;
+    ha->subdevice_id = pcistr->subdevice_id;
+    ha->irq = pcistr->irq;
     
     if (ha->stype <= PCI_DEVICE_ID_VORTEX_GDT6000B) {  /* GDT6000/B */
         TRACE2(("init_pci() dpmem %lx irq %d\n",pcistr->dpmem,ha->irq));
@@ -1914,7 +1975,10 @@
     /* 3. send to controller firmware */
     gdth_internal_cmd(hanum,SCREENSERVICE,GDT_REALTIME, *(ulong32 *)&rtc[0],
                       *(ulong32 *)&rtc[4], *(ulong32 *)&rtc[8]);
-#endif   
+#endif  
+ 
+    /* unfreeze all IOs */
+    gdth_internal_cmd(hanum,CACHESERVICE,GDT_UNFREEZE_IO,0,0,0);
  
     /* initialize cache service */
     if (!gdth_internal_cmd(hanum,CACHESERVICE,GDT_INIT,LINUX_OS,0,0)) {
@@ -2599,7 +2663,10 @@
         inq.version   = 2;
         inq.resp_aenc = 2;
         inq.add_length= 32;
-        strcpy(inq.vendor,"ICP    ");
+        if (ha->oem_id == OEM_ID_INTEL)
+            strcpy(inq.vendor,"Intel  ");
+        else 
+            strcpy(inq.vendor,"ICP    ");
         sprintf(inq.product,"Host Drive  #%02d",t);
         strcpy(inq.revision,"   ");
         gdth_copy_internal_data(scp,(char*)&inq,sizeof(gdth_inq_data));
@@ -3690,7 +3757,7 @@
         if (ha->service == CACHESERVICE && ha->status == 56) {
             TRACE2(("gdth_async_event(): new host drive %d created\n",
                     (ushort)ha->info));
-            gdth_analyse_hdrive(hanum, (ushort)ha->info);
+            /* gdth_analyse_hdrive(hanum, (ushort)ha->info); */
         }   
     }
     return 1;
@@ -3938,7 +4005,7 @@
             if (request_dma(ha->drq,"gdth")) {
                 printk("GDT-ISA: Unable to allocate DMA channel\n");
 #if LINUX_VERSION_CODE >= 0x010346 
-                free_irq(ha->irq,NULL);
+                free_irq(ha->irq,ha);
 #else
                 free_irq(ha->irq);
 #endif
@@ -3984,7 +4051,7 @@
                     scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH);
 #endif
 #if LINUX_VERSION_CODE >= 0x010346 
-                free_irq(ha->irq,NULL);
+                free_irq(ha->irq,ha);
 #else
                 free_irq(ha->irq);
 #endif
@@ -4085,7 +4152,7 @@
                     scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH);
 #endif
 #if LINUX_VERSION_CODE >= 0x010346 
-                free_irq(ha->irq,NULL);
+                free_irq(ha->irq,ha);
 #else
                 free_irq(ha->irq);
 #endif
@@ -4194,7 +4261,7 @@
                     scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH);
 #endif
 #if LINUX_VERSION_CODE >= 0x010346 
-                free_irq(ha->irq,NULL);
+                free_irq(ha->irq,ha);
 #else
                 free_irq(ha->irq);
 #endif
@@ -4264,7 +4331,7 @@
 
         if (shp->irq) {
 #if LINUX_VERSION_CODE >= 0x010346
-            free_irq(shp->irq,NULL);
+            free_irq(shp->irq,ha);
 #else
             free_irq(shp->irq);
 #endif
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/gdth.h linux/drivers/scsi/gdth.h
--- v2.4.9/linux/drivers/scsi/gdth.h	Sat May 19 17:43:06 2001
+++ linux/drivers/scsi/gdth.h	Fri Sep  7 09:28:37 2001
@@ -10,7 +10,7 @@
  *
  * <achim@vortex.de>
  *
- * $Id: gdth.h,v 1.38 2001/03/15 15:06:23 achim Exp $
+ * $Id: gdth.h,v 1.44 2001/08/21 11:19:05 achim Exp $
  */
 
 #include <linux/version.h>
@@ -29,13 +29,17 @@
 /* defines, macros */
 
 /* driver version */
-#define GDTH_VERSION_STR        "1.28"
-#define GDTH_VERSION            1
-#define GDTH_SUBVERSION         28
+#define GDTH_VERSION_STR        "2.03"
+#define GDTH_VERSION            2
+#define GDTH_SUBVERSION         3
 
 /* protocol version */
 #define PROTOCOL_VERSION        1
 
+/* OEM IDs */
+#define OEM_ID_ICP	0x941c
+#define OEM_ID_INTEL	0x8000
+
 /* controller classes */
 #define GDT_ISA         0x01                    /* ISA controller */
 #define GDT_EISA        0x02                    /* EISA controller */
@@ -54,6 +58,9 @@
 #ifndef PCI_VENDOR_ID_VORTEX
 #define PCI_VENDOR_ID_VORTEX            0x1119  /* PCI controller vendor ID */
 #endif
+#ifndef PCI_VENDOR_ID_INTEL
+#define PCI_VENDOR_ID_INTEL             0x8086  
+#endif
 
 #ifndef PCI_DEVICE_ID_VORTEX_GDT60x0
 /* GDT_PCI */
@@ -125,6 +132,16 @@
 #define PCI_DEVICE_ID_VORTEX_GDTMAXRP   0x2ff   
 #endif
 
+#ifndef PCI_DEVICE_ID_VORTEX_GDTNEWRX
+/* new GDT Rx Controller */
+#define PCI_DEVICE_ID_VORTEX_GDTNEWRX	0x300
+#endif
+	
+#ifndef PCI_DEVICE_ID_INTEL_SRC
+/* Intel Storage RAID Controller */
+#define PCI_DEVICE_ID_INTEL_SRC		0x600
+#endif
+
 /* limits */
 #define GDTH_SCRATCH    PAGE_SIZE               /* 4KB scratch buffer */
 #define GDTH_SCRATCH_ORD 0                      /* order 0 means 1 page */
@@ -202,6 +219,8 @@
 #define GDT_CLUST_INFO  22                      /* cluster info */
 #define GDT_RW_ATTRIBS  23                      /* R/W attribs (write thru,..)*/
 #define GDT_CLUST_RESET 24                      /* releases the cluster drives*/
+#define GDT_FREEZE_IO   25                      /* freezes all IOs */
+#define GDT_UNFREEZE_IO 26                      /* unfreezes all IOs */
 
 /* raw service commands */
 #define GDT_RESERVE     14                      /* reserve dev. to raw serv. */
@@ -843,7 +862,9 @@
 #if LINUX_VERSION_CODE >= 0x02015C
     struct pci_dev      *pdev;
 #endif
+    ushort              vendor_id;              /* vendor (ICP, Intel, ..) */
     ushort              device_id;              /* device ID (0,..,9) */
+    ushort              subdevice_id;           /* sub device ID */
     unchar              bus;                    /* PCI bus */
     unchar              device_fn;              /* PCI device/function no. */
     ulong               dpmem;                  /* DPRAM address */
@@ -855,9 +876,11 @@
 
 /* controller information structure */
 typedef struct {
+    ushort              oem_id;                 /* OEM */
     ushort              type;                   /* controller class */
     ushort              raw_feat;               /* feat. raw service (s/g,..) */
-    ulong32             stype;                  /* controller subtype */
+    ulong32             stype;                  /* subtype (PCI: device ID) */
+    ushort              subdevice_id;           /* sub device ID (PCI) */
     ushort              fw_vers;                /* firmware version */
     ushort              cache_feat;             /* feat. cache serv. (s/g,..) */
     ushort              bmic;                   /* BMIC address (EISA) */
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/gdth_ioctl.h linux/drivers/scsi/gdth_ioctl.h
--- v2.4.9/linux/drivers/scsi/gdth_ioctl.h	Sat May 19 17:43:06 2001
+++ linux/drivers/scsi/gdth_ioctl.h	Fri Sep  7 09:28:37 2001
@@ -2,7 +2,7 @@
 #define _GDTH_IOCTL_H
 
 /* gdth_ioctl.h
- * $Id: gdth_ioctl.h,v 1.9 2001/01/10 14:39:37 achim Exp $
+ * $Id: gdth_ioctl.h,v 1.10 2001/05/22 06:28:59 achim Exp $
  */
 
 /* IOCTLs */
@@ -83,6 +83,8 @@
             ushort          bios_ver;           /* not used */
             ushort          access;             /* not used */
             ushort          ext_type;           /* extended type */
+            ushort          device_id;          /* device ID */
+            ushort          sub_device_id;      /* sub device ID */
         } ctrtype;
         struct {
             unchar          version;            /* OS version */
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/gdth_proc.c linux/drivers/scsi/gdth_proc.c
--- v2.4.9/linux/drivers/scsi/gdth_proc.c	Sun Aug 12 13:28:00 2001
+++ linux/drivers/scsi/gdth_proc.c	Fri Sep  7 09:28:37 2001
@@ -1,9 +1,11 @@
 /* gdth_proc.c 
- * $Id: gdth_proc.c,v 1.27 2001/03/14 10:47:00 achim Exp $
+ * $Id: gdth_proc.c,v 1.33 2001/08/10 07:54:39 achim Exp $
  */
 
 #include "gdth_ioctl.h"
+#if LINUX_VERSION_CODE >= 0x020407
 #include <linux/completion.h>
+#endif
 
 int gdth_proc_info(char *buffer,char **start,off_t offset,int length,   
                    int hostno,int inout)
@@ -48,7 +50,7 @@
     sdev = scsi_get_host_dev(gdth_ctr_vtab[vh]);
     scp  = scsi_allocate_device(sdev, 1, FALSE);
     if (!scp)
-	    return -ENOMEM;
+        return -ENOMEM;
     scp->cmd_len = 12;
     scp->use_sg = 0;
 #else
@@ -176,7 +178,7 @@
     }
 
     if (wb_mode) {
-        if (!gdth_ioctl_alloc(hanum, sizeof(gdth_cpar_str)))
+        if (!gdth_ioctl_alloc(hanum, sizeof(gdth_cpar_str), TRUE))
             return(-EBUSY);
         pcpar = (gdth_cpar_str *)ha->pscratch;
         memcpy( pcpar, &ha->cpar, sizeof(gdth_cpar_str) );
@@ -192,7 +194,7 @@
 #else
         gdth_do_cmd(&scp, &gdtcmd, cmnd, 30);
 #endif
-        gdth_ioctl_free(hanum);
+        gdth_ioctl_free(hanum, ha->pscratch);
         printk("Done.\n");
         return(orig_length);
     }
@@ -270,7 +272,8 @@
         } else {
             return(-EINVAL);
         }
-        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str)+add_size+add_size2 ))
+        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str)+add_size+add_size2,
+                               TRUE ))
             return(-EBUSY);
         piord = (gdth_iord_str *)ha->pscratch;
 
@@ -294,7 +297,7 @@
         break;
 
       case GDTIOCTL_DRVERS:
-        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
             return(-EBUSY);
         piord = (gdth_iord_str *)ha->pscratch;
         piord->size = sizeof(gdth_iord_str);
@@ -303,25 +306,33 @@
         break;
 
       case GDTIOCTL_CTRTYPE:
-        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
             return(-EBUSY);
         piord = (gdth_iord_str *)ha->pscratch;
         piord->size = sizeof(gdth_iord_str);
         piord->status = S_OK;
         if (ha->type == GDT_ISA || ha->type == GDT_EISA) {
             piord->iu.ctrtype.type = (unchar)((ha->stype>>20) - 0x10);
-        } else if (ha->type != GDT_PCIMPR) {
-            piord->iu.ctrtype.type = (unchar)((ha->stype<<8) + 6);
         } else {
-            piord->iu.ctrtype.type = 0xfe;
-            piord->iu.ctrtype.ext_type = 0x6000 | ha->stype;
+            if (ha->type != GDT_PCIMPR) {
+                piord->iu.ctrtype.type = (unchar)((ha->stype<<4) + 6);
+            } else {
+                piord->iu.ctrtype.type = 
+                    (ha->oem_id == OEM_ID_INTEL ? 0xfd : 0xfe);
+                if (ha->stype >= 0x300)
+                    piord->iu.ctrtype.ext_type = 0x6000 | ha->subdevice_id;
+                else 
+                    piord->iu.ctrtype.ext_type = 0x6000 | ha->stype;
+            }
+            piord->iu.ctrtype.device_id = ha->stype;
+            piord->iu.ctrtype.sub_device_id = ha->subdevice_id;
         }
         piord->iu.ctrtype.info = ha->brd_phys;
-        piord->iu.ctrtype.oem_id = (ushort)GDT3_ID;
+        piord->iu.ctrtype.oem_id = ha->oem_id;
         break;
 
       case GDTIOCTL_CTRCNT:
-        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
             return(-EBUSY);
         piord = (gdth_iord_str *)ha->pscratch;
         piord->size = sizeof(gdth_iord_str);
@@ -330,7 +341,7 @@
         break;
 
       case GDTIOCTL_OSVERS:
-        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
             return(-EBUSY);
         piord = (gdth_iord_str *)ha->pscratch;
         piord->size = sizeof(gdth_iord_str);
@@ -341,7 +352,7 @@
         break;
 
       case GDTIOCTL_LOCKDRV:
-        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
             return(-EBUSY);
         piord = (gdth_iord_str *)ha->pscratch;
         for (i = 0; i < piowr->iu.lockdrv.drive_cnt; ++i) {
@@ -367,7 +378,7 @@
         break;
 
       case GDTIOCTL_LOCKCHN:
-        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
             return(-EBUSY);
         i = piowr->iu.lockchn.channel;
         if (i < ha->bus_cnt) {
@@ -395,7 +406,7 @@
         break;
 
       case GDTIOCTL_EVENT:
-        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
             return(-EBUSY);
         piord = (gdth_iord_str *)ha->pscratch;
         if (piowr->iu.event.erase == 0xff) {
@@ -430,7 +441,7 @@
         break;
 
       case GDTIOCTL_SCSI:
-        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
             return(-EBUSY);
         piord = (gdth_iord_str *)ha->pscratch;
         piord->size = sizeof(gdth_iord_str);
@@ -451,7 +462,7 @@
         break;
 
       case GDTIOCTL_RESET_BUS:
-        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
             return(-EBUSY);
         piord = (gdth_iord_str *)ha->pscratch;
         piord->size = sizeof(gdth_iord_str);
@@ -475,7 +486,7 @@
         break;
 
       case GDTIOCTL_HDRLIST:
-        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
             return(-EBUSY);
         piord = (gdth_iord_str *)ha->pscratch;
         piord->size = sizeof(gdth_iord_str);
@@ -509,7 +520,7 @@
         break;
 
       case GDTIOCTL_RESCAN:
-        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
             return(-EBUSY);
         piord = (gdth_iord_str *)ha->pscratch;
         piord->size = sizeof(gdth_iord_str);
@@ -635,7 +646,7 @@
         break;
 
       case GDTIOCTL_RESET_DRV:
-        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
             return(-EBUSY);
         piord = (gdth_iord_str *)ha->pscratch;
         piord->size = sizeof(gdth_iord_str);
@@ -684,6 +695,7 @@
     char hrec[161];
     struct timeval tv;
 
+    char *buf;
     gdth_dskstat_str *pds;
     gdth_diskinfo_str *pdi;
     gdth_arrayinf_str *pai;
@@ -701,6 +713,8 @@
 #if LINUX_VERSION_CODE >= 0x020322
     sdev = scsi_get_host_dev(gdth_ctr_vtab[vh]);
     scp  = scsi_allocate_device(sdev, 1, FALSE);
+    if (!scp)
+        return -ENOMEM;
     scp->cmd_len = 12;
     scp->use_sg = 0;
 #else
@@ -784,12 +798,13 @@
             len += size;  pos = begin + len;
             flag = FALSE;
             
-            if (!gdth_ioctl_alloc(hanum, GDTH_SCRATCH))
+            buf = gdth_ioctl_alloc(hanum, GDTH_SCRATCH, FALSE);
+            if (!buf) 
                 goto stop_output;
             for (i = 0; i < ha->bus_cnt; ++i) {
                 /* 2.a statistics (and retries/reassigns) */
                 TRACE2(("pdr_statistics() chn %d\n",i));                
-                pds = (gdth_dskstat_str *)(ha->pscratch + GDTH_SCRATCH/4);
+                pds = (gdth_dskstat_str *)(buf + GDTH_SCRATCH/4);
                 gdtcmd.Service = CACHESERVICE;
                 gdtcmd.OpCode = GDT_IOCTL;
                 gdtcmd.u.ioctl.p_param = virt_to_bus(pds);
@@ -819,7 +834,7 @@
                     /* 2.b drive info */
                     TRACE2(("scsi_drv_info() chn %d dev %d\n",
                         i, ha->raw[i].id_list[j]));             
-                    pdi = (gdth_diskinfo_str *)ha->pscratch;
+                    pdi = (gdth_diskinfo_str *)buf;
                     gdtcmd.Service = CACHESERVICE;
                     gdtcmd.OpCode = GDT_IOCTL;
                     gdtcmd.u.ioctl.p_param = virt_to_bus(pdi);
@@ -874,7 +889,7 @@
                         /* 2.c grown defects */
                         TRACE2(("scsi_drv_defcnt() chn %d dev %d\n",
                                 i, ha->raw[i].id_list[j]));             
-                        pdef = (gdth_defcnt_str *)ha->pscratch;
+                        pdef = (gdth_defcnt_str *)buf;
                         gdtcmd.Service = CACHESERVICE;
                         gdtcmd.OpCode = GDT_IOCTL;
                         gdtcmd.u.ioctl.p_param = virt_to_bus(pdef);
@@ -905,7 +920,7 @@
                         goto stop_output;
                 }
             }
-            gdth_ioctl_free(hanum);
+            gdth_ioctl_free(hanum, buf);
 
             if (!flag) {
                 size = sprintf(buffer+len, "\n --\n");
@@ -917,7 +932,8 @@
             len += size;  pos = begin + len;
             flag = FALSE;
 
-            if (!gdth_ioctl_alloc(hanum, GDTH_SCRATCH))
+            buf = gdth_ioctl_alloc(hanum, GDTH_SCRATCH, FALSE);
+            if (!buf) 
                 goto stop_output;
             for (i = 0; i < MAX_LDRIVES; ++i) {
                 if (!ha->hdr[i].is_logdrv)
@@ -928,7 +944,7 @@
                 do {
                     /* 3.a log. drive info */
                     TRACE2(("cache_drv_info() drive no %d\n",drv_no));
-                    pcdi = (gdth_cdrinfo_str *)ha->pscratch;
+                    pcdi = (gdth_cdrinfo_str *)buf;
                     gdtcmd.Service = CACHESERVICE;
                     gdtcmd.OpCode = GDT_IOCTL;
                     gdtcmd.u.ioctl.p_param = virt_to_bus(pcdi);
@@ -1018,7 +1034,7 @@
                 if (pos > offset + length)
                     goto stop_output;
             }       
-            gdth_ioctl_free(hanum);
+            gdth_ioctl_free(hanum, buf);
         
             if (!flag) {
                 size = sprintf(buffer+len, "\n --\n");
@@ -1030,14 +1046,15 @@
             len += size;  pos = begin + len;
             flag = FALSE;
 
-            if (!gdth_ioctl_alloc(hanum, GDTH_SCRATCH))
+            buf = gdth_ioctl_alloc(hanum, GDTH_SCRATCH, FALSE);
+            if (!buf) 
                 goto stop_output;
             for (i = 0; i < MAX_LDRIVES; ++i) {
                 if (!(ha->hdr[i].is_arraydrv && ha->hdr[i].is_master))
                     continue;
                 /* 4.a array drive info */
                 TRACE2(("array_info() drive no %d\n",i));
-                pai = (gdth_arrayinf_str *)ha->pscratch;
+                pai = (gdth_arrayinf_str *)buf;
                 gdtcmd.Service = CACHESERVICE;
                 gdtcmd.OpCode = GDT_IOCTL;
                 gdtcmd.u.ioctl.p_param = virt_to_bus(pai);
@@ -1095,7 +1112,7 @@
                         goto stop_output;
                 }
             }
-            gdth_ioctl_free(hanum);
+            gdth_ioctl_free(hanum, buf);
         
             if (!flag) {
                 size = sprintf(buffer+len, "\n --\n");
@@ -1107,7 +1124,8 @@
             len += size;  pos = begin + len;
             flag = FALSE;
 
-            if (!gdth_ioctl_alloc(hanum, GDTH_SCRATCH))
+            buf = gdth_ioctl_alloc(hanum, GDTH_SCRATCH, FALSE);
+            if (!buf) 
                 goto stop_output;
             for (i = 0; i < MAX_LDRIVES; ++i) {
                 if (!ha->hdr[i].is_logdrv || 
@@ -1115,7 +1133,7 @@
                     continue;
                 /* 5.a get host drive list */
                 TRACE2(("host_get() drv_no %d\n",i));           
-                phg = (gdth_hget_str *)ha->pscratch;
+                phg = (gdth_hget_str *)buf;
                 gdtcmd.Service = CACHESERVICE;
                 gdtcmd.OpCode = GDT_IOCTL;
                 gdtcmd.u.ioctl.p_param = virt_to_bus(phg);
@@ -1146,7 +1164,7 @@
                     }
                 }
             }
-            gdth_ioctl_free(hanum);
+            gdth_ioctl_free(hanum, buf);
 
             for (i = 0; i < MAX_HDRIVES; ++i) {
                 if (!(ha->hdr[i].present))
@@ -1210,7 +1228,7 @@
             goto stop_output;
         length = piord->size;
         memcpy(buffer+len, (char *)piord, length);
-        gdth_ioctl_free(hanum);
+        gdth_ioctl_free(hanum, ha->pscratch);
         len = length; 
     }
 
@@ -1232,7 +1250,13 @@
                         char *cmnd, int timeout)
 {
     unsigned bufflen;
+#if LINUX_VERSION_CODE >= 0x020407
     DECLARE_COMPLETION(wait);
+#elif LINUX_VERSION_CODE >= 0x020322
+    DECLARE_MUTEX_LOCKED(sem);
+#else
+    struct semaphore sem = MUTEX_LOCKED;
+#endif
 
     TRACE2(("gdth_do_cmd()\n"));
     if (gdtcmd != NULL) { 
@@ -1243,7 +1267,12 @@
         bufflen = 0;
     }
     scp->request.rq_status = RQ_SCSI_BUSY;
+#if LINUX_VERSION_CODE >= 0x020407
     scp->request.waiting = &wait;
+    scsi_do_cmd(scp, cmnd, gdtcmd, bufflen, gdth_scsi_done, timeout*HZ, 1);
+    wait_for_completion(&wait);
+#else
+    scp->request.sem = &sem;
 #if LINUX_VERSION_CODE >= 0x020322
     scsi_do_cmd(scp, cmnd, gdtcmd, bufflen, gdth_scsi_done, timeout*HZ, 1);
 #else
@@ -1251,7 +1280,8 @@
     scsi_do_cmd(scp, cmnd, gdtcmd, bufflen, gdth_scsi_done, timeout*HZ, 1);
     GDTH_UNLOCK_SCSI_DOCMD();
 #endif
-    wait_for_completion(&wait);
+    down(&sem);
+#endif
 }
 
 void gdth_scsi_done(Scsi_Cmnd *scp)
@@ -1260,15 +1290,20 @@
 
     scp->request.rq_status = RQ_SCSI_DONE;
 
+#if LINUX_VERSION_CODE >= 0x020407
     if (scp->request.waiting != NULL)
         complete(scp->request.waiting);
+#else
+    if (scp->request.sem != NULL)
+        up(scp->request.sem);
+#endif
 }
 
-static int gdth_ioctl_alloc(int hanum, ushort size)
+static char *gdth_ioctl_alloc(int hanum, ushort size, int scratch)
 {
     gdth_ha_str *ha;
     ulong flags;
-    int ret_val;
+    char *ret_val;
 
     if (size == 0 || size > GDTH_SCRATCH)
         return FALSE;
@@ -1276,17 +1311,26 @@
     ha = HADATA(gdth_ctr_tab[hanum]);
     GDTH_LOCK_HA(ha, flags);
 
-    if (!ha->scratch_busy) {
-        ha->scratch_busy = TRUE;
-        ret_val = TRUE;
-    } else
-        ret_val = FALSE;
+    if (scratch) { 
+        if (!ha->scratch_busy) {
+            ha->scratch_busy = TRUE;
+            ret_val = ha->pscratch;
+        } else
+            ret_val = NULL;
+    } else {
+#if LINUX_VERSION_CODE >= 0x020322
+        ret_val = (void *) __get_free_pages(GFP_ATOMIC | GFP_DMA, 
+                                            GDTH_SCRATCH_ORD);
+#else
+        ret_val = scsi_init_malloc(GDTH_SCRATCH, GFP_ATOMIC | GFP_DMA);
+#endif
+    }
 
     GDTH_UNLOCK_HA(ha, flags);
     return ret_val;
 }
 
-static void gdth_ioctl_free(int hanum)
+static void gdth_ioctl_free(int hanum, char *buf)
 {
     gdth_ha_str *ha;
     ulong flags;
@@ -1294,7 +1338,15 @@
     ha = HADATA(gdth_ctr_tab[hanum]);
     GDTH_LOCK_HA(ha, flags);
 
-    ha->scratch_busy = FALSE;
+    if (buf == ha->pscratch) {
+        ha->scratch_busy = FALSE;
+    } else {
+#if LINUX_VERSION_CODE >= 0x020322
+        free_pages((unsigned long)buf, GDTH_SCRATCH_ORD);
+#else
+        scsi_init_free((void *)buf, GDTH_SCRATCH);
+#endif
+    }
 
     GDTH_UNLOCK_HA(ha, flags);
 }
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/gdth_proc.h linux/drivers/scsi/gdth_proc.h
--- v2.4.9/linux/drivers/scsi/gdth_proc.h	Sat May 19 17:43:06 2001
+++ linux/drivers/scsi/gdth_proc.h	Fri Sep  7 09:28:37 2001
@@ -2,7 +2,7 @@
 #define _GDTH_PROC_H
 
 /* gdth_proc.h 
- * $Id: gdth_proc.h,v 1.10 2000/07/24 09:30:01 achim Exp $
+ * $Id: gdth_proc.h,v 1.11 2001/07/25 15:37:40 achim Exp $
  */
 
 static int gdth_set_info(char *buffer,int length,int vh,int hanum,int busnum);
@@ -19,8 +19,8 @@
 static void gdth_do_cmd(Scsi_Cmnd *scp, gdth_cmd_str *cmd, 
                         char *cmnd, int timeout);
 
-static int gdth_ioctl_alloc(int hanum, ushort size);
-static void gdth_ioctl_free(int hanum);
+static char *gdth_ioctl_alloc(int hanum, ushort size, int scratch);
+static void gdth_ioctl_free(int hanum, char *buf);
 static int gdth_ioctl_check_bin(int hanum, ushort size);
 static void gdth_wait_completion(int hanum, int busnum, int id);
 static void gdth_stop_timeout(int hanum, int busnum, int id);
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/lasi700.c linux/drivers/scsi/lasi700.c
--- v2.4.9/linux/drivers/scsi/lasi700.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/lasi700.c	Sun Sep  9 11:58:36 2001
@@ -0,0 +1,188 @@
+/* -*- mode: c; c-basic-offset: 8 -*- */
+
+/* PARISC LASI driver for the 53c700 chip
+ *
+ * Copyright (C) 2001 by James.Bottomley@HansenPartnership.com
+**-----------------------------------------------------------------------------
+**  
+**  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+**
+**-----------------------------------------------------------------------------
+ */
+
+/*
+ * Many thanks to Richard Hirst <rhirst@linuxcare.com> for patiently
+ * debugging this driver on the parisc architecture and suggesting
+ * many improvements and bug fixes.
+ *
+ * Thanks also go to Linuxcare Inc. for providing several PARISC
+ * machines for me to debug the driver on.
+ */
+
+#ifndef __hppa__
+#error "lasi700 only compiles on hppa architecture"
+#endif
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/stat.h>
+#include <linux/mm.h>
+#include <linux/blk.h>
+#include <linux/sched.h>
+#include <linux/version.h>
+#include <linux/config.h>
+#include <linux/ioport.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/delay.h>
+#include <asm/gsc.h>
+
+#include <linux/module.h>
+
+#include "scsi.h"
+#include "hosts.h"
+#include "constants.h"
+
+#include "lasi700.h"
+#include "53c700.h"
+
+#ifdef MODULE
+
+char *lasi700;			/* command line from insmod */
+
+MODULE_AUTHOR("James Bottomley");
+MODULE_DESCRIPTION("lasi700 SCSI Driver");
+MODULE_LICENSE("GPL");
+MODULE_PARM(lasi700, "s");
+
+#endif
+
+#ifdef MODULE
+#define ARG_SEP ' '
+#else
+#define ARG_SEP ','
+#endif
+
+static unsigned long __initdata opt_base;
+static int __initdata opt_irq;
+
+static int __init
+param_setup(char *string)
+{
+	char *pos = string, *next;
+
+	while(pos != NULL && (next = strchr(pos, ':')) != NULL) {
+		int val = (int)simple_strtoul(++next, NULL, 0);
+		
+		if(!strncmp(pos, "addr:", 5))
+			opt_base = val;
+		else if(!strncmp(pos, "irq:", 4))
+			opt_irq = val;
+
+		if((pos = strchr(pos, ARG_SEP)) != NULL)
+			pos++;
+	}
+	return 1;
+}
+
+#ifndef MODULE
+__setup("lasi700=", param_setup);
+#endif
+
+static Scsi_Host_Template __initdata *host_tpnt = NULL;
+static int __initdata host_count = 0;
+static struct parisc_device_id lasi700_scsi_tbl[] = {
+	LASI700_ID_TABLE,
+	{ 0 }
+};
+
+MODULE_DEVICE_TABLE(parisc, lasi700_scsi_tbl);
+
+static struct parisc_driver lasi700_driver = LASI700_DRIVER;
+
+static int __init
+lasi700_detect(Scsi_Host_Template *tpnt)
+{
+	host_tpnt = tpnt;
+
+#ifdef MODULE
+	if(lasi700)
+		param_setup(lasi700);
+#endif
+
+	register_parisc_driver(&lasi700_driver);
+
+	return (host_count != 0);
+}
+
+static int __init
+lasi700_driver_callback(struct parisc_device *dev)
+{
+	unsigned long base = dev->hpa + LASI_SCSI_CORE_OFFSET;
+	int irq = busdevice_alloc_irq(dev);
+	struct Scsi_Host *host;
+	struct NCR_700_Host_Parameters *hostdata =
+		kmalloc(sizeof(struct NCR_700_Host_Parameters),
+			GFP_KERNEL);
+	if(hostdata == NULL) {
+		printk(KERN_ERR "lasi700: Failed to allocate host data\n");
+		return 1;
+	}
+	memset(hostdata, 0, sizeof(struct NCR_700_Host_Parameters));
+	if(request_mem_region(base, 64, "lasi700") == NULL) {
+		printk(KERN_ERR "lasi700: Failed to claim memory region\n");
+		kfree(hostdata);
+		return 1;
+	}
+	hostdata->base = base;
+	hostdata->differential = 0;
+	hostdata->clock = LASI700_CLOCK;
+	hostdata->force_le_on_be = 1;
+	if((host = NCR_700_detect(host_tpnt, hostdata)) == NULL) {
+		kfree(hostdata);
+		release_mem_region(host->base, 64);
+		return 1;
+	}
+	host->irq = irq;
+	if(request_irq(irq, NCR_700_intr, SA_SHIRQ, "lasi700", host)) {
+		printk(KERN_ERR "lasi700: irq problem, detatching\n");
+		scsi_unregister(host);
+		NCR_700_release(host);
+		return 1;
+	}
+	host_count++;
+	return 0;
+}
+
+static int
+lasi700_release(struct Scsi_Host *host)
+{
+	struct D700_Host_Parameters *hostdata = 
+		(struct D700_Host_Parameters *)host->hostdata[0];
+
+	NCR_700_release(host);
+	kfree(hostdata);
+	free_irq(host->irq, host);
+	release_mem_region(host->base, 64);
+	return 1;
+}
+
+static Scsi_Host_Template driver_template = LASI700_SCSI;
+
+#include "scsi_module.c"
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/lasi700.h linux/drivers/scsi/lasi700.h
--- v2.4.9/linux/drivers/scsi/lasi700.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/lasi700.h	Sun Sep  9 11:58:36 2001
@@ -0,0 +1,57 @@
+/* -*- mode: c; c-basic-offset: 8 -*- */
+
+/* PARISC LASI driver for the 53c700 chip
+ *
+ * Copyright (C) 2001 by James.Bottomley@HansenPartnership.com
+**-----------------------------------------------------------------------------
+**  
+**  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+**
+**-----------------------------------------------------------------------------
+ */
+
+#ifndef _LASI700_H
+#define _LASI700_H
+
+static int lasi700_detect(Scsi_Host_Template *);
+static int lasi700_driver_callback(struct parisc_device *dev);
+static int lasi700_release(struct Scsi_Host *host);
+
+
+#define LASI700_SCSI {				\
+	name:		"LASI SCSI 53c700",	\
+	proc_name:	"lasi700",		\
+	detect:		lasi700_detect,		\
+	release:	lasi700_release,	\
+	this_id:	7,			\
+}
+
+#define LASI700_ID_TABLE {			\
+	hw_type:	HPHW_FIO,		\
+	sversion:	0x071,			\
+	hversion:	HVERSION_ANY_ID,	\
+	hversion_rev:	HVERSION_REV_ANY_ID,	\
+}
+
+#define LASI700_DRIVER {			\
+	name:		"Lasi SCSI",		\
+	id_table:	lasi700_scsi_tbl,	\
+	probe:		lasi700_driver_callback,\
+}
+
+#define LASI700_CLOCK	25
+#define LASI_SCSI_CORE_OFFSET 0x100
+
+#endif
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/megaraid.c linux/drivers/scsi/megaraid.c
--- v2.4.9/linux/drivers/scsi/megaraid.c	Mon Aug 27 12:41:44 2001
+++ linux/drivers/scsi/megaraid.c	Sun Sep  9 10:52:35 2001
@@ -3138,16 +3138,18 @@
 	 * First argument (major) to register_chrdev implies a dynamic major
 	 * number allocation.
 	 */
-	major = register_chrdev (0, "megadev", &megadev_fops);
+	if (count) {
+		major = register_chrdev (0, "megadev", &megadev_fops);
 
-	/*
-	 * Register the Shutdown Notification hook in kernel
-	 */
-	if (register_reboot_notifier (&mega_notifier)) {
-		printk ("MegaRAID Shutdown routine not registered!!\n");
-	}
+		/*
+		 * Register the Shutdown Notification hook in kernel
+		 */
+		if (register_reboot_notifier (&mega_notifier)) {
+			printk ("MegaRAID Shutdown routine not registered!!\n");
+		}
 
-	init_MUTEX (&mimd_entry_mtx);
+		init_MUTEX (&mimd_entry_mtx);
+	}
 
 	return count;
 }
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/pcmcia/nsp_cs.c linux/drivers/scsi/pcmcia/nsp_cs.c
--- v2.4.9/linux/drivers/scsi/pcmcia/nsp_cs.c	Sun Aug 12 13:28:00 2001
+++ linux/drivers/scsi/pcmcia/nsp_cs.c	Fri Sep  7 09:28:37 2001
@@ -9,7 +9,7 @@
     Ver.0.1   Initial version
 
     This software may be used and distributed according to the terms of
-    the GNU Public License.
+    the GNU General Public License.
 
 ======================================================================*/
 
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/pcmcia/nsp_debug.c linux/drivers/scsi/pcmcia/nsp_debug.c
--- v2.4.9/linux/drivers/scsi/pcmcia/nsp_debug.c	Sun Aug 12 13:28:00 2001
+++ linux/drivers/scsi/pcmcia/nsp_debug.c	Fri Sep  7 09:28:37 2001
@@ -3,7 +3,7 @@
       By: YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>
 
     This software may be used and distributed according to the terms of
-    the GNU Public License.
+    the GNU General Public License.
 =========================================================================*/
 
 /* $Id: nsp_debug.c,v 1.6 2001/07/04 14:43:53 elca Exp $ */
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/pcmcia/nsp_message.c linux/drivers/scsi/pcmcia/nsp_message.c
--- v2.4.9/linux/drivers/scsi/pcmcia/nsp_message.c	Sun Aug 12 13:28:00 2001
+++ linux/drivers/scsi/pcmcia/nsp_message.c	Fri Sep  7 09:28:37 2001
@@ -3,7 +3,7 @@
       By: YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>
 
    This software may be used and distributed according to the terms of
-   the GNU Public License.
+   the GNU General Public License.
  */
 
 /* $Id: nsp_message.c,v 1.6 2001/07/05 10:56:37 elca Exp $ */
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/qlogicfc.c linux/drivers/scsi/qlogicfc.c
--- v2.4.9/linux/drivers/scsi/qlogicfc.c	Mon Aug 27 12:41:44 2001
+++ linux/drivers/scsi/qlogicfc.c	Fri Sep  7 09:28:37 2001
@@ -98,8 +98,6 @@
    isp2200's firmware. 
 */
 
-#define RELOAD_FIRMWARE		0
-
 #define USE_NVRAM_DEFAULTS      1
 
 #define ISP2x00_PORTDB          1
@@ -440,7 +438,16 @@
 #define MBOX_SEND_CHANGE_REQUEST        0x0070
 #define MBOX_PORT_LOGOUT                0x0071
 
-//#include "qlogicfc_asm.c"
+/*
+ *	Firmware if needed (note this is a hack, it belongs in a seperate
+ *	module.
+ */
+ 
+#ifdef CONFIG_SCSI_QLOGIC_FC_FIRMWARE
+#include "qlogicfc_asm.c"
+#else
+static unsigned short risc_code_addr01 = 0x1000 ;
+#endif
 
 /* Each element in mbox_param is an 8 bit bitmap where each bit indicates
    if that mbox should be copied as input.  For example 0x2 would mean
@@ -1853,7 +1860,6 @@
 	struct isp2x00_hostdata *hostdata;
 	int loop_count;
 	dma64_addr_t busaddr;
-	unsigned short risc_code_addr01 = 0x1000 ;
 
 	ENTER("isp2x00_reset_hardware");
 
@@ -1892,7 +1898,7 @@
 
 	DEBUG(printk("qlogicfc%d : verifying checksum\n", hostdata->host_id));
 
-#if RELOAD_FIRMWARE
+#if defined(CONFIG_SCSI_QLOGIC_FC_FIRMWARE)
 	{
 		int i;
 		unsigned short * risc_code = NULL;
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/qlogicfc_asm.c linux/drivers/scsi/qlogicfc_asm.c
--- v2.4.9/linux/drivers/scsi/qlogicfc_asm.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/qlogicfc_asm.c	Fri Sep  7 09:28:37 2001
@@ -0,0 +1,9751 @@
+/************************************************************************
+ *									*
+ * 	 --- ISP2100 Fabric Initiator/Target Firmware ---               *
+ *                   with expanded LUN addressing                       *
+ *                   and FcTape (FCP-2) support                         *
+ *									*
+ *									*
+ ************************************************************************
+  Copyright (C) 2000 and 2001 Qlogic Corporation 
+  (www.qlogic.com)
+
+  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.
+************************************************************************/
+
+/*
+ *	Firmware Version 1.19.16 (10:36 Nov 02, 2000)
+ */
+
+unsigned short risc_code_addr01 = 0x1000 ;
+
+unsigned short risc_code_length2100 = 0x9260;
+unsigned short risc_code2100[] = {
+	0x0078, 0x102d, 0x0000, 0x9260, 0x0000, 0x0001, 0x0013, 0x0010,
+	0x0017, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2031, 0x3939,
+	0x3920, 0x514c, 0x4f47, 0x4943, 0x2043, 0x4f52, 0x504f, 0x5241,
+	0x5449, 0x4f4e, 0x2049, 0x5350, 0x3231, 0x3030, 0x2046, 0x6972,
+	0x6d77, 0x6172, 0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030,
+	0x312e, 0x3139, 0x2020, 0x2020, 0x2400, 0x2091, 0x2000, 0x20c1,
+	0x0021, 0x2039, 0xffff, 0x2019, 0xaaaa, 0x2760, 0x2069, 0x7fff,
+	0x20c1, 0x0020, 0x2c2c, 0x2d34, 0x2762, 0x236a, 0x2c24, 0x2d04,
+	0x266a, 0x2562, 0xa406, 0x00c0, 0x1052, 0x20c1, 0x0021, 0x2c2c,
+	0x2362, 0x2c04, 0x2562, 0xa306, 0x0040, 0x1052, 0x20c1, 0x0020,
+	0x2039, 0x8fff, 0x20a1, 0xaa00, 0x2708, 0x810d, 0x810d, 0x810d,
+	0x810d, 0xa18c, 0x000f, 0x2001, 0x000a, 0xa112, 0xa00e, 0x21a8,
+	0x41a4, 0x3400, 0x8211, 0x00c0, 0x105f, 0x2708, 0x3400, 0xa102,
+	0x0040, 0x106f, 0x0048, 0x106f, 0x20a8, 0xa00e, 0x41a4, 0x20a1,
+	0xa260, 0x2009, 0x0000, 0x20a9, 0x07a0, 0x41a4, 0x3400, 0x20c9,
+	0xa7ff, 0x2059, 0x0000, 0x2b78, 0x7823, 0x0004, 0x2089, 0x255d,
+	0x2051, 0xa300, 0x2a70, 0x775e, 0xa786, 0x8fff, 0x0040, 0x1092,
+	0x705b, 0xca00, 0x7057, 0xc9f1, 0x7063, 0x0200, 0x7067, 0x0200,
+	0x0078, 0x109a, 0x7057, 0xba01, 0x7063, 0x0100, 0x7067, 0x0100,
+	0x705b, 0xba00, 0x1078, 0x12df, 0x1078, 0x13c0, 0x1078, 0x1569,
+	0x1078, 0x1ca4, 0x1078, 0x4229, 0x1078, 0x74cf, 0x1078, 0x134b,
+	0x1078, 0x2a3f, 0x1078, 0x4da2, 0x1078, 0x48b2, 0x1078, 0x57df,
+	0x1078, 0x21f7, 0x1078, 0x5abf, 0x1078, 0x5369, 0x1078, 0x210d,
+	0x1078, 0x21d4, 0x2091, 0x3009, 0x7823, 0x0000, 0x0090, 0x10cf,
+	0x7820, 0xa086, 0x0002, 0x00c0, 0x10cf, 0x7823, 0x4000, 0x0068,
+	0x10c7, 0x781b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x2a70,
+	0x7003, 0x0000, 0x2001, 0x017f, 0x2003, 0x0000, 0x2a70, 0x7000,
+	0xa08e, 0x0003, 0x00c0, 0x10ef, 0x1078, 0x35bc, 0x1078, 0x2a67,
+	0x1078, 0x4df2, 0x1078, 0x4a75, 0x2009, 0x0100, 0x2104, 0xa082,
+	0x0002, 0x0048, 0x10f3, 0x1078, 0x57fb, 0x0078, 0x10d6, 0x1079,
+	0x10f7, 0x0078, 0x10dc, 0x1078, 0x6fa9, 0x0078, 0x10eb, 0x1101,
+	0x1102, 0x11be, 0x10ff, 0x1246, 0x12dc, 0x12dd, 0x12de, 0x1078,
+	0x1328, 0x007c, 0x127e, 0x0f7e, 0x2091, 0x8000, 0x7000, 0xa086,
+	0x0001, 0x00c0, 0x1198, 0x1078, 0x3a43, 0x2079, 0x0100, 0x7844,
+	0xa005, 0x00c0, 0x1198, 0x2011, 0x4129, 0x1078, 0x58d4, 0x1078,
+	0x1ab1, 0x780f, 0x00ff, 0x7840, 0xa084, 0xfffb, 0x7842, 0x2011,
+	0x8010, 0x73c0, 0x1078, 0x3579, 0x2001, 0xffff, 0x1078, 0x5975,
+	0x7238, 0xc284, 0x723a, 0x2001, 0xa30c, 0x2014, 0xc2ac, 0x2202,
+	0x1078, 0x6db5, 0x2011, 0x0004, 0x1078, 0x8a59, 0x1078, 0x47ce,
+	0x1078, 0x4211, 0x0040, 0x1144, 0x7083, 0x0001, 0x70bb, 0x0000,
+	0x1078, 0x3bf5, 0x0078, 0x1198, 0x1078, 0x4897, 0x0040, 0x114d,
+	0x7a0c, 0xc2b4, 0x7a0e, 0x0078, 0x1159, 0x1078, 0x8ddf, 0x70c8,
+	0xd09c, 0x00c0, 0x1159, 0x7094, 0xa005, 0x0040, 0x1159, 0x1078,
+	0x41f5, 0x70d3, 0x0000, 0x70cf, 0x0000, 0x72c8, 0x2079, 0xa351,
+	0x7804, 0xd0ac, 0x0040, 0x1165, 0xc295, 0x72ca, 0xa296, 0x0004,
+	0x0040, 0x1186, 0x2011, 0x0001, 0x1078, 0x8a59, 0x708f, 0x0000,
+	0x7093, 0xffff, 0x7003, 0x0002, 0x0f7f, 0x1078, 0x260d, 0x2011,
+	0x0005, 0x1078, 0x6ef2, 0x1078, 0x6109, 0x0c7e, 0x2061, 0x0100,
+	0x60e3, 0x0008, 0x0c7f, 0x127f, 0x0078, 0x119a, 0x708f, 0x0000,
+	0x7093, 0xffff, 0x7003, 0x0002, 0x2011, 0x0005, 0x1078, 0x6ef2,
+	0x1078, 0x6109, 0x0c7e, 0x2061, 0x0100, 0x60e3, 0x0008, 0x0c7f,
+	0x0f7f, 0x127f, 0x007c, 0x0c7e, 0x20a9, 0x0082, 0x2009, 0x007e,
+	0x017e, 0x027e, 0x037e, 0x2110, 0x027e, 0x2019, 0x0029, 0x1078,
+	0x71e0, 0x027f, 0x1078, 0xa190, 0x037f, 0x027f, 0x017f, 0x1078,
+	0x2921, 0x8108, 0x00f0, 0x11a0, 0x0c7f, 0x706b, 0x0000, 0x706c,
+	0xa084, 0x00ff, 0x706e, 0x7097, 0x0000, 0x007c, 0x127e, 0x2091,
+	0x8000, 0x7000, 0xa086, 0x0002, 0x00c0, 0x1244, 0x7090, 0xa086,
+	0xffff, 0x0040, 0x11d1, 0x1078, 0x260d, 0x1078, 0x6109, 0x0078,
+	0x1244, 0x70c8, 0xd09c, 0x0040, 0x11fd, 0xd084, 0x0040, 0x11fd,
+	0x0f7e, 0x2079, 0x0100, 0x790c, 0xc1b5, 0x790e, 0x0f7f, 0xd08c,
+	0x0040, 0x11fd, 0x70cc, 0xa086, 0xffff, 0x0040, 0x11f9, 0x1078,
+	0x278a, 0x1078, 0x6109, 0x70c8, 0xd094, 0x00c0, 0x1244, 0x2011,
+	0x0001, 0x2019, 0x0000, 0x1078, 0x27c2, 0x1078, 0x6109, 0x0078,
+	0x1244, 0x70d0, 0xa005, 0x00c0, 0x1244, 0x708c, 0xa005, 0x00c0,
+	0x1244, 0x1078, 0x4897, 0x00c0, 0x1244, 0x2001, 0xa352, 0x2004,
+	0xd0ac, 0x0040, 0x1227, 0x157e, 0x0c7e, 0x20a9, 0x007f, 0x2009,
+	0x0000, 0x017e, 0x1078, 0x4501, 0x00c0, 0x121a, 0x6000, 0xd0ec,
+	0x00c0, 0x1222, 0x017f, 0x8108, 0x00f0, 0x1211, 0x0c7f, 0x157f,
+	0x0078, 0x1227, 0x017f, 0x0c7f, 0x157f, 0x0078, 0x1244, 0x7003,
+	0x0003, 0x7093, 0xffff, 0x2001, 0x0000, 0x1078, 0x2480, 0x1078,
+	0x35f7, 0x2001, 0xa5ac, 0x2004, 0xa086, 0x0005, 0x00c0, 0x123c,
+	0x2011, 0x0000, 0x1078, 0x6ef2, 0x2011, 0x0000, 0x1078, 0x6efc,
+	0x1078, 0x6109, 0x1078, 0x61d3, 0x127f, 0x007c, 0x017e, 0x0f7e,
+	0x127e, 0x2091, 0x8000, 0x2079, 0x0100, 0x2009, 0x00f7, 0x1078,
+	0x41de, 0x7940, 0xa18c, 0x0010, 0x7942, 0x7924, 0xd1b4, 0x0040,
+	0x125b, 0x7827, 0x0040, 0xd19c, 0x0040, 0x1260, 0x7827, 0x0008,
+	0x007e, 0x037e, 0x157e, 0xa006, 0x1078, 0x5975, 0x7900, 0xa18a,
+	0x0003, 0x0050, 0x1289, 0x7954, 0xd1ac, 0x00c0, 0x1289, 0x2009,
+	0x00f8, 0x1078, 0x41de, 0x7843, 0x0090, 0x7843, 0x0010, 0x20a9,
+	0x09c4, 0x7820, 0xd09c, 0x00c0, 0x1281, 0x7824, 0xd0ac, 0x00c0,
+	0x12ca, 0x00f0, 0x1279, 0x2001, 0x0001, 0x1078, 0x2480, 0x0078,
+	0x12d5, 0x7853, 0x0000, 0x782f, 0x0020, 0x20a9, 0x0050, 0x00e0,
+	0x128f, 0x2091, 0x6000, 0x00f0, 0x128f, 0x7853, 0x0400, 0x782f,
+	0x0000, 0x2009, 0x00f8, 0x1078, 0x41de, 0x20a9, 0x000e, 0x0005,
+	0x00f0, 0x129f, 0x7853, 0x1400, 0x7843, 0x0090, 0x7843, 0x0010,
+	0x2019, 0x61a8, 0x7854, 0x0005, 0x0005, 0xd08c, 0x0040, 0x12b4,
+	0x7824, 0xd0ac, 0x00c0, 0x12ca, 0x8319, 0x00c0, 0x12aa, 0x2009,
+	0xa331, 0x2104, 0x8000, 0x200a, 0xa084, 0xfff0, 0x0040, 0x12c4,
+	0x200b, 0x0000, 0x1078, 0x251e, 0x2001, 0x0001, 0x1078, 0x2480,
+	0x0078, 0x12d3, 0x2001, 0xa331, 0x2003, 0x0000, 0x7828, 0xc09d,
+	0x782a, 0x7827, 0x0048, 0x7853, 0x0400, 0x157f, 0x037f, 0x007f,
+	0x127f, 0x0f7f, 0x017f, 0x007c, 0x007c, 0x007c, 0x007c, 0x2a70,
+	0x2009, 0x0100, 0x2104, 0xa082, 0x0002, 0x0048, 0x12eb, 0x704f,
+	0xffff, 0x0078, 0x12ed, 0x704f, 0x0000, 0x7053, 0xffff, 0x706b,
+	0x0000, 0x706f, 0x0000, 0x1078, 0x8ddf, 0x2061, 0xa58c, 0x6003,
+	0x0909, 0x6007, 0x0000, 0x600b, 0x8800, 0x600f, 0x0200, 0x6013,
+	0x00ff, 0x6017, 0x0003, 0x601b, 0x0000, 0x601f, 0x07d0, 0x2061,
+	0xa594, 0x6003, 0x8000, 0x6007, 0x0000, 0x600b, 0x0000, 0x600f,
+	0x0200, 0x6013, 0x00ff, 0x6017, 0x0000, 0x601b, 0x0001, 0x601f,
+	0x0000, 0x2061, 0xa5a3, 0x6003, 0x514c, 0x6007, 0x4f47, 0x600b,
+	0x4943, 0x600f, 0x2020, 0x2001, 0xa325, 0x2003, 0x0000, 0x007c,
+	0x2091, 0x8000, 0x0068, 0x132a, 0x007e, 0x017e, 0x2079, 0x0000,
+	0x7818, 0xd084, 0x00c0, 0x1330, 0x017f, 0x792e, 0x007f, 0x782a,
+	0x007f, 0x7826, 0x3900, 0x783a, 0x7823, 0x8002, 0x781b, 0x0001,
+	0x2091, 0x5000, 0x2091, 0x4080, 0x2079, 0xa300, 0x7803, 0x0005,
+	0x0078, 0x1348, 0x007c, 0x2071, 0xa300, 0x7158, 0x712e, 0x2021,
+	0x0001, 0xa190, 0x002d, 0xa298, 0x002d, 0x0048, 0x1361, 0x705c,
+	0xa302, 0x00c8, 0x1361, 0x220a, 0x2208, 0x2310, 0x8420, 0x0078,
+	0x1353, 0x200b, 0x0000, 0x74a6, 0x74aa, 0x007c, 0x0e7e, 0x127e,
+	0x2091, 0x8000, 0x2071, 0xa300, 0x70a8, 0xa0ea, 0x0010, 0x00c8,
+	0x1374, 0xa06e, 0x0078, 0x137e, 0x8001, 0x70aa, 0x702c, 0x2068,
+	0x2d04, 0x702e, 0x206b, 0x0000, 0x6807, 0x0000, 0x127f, 0x0e7f,
+	0x007c, 0x0e7e, 0x2071, 0xa300, 0x127e, 0x2091, 0x8000, 0x70a8,
+	0x8001, 0x00c8, 0x138e, 0xa06e, 0x0078, 0x1397, 0x70aa, 0x702c,
+	0x2068, 0x2d04, 0x702e, 0x206b, 0x0000, 0x6807, 0x0000, 0x127f,
+	0x0e7f, 0x007c, 0x0e7e, 0x127e, 0x2091, 0x8000, 0x2071, 0xa300,
+	0x702c, 0x206a, 0x2d00, 0x702e, 0x70a8, 0x8000, 0x70aa, 0x127f,
+	0x0e7f, 0x007c, 0x8dff, 0x0040, 0x13b6, 0x6804, 0x6807, 0x0000,
+	0x007e, 0x1078, 0x139a, 0x0d7f, 0x0078, 0x13aa, 0x007c, 0x0e7e,
+	0x2071, 0xa300, 0x70a8, 0xa08a, 0x0010, 0xa00d, 0x0e7f, 0x007c,
+	0x0e7e, 0x2071, 0xa5d0, 0x7007, 0x0000, 0x701b, 0x0000, 0x701f,
+	0x0000, 0x2071, 0x0000, 0x7010, 0xa085, 0x8004, 0x7012, 0x0e7f,
+	0x007c, 0x0e7e, 0x2270, 0x700b, 0x0000, 0x2071, 0xa5d0, 0x7018,
+	0xa088, 0xa5d9, 0x220a, 0x8000, 0xa084, 0x0007, 0x701a, 0x7004,
+	0xa005, 0x00c0, 0x13e9, 0x0f7e, 0x2079, 0x0010, 0x1078, 0x13fa,
+	0x0f7f, 0x0e7f, 0x007c, 0x0e7e, 0x2071, 0xa5d0, 0x7004, 0xa005,
+	0x00c0, 0x13f8, 0x0f7e, 0x2079, 0x0010, 0x1078, 0x13fa, 0x0f7f,
+	0x0e7f, 0x007c, 0x7000, 0x0079, 0x13fd, 0x1401, 0x146b, 0x1488,
+	0x1488, 0x7018, 0x711c, 0xa106, 0x00c0, 0x1409, 0x7007, 0x0000,
+	0x007c, 0x0d7e, 0xa180, 0xa5d9, 0x2004, 0x700a, 0x2068, 0x8108,
+	0xa18c, 0x0007, 0x711e, 0x7803, 0x0026, 0x6824, 0x7832, 0x6828,
+	0x7836, 0x682c, 0x783a, 0x6830, 0x783e, 0x6810, 0x700e, 0x680c,
+	0x7016, 0x6804, 0x0d7f, 0xd084, 0x0040, 0x142b, 0x7007, 0x0001,
+	0x1078, 0x1430, 0x007c, 0x7007, 0x0002, 0x1078, 0x1446, 0x007c,
+	0x017e, 0x027e, 0x710c, 0x2011, 0x0040, 0xa182, 0x0040, 0x00c8,
+	0x143b, 0x2110, 0xa006, 0x700e, 0x7212, 0x8203, 0x7822, 0x7803,
+	0x0020, 0x7803, 0x0041, 0x027f, 0x017f, 0x007c, 0x017e, 0x027e,
+	0x137e, 0x147e, 0x157e, 0x7014, 0x2098, 0x20a1, 0x0014, 0x7803,
+	0x0026, 0x710c, 0x2011, 0x0040, 0xa182, 0x0040, 0x00c8, 0x145a,
+	0x2110, 0xa006, 0x700e, 0x22a8, 0x53a6, 0x8203, 0x7822, 0x7803,
+	0x0020, 0x3300, 0x7016, 0x7803, 0x0001, 0x157f, 0x147f, 0x137f,
+	0x027f, 0x017f, 0x007c, 0x137e, 0x147e, 0x157e, 0x2099, 0xa3f9,
+	0x20a1, 0x0018, 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x127e,
+	0x2091, 0x8000, 0x7803, 0x0041, 0x7007, 0x0003, 0x7000, 0xc084,
+	0x7002, 0x700b, 0xa3f4, 0x127f, 0x157f, 0x147f, 0x137f, 0x007c,
+	0x137e, 0x147e, 0x157e, 0x2001, 0xa428, 0x209c, 0x20a1, 0x0014,
+	0x7803, 0x0026, 0x2001, 0xa429, 0x20ac, 0x53a6, 0x2099, 0xa42a,
+	0x20a1, 0x0018, 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x127e,
+	0x2091, 0x8000, 0x7803, 0x0001, 0x7007, 0x0004, 0x7000, 0xc08c,
+	0x7002, 0x700b, 0xa425, 0x127f, 0x157f, 0x147f, 0x137f, 0x007c,
+	0x017e, 0x0e7e, 0x2071, 0xa5d0, 0x0f7e, 0x2079, 0x0010, 0x7904,
+	0x7803, 0x0002, 0xd1fc, 0x0040, 0x14c2, 0xa18c, 0x0700, 0x7004,
+	0x1079, 0x14c6, 0x0f7f, 0x0e7f, 0x017f, 0x007c, 0x13fa, 0x14ce,
+	0x14fb, 0x1523, 0x1556, 0x14cc, 0x0078, 0x14cc, 0xa18c, 0x0700,
+	0x00c0, 0x14f4, 0x137e, 0x147e, 0x157e, 0x7014, 0x20a0, 0x2099,
+	0x0014, 0x7803, 0x0040, 0x7010, 0x20a8, 0x53a5, 0x3400, 0x7016,
+	0x157f, 0x147f, 0x137f, 0x700c, 0xa005, 0x0040, 0x1510, 0x1078,
+	0x1430, 0x007c, 0x7008, 0xa080, 0x0002, 0x2003, 0x0100, 0x7007,
+	0x0000, 0x1078, 0x13fa, 0x007c, 0x7008, 0xa080, 0x0002, 0x2003,
+	0x0200, 0x0078, 0x14ef, 0xa18c, 0x0700, 0x00c0, 0x1506, 0x700c,
+	0xa005, 0x0040, 0x1510, 0x1078, 0x1446, 0x007c, 0x7008, 0xa080,
+	0x0002, 0x2003, 0x0200, 0x7007, 0x0000, 0x1078, 0x13fa, 0x007c,
+	0x0d7e, 0x7008, 0x2068, 0x7830, 0x6826, 0x7834, 0x682a, 0x7838,
+	0x682e, 0x783c, 0x6832, 0x680b, 0x0100, 0x0d7f, 0x7007, 0x0000,
+	0x1078, 0x13fa, 0x007c, 0xa18c, 0x0700, 0x00c0, 0x1550, 0x137e,
+	0x147e, 0x157e, 0x2001, 0xa3f7, 0x2004, 0xa080, 0x000d, 0x20a0,
+	0x2099, 0x0014, 0x7803, 0x0040, 0x20a9, 0x0020, 0x53a5, 0x2001,
+	0xa3f9, 0x2004, 0xd0bc, 0x0040, 0x1546, 0x2001, 0xa402, 0x2004,
+	0xa080, 0x000d, 0x20a0, 0x20a9, 0x0020, 0x53a5, 0x157f, 0x147f,
+	0x137f, 0x7007, 0x0000, 0x1078, 0x4e9b, 0x1078, 0x13fa, 0x007c,
+	0x2011, 0x8003, 0x1078, 0x3579, 0x0078, 0x1554, 0xa18c, 0x0700,
+	0x00c0, 0x1563, 0x2001, 0xa427, 0x2003, 0x0100, 0x7007, 0x0000,
+	0x1078, 0x13fa, 0x007c, 0x2011, 0x8004, 0x1078, 0x3579, 0x0078,
+	0x1567, 0x127e, 0x2091, 0x2100, 0x2079, 0x0030, 0x2071, 0xa5e1,
+	0x7803, 0x0004, 0x7003, 0x0000, 0x700f, 0xa5e7, 0x7013, 0xa5e7,
+	0x780f, 0x0076, 0x7803, 0x0004, 0x127f, 0x007c, 0x6934, 0xa184,
+	0x0007, 0x0079, 0x1583, 0x158b, 0x15d1, 0x158b, 0x158b, 0x158b,
+	0x15b6, 0x159a, 0x158f, 0xa085, 0x0001, 0x0078, 0x15eb, 0x684c,
+	0xd0bc, 0x0040, 0x158b, 0x6860, 0x682e, 0x685c, 0x682a, 0x6858,
+	0x0078, 0x15d9, 0xa18c, 0x00ff, 0xa186, 0x001e, 0x00c0, 0x158b,
+	0x684c, 0xd0bc, 0x0040, 0x158b, 0x6860, 0x682e, 0x685c, 0x682a,
+	0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080,
+	0x2015, 0x2004, 0x6832, 0x6858, 0x0078, 0x15e1, 0xa18c, 0x00ff,
+	0xa186, 0x0015, 0x00c0, 0x158b, 0x684c, 0xd0ac, 0x0040, 0x158b,
+	0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080,
+	0x2015, 0x2004, 0x6832, 0xa006, 0x682e, 0x682a, 0x6858, 0x0078,
+	0x15e1, 0x684c, 0xd0ac, 0x0040, 0x158b, 0xa006, 0x682e, 0x682a,
+	0x6858, 0xa18c, 0x000f, 0xa188, 0x2015, 0x210c, 0x6932, 0x2d08,
+	0x691a, 0x6826, 0x684c, 0xc0dd, 0x684e, 0xa006, 0x680a, 0x697c,
+	0x6912, 0x6980, 0x6916, 0x007c, 0x20e1, 0x0007, 0x20e1, 0x2000,
+	0x2001, 0x020a, 0x2004, 0x82ff, 0x0040, 0x160e, 0xa280, 0x0004,
+	0x0d7e, 0x206c, 0x684c, 0xd0dc, 0x00c0, 0x160a, 0x1078, 0x157e,
+	0x0040, 0x160a, 0x0d7f, 0xa280, 0x0000, 0x2003, 0x0002, 0xa016,
+	0x0078, 0x160e, 0x6808, 0x8000, 0x680a, 0x0d7f, 0x127e, 0x047e,
+	0x037e, 0x027e, 0x2091, 0x2100, 0x027f, 0x037f, 0x047f, 0x7000,
+	0xa005, 0x00c0, 0x1622, 0x7206, 0x2001, 0x1643, 0x007e, 0x2260,
+	0x0078, 0x17be, 0x710c, 0x220a, 0x8108, 0x230a, 0x8108, 0x240a,
+	0x8108, 0xa182, 0xa602, 0x0048, 0x162f, 0x2009, 0xa5e7, 0x710e,
+	0x7010, 0xa102, 0xa082, 0x0009, 0x0040, 0x163a, 0xa080, 0x001b,
+	0x00c0, 0x163d, 0x2009, 0x0138, 0x200a, 0x7000, 0xa005, 0x00c0,
+	0x1643, 0x1078, 0x179f, 0x127f, 0x007c, 0x127e, 0x027e, 0x037e,
+	0x0c7e, 0x007e, 0x2091, 0x2100, 0x007f, 0x047f, 0x037f, 0x027f,
+	0x0d7e, 0x0c7e, 0x2460, 0x6110, 0x2168, 0x6a62, 0x6b5e, 0xa005,
+	0x0040, 0x16cf, 0x6808, 0xa005, 0x0040, 0x173c, 0x7000, 0xa005,
+	0x00c0, 0x1664, 0x0078, 0x16c4, 0x700c, 0x7110, 0xa106, 0x00c0,
+	0x1745, 0x7004, 0xa406, 0x00c0, 0x16c4, 0x2001, 0x0005, 0x2004,
+	0xd08c, 0x0040, 0x1681, 0x047e, 0x1078, 0x18e2, 0x047f, 0x2460,
+	0x6010, 0xa080, 0x0002, 0x2004, 0xa005, 0x0040, 0x173c, 0x0078,
+	0x165e, 0x2001, 0x0207, 0x2004, 0xd09c, 0x00c0, 0x166d, 0x7804,
+	0xa084, 0x6000, 0x0040, 0x1692, 0xa086, 0x6000, 0x0040, 0x1692,
+	0x0078, 0x166d, 0x7100, 0xa186, 0x0002, 0x00c0, 0x16b2, 0x0e7e,
+	0x2b68, 0x6818, 0x2060, 0x1078, 0x1fea, 0x2804, 0xac70, 0x6034,
+	0xd09c, 0x00c0, 0x16a7, 0x7108, 0x720c, 0x0078, 0x16a9, 0x7110,
+	0x7214, 0x6810, 0xa100, 0x6812, 0x6814, 0xa201, 0x6816, 0x0e7f,
+	0x0078, 0x16b6, 0xa186, 0x0001, 0x00c0, 0x16be, 0x7820, 0x6910,
+	0xa100, 0x6812, 0x7824, 0x6914, 0xa101, 0x6816, 0x7803, 0x0004,
+	0x7003, 0x0000, 0x7004, 0x2060, 0x6100, 0xa18e, 0x0004, 0x00c0,
+	0x1745, 0x2009, 0x0048, 0x1078, 0x756c, 0x0078, 0x1745, 0x6808,
+	0xa005, 0x0040, 0x173c, 0x7000, 0xa005, 0x00c0, 0x16d9, 0x0078,
+	0x173c, 0x700c, 0x7110, 0xa106, 0x00c0, 0x16e2, 0x7004, 0xa406,
+	0x00c0, 0x173c, 0x2001, 0x0005, 0x2004, 0xd08c, 0x0040, 0x16f6,
+	0x047e, 0x1078, 0x18e2, 0x047f, 0x2460, 0x6010, 0xa080, 0x0002,
+	0x2004, 0xa005, 0x0040, 0x173c, 0x0078, 0x16d3, 0x2001, 0x0207,
+	0x2004, 0xd09c, 0x00c0, 0x16e2, 0x2001, 0x0005, 0x2004, 0xd08c,
+	0x00c0, 0x16e8, 0x7804, 0xa084, 0x6000, 0x0040, 0x170d, 0xa086,
+	0x6000, 0x0040, 0x170d, 0x0078, 0x16e2, 0x7007, 0x0000, 0xa016,
+	0x2218, 0x7000, 0xa08e, 0x0001, 0x0040, 0x172e, 0xa08e, 0x0002,
+	0x00c0, 0x173c, 0x0c7e, 0x0e7e, 0x6818, 0x2060, 0x1078, 0x1fea,
+	0x2804, 0xac70, 0x6034, 0xd09c, 0x00c0, 0x172a, 0x7308, 0x720c,
+	0x0078, 0x172c, 0x7310, 0x7214, 0x0e7f, 0x0c7f, 0x7820, 0xa318,
+	0x7824, 0xa211, 0x6810, 0xa300, 0x6812, 0x6814, 0xa201, 0x6816,
+	0x7803, 0x0004, 0x7003, 0x0000, 0x6100, 0xa18e, 0x0004, 0x00c0,
+	0x1745, 0x2009, 0x0048, 0x1078, 0x756c, 0x0c7f, 0x0d7f, 0x127f,
+	0x007c, 0x0f7e, 0x0e7e, 0x027e, 0x037e, 0x047e, 0x1078, 0x1af7,
+	0x027e, 0x2071, 0xa5e1, 0x7000, 0xa086, 0x0000, 0x0040, 0x1790,
+	0x7004, 0xac06, 0x00c0, 0x1781, 0x2079, 0x0030, 0x7000, 0xa086,
+	0x0003, 0x0040, 0x1781, 0x7804, 0xd0fc, 0x00c0, 0x177d, 0x2001,
+	0x0207, 0x2004, 0xd09c, 0x00c0, 0x1763, 0x7803, 0x0004, 0x7804,
+	0xd0ac, 0x00c0, 0x176f, 0x7803, 0x0002, 0x7803, 0x0009, 0x7003,
+	0x0003, 0x7007, 0x0000, 0x0078, 0x1781, 0x1078, 0x18e2, 0x0078,
+	0x1753, 0x157e, 0x20a9, 0x0009, 0x2009, 0xa5e7, 0x2104, 0xac06,
+	0x00c0, 0x178b, 0x200a, 0xa188, 0x0003, 0x00f0, 0x1786, 0x157f,
+	0x027f, 0x2001, 0x015d, 0x201c, 0x831a, 0x2302, 0x2001, 0x0138,
+	0x2202, 0x047f, 0x037f, 0x027f, 0x0e7f, 0x0f7f, 0x007c, 0x700c,
+	0x7110, 0xa106, 0x00c0, 0x17a7, 0x7003, 0x0000, 0x007c, 0x2104,
+	0x7006, 0x2060, 0x8108, 0x211c, 0x8108, 0x2124, 0x8108, 0xa182,
+	0xa602, 0x0048, 0x17b5, 0x2009, 0xa5e7, 0x7112, 0x700c, 0xa106,
+	0x00c0, 0x17be, 0x2001, 0x0138, 0x2003, 0x0008, 0x8cff, 0x00c0,
+	0x17c5, 0x1078, 0x1b22, 0x0078, 0x1823, 0x6010, 0x2068, 0x2d58,
+	0x6828, 0xa406, 0x00c0, 0x17d0, 0x682c, 0xa306, 0x0040, 0x17fe,
+	0x601c, 0xa086, 0x0008, 0x0040, 0x17fe, 0x6024, 0xd0f4, 0x00c0,
+	0x17fa, 0xd0d4, 0x0040, 0x17f6, 0x6038, 0xa402, 0x6034, 0xa303,
+	0x0040, 0x17e4, 0x00c8, 0x17f6, 0x643a, 0x6336, 0x6c2a, 0x6b2e,
+	0x047e, 0x037e, 0x2400, 0x6c7c, 0xa402, 0x6812, 0x2300, 0x6b80,
+	0xa303, 0x6816, 0x037f, 0x047f, 0x0078, 0x17fa, 0x1078, 0x8d8e,
+	0x0040, 0x17c1, 0x1078, 0x2035, 0x00c0, 0x17c1, 0x0c7e, 0x7004,
+	0x2060, 0x6024, 0xc0d4, 0x6026, 0x0c7f, 0x684c, 0xd0f4, 0x0040,
+	0x180f, 0x6817, 0xffff, 0x6813, 0xffff, 0x0078, 0x17c1, 0x6824,
+	0x2050, 0x6818, 0x2060, 0x6830, 0x2040, 0x6034, 0xa0cc, 0x000f,
+	0x2009, 0x0011, 0x1078, 0x1824, 0x0040, 0x1822, 0x2009, 0x0001,
+	0x1078, 0x1824, 0x2d58, 0x007c, 0x8aff, 0x0040, 0x18bb, 0xa03e,
+	0x2730, 0x6850, 0xd0fc, 0x00c0, 0x1846, 0xd0f4, 0x00c0, 0x1856,
+	0x0d7e, 0x2804, 0xac68, 0x2900, 0x0079, 0x1836, 0x189d, 0x185d,
+	0x185d, 0x189d, 0x189d, 0x1895, 0x189d, 0x185d, 0x189d, 0x1863,
+	0x1863, 0x189d, 0x189d, 0x189d, 0x188c, 0x1863, 0xc0fc, 0x6852,
+	0x6b6c, 0x6a70, 0x6d1c, 0x6c20, 0x0d7e, 0xd99c, 0x0040, 0x18a0,
+	0x2804, 0xac68, 0x6f08, 0x6e0c, 0x0078, 0x18a0, 0xc0f4, 0x6852,
+	0x6b6c, 0x6a70, 0x0d7e, 0x0078, 0x18a7, 0x6b08, 0x6a0c, 0x6d00,
+	0x6c04, 0x0078, 0x18a0, 0x7b0c, 0xd3bc, 0x0040, 0x1884, 0x7004,
+	0x0e7e, 0x2070, 0x701c, 0x0e7f, 0xa086, 0x0008, 0x00c0, 0x1884,
+	0x7b08, 0xa39c, 0x0fff, 0x2d20, 0x0d7f, 0x0d7e, 0x6a14, 0x82ff,
+	0x00c0, 0x187f, 0x6810, 0xa302, 0x0048, 0x187f, 0x6b10, 0x2011,
+	0x0000, 0x2468, 0x0078, 0x1886, 0x6b10, 0x6a14, 0x6d00, 0x6c04,
+	0x6f08, 0x6e0c, 0x0078, 0x18a0, 0x0d7f, 0x0d7e, 0x6834, 0xa084,
+	0x00ff, 0xa086, 0x001e, 0x00c0, 0x189d, 0x0d7f, 0x1078, 0x1fd1,
+	0x00c0, 0x1824, 0xa00e, 0x0078, 0x18bb, 0x0d7f, 0x1078, 0x1328,
+	0x7b22, 0x7a26, 0x7d32, 0x7c36, 0x7f3a, 0x7e3e, 0x7902, 0x7000,
+	0x8000, 0x7002, 0x0d7f, 0x6828, 0xa300, 0x682a, 0x682c, 0xa201,
+	0x682e, 0x2300, 0x6b10, 0xa302, 0x6812, 0x2200, 0x6a14, 0xa203,
+	0x6816, 0x1078, 0x1fd1, 0x007c, 0x1078, 0x1328, 0x1078, 0x1c52,
+	0x7004, 0x2060, 0x0d7e, 0x6010, 0x2068, 0x7003, 0x0000, 0x1078,
+	0x1ac6, 0x1078, 0x8a44, 0x0040, 0x18db, 0x6808, 0x8001, 0x680a,
+	0x697c, 0x6912, 0x6980, 0x6916, 0x682b, 0xffff, 0x682f, 0xffff,
+	0x6850, 0xc0bd, 0x6852, 0x0d7f, 0x1078, 0x8758, 0x0078, 0x1aad,
+	0x1078, 0x1328, 0x127e, 0x2091, 0x2100, 0x007e, 0x017e, 0x2b68,
+	0x6818, 0x2060, 0x7904, 0x7803, 0x0002, 0xa184, 0x0700, 0x00c0,
+	0x18be, 0xa184, 0x0003, 0xa086, 0x0003, 0x0040, 0x18e0, 0x7000,
+	0x0079, 0x18fa, 0x1902, 0x1904, 0x1a06, 0x1a84, 0x1a9b, 0x1902,
+	0x1902, 0x1902, 0x1078, 0x1328, 0x8001, 0x7002, 0xa184, 0x0880,
+	0x00c0, 0x1919, 0x8aff, 0x0040, 0x199b, 0x2009, 0x0001, 0x1078,
+	0x1824, 0x0040, 0x1aad, 0x2009, 0x0001, 0x1078, 0x1824, 0x0078,
+	0x1aad, 0x7803, 0x0004, 0x7003, 0x0000, 0xd1bc, 0x00c0, 0x1979,
+	0x027e, 0x037e, 0x7808, 0xd0ec, 0x00c0, 0x1930, 0x7c20, 0x7d24,
+	0x7e30, 0x7f34, 0x7803, 0x0009, 0x7003, 0x0004, 0x0078, 0x1932,
+	0x1078, 0x1b9f, 0x6b28, 0x6a2c, 0x2400, 0x686e, 0xa31a, 0x2500,
+	0x6872, 0xa213, 0x6b2a, 0x6a2e, 0x0c7e, 0x7004, 0x2060, 0x6024,
+	0xd0f4, 0x00c0, 0x1945, 0x633a, 0x6236, 0x0c7f, 0x2400, 0x6910,
+	0xa100, 0x6812, 0x2500, 0x6914, 0xa101, 0x6816, 0x037f, 0x027f,
+	0x2600, 0x681e, 0x2700, 0x6822, 0x1078, 0x1fea, 0x2a00, 0x6826,
+	0x2c00, 0x681a, 0x2800, 0x6832, 0x6850, 0xc0fd, 0x6852, 0x6808,
+	0x8001, 0x680a, 0x00c0, 0x196e, 0x684c, 0xd0e4, 0x0040, 0x196e,
+	0x7004, 0x2060, 0x2009, 0x0048, 0x1078, 0x756c, 0x7000, 0xa086,
+	0x0004, 0x0040, 0x1aad, 0x7003, 0x0000, 0x1078, 0x179f, 0x0078,
+	0x1aad, 0x057e, 0x7d0c, 0xd5bc, 0x00c0, 0x1980, 0x1078, 0xa20c,
+	0x057f, 0x1078, 0x1ac6, 0x0f7e, 0x7004, 0x2078, 0x1078, 0x4893,
+	0x0040, 0x198d, 0x7824, 0xc0f5, 0x7826, 0x0f7f, 0x682b, 0xffff,
+	0x682f, 0xffff, 0x6808, 0x8001, 0x680a, 0x697c, 0x6912, 0x6980,
+	0x6916, 0x0078, 0x1aad, 0x7004, 0x0c7e, 0x2060, 0x6024, 0x0c7f,
+	0xd0f4, 0x0040, 0x19a8, 0x6808, 0x8001, 0x680a, 0x0078, 0x1aad,
+	0x684c, 0xc0f5, 0x684e, 0x7814, 0xa005, 0x00c0, 0x19c0, 0x7003,
+	0x0000, 0x6808, 0x8001, 0x680a, 0x00c0, 0x19bc, 0x7004, 0x2060,
+	0x2009, 0x0048, 0x1078, 0x756c, 0x1078, 0x179f, 0x0078, 0x1aad,
+	0x7814, 0x6910, 0xa102, 0x6812, 0x6914, 0xa183, 0x0000, 0x6816,
+	0x7814, 0x7908, 0xa18c, 0x0fff, 0xa188, 0x0007, 0x8114, 0x8214,
+	0x8214, 0xa10a, 0x8104, 0x8004, 0x8004, 0xa20a, 0x810b, 0x810b,
+	0x810b, 0x1078, 0x1b4d, 0x7803, 0x0004, 0x780f, 0xffff, 0x7803,
+	0x0001, 0x7804, 0xd0fc, 0x0040, 0x19e1, 0x7803, 0x0002, 0x7803,
+	0x0004, 0x780f, 0x0076, 0x7004, 0x7007, 0x0000, 0x2060, 0x2009,
+	0x0048, 0x1078, 0x756c, 0x1078, 0x1b81, 0x0040, 0x19bc, 0x7908,
+	0xd1ec, 0x00c0, 0x19ff, 0x2009, 0x0009, 0x0078, 0x1a01, 0x2009,
+	0x0019, 0x7902, 0x7003, 0x0003, 0x0078, 0x1aad, 0x8001, 0x7002,
+	0xd194, 0x0040, 0x1a18, 0x7804, 0xd0fc, 0x00c0, 0x18ea, 0x8aff,
+	0x0040, 0x1aad, 0x2009, 0x0001, 0x1078, 0x1824, 0x0078, 0x1aad,
+	0xa184, 0x0880, 0x00c0, 0x1a25, 0x8aff, 0x0040, 0x1aad, 0x2009,
+	0x0001, 0x1078, 0x1824, 0x0078, 0x1aad, 0x7803, 0x0004, 0x7003,
+	0x0000, 0xd1bc, 0x00c0, 0x1a65, 0x027e, 0x037e, 0x7808, 0xd0ec,
+	0x00c0, 0x1a38, 0x7803, 0x0009, 0x7003, 0x0004, 0x0078, 0x1a3a,
+	0x1078, 0x1b9f, 0x6b28, 0x6a2c, 0x1078, 0x1fea, 0x0d7e, 0x0f7e,
+	0x2d78, 0x2804, 0xac68, 0x6034, 0xd09c, 0x00c0, 0x1a55, 0x6808,
+	0x2008, 0xa31a, 0x680c, 0xa213, 0x7810, 0xa100, 0x7812, 0x690c,
+	0x7814, 0xa101, 0x7816, 0x0078, 0x1a61, 0x6810, 0x2008, 0xa31a,
+	0x6814, 0xa213, 0x7810, 0xa100, 0x7812, 0x6914, 0x7814, 0xa101,
+	0x7816, 0x0f7f, 0x0d7f, 0x0078, 0x1934, 0x057e, 0x7d0c, 0x1078,
+	0xa20c, 0x057f, 0x1078, 0x1ac6, 0x0f7e, 0x7004, 0x2078, 0x1078,
+	0x4893, 0x0040, 0x1a76, 0x7824, 0xc0f5, 0x7826, 0x0f7f, 0x682b,
+	0xffff, 0x682f, 0xffff, 0x6808, 0x8001, 0x680a, 0x697c, 0x6912,
+	0x6980, 0x6916, 0x0078, 0x1aad, 0x7803, 0x0004, 0x7003, 0x0000,
+	0x7004, 0xa00d, 0x0040, 0x1a97, 0x6808, 0x8001, 0x680a, 0x00c0,
+	0x1a97, 0x7004, 0x2060, 0x2009, 0x0048, 0x1078, 0x756c, 0x1078,
+	0x179f, 0x0078, 0x1aad, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004,
+	0x2060, 0x6010, 0xa005, 0x0040, 0x1a97, 0x2068, 0x6808, 0x8000,
+	0x680a, 0x6c28, 0x6b2c, 0x1078, 0x17be, 0x017f, 0x007f, 0x127f,
+	0x007c, 0x127e, 0x2091, 0x2100, 0x7000, 0xa086, 0x0003, 0x00c0,
+	0x1ac4, 0x700c, 0x7110, 0xa106, 0x0040, 0x1ac4, 0x20e1, 0x9028,
+	0x700f, 0xa5e7, 0x7013, 0xa5e7, 0x127f, 0x007c, 0x0c7e, 0x1078,
+	0x1af7, 0x20e1, 0x9028, 0x700c, 0x7110, 0xa106, 0x0040, 0x1aed,
+	0x2104, 0xa005, 0x0040, 0x1ada, 0x2060, 0x6010, 0x2060, 0x6008,
+	0x8001, 0x600a, 0xa188, 0x0003, 0xa182, 0xa602, 0x0048, 0x1ae2,
+	0x2009, 0xa5e7, 0x7112, 0x700c, 0xa106, 0x00c0, 0x1acb, 0x2001,
+	0x0138, 0x2003, 0x0008, 0x0078, 0x1acb, 0x2001, 0x015d, 0x200c,
+	0x810a, 0x2102, 0x2001, 0x0138, 0x2202, 0x0c7f, 0x007c, 0x2001,
+	0x0138, 0x2014, 0x2003, 0x0000, 0x2021, 0xb015, 0x2001, 0x0141,
+	0x201c, 0xd3dc, 0x00c0, 0x1b14, 0x2001, 0x0109, 0x201c, 0xa39c,
+	0x0048, 0x00c0, 0x1b14, 0x2001, 0x0111, 0x201c, 0x83ff, 0x00c0,
+	0x1b14, 0x8421, 0x00c0, 0x1afe, 0x007c, 0x2011, 0x0201, 0x2009,
+	0x003c, 0x2204, 0xa005, 0x00c0, 0x1b21, 0x8109, 0x00c0, 0x1b19,
+	0x007c, 0x007c, 0x1078, 0x1b15, 0x0040, 0x1b4a, 0x7908, 0xd1ec,
+	0x00c0, 0x1b3a, 0x1078, 0x1b81, 0x0040, 0x1b3a, 0x7803, 0x0009,
+	0x7904, 0xd1fc, 0x0040, 0x1b30, 0x7803, 0x0006, 0x1078, 0x1b15,
+	0x0040, 0x1b4a, 0x780c, 0xd0a4, 0x00c0, 0x1b4a, 0x7007, 0x0000,
+	0x1078, 0x1b81, 0x0040, 0x1b4c, 0x7803, 0x0019, 0x7003, 0x0003,
+	0x0078, 0x1b4c, 0x1078, 0x1ac6, 0x007c, 0x0e7e, 0x2071, 0x0200,
+	0x7808, 0xa084, 0xf000, 0xa10d, 0x1078, 0x1af7, 0x2019, 0x5000,
+	0x8319, 0x0040, 0x1b6b, 0x2001, 0xa602, 0x2004, 0xa086, 0x0000,
+	0x0040, 0x1b6b, 0x2001, 0x0021, 0xd0fc, 0x0040, 0x1b58, 0x1078,
+	0x1e5d, 0x0078, 0x1b56, 0x20e1, 0x7000, 0x7324, 0x7420, 0x7028,
+	0x7028, 0x7426, 0x7037, 0x0001, 0x810f, 0x712e, 0x702f, 0x0100,
+	0x7037, 0x0008, 0x7326, 0x7422, 0x2001, 0x0138, 0x2202, 0x0e7f,
+	0x007c, 0x7908, 0xa18c, 0x0fff, 0xa182, 0x0009, 0x0048, 0x1b8c,
+	0xa085, 0x0001, 0x0078, 0x1b9e, 0x2001, 0x020a, 0x81ff, 0x0040,
+	0x1b97, 0x20e1, 0x6000, 0x200c, 0x200c, 0x200c, 0x200c, 0x20e1,
+	0x7000, 0x200c, 0x200c, 0x7003, 0x0000, 0xa006, 0x007c, 0x7c20,
+	0x7d24, 0x7e30, 0x7f34, 0x700c, 0x7110, 0xa106, 0x0040, 0x1c24,
+	0x7004, 0x017e, 0x210c, 0xa106, 0x017f, 0x0040, 0x1c24, 0x0d7e,
+	0x0c7e, 0x216c, 0x2d00, 0xa005, 0x0040, 0x1c22, 0x6824, 0xd0d4,
+	0x00c0, 0x1c22, 0x6810, 0x2068, 0x6850, 0xd0fc, 0x0040, 0x1bec,
+	0x8108, 0x2104, 0x6b2c, 0xa306, 0x00c0, 0x1c22, 0x8108, 0x2104,
+	0x6a28, 0xa206, 0x00c0, 0x1c22, 0x6850, 0xc0fc, 0xc0f5, 0x6852,
+	0x686c, 0x7822, 0x6870, 0x7826, 0x681c, 0x7832, 0x6820, 0x7836,
+	0x6818, 0x2060, 0x6034, 0xd09c, 0x0040, 0x1be7, 0x6830, 0x2004,
+	0xac68, 0x6808, 0x783a, 0x680c, 0x783e, 0x0078, 0x1c20, 0xa006,
+	0x783a, 0x783e, 0x0078, 0x1c20, 0x8108, 0x2104, 0xa005, 0x00c0,
+	0x1c22, 0x8108, 0x2104, 0xa005, 0x00c0, 0x1c22, 0x6850, 0xc0f5,
+	0x6852, 0x6830, 0x2004, 0x6918, 0xa160, 0xa180, 0x000d, 0x2004,
+	0xd09c, 0x00c0, 0x1c12, 0x6008, 0x7822, 0x686e, 0x600c, 0x7826,
+	0x6872, 0x6000, 0x7832, 0x6004, 0x7836, 0xa006, 0x783a, 0x783e,
+	0x0078, 0x1c20, 0x6010, 0x7822, 0x686e, 0x6014, 0x7826, 0x6872,
+	0x6000, 0x7832, 0x6004, 0x7836, 0x6008, 0x783a, 0x600c, 0x783e,
+	0x7803, 0x0011, 0x0c7f, 0x0d7f, 0x007c, 0x0f7e, 0x0e7e, 0x017e,
+	0x027e, 0x2071, 0xa5e1, 0x2079, 0x0030, 0x2011, 0x0050, 0x7000,
+	0xa086, 0x0000, 0x0040, 0x1c4d, 0x8211, 0x0040, 0x1c4b, 0x2001,
+	0x0005, 0x2004, 0xd08c, 0x0040, 0x1c34, 0x7904, 0xa18c, 0x0780,
+	0x017e, 0x1078, 0x18e2, 0x017f, 0x81ff, 0x00c0, 0x1c4b, 0x2011,
+	0x0050, 0x0078, 0x1c2f, 0xa085, 0x0001, 0x027f, 0x017f, 0x0e7f,
+	0x0f7f, 0x007c, 0x7803, 0x0004, 0x2009, 0x0064, 0x7804, 0xd0ac,
+	0x0040, 0x1ca3, 0x8109, 0x00c0, 0x1c56, 0x2009, 0x0100, 0x210c,
+	0xa18a, 0x0003, 0x1048, 0x1328, 0x1078, 0x1f75, 0x0e7e, 0x0f7e,
+	0x2071, 0xa5d0, 0x2079, 0x0010, 0x7004, 0xa086, 0x0000, 0x0040,
+	0x1c9b, 0x7800, 0x007e, 0x7820, 0x007e, 0x7830, 0x007e, 0x7834,
+	0x007e, 0x7838, 0x007e, 0x783c, 0x007e, 0x7803, 0x0004, 0x7823,
+	0x0000, 0x0005, 0x0005, 0x2079, 0x0030, 0x7804, 0xd0ac, 0x10c0,
+	0x1328, 0x2079, 0x0010, 0x007f, 0x783e, 0x007f, 0x783a, 0x007f,
+	0x7836, 0x007f, 0x7832, 0x007f, 0x7822, 0x007f, 0x7802, 0x0f7f,
+	0x0e7f, 0x0078, 0x1ca1, 0x0f7f, 0x0e7f, 0x7804, 0xd0ac, 0x10c0,
+	0x1328, 0x1078, 0x61d3, 0x007c, 0x0e7e, 0x2071, 0xa602, 0x7003,
+	0x0000, 0x0e7f, 0x007c, 0x0d7e, 0xa280, 0x0004, 0x206c, 0x694c,
+	0xd1dc, 0x00c0, 0x1d26, 0x6934, 0xa184, 0x0007, 0x0079, 0x1cb8,
+	0x1cc0, 0x1d11, 0x1cc0, 0x1cc0, 0x1cc0, 0x1cf6, 0x1cd3, 0x1cc2,
+	0x1078, 0x1328, 0x684c, 0xd0b4, 0x0040, 0x1e34, 0x6860, 0x682e,
+	0x6816, 0x685c, 0x682a, 0x6812, 0x687c, 0x680a, 0x6880, 0x680e,
+	0x6958, 0x0078, 0x1d19, 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e,
+	0x00c0, 0x1cc0, 0x684c, 0xd0b4, 0x0040, 0x1e34, 0x6860, 0x682e,
+	0x6816, 0x685c, 0x682a, 0x6812, 0x687c, 0x680a, 0x6880, 0x680e,
+	0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080,
+	0x2015, 0x2004, 0x6832, 0x6958, 0x0078, 0x1d22, 0xa18c, 0x00ff,
+	0xa186, 0x0015, 0x00c0, 0x1d26, 0x684c, 0xd0b4, 0x0040, 0x1e34,
+	0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080,
+	0x2015, 0x2004, 0x6832, 0x6958, 0xa006, 0x682e, 0x682a, 0x0078,
+	0x1d22, 0x684c, 0xd0b4, 0x0040, 0x18bc, 0x6958, 0xa006, 0x682e,
+	0x682a, 0x2d00, 0x681a, 0x6834, 0xa084, 0x000f, 0xa080, 0x2015,
+	0x2004, 0x6832, 0x6926, 0x684c, 0xc0dd, 0x684e, 0x0d7f, 0x007c,
+	0x0f7e, 0x2079, 0x0020, 0x7804, 0xd0fc, 0x10c0, 0x1e5d, 0x0e7e,
+	0x0d7e, 0x2071, 0xa602, 0x7000, 0xa005, 0x00c0, 0x1dab, 0x0c7e,
+	0x7206, 0xa280, 0x0004, 0x205c, 0x7004, 0x2068, 0x7803, 0x0004,
+	0x6818, 0x0d7e, 0x2068, 0x686c, 0x7812, 0x6890, 0x0f7e, 0x20e1,
+	0x9040, 0x2079, 0x0200, 0x781a, 0x2079, 0x0100, 0x8004, 0x78d6,
+	0x0f7f, 0x0d7f, 0x2b68, 0x6824, 0x2050, 0x6818, 0x2060, 0x6830,
+	0x2040, 0x6034, 0xa0cc, 0x000f, 0x6908, 0x2001, 0x04fd, 0x2004,
+	0xa086, 0x0007, 0x0040, 0x1d6d, 0xa184, 0x0007, 0x0040, 0x1d6d,
+	0x017e, 0x2009, 0x0008, 0xa102, 0x017f, 0xa108, 0x791a, 0x7116,
+	0x701e, 0x680c, 0xa081, 0x0000, 0x781e, 0x701a, 0xa006, 0x700e,
+	0x7012, 0x7004, 0x692c, 0x6814, 0xa106, 0x00c0, 0x1d84, 0x6928,
+	0x6810, 0xa106, 0x0040, 0x1d91, 0x037e, 0x047e, 0x6b14, 0x6c10,
+	0x1078, 0x2035, 0x047f, 0x037f, 0x0040, 0x1d91, 0x0c7f, 0x0078,
+	0x1dab, 0x8aff, 0x00c0, 0x1d99, 0x0c7f, 0xa085, 0x0001, 0x0078,
+	0x1dab, 0x127e, 0x2091, 0x8000, 0x2079, 0x0020, 0x2009, 0x0001,
+	0x1078, 0x1daf, 0x0040, 0x1da8, 0x2009, 0x0001, 0x1078, 0x1daf,
+	0x127f, 0x0c7f, 0xa006, 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x077e,
+	0x067e, 0x057e, 0x047e, 0x037e, 0x027e, 0x8aff, 0x0040, 0x1e2d,
+	0x700c, 0x7214, 0xa23a, 0x7010, 0x7218, 0xa203, 0x0048, 0x1e2c,
+	0xa705, 0x0040, 0x1e2c, 0xa03e, 0x2730, 0x6850, 0xd0fc, 0x00c0,
+	0x1ddf, 0x0d7e, 0x2804, 0xac68, 0x2900, 0x0079, 0x1dcf, 0x1e0e,
+	0x1def, 0x1def, 0x1e0e, 0x1e0e, 0x1e06, 0x1e0e, 0x1def, 0x1e0e,
+	0x1df5, 0x1df5, 0x1e0e, 0x1e0e, 0x1e0e, 0x1dfd, 0x1df5, 0xc0fc,
+	0x6852, 0x6b6c, 0x6a70, 0x6d1c, 0x6c20, 0xd99c, 0x0040, 0x1e12,
+	0x0d7e, 0x2804, 0xac68, 0x6f08, 0x6e0c, 0x0078, 0x1e11, 0x6b08,
+	0x6a0c, 0x6d00, 0x6c04, 0x0078, 0x1e11, 0x6b10, 0x6a14, 0x6d00,
+	0x6c04, 0x6f08, 0x6e0c, 0x0078, 0x1e11, 0x0d7f, 0x0d7e, 0x6834,
+	0xa084, 0x00ff, 0xa086, 0x001e, 0x00c0, 0x1e0e, 0x0d7f, 0x1078,
+	0x1fd1, 0x00c0, 0x1db5, 0xa00e, 0x0078, 0x1e2d, 0x0d7f, 0x1078,
+	0x1328, 0x0d7f, 0x7b22, 0x7a26, 0x7d32, 0x7c36, 0x7f3a, 0x7e3e,
+	0x7902, 0x7000, 0x8000, 0x7002, 0x6828, 0xa300, 0x682a, 0x682c,
+	0xa201, 0x682e, 0x700c, 0xa300, 0x700e, 0x7010, 0xa201, 0x7012,
+	0x1078, 0x1fd1, 0x0078, 0x1e2d, 0xa006, 0x027f, 0x037f, 0x047f,
+	0x057f, 0x067f, 0x077f, 0x007c, 0x1078, 0x1328, 0x027e, 0x2001,
+	0x0105, 0x2003, 0x0010, 0x20e1, 0x9040, 0x7803, 0x0004, 0x7003,
+	0x0000, 0x7004, 0x2060, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x8a44,
+	0x0040, 0x1e4d, 0x6850, 0xc0bd, 0x6852, 0x0d7f, 0x1078, 0x8758,
+	0x20e1, 0x9040, 0x1078, 0x719a, 0x2011, 0x0000, 0x1078, 0x6efc,
+	0x1078, 0x61d3, 0x027f, 0x0078, 0x1f29, 0x127e, 0x2091, 0x2200,
+	0x007e, 0x017e, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x2079, 0x0020,
+	0x2071, 0xa602, 0x2b68, 0x6818, 0x2060, 0x7904, 0x7803, 0x0002,
+	0xa184, 0x0700, 0x00c0, 0x1e36, 0x7000, 0x0079, 0x1e77, 0x1f29,
+	0x1e7b, 0x1ef6, 0x1f27, 0x8001, 0x7002, 0xd19c, 0x00c0, 0x1e8f,
+	0x8aff, 0x0040, 0x1eae, 0x2009, 0x0001, 0x1078, 0x1daf, 0x0040,
+	0x1f29, 0x2009, 0x0001, 0x1078, 0x1daf, 0x0078, 0x1f29, 0x7803,
+	0x0004, 0xd194, 0x0040, 0x1e9f, 0x6850, 0xc0fc, 0x6852, 0x8aff,
+	0x00c0, 0x1ea4, 0x684c, 0xc0f5, 0x684e, 0x0078, 0x1ea4, 0x1078,
+	0x1fea, 0x6850, 0xc0fd, 0x6852, 0x2a00, 0x6826, 0x2c00, 0x681a,
+	0x2800, 0x6832, 0x7003, 0x0000, 0x0078, 0x1f29, 0x711c, 0x81ff,
+	0x0040, 0x1ec4, 0x7918, 0x7922, 0x7827, 0x0000, 0x7803, 0x0001,
+	0x7000, 0x8000, 0x7002, 0x700c, 0xa100, 0x700e, 0x7010, 0xa081,
+	0x0000, 0x7012, 0x0078, 0x1f29, 0x0f7e, 0x027e, 0x781c, 0x007e,
+	0x7818, 0x007e, 0x2079, 0x0100, 0x7a14, 0xa284, 0x0004, 0xa085,
+	0x0012, 0x7816, 0x037e, 0x2019, 0x1000, 0x8319, 0x1040, 0x1328,
+	0x7820, 0xd0bc, 0x00c0, 0x1ed5, 0x037f, 0x79c8, 0x007f, 0xa102,
+	0x017f, 0x007e, 0x017e, 0x79c4, 0x007f, 0xa103, 0x78c6, 0x007f,
+	0x78ca, 0xa284, 0x0004, 0xa085, 0x0012, 0x7816, 0x027f, 0x0f7f,
+	0x7803, 0x0008, 0x7003, 0x0000, 0x0078, 0x1f29, 0x8001, 0x7002,
+	0xd194, 0x0040, 0x1f0b, 0x7804, 0xd0fc, 0x00c0, 0x1e6d, 0xd19c,
+	0x00c0, 0x1f25, 0x8aff, 0x0040, 0x1f29, 0x2009, 0x0001, 0x1078,
+	0x1daf, 0x0078, 0x1f29, 0x027e, 0x037e, 0x6b28, 0x6a2c, 0x1078,
+	0x1fea, 0x0d7e, 0x2804, 0xac68, 0x6034, 0xd09c, 0x00c0, 0x1f1e,
+	0x6808, 0xa31a, 0x680c, 0xa213, 0x0078, 0x1f22, 0x6810, 0xa31a,
+	0x6814, 0xa213, 0x0d7f, 0x0078, 0x1e9f, 0x0078, 0x1e9f, 0x1078,
+	0x1328, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x017f, 0x007f, 0x127f,
+	0x007c, 0x0f7e, 0x0e7e, 0x2071, 0xa602, 0x7000, 0xa086, 0x0000,
+	0x0040, 0x1f72, 0x2079, 0x0020, 0x017e, 0x2009, 0x0207, 0x210c,
+	0xd194, 0x0040, 0x1f4f, 0x2009, 0x020c, 0x210c, 0xa184, 0x0003,
+	0x0040, 0x1f4f, 0x20e1, 0x9040, 0x2001, 0x020c, 0x2102, 0x2009,
+	0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0xa106, 0x00c0, 0x1f5a,
+	0x20e1, 0x9040, 0x7804, 0xd0fc, 0x0040, 0x1f3d, 0x1078, 0x1e5d,
+	0x7000, 0xa086, 0x0000, 0x00c0, 0x1f3d, 0x017f, 0x7803, 0x0004,
+	0x7804, 0xd0ac, 0x00c0, 0x1f68, 0x20e1, 0x9040, 0x7803, 0x0002,
+	0x7003, 0x0000, 0x0e7f, 0x0f7f, 0x007c, 0x027e, 0x0c7e, 0x0d7e,
+	0x0e7e, 0x0f7e, 0x2071, 0xa602, 0x2079, 0x0020, 0x7000, 0xa086,
+	0x0000, 0x0040, 0x1fae, 0x7004, 0x2060, 0x6010, 0x2068, 0x1078,
+	0x8a44, 0x0040, 0x1f98, 0x6850, 0xc0b5, 0x6852, 0x680c, 0x7a1c,
+	0xa206, 0x00c0, 0x1f98, 0x6808, 0x7a18, 0xa206, 0x0040, 0x1fb4,
+	0x2001, 0x0105, 0x2003, 0x0010, 0x20e1, 0x9040, 0x7803, 0x0004,
+	0x7003, 0x0000, 0x7004, 0x2060, 0x1078, 0x8758, 0x20e1, 0x9040,
+	0x1078, 0x719a, 0x2011, 0x0000, 0x1078, 0x6efc, 0x0f7f, 0x0e7f,
+	0x0d7f, 0x0c7f, 0x027f, 0x007c, 0x6810, 0x6a14, 0xa205, 0x00c0,
+	0x1f98, 0x684c, 0xc0dc, 0x684e, 0x2c10, 0x1078, 0x1cab, 0x2001,
+	0x0105, 0x2003, 0x0010, 0x20e1, 0x9040, 0x7803, 0x0004, 0x7003,
+	0x0000, 0x2069, 0xa5ab, 0x6833, 0x0000, 0x683f, 0x0000, 0x0078,
+	0x1fae, 0x8840, 0x2804, 0xa005, 0x00c0, 0x1fe5, 0x6004, 0xa005,
+	0x0040, 0x1fe7, 0x681a, 0x2060, 0x6034, 0xa084, 0x000f, 0xa080,
+	0x2015, 0x2044, 0x88ff, 0x1040, 0x1328, 0x8a51, 0x007c, 0x2051,
+	0x0000, 0x007c, 0x8a50, 0x8841, 0x2804, 0xa005, 0x00c0, 0x2004,
+	0x2c00, 0xad06, 0x0040, 0x1ff9, 0x6000, 0xa005, 0x00c0, 0x1ff9,
+	0x2d00, 0x2060, 0x681a, 0x6034, 0xa084, 0x000f, 0xa080, 0x2025,
+	0x2044, 0x88ff, 0x1040, 0x1328, 0x007c, 0x0000, 0x0011, 0x0015,
+	0x0019, 0x001d, 0x0021, 0x0025, 0x0029, 0x0000, 0x000f, 0x0015,
+	0x001b, 0x0021, 0x0027, 0x0000, 0x0000, 0x0000, 0x200a, 0x2006,
+	0x0000, 0x0000, 0x2014, 0x0000, 0x200a, 0x0000, 0x2011, 0x200e,
+	0x0000, 0x0000, 0x0000, 0x2014, 0x2011, 0x0000, 0x200c, 0x200c,
+	0x0000, 0x0000, 0x2014, 0x0000, 0x200c, 0x0000, 0x2012, 0x2012,
+	0x0000, 0x0000, 0x0000, 0x2014, 0x2012, 0x0a7e, 0x097e, 0x087e,
+	0x6b2e, 0x6c2a, 0x6858, 0xa055, 0x0040, 0x20d8, 0x2d60, 0x6034,
+	0xa0cc, 0x000f, 0xa9c0, 0x2015, 0xa986, 0x0007, 0x0040, 0x2050,
+	0xa986, 0x000e, 0x0040, 0x2050, 0xa986, 0x000f, 0x00c0, 0x2054,
+	0x605c, 0xa422, 0x6060, 0xa31a, 0x2804, 0xa045, 0x00c0, 0x2062,
+	0x0050, 0x205c, 0x0078, 0x20d8, 0x6004, 0xa065, 0x0040, 0x20d8,
+	0x0078, 0x203f, 0x2804, 0xa005, 0x0040, 0x2080, 0xac68, 0xd99c,
+	0x00c0, 0x2070, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0078, 0x2074,
+	0x6810, 0xa422, 0x6814, 0xa31b, 0x0048, 0x209f, 0x2300, 0xa405,
+	0x0040, 0x2086, 0x8a51, 0x0040, 0x20d8, 0x8840, 0x0078, 0x2062,
+	0x6004, 0xa065, 0x0040, 0x20d8, 0x0078, 0x203f, 0x8a51, 0x0040,
+	0x20d8, 0x8840, 0x2804, 0xa005, 0x00c0, 0x2099, 0x6004, 0xa065,
+	0x0040, 0x20d8, 0x6034, 0xa0cc, 0x000f, 0xa9c0, 0x2015, 0x2804,
+	0x2040, 0x2b68, 0x6850, 0xc0fc, 0x6852, 0x0078, 0x20cc, 0x8422,
+	0x8420, 0x831a, 0xa399, 0x0000, 0x0d7e, 0x2b68, 0x6c6e, 0x6b72,
+	0x0d7f, 0xd99c, 0x00c0, 0x20ba, 0x6908, 0x2400, 0xa122, 0x690c,
+	0x2300, 0xa11b, 0x1048, 0x1328, 0x6800, 0xa420, 0x6804, 0xa319,
+	0x0078, 0x20c6, 0x6910, 0x2400, 0xa122, 0x6914, 0x2300, 0xa11b,
+	0x1048, 0x1328, 0x6800, 0xa420, 0x6804, 0xa319, 0x2b68, 0x6c1e,
+	0x6b22, 0x6850, 0xc0fd, 0x6852, 0x2c00, 0x681a, 0x2800, 0x6832,
+	0x2a00, 0x6826, 0x007f, 0x007f, 0x007f, 0xa006, 0x0078, 0x20dd,
+	0x087f, 0x097f, 0x0a7f, 0xa085, 0x0001, 0x007c, 0x2001, 0x0005,
+	0x2004, 0xa084, 0x0007, 0x0079, 0x20e5, 0x20ed, 0x20ee, 0x20f1,
+	0x20f4, 0x20f9, 0x20fc, 0x2101, 0x2106, 0x007c, 0x1078, 0x1e5d,
+	0x007c, 0x1078, 0x18e2, 0x007c, 0x1078, 0x18e2, 0x1078, 0x1e5d,
+	0x007c, 0x1078, 0x14b0, 0x007c, 0x1078, 0x1e5d, 0x1078, 0x14b0,
+	0x007c, 0x1078, 0x18e2, 0x1078, 0x14b0, 0x007c, 0x1078, 0x18e2,
+	0x1078, 0x1e5d, 0x1078, 0x14b0, 0x007c, 0x127e, 0x2091, 0x2300,
+	0x2079, 0x0200, 0x2071, 0xa880, 0x2069, 0xa300, 0x2009, 0x0004,
+	0x7912, 0x7817, 0x0004, 0x1078, 0x24b5, 0x781b, 0x0002, 0x20e1,
+	0x8700, 0x127f, 0x007c, 0x127e, 0x2091, 0x2300, 0x781c, 0xa084,
+	0x0007, 0x0079, 0x212b, 0x214f, 0x2133, 0x2137, 0x213b, 0x2141,
+	0x2145, 0x2149, 0x214d, 0x1078, 0x5372, 0x0078, 0x214f, 0x1078,
+	0x53b3, 0x0078, 0x214f, 0x1078, 0x5372, 0x1078, 0x53b3, 0x0078,
+	0x214f, 0x1078, 0x2151, 0x0078, 0x214f, 0x1078, 0x2151, 0x0078,
+	0x214f, 0x1078, 0x2151, 0x0078, 0x214f, 0x1078, 0x2151, 0x127f,
+	0x007c, 0x007e, 0x017e, 0x027e, 0x7930, 0xa184, 0x0003, 0x0040,
+	0x215d, 0x20e1, 0x9040, 0x0078, 0x2186, 0xa184, 0x0030, 0x0040,
+	0x216e, 0x6a00, 0xa286, 0x0003, 0x00c0, 0x2168, 0x0078, 0x216a,
+	0x1078, 0x4171, 0x20e1, 0x9010, 0x0078, 0x2186, 0xa184, 0x00c0,
+	0x0040, 0x2180, 0x0e7e, 0x037e, 0x047e, 0x057e, 0x2071, 0xa5e1,
+	0x1078, 0x1ac6, 0x057f, 0x047f, 0x037f, 0x0e7f, 0x0078, 0x2186,
+	0xa184, 0x0300, 0x0040, 0x2186, 0x20e1, 0x9020, 0x7932, 0x027f,
+	0x017f, 0x007f, 0x007c, 0x017e, 0x0e7e, 0x0f7e, 0x2071, 0xa300,
+	0x7128, 0x2001, 0xa58f, 0x2102, 0x2001, 0xa597, 0x2102, 0xa182,
+	0x0211, 0x00c8, 0x219f, 0x2009, 0x0008, 0x0078, 0x21c9, 0xa182,
+	0x0259, 0x00c8, 0x21a7, 0x2009, 0x0007, 0x0078, 0x21c9, 0xa182,
+	0x02c1, 0x00c8, 0x21af, 0x2009, 0x0006, 0x0078, 0x21c9, 0xa182,
+	0x0349, 0x00c8, 0x21b7, 0x2009, 0x0005, 0x0078, 0x21c9, 0xa182,
+	0x0421, 0x00c8, 0x21bf, 0x2009, 0x0004, 0x0078, 0x21c9, 0xa182,
+	0x0581, 0x00c8, 0x21c7, 0x2009, 0x0003, 0x0078, 0x21c9, 0x2009,
+	0x0002, 0x2079, 0x0200, 0x7912, 0x7817, 0x0004, 0x1078, 0x24b5,
+	0x0f7f, 0x0e7f, 0x017f, 0x007c, 0x127e, 0x2091, 0x2200, 0x2061,
+	0x0100, 0x2071, 0xa300, 0x6024, 0x6026, 0x6053, 0x0030, 0x6033,
+	0x00ef, 0x60e7, 0x0000, 0x60eb, 0x00ef, 0x60e3, 0x0008, 0x604b,
+	0xf7f7, 0x6043, 0x0000, 0x602f, 0x0080, 0x602f, 0x0000, 0x6007,
+	0x0eaf, 0x600f, 0x00ff, 0x602b, 0x002f, 0x127f, 0x007c, 0x2001,
+	0xa32f, 0x2003, 0x0000, 0x2001, 0xa32e, 0x2003, 0x0001, 0x007c,
+	0x127e, 0x2091, 0x2200, 0x007e, 0x017e, 0x027e, 0x6124, 0xa184,
+	0x002c, 0x00c0, 0x220f, 0xa184, 0x0007, 0x0079, 0x2215, 0xa195,
+	0x0004, 0xa284, 0x0007, 0x0079, 0x2215, 0x2241, 0x221d, 0x2221,
+	0x2225, 0x222b, 0x222f, 0x2235, 0x223b, 0x1078, 0x5ad2, 0x0078,
+	0x2241, 0x1078, 0x5bc1, 0x0078, 0x2241, 0x1078, 0x5bc1, 0x1078,
+	0x5ad2, 0x0078, 0x2241, 0x1078, 0x2246, 0x0078, 0x2241, 0x1078,
+	0x5ad2, 0x1078, 0x2246, 0x0078, 0x2241, 0x1078, 0x5bc1, 0x1078,
+	0x2246, 0x0078, 0x2241, 0x1078, 0x5bc1, 0x1078, 0x5ad2, 0x1078,
+	0x2246, 0x027f, 0x017f, 0x007f, 0x127f, 0x007c, 0x6124, 0xd1ac,
+	0x0040, 0x2342, 0x017e, 0x047e, 0x0c7e, 0x644c, 0xa486, 0xf0f0,
+	0x00c0, 0x2259, 0x2061, 0x0100, 0x644a, 0x6043, 0x0090, 0x6043,
+	0x0010, 0x74c2, 0xa48c, 0xff00, 0x7034, 0xd084, 0x0040, 0x2271,
+	0xa186, 0xf800, 0x00c0, 0x2271, 0x7038, 0xd084, 0x00c0, 0x2271,
+	0xc085, 0x703a, 0x037e, 0x2418, 0x2011, 0x8016, 0x1078, 0x3579,
+	0x037f, 0xa196, 0xff00, 0x0040, 0x22b3, 0x6030, 0xa084, 0x00ff,
+	0x810f, 0xa116, 0x0040, 0x22b3, 0x7130, 0xd184, 0x00c0, 0x22b3,
+	0x2011, 0xa352, 0x2214, 0xd2ec, 0x0040, 0x228e, 0xc18d, 0x7132,
+	0x2011, 0xa352, 0x2214, 0xd2ac, 0x00c0, 0x22b3, 0x6240, 0xa294,
+	0x0010, 0x0040, 0x229a, 0x6248, 0xa294, 0xff00, 0xa296, 0xff00,
+	0x0040, 0x22b3, 0x7030, 0xd08c, 0x0040, 0x2305, 0x7034, 0xd08c,
+	0x00c0, 0x22aa, 0x2001, 0xa30c, 0x200c, 0xd1ac, 0x00c0, 0x2305,
+	0xc1ad, 0x2102, 0x037e, 0x73c0, 0x2011, 0x8013, 0x1078, 0x3579,
+	0x037f, 0x0078, 0x2305, 0x7034, 0xd08c, 0x00c0, 0x22bf, 0x2001,
+	0xa30c, 0x200c, 0xd1ac, 0x00c0, 0x2305, 0xc1ad, 0x2102, 0x037e,
+	0x73c0, 0x2011, 0x8013, 0x1078, 0x3579, 0x037f, 0x7130, 0xc185,
+	0x7132, 0x2011, 0xa352, 0x220c, 0xd1a4, 0x0040, 0x22e9, 0x017e,
+	0x2009, 0x0001, 0x2011, 0x0100, 0x1078, 0x5a6d, 0x2019, 0x000e,
+	0x1078, 0x9e3b, 0xa484, 0x00ff, 0xa080, 0x293f, 0x200c, 0xa18c,
+	0xff00, 0x810f, 0x8127, 0xa006, 0x2009, 0x000e, 0x1078, 0x9ec0,
+	0x017f, 0xd1ac, 0x00c0, 0x22f6, 0x017e, 0x2009, 0x0000, 0x2019,
+	0x0004, 0x1078, 0x27e2, 0x017f, 0x0078, 0x2305, 0x157e, 0x20a9,
+	0x007f, 0x2009, 0x0000, 0x1078, 0x4501, 0x00c0, 0x2301, 0x1078,
+	0x4235, 0x8108, 0x00f0, 0x22fb, 0x157f, 0x0c7f, 0x047f, 0x0f7e,
+	0x2079, 0xa5be, 0x783c, 0xa086, 0x0000, 0x0040, 0x2317, 0x6027,
+	0x0004, 0x783f, 0x0000, 0x2079, 0x0140, 0x7803, 0x0000, 0x0f7f,
+	0x2011, 0x0003, 0x1078, 0x6ef2, 0x2011, 0x0002, 0x1078, 0x6efc,
+	0x1078, 0x6dda, 0x1078, 0x595a, 0x037e, 0x2019, 0x0000, 0x1078,
+	0x6e6c, 0x037f, 0x60e3, 0x0000, 0x017f, 0x2001, 0xa300, 0x2014,
+	0xa296, 0x0004, 0x00c0, 0x233a, 0xd19c, 0x00c0, 0x233a, 0x6228,
+	0xc29d, 0x622a, 0x2003, 0x0001, 0x2001, 0xa321, 0x2003, 0x0000,
+	0x6027, 0x0020, 0xd194, 0x0040, 0x2426, 0x0f7e, 0x2079, 0xa5be,
+	0x783c, 0xa086, 0x0001, 0x00c0, 0x2366, 0x017e, 0x6027, 0x0004,
+	0x783f, 0x0000, 0x2079, 0x0140, 0x7803, 0x1000, 0x7803, 0x0000,
+	0x2079, 0xa5ab, 0x7807, 0x0000, 0x7833, 0x0000, 0x1078, 0x6109,
+	0x1078, 0x61d3, 0x017f, 0x0f7f, 0x0078, 0x2426, 0x0f7f, 0x017e,
+	0x3900, 0xa082, 0xa6cd, 0x00c8, 0x2371, 0x017e, 0x1078, 0x728a,
+	0x017f, 0x6220, 0xd2b4, 0x0040, 0x23dc, 0x1078, 0x595a, 0x1078,
+	0x6c41, 0x6027, 0x0004, 0x0f7e, 0x2019, 0xa5b4, 0x2304, 0xa07d,
+	0x0040, 0x23b2, 0x7804, 0xa086, 0x0032, 0x00c0, 0x23b2, 0x0d7e,
+	0x0c7e, 0x0e7e, 0x2069, 0x0140, 0x618c, 0x6288, 0x7818, 0x608e,
+	0x7808, 0x608a, 0x6043, 0x0002, 0x2001, 0x0003, 0x8001, 0x00c0,
+	0x2396, 0x6043, 0x0000, 0x6803, 0x1000, 0x6803, 0x0000, 0x618e,
+	0x628a, 0x1078, 0x6010, 0x1078, 0x6109, 0x7810, 0x2070, 0x7037,
+	0x0103, 0x2f60, 0x1078, 0x753d, 0x0e7f, 0x0c7f, 0x0d7f, 0x0f7f,
+	0x017f, 0x007c, 0x0f7f, 0x0d7e, 0x2069, 0x0140, 0x6804, 0xa084,
+	0x4000, 0x0040, 0x23bf, 0x6803, 0x1000, 0x6803, 0x0000, 0x0d7f,
+	0x0c7e, 0x2061, 0xa5ab, 0x6028, 0xa09a, 0x00c8, 0x00c8, 0x23cf,
+	0x8000, 0x602a, 0x0c7f, 0x1078, 0x6c33, 0x0078, 0x2425, 0x2019,
+	0xa5b4, 0x2304, 0xa065, 0x0040, 0x23d9, 0x2009, 0x0027, 0x1078,
+	0x756c, 0x0c7f, 0x0078, 0x2425, 0xd2bc, 0x0040, 0x2425, 0x1078,
+	0x5967, 0x6017, 0x0010, 0x6027, 0x0004, 0x0d7e, 0x2069, 0x0140,
+	0x6804, 0xa084, 0x4000, 0x0040, 0x23f1, 0x6803, 0x1000, 0x6803,
+	0x0000, 0x0d7f, 0x0c7e, 0x2061, 0xa5ab, 0x6044, 0xa09a, 0x00c8,
+	0x00c8, 0x2414, 0x8000, 0x6046, 0x603c, 0x0c7f, 0xa005, 0x0040,
+	0x2425, 0x2009, 0x07d0, 0x1078, 0x595f, 0xa080, 0x0007, 0x2004,
+	0xa086, 0x0006, 0x00c0, 0x2410, 0x6017, 0x0012, 0x0078, 0x2425,
+	0x6017, 0x0016, 0x0078, 0x2425, 0x037e, 0x2019, 0x0001, 0x1078,
+	0x6e6c, 0x037f, 0x2019, 0xa5ba, 0x2304, 0xa065, 0x0040, 0x2424,
+	0x2009, 0x004f, 0x1078, 0x756c, 0x0c7f, 0x017f, 0xd19c, 0x0040,
+	0x247c, 0x7034, 0xd0ac, 0x00c0, 0x2457, 0x017e, 0x157e, 0x6027,
+	0x0008, 0x602f, 0x0020, 0x20a9, 0x000a, 0x00f0, 0x2435, 0x602f,
+	0x0000, 0x6150, 0xa185, 0x1400, 0x6052, 0x20a9, 0x0320, 0x00e0,
+	0x243f, 0x2091, 0x6000, 0x6020, 0xd09c, 0x00c0, 0x244e, 0x157f,
+	0x6152, 0x017f, 0x6027, 0x0008, 0x0078, 0x247c, 0x1078, 0x250d,
+	0x00f0, 0x243f, 0x157f, 0x6152, 0x017f, 0x6027, 0x0008, 0x017e,
+	0x6028, 0xc09c, 0x602a, 0x2011, 0x0003, 0x1078, 0x6ef2, 0x2011,
+	0x0002, 0x1078, 0x6efc, 0x1078, 0x6dda, 0x1078, 0x595a, 0x037e,
+	0x2019, 0x0000, 0x1078, 0x6e6c, 0x037f, 0x60e3, 0x0000, 0x1078,
+	0xa22a, 0x1078, 0xa248, 0x2001, 0xa300, 0x2003, 0x0004, 0x6027,
+	0x0008, 0x1078, 0x1246, 0x017f, 0xa18c, 0xffd0, 0x6126, 0x007c,
+	0x007e, 0x017e, 0x027e, 0x0e7e, 0x0f7e, 0x127e, 0x2091, 0x8000,
+	0x2071, 0xa300, 0x71b8, 0x70ba, 0xa116, 0x0040, 0x24ae, 0x81ff,
+	0x0040, 0x2498, 0x2011, 0x8011, 0x1078, 0x3579, 0x0078, 0x24ae,
+	0x2011, 0x8012, 0x1078, 0x3579, 0x2001, 0xa371, 0x2004, 0xd0fc,
+	0x00c0, 0x24ae, 0x037e, 0x0c7e, 0x2061, 0x0100, 0x2019, 0x0028,
+	0x2009, 0x0000, 0x1078, 0x27e2, 0x0c7f, 0x037f, 0x127f, 0x0f7f,
+	0x0e7f, 0x027f, 0x017f, 0x007f, 0x007c, 0x0c7e, 0x0f7e, 0x007e,
+	0x027e, 0x2061, 0x0100, 0xa190, 0x24d1, 0x2204, 0x60f2, 0x2011,
+	0x24de, 0x6000, 0xa082, 0x0003, 0x00c8, 0x24ca, 0x2001, 0x00ff,
+	0x0078, 0x24cb, 0x2204, 0x60ee, 0x027f, 0x007f, 0x0f7f, 0x0c7f,
+	0x007c, 0x0840, 0x0840, 0x0840, 0x0580, 0x0420, 0x0348, 0x02c0,
+	0x0258, 0x0210, 0x01a8, 0x01a8, 0x01a8, 0x01a8, 0x0140, 0x00f8,
+	0x00d0, 0x00b0, 0x00a0, 0x2028, 0xa18c, 0x00ff, 0x2130, 0xa094,
+	0xff00, 0x00c0, 0x24ee, 0x81ff, 0x0040, 0x24f2, 0x1078, 0x5623,
+	0x0078, 0x24f9, 0xa080, 0x293f, 0x200c, 0xa18c, 0xff00, 0x810f,
+	0xa006, 0x007c, 0xa080, 0x293f, 0x200c, 0xa18c, 0x00ff, 0x007c,
+	0x0c7e, 0x2061, 0xa300, 0x6030, 0x0040, 0x2509, 0xc09d, 0x0078,
+	0x250a, 0xc09c, 0x6032, 0x0c7f, 0x007c, 0x007e, 0x157e, 0x0f7e,
+	0x2079, 0x0100, 0x20a9, 0x000a, 0x7854, 0xd08c, 0x00c0, 0x251a,
+	0x00f0, 0x2514, 0x0f7f, 0x157f, 0x007f, 0x007c, 0x0c7e, 0x007e,
+	0x2061, 0x0100, 0x6030, 0x007e, 0x6048, 0x007e, 0x60e4, 0x007e,
+	0x60e8, 0x007e, 0x6050, 0x007e, 0x60f0, 0x007e, 0x60ec, 0x007e,
+	0x600c, 0x007e, 0x6004, 0x007e, 0x6028, 0x007e, 0x60e0, 0x007e,
+	0x602f, 0x0100, 0x602f, 0x0000, 0x0005, 0x0005, 0x0005, 0x0005,
+	0x602f, 0x0040, 0x602f, 0x0000, 0x007f, 0x60e2, 0x007f, 0x602a,
+	0x007f, 0x6006, 0x007f, 0x600e, 0x007f, 0x60ee, 0x007f, 0x60f2,
+	0x007f, 0x6052, 0x007f, 0x60ea, 0x007f, 0x60e6, 0x007f, 0x604a,
+	0x007f, 0x6032, 0x007f, 0x0c7f, 0x007c, 0x257d, 0x2581, 0x2585,
+	0x258b, 0x2591, 0x2597, 0x259d, 0x25a5, 0x25ad, 0x25b3, 0x25b9,
+	0x25c1, 0x25c9, 0x25d1, 0x25d9, 0x25e3, 0x25ed, 0x25ed, 0x25ed,
+	0x25ed, 0x25ed, 0x25ed, 0x25ed, 0x25ed, 0x25ed, 0x25ed, 0x25ed,
+	0x25ed, 0x25ed, 0x25ed, 0x25ed, 0x25ed, 0x107e, 0x007e, 0x0078,
+	0x2606, 0x107e, 0x007e, 0x0078, 0x2606, 0x107e, 0x007e, 0x1078,
+	0x2200, 0x0078, 0x2606, 0x107e, 0x007e, 0x1078, 0x2200, 0x0078,
+	0x2606, 0x107e, 0x007e, 0x1078, 0x20de, 0x0078, 0x2606, 0x107e,
+	0x007e, 0x1078, 0x20de, 0x0078, 0x2606, 0x107e, 0x007e, 0x1078,
+	0x2200, 0x1078, 0x20de, 0x0078, 0x2606, 0x107e, 0x007e, 0x1078,
+	0x2200, 0x1078, 0x20de, 0x0078, 0x2606, 0x107e, 0x007e, 0x1078,
+	0x2123, 0x0078, 0x2606, 0x107e, 0x007e, 0x1078, 0x2123, 0x0078,
+	0x2606, 0x107e, 0x007e, 0x1078, 0x2200, 0x1078, 0x2123, 0x0078,
+	0x2606, 0x107e, 0x007e, 0x1078, 0x2200, 0x1078, 0x2123, 0x0078,
+	0x2606, 0x107e, 0x007e, 0x1078, 0x20de, 0x1078, 0x2123, 0x0078,
+	0x2606, 0x107e, 0x007e, 0x1078, 0x20de, 0x1078, 0x2123, 0x0078,
+	0x2606, 0x107e, 0x007e, 0x1078, 0x2200, 0x1078, 0x20de, 0x1078,
+	0x2123, 0x0078, 0x2606, 0x107e, 0x007e, 0x1078, 0x2200, 0x1078,
+	0x20de, 0x1078, 0x2123, 0x0078, 0x2606, 0x0005, 0x0078, 0x25ed,
+	0xb084, 0x003c, 0x8004, 0x8004, 0x0079, 0x25f6, 0x2606, 0x2583,
+	0x2587, 0x258d, 0x2593, 0x2599, 0x259f, 0x25a7, 0x25af, 0x25b5,
+	0x25bb, 0x25c3, 0x25cb, 0x25d3, 0x25db, 0x25e5, 0x0008, 0x25f0,
+	0x007f, 0x107f, 0x2091, 0x8001, 0x007c, 0x0c7e, 0x027e, 0x047e,
+	0x2021, 0x0000, 0x1078, 0x4897, 0x00c0, 0x2705, 0x70c8, 0xd09c,
+	0x0040, 0x2624, 0xd084, 0x00c0, 0x2624, 0xd0bc, 0x00c0, 0x2705,
+	0x1078, 0x2709, 0x0078, 0x2705, 0xd094, 0x0040, 0x262b, 0x7093,
+	0xffff, 0x0078, 0x2705, 0x2001, 0x010c, 0x203c, 0x7280, 0xd284,
+	0x0040, 0x2694, 0xd28c, 0x00c0, 0x2694, 0x037e, 0x7390, 0xa38e,
+	0xffff, 0x0040, 0x263e, 0x83ff, 0x00c0, 0x2640, 0x2019, 0x0001,
+	0x8314, 0xa2e0, 0xa9c0, 0x2c04, 0xa38c, 0x0001, 0x0040, 0x264d,
+	0xa084, 0xff00, 0x8007, 0x0078, 0x264f, 0xa084, 0x00ff, 0xa70e,
+	0x0040, 0x2689, 0xa08e, 0x0000, 0x0040, 0x2689, 0xa08e, 0x00ff,
+	0x00c0, 0x2666, 0x7230, 0xd284, 0x00c0, 0x268f, 0x7280, 0xc28d,
+	0x7282, 0x7093, 0xffff, 0x037f, 0x0078, 0x2694, 0x2009, 0x0000,
+	0x1078, 0x24e3, 0x1078, 0x4499, 0x00c0, 0x268c, 0x6004, 0xa084,
+	0x00ff, 0xa086, 0x0006, 0x00c0, 0x2683, 0x7030, 0xd08c, 0x0040,
+	0x267d, 0x6000, 0xd0bc, 0x0040, 0x2683, 0x1078, 0x271f, 0x0040,
+	0x268c, 0x0078, 0x2689, 0x1078, 0x2857, 0x1078, 0x274c, 0x0040,
+	0x268c, 0x8318, 0x0078, 0x2640, 0x7392, 0x0078, 0x2691, 0x7093,
+	0xffff, 0x037f, 0x0078, 0x2705, 0xa780, 0x293f, 0x203c, 0xa7bc,
+	0xff00, 0x873f, 0x2041, 0x007e, 0x7090, 0xa096, 0xffff, 0x00c0,
+	0x26a6, 0x2009, 0x0000, 0x28a8, 0x0078, 0x26b2, 0xa812, 0x0048,
+	0x26ae, 0x2008, 0xa802, 0x20a8, 0x0078, 0x26b2, 0x7093, 0xffff,
+	0x0078, 0x2705, 0x2700, 0x157e, 0x017e, 0xa106, 0x0040, 0x26f9,
+	0xc484, 0x1078, 0x4501, 0x0040, 0x26c3, 0x1078, 0x4499, 0x00c0,
+	0x2702, 0x0078, 0x26c4, 0xc485, 0x6004, 0xa084, 0x00ff, 0xa086,
+	0x0006, 0x00c0, 0x26d3, 0x7030, 0xd08c, 0x0040, 0x26f1, 0x6000,
+	0xd0bc, 0x00c0, 0x26f1, 0x7280, 0xd28c, 0x0040, 0x26e9, 0x6004,
+	0xa084, 0x00ff, 0xa082, 0x0006, 0x0048, 0x26f9, 0xd484, 0x00c0,
+	0x26e5, 0x1078, 0x44bc, 0x0078, 0x26e7, 0x1078, 0x2921, 0x0078,
+	0x26f9, 0x1078, 0x2857, 0x1078, 0x274c, 0x0040, 0x2702, 0x0078,
+	0x26f9, 0x1078, 0x28ec, 0x0040, 0x26f9, 0x1078, 0x271f, 0x0040,
+	0x2702, 0x017f, 0x8108, 0x157f, 0x00f0, 0x26b2, 0x7093, 0xffff,
+	0x0078, 0x2705, 0x017f, 0x157f, 0x7192, 0x047f, 0x027f, 0x0c7f,
+	0x007c, 0x0c7e, 0x017e, 0x7093, 0x0000, 0x2009, 0x007e, 0x1078,
+	0x4499, 0x00c0, 0x271c, 0x1078, 0x2857, 0x1078, 0x274c, 0x0040,
+	0x271c, 0x70c8, 0xc0bd, 0x70ca, 0x017f, 0x0c7f, 0x007c, 0x017e,
+	0x077e, 0x0d7e, 0x0c7e, 0x2c68, 0x2001, 0xa356, 0x2004, 0xa084,
+	0x00ff, 0x6842, 0x1078, 0x74d7, 0x0040, 0x2747, 0x2d00, 0x601a,
+	0x601f, 0x0001, 0x2001, 0x0000, 0x1078, 0x442b, 0x2001, 0x0000,
+	0x1078, 0x443f, 0x127e, 0x2091, 0x8000, 0x708c, 0x8000, 0x708e,
+	0x127f, 0x2009, 0x0004, 0x1078, 0x756c, 0xa085, 0x0001, 0x0c7f,
+	0x0d7f, 0x077f, 0x017f, 0x007c, 0x017e, 0x077e, 0x0d7e, 0x0c7e,
+	0x2c68, 0x2001, 0xa356, 0x2004, 0xa084, 0x00ff, 0x6842, 0x1078,
+	0x74d7, 0x0040, 0x2785, 0x2d00, 0x601a, 0x6800, 0xc0c4, 0x6802,
+	0x68a0, 0xa086, 0x007e, 0x0040, 0x276e, 0x6804, 0xa084, 0x00ff,
+	0xa086, 0x0006, 0x00c0, 0x276e, 0x1078, 0x2813, 0x601f, 0x0001,
+	0x2001, 0x0000, 0x1078, 0x442b, 0x2001, 0x0002, 0x1078, 0x443f,
+	0x127e, 0x2091, 0x8000, 0x708c, 0x8000, 0x708e, 0x127f, 0x2009,
+	0x0002, 0x1078, 0x756c, 0xa085, 0x0001, 0x0c7f, 0x0d7f, 0x077f,
+	0x017f, 0x007c, 0x0c7e, 0x027e, 0x2009, 0x0080, 0x1078, 0x4499,
+	0x00c0, 0x2798, 0x1078, 0x279b, 0x0040, 0x2798, 0x70cf, 0xffff,
+	0x027f, 0x0c7f, 0x007c, 0x017e, 0x077e, 0x0d7e, 0x0c7e, 0x2c68,
+	0x1078, 0x74d7, 0x0040, 0x27bd, 0x2d00, 0x601a, 0x601f, 0x0001,
+	0x2001, 0x0000, 0x1078, 0x442b, 0x2001, 0x0002, 0x1078, 0x443f,
+	0x127e, 0x2091, 0x8000, 0x70d0, 0x8000, 0x70d2, 0x127f, 0x2009,
+	0x0002, 0x1078, 0x756c, 0xa085, 0x0001, 0x0c7f, 0x0d7f, 0x077f,
+	0x017f, 0x007c, 0x0c7e, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x2009,
+	0x007f, 0x1078, 0x4499, 0x00c0, 0x27de, 0x2c68, 0x1078, 0x74d7,
+	0x0040, 0x27de, 0x2d00, 0x601a, 0x6312, 0x601f, 0x0001, 0x620a,
+	0x2009, 0x0022, 0x1078, 0x756c, 0xa085, 0x0001, 0x127f, 0x0d7f,
+	0x0c7f, 0x007c, 0x0e7e, 0x0c7e, 0x067e, 0x037e, 0x027e, 0x1078,
+	0x5d60, 0x1078, 0x5d02, 0x1078, 0x7ddf, 0x2130, 0x81ff, 0x0040,
+	0x27f7, 0x20a9, 0x007e, 0x2009, 0x0000, 0x0078, 0x27fb, 0x20a9,
+	0x007f, 0x2009, 0x0000, 0x017e, 0x1078, 0x4501, 0x00c0, 0x2804,
+	0x1078, 0x471b, 0x1078, 0x4235, 0x017f, 0x8108, 0x00f0, 0x27fb,
+	0x86ff, 0x00c0, 0x280d, 0x1078, 0x119b, 0x027f, 0x037f, 0x067f,
+	0x0c7f, 0x0e7f, 0x007c, 0x0e7e, 0x0c7e, 0x037e, 0x027e, 0x017e,
+	0x6218, 0x2270, 0x72a0, 0x027e, 0x2019, 0x0029, 0x1078, 0x5d53,
+	0x077e, 0x2039, 0x0000, 0x1078, 0x5c78, 0x2c08, 0x1078, 0x9c38,
+	0x077f, 0x017f, 0x2e60, 0x1078, 0x471b, 0x6210, 0x6314, 0x1078,
+	0x4235, 0x6212, 0x6316, 0x017f, 0x027f, 0x037f, 0x0c7f, 0x0e7f,
+	0x007c, 0x0e7e, 0x007e, 0x6018, 0xa080, 0x0028, 0x2004, 0xd0bc,
+	0x00c0, 0x284d, 0x2071, 0xa300, 0x708c, 0xa005, 0x0040, 0x284a,
+	0x8001, 0x708e, 0x007f, 0x0e7f, 0x007c, 0x2071, 0xa300, 0x70d0,
+	0xa005, 0x0040, 0x284a, 0x8001, 0x70d2, 0x0078, 0x284a, 0x6000,
+	0xc08c, 0x6002, 0x007c, 0x0f7e, 0x0e7e, 0x0c7e, 0x037e, 0x027e,
+	0x017e, 0x157e, 0x2178, 0x81ff, 0x00c0, 0x286a, 0x20a9, 0x0001,
+	0x0078, 0x2885, 0x2001, 0xa352, 0x2004, 0xd0c4, 0x0040, 0x2881,
+	0xd0a4, 0x0040, 0x2881, 0x047e, 0x6018, 0xa080, 0x0028, 0x2024,
+	0xa4a4, 0x00ff, 0x8427, 0xa006, 0x2009, 0x002d, 0x1078, 0x9ec0,
+	0x047f, 0x20a9, 0x00ff, 0x2011, 0x0000, 0x027e, 0xa28e, 0x007e,
+	0x0040, 0x28c9, 0xa28e, 0x007f, 0x0040, 0x28c9, 0xa28e, 0x0080,
+	0x0040, 0x28c9, 0xa288, 0xa434, 0x210c, 0x81ff, 0x0040, 0x28c9,
+	0x8fff, 0x1040, 0x28d5, 0x0c7e, 0x2160, 0x2001, 0x0001, 0x1078,
+	0x48a2, 0x0c7f, 0x2019, 0x0029, 0x1078, 0x5d53, 0x077e, 0x2039,
+	0x0000, 0x1078, 0x5c78, 0x0c7e, 0x027e, 0x2160, 0x6204, 0xa294,
+	0x00ff, 0xa286, 0x0006, 0x00c0, 0x28b9, 0x6007, 0x0404, 0x0078,
+	0x28be, 0x2001, 0x0004, 0x8007, 0xa215, 0x6206, 0x027f, 0x0c7f,
+	0x017e, 0x2c08, 0x1078, 0x9c38, 0x017f, 0x077f, 0x2160, 0x1078,
+	0x471b, 0x027f, 0x8210, 0x00f0, 0x2885, 0x157f, 0x017f, 0x027f,
+	0x037f, 0x0c7f, 0x0e7f, 0x0f7f, 0x007c, 0x047e, 0x027e, 0x017e,
+	0x2001, 0xa352, 0x2004, 0xd0c4, 0x0040, 0x28e8, 0xd0a4, 0x0040,
+	0x28e8, 0xa006, 0x2220, 0x8427, 0x2009, 0x0029, 0x1078, 0x9ec0,
+	0x017f, 0x027f, 0x047f, 0x007c, 0x017e, 0x027e, 0x037e, 0x0c7e,
+	0x7280, 0x82ff, 0x0040, 0x291a, 0xa290, 0xa352, 0x2214, 0xd2ac,
+	0x00c0, 0x291a, 0x2100, 0x1078, 0x24fa, 0x81ff, 0x0040, 0x291c,
+	0x2019, 0x0001, 0x8314, 0xa2e0, 0xa9c0, 0x2c04, 0xd384, 0x0040,
+	0x290e, 0xa084, 0xff00, 0x8007, 0x0078, 0x2910, 0xa084, 0x00ff,
+	0xa116, 0x0040, 0x291c, 0xa096, 0x00ff, 0x0040, 0x291a, 0x8318,
+	0x0078, 0x2902, 0xa085, 0x0001, 0x0c7f, 0x037f, 0x027f, 0x017f,
+	0x007c, 0x017e, 0x0c7e, 0x127e, 0x2091, 0x8000, 0xa180, 0xa434,
+	0x2004, 0xa065, 0x0040, 0x293b, 0x017e, 0x0c7e, 0x1078, 0x8ec0,
+	0x017f, 0x1040, 0x1328, 0x611a, 0x1078, 0x2813, 0x1078, 0x753d,
+	0x017f, 0x1078, 0x44bc, 0x127f, 0x0c7f, 0x017f, 0x007c, 0x7eef,
+	0x7de8, 0x7ce4, 0x80e2, 0x7be1, 0x80e0, 0x80dc, 0x80da, 0x7ad9,
+	0x80d6, 0x80d5, 0x80d4, 0x80d3, 0x80d2, 0x80d1, 0x79ce, 0x78cd,
+	0x80cc, 0x80cb, 0x80ca, 0x80c9, 0x80c7, 0x80c6, 0x77c5, 0x76c3,
+	0x80bc, 0x80ba, 0x75b9, 0x80b6, 0x74b5, 0x73b4, 0x72b3, 0x80b2,
+	0x80b1, 0x80ae, 0x71ad, 0x80ac, 0x70ab, 0x6faa, 0x6ea9, 0x80a7,
+	0x6da6, 0x6ca5, 0x6ba3, 0x6a9f, 0x699e, 0x689d, 0x809b, 0x8098,
+	0x6797, 0x6690, 0x658f, 0x6488, 0x6384, 0x6282, 0x8081, 0x8080,
+	0x617c, 0x607a, 0x8079, 0x5f76, 0x8075, 0x8074, 0x8073, 0x8072,
+	0x8071, 0x806e, 0x5e6d, 0x806c, 0x5d6b, 0x5c6a, 0x5b69, 0x8067,
+	0x5a66, 0x5965, 0x5863, 0x575c, 0x565a, 0x5559, 0x8056, 0x8055,
+	0x5454, 0x5353, 0x5252, 0x5151, 0x504e, 0x4f4d, 0x804c, 0x804b,
+	0x4e4a, 0x4d49, 0x8047, 0x4c46, 0x8045, 0x8043, 0x803c, 0x803a,
+	0x8039, 0x8036, 0x4b35, 0x8034, 0x4a33, 0x4932, 0x4831, 0x802e,
+	0x472d, 0x462c, 0x452b, 0x442a, 0x4329, 0x4227, 0x8026, 0x8025,
+	0x4123, 0x401f, 0x3f1e, 0x3e1d, 0x3d1b, 0x3c18, 0x8017, 0x8010,
+	0x3b0f, 0x3a08, 0x8004, 0x3902, 0x8001, 0x8000, 0x8000, 0x3800,
+	0x3700, 0x3600, 0x8000, 0x3500, 0x8000, 0x8000, 0x8000, 0x3400,
+	0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x3300, 0x3200,
+	0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x3100, 0x3000,
+	0x8000, 0x8000, 0x2f00, 0x8000, 0x2e00, 0x2d00, 0x2c00, 0x8000,
+	0x8000, 0x8000, 0x2b00, 0x8000, 0x2a00, 0x2900, 0x2800, 0x8000,
+	0x2700, 0x2600, 0x2500, 0x2400, 0x2300, 0x2200, 0x8000, 0x8000,
+	0x2100, 0x2000, 0x1f00, 0x1e00, 0x1d00, 0x1c00, 0x8000, 0x8000,
+	0x1b00, 0x1a00, 0x8000, 0x1900, 0x8000, 0x8000, 0x8000, 0x8000,
+	0x8000, 0x8000, 0x1800, 0x8000, 0x1700, 0x1600, 0x1500, 0x8000,
+	0x1400, 0x1300, 0x1200, 0x1100, 0x1000, 0x0f00, 0x8000, 0x8000,
+	0x0e00, 0x0d00, 0x0c00, 0x0b00, 0x0a00, 0x0900, 0x8000, 0x8000,
+	0x0800, 0x0700, 0x8000, 0x0600, 0x8000, 0x8000, 0x8000, 0x0500,
+	0x0400, 0x0300, 0x8000, 0x0200, 0x8000, 0x8000, 0x8000, 0x0100,
+	0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x0000, 0x8000,
+	0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
+	0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x2071,
+	0xa381, 0x7003, 0x0002, 0xa006, 0x7012, 0x7016, 0x703a, 0x703e,
+	0x7033, 0xa391, 0x7037, 0xa391, 0x7007, 0x0001, 0x2061, 0xa3d1,
+	0x6003, 0x0002, 0x007c, 0x0090, 0x2a66, 0x0068, 0x2a66, 0x2071,
+	0xa381, 0x2b78, 0x7818, 0xd084, 0x00c0, 0x2a66, 0x2a60, 0x7820,
+	0xa08e, 0x0069, 0x00c0, 0x2b56, 0x0079, 0x2aea, 0x007c, 0x2071,
+	0xa381, 0x7004, 0x0079, 0x2a6c, 0x2a70, 0x2a71, 0x2a7b, 0x2a8d,
+	0x007c, 0x0090, 0x2a7a, 0x0068, 0x2a7a, 0x2b78, 0x7818, 0xd084,
+	0x0040, 0x2a99, 0x007c, 0x2b78, 0x2061, 0xa3d1, 0x6008, 0xa08e,
+	0x0100, 0x0040, 0x2a88, 0xa086, 0x0200, 0x0040, 0x2b4e, 0x007c,
+	0x7014, 0x2068, 0x2a60, 0x7018, 0x007a, 0x7010, 0x2068, 0x6834,
+	0xa086, 0x0103, 0x0040, 0x2a95, 0x007c, 0x2a60, 0x2b78, 0x7018,
+	0x007a, 0x2a60, 0x7820, 0xa08a, 0x0040, 0x00c8, 0x2aa2, 0x61b8,
+	0x0079, 0x2aaa, 0x2100, 0xa08a, 0x003f, 0x00c8, 0x2b4a, 0x61b8,
+	0x0079, 0x2aea, 0x2b2c, 0x2b5e, 0x2b66, 0x2b6a, 0x2b72, 0x2b78,
+	0x2b7c, 0x2b88, 0x2b8c, 0x2b96, 0x2b9a, 0x2b4a, 0x2b4a, 0x2b4a,
+	0x2b9e, 0x2b4a, 0x2bae, 0x2bc5, 0x2bdc, 0x2c58, 0x2c5d, 0x2c8a,
+	0x2ce4, 0x2cf5, 0x2d13, 0x2d54, 0x2d5e, 0x2d6b, 0x2d7e, 0x2d9d,
+	0x2da6, 0x2de3, 0x2de9, 0x2b4a, 0x2e05, 0x2b4a, 0x2b4a, 0x2b4a,
+	0x2b4a, 0x2b4a, 0x2e0c, 0x2e16, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a,
+	0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a, 0x2e1e, 0x2b4a, 0x2b4a, 0x2b4a,
+	0x2b4a, 0x2b4a, 0x2e30, 0x2e47, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a,
+	0x2b4a, 0x2b4a, 0x2e59, 0x2eb0, 0x2f0e, 0x2f1f, 0x2b4a, 0x2b4a,
+	0x2b4a, 0x38f1, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a,
+	0x2b4a, 0x2b4a, 0x2b96, 0x2b9a, 0x2f36, 0x2b4a, 0x2f43, 0x397d,
+	0x39da, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a,
+	0x2b4a, 0x2b4a, 0x2f90, 0x30c5, 0x30e1, 0x30ed, 0x3150, 0x31a9,
+	0x31b4, 0x31f3, 0x3202, 0x3211, 0x3214, 0x2f47, 0x3238, 0x3284,
+	0x3291, 0x33a2, 0x34cd, 0x34f7, 0x3604, 0x3614, 0x3621, 0x365b,
+	0x372a, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a, 0x3792, 0x37ae, 0x3828,
+	0x38e2, 0x713c, 0x0078, 0x2b2c, 0x2021, 0x4000, 0x1078, 0x3553,
+	0x127e, 0x2091, 0x8000, 0x0068, 0x2b39, 0x7818, 0xd084, 0x0040,
+	0x2b3c, 0x127f, 0x0078, 0x2b30, 0x7c22, 0x7926, 0x7a2a, 0x7b2e,
+	0x781b, 0x0001, 0x2091, 0x4080, 0x7007, 0x0001, 0x2091, 0x5000,
+	0x127f, 0x007c, 0x2021, 0x4001, 0x0078, 0x2b2e, 0x2021, 0x4002,
+	0x0078, 0x2b2e, 0x2021, 0x4003, 0x0078, 0x2b2e, 0x2021, 0x4005,
+	0x0078, 0x2b2e, 0x2021, 0x4006, 0x0078, 0x2b2e, 0xa02e, 0x2520,
+	0x7b28, 0x7a2c, 0x7824, 0x7930, 0x0078, 0x3562, 0x7823, 0x0004,
+	0x7824, 0x007a, 0xa02e, 0x2520, 0x7b28, 0x7a2c, 0x7824, 0x7930,
+	0x0078, 0x3566, 0x7924, 0x7828, 0x2114, 0x200a, 0x0078, 0x2b2c,
+	0x7924, 0x2114, 0x0078, 0x2b2c, 0x2099, 0x0009, 0x20a1, 0x0009,
+	0x20a9, 0x0007, 0x53a3, 0x7924, 0x7a28, 0x7b2c, 0x0078, 0x2b2c,
+	0x7824, 0x2060, 0x0078, 0x2ba0, 0x2009, 0x0001, 0x2011, 0x0013,
+	0x2019, 0x0010, 0x783b, 0x0017, 0x0078, 0x2b2c, 0x7d38, 0x7c3c,
+	0x0078, 0x2b60, 0x7d38, 0x7c3c, 0x0078, 0x2b6c, 0x2061, 0x1000,
+	0x610c, 0xa006, 0x2c14, 0xa200, 0x8c60, 0x8109, 0x00c0, 0x2ba2,
+	0x2010, 0xa005, 0x0040, 0x2b2c, 0x0078, 0x2b52, 0x2069, 0xa351,
+	0x7824, 0x7930, 0xa11a, 0x00c8, 0x2b5a, 0x8019, 0x0040, 0x2b5a,
+	0x684a, 0x6942, 0x782c, 0x6852, 0x7828, 0x6856, 0xa006, 0x685a,
+	0x685e, 0x1078, 0x4dbd, 0x0078, 0x2b2c, 0x2069, 0xa351, 0x7824,
+	0x7934, 0xa11a, 0x00c8, 0x2b5a, 0x8019, 0x0040, 0x2b5a, 0x684e,
+	0x6946, 0x782c, 0x6862, 0x7828, 0x6866, 0xa006, 0x686a, 0x686e,
+	0x1078, 0x494d, 0x0078, 0x2b2c, 0xa02e, 0x2520, 0x81ff, 0x00c0,
+	0x2b56, 0x7924, 0x7b28, 0x7a2c, 0x20a9, 0x0005, 0x20a1, 0xa388,
+	0x41a1, 0x1078, 0x3518, 0x0040, 0x2b56, 0x2009, 0x0020, 0x1078,
+	0x3562, 0x701b, 0x2bf4, 0x007c, 0x6834, 0x2008, 0xa084, 0x00ff,
+	0xa096, 0x0011, 0x0040, 0x2c00, 0xa096, 0x0019, 0x00c0, 0x2b56,
+	0x810f, 0xa18c, 0x00ff, 0x0040, 0x2b56, 0x710e, 0x700c, 0x8001,
+	0x0040, 0x2c31, 0x700e, 0x1078, 0x3518, 0x0040, 0x2b56, 0x2009,
+	0x0020, 0x2061, 0xa3d1, 0x6224, 0x6328, 0x642c, 0x6530, 0xa290,
+	0x0040, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x1078,
+	0x3562, 0x701b, 0x2c24, 0x007c, 0x6834, 0xa084, 0x00ff, 0xa096,
+	0x0002, 0x0040, 0x2c2f, 0xa096, 0x000a, 0x00c0, 0x2b56, 0x0078,
+	0x2c06, 0x7010, 0x2068, 0x6838, 0xc0fd, 0x683a, 0x1078, 0x436e,
+	0x00c0, 0x2c3f, 0x7007, 0x0003, 0x701b, 0x2c41, 0x007c, 0x1078,
+	0x4a60, 0x127e, 0x2091, 0x8000, 0x20a9, 0x0005, 0x2099, 0xa388,
+	0x530a, 0x2100, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9,
+	0x0000, 0xad80, 0x000d, 0x2009, 0x0020, 0x127f, 0x0078, 0x3566,
+	0x61a0, 0x7824, 0x60a2, 0x0078, 0x2b2c, 0x2091, 0x8000, 0x7823,
+	0x4000, 0x7827, 0x4953, 0x782b, 0x5020, 0x782f, 0x2020, 0x2009,
+	0x017f, 0x2104, 0x7832, 0x3f00, 0x7836, 0x2061, 0x0100, 0x6200,
+	0x2061, 0x0200, 0x603c, 0x8007, 0xa205, 0x783a, 0x2009, 0x04fd,
+	0x2104, 0x783e, 0x781b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080,
+	0x2071, 0x0010, 0x20c1, 0x00f0, 0xa08a, 0x0003, 0x00c8, 0x0427,
+	0x0078, 0x0423, 0x81ff, 0x00c0, 0x2b56, 0x7924, 0x810f, 0xa18c,
+	0x00ff, 0x1078, 0x4501, 0x00c0, 0x2b5a, 0x7e38, 0xa684, 0x3fff,
+	0xa082, 0x4000, 0x0048, 0x2c9e, 0x0078, 0x2b5a, 0x7c28, 0x7d2c,
+	0x1078, 0x46d6, 0xd28c, 0x00c0, 0x2ca9, 0x1078, 0x466a, 0x0078,
+	0x2cab, 0x1078, 0x46a4, 0x00c0, 0x2cd5, 0x2061, 0xaa00, 0x127e,
+	0x2091, 0x8000, 0x6000, 0xa086, 0x0000, 0x0040, 0x2cc3, 0x6010,
+	0xa06d, 0x0040, 0x2cc3, 0x683c, 0xa406, 0x00c0, 0x2cc3, 0x6840,
+	0xa506, 0x0040, 0x2cce, 0x127f, 0xace0, 0x0010, 0x2001, 0xa315,
+	0x2004, 0xac02, 0x00c8, 0x2b56, 0x0078, 0x2caf, 0x1078, 0x8758,
+	0x127f, 0x0040, 0x2b56, 0x0078, 0x2b2c, 0xa00e, 0x2001, 0x0005,
+	0x1078, 0x4a60, 0x127e, 0x2091, 0x8000, 0x1078, 0x8cc0, 0x1078,
+	0x4982, 0x127f, 0x0078, 0x2b2c, 0x81ff, 0x00c0, 0x2b56, 0x1078,
+	0x3530, 0x0040, 0x2b5a, 0x1078, 0x45a7, 0x0040, 0x2b56, 0x1078,
+	0x46e4, 0x0040, 0x2b56, 0x0078, 0x2b2c, 0x81ff, 0x00c0, 0x2b56,
+	0x1078, 0x3542, 0x0040, 0x2b5a, 0x1078, 0x475f, 0x0040, 0x2b56,
+	0x2019, 0x0005, 0x1078, 0x4705, 0x0040, 0x2b56, 0x7828, 0xa08a,
+	0x1000, 0x00c8, 0x2b5a, 0x8003, 0x800b, 0x810b, 0xa108, 0x1078,
+	0x58e1, 0x0078, 0x2b2c, 0x127e, 0x2091, 0x8000, 0x81ff, 0x0040,
+	0x2d1d, 0x2009, 0x0001, 0x0078, 0x2d4e, 0x2029, 0x00ff, 0x644c,
+	0x2400, 0xa506, 0x0040, 0x2d48, 0x2508, 0x1078, 0x4501, 0x00c0,
+	0x2d48, 0x1078, 0x475f, 0x00c0, 0x2d33, 0x2009, 0x0002, 0x62a8,
+	0x2518, 0x0078, 0x2d4e, 0x2019, 0x0004, 0x1078, 0x4705, 0x00c0,
+	0x2d3d, 0x2009, 0x0006, 0x0078, 0x2d4e, 0x7824, 0xa08a, 0x1000,
+	0x00c8, 0x2d51, 0x8003, 0x800b, 0x810b, 0xa108, 0x1078, 0x58e1,
+	0x8529, 0x00c8, 0x2d20, 0x127f, 0x0078, 0x2b2c, 0x127f, 0x0078,
+	0x2b56, 0x127f, 0x0078, 0x2b5a, 0x1078, 0x3530, 0x0040, 0x2b5a,
+	0x1078, 0x461b, 0x1078, 0x46d6, 0x0078, 0x2b2c, 0x81ff, 0x00c0,
+	0x2b56, 0x1078, 0x3530, 0x0040, 0x2b5a, 0x1078, 0x460a, 0x1078,
+	0x46d6, 0x0078, 0x2b2c, 0x81ff, 0x00c0, 0x2b56, 0x1078, 0x3530,
+	0x0040, 0x2b5a, 0x1078, 0x46a7, 0x0040, 0x2b56, 0x1078, 0x43c1,
+	0x1078, 0x4663, 0x1078, 0x46d6, 0x0078, 0x2b2c, 0x1078, 0x3530,
+	0x0040, 0x2b5a, 0x1078, 0x45a7, 0x0040, 0x2b56, 0x62a0, 0x2019,
+	0x0005, 0x0c7e, 0x1078, 0x471b, 0x0c7f, 0x1078, 0x5d53, 0x077e,
+	0x2039, 0x0000, 0x1078, 0x5c78, 0x2009, 0x0000, 0x1078, 0x9c38,
+	0x077f, 0x1078, 0x46d6, 0x0078, 0x2b2c, 0x1078, 0x3530, 0x0040,
+	0x2b5a, 0x1078, 0x46d6, 0x2208, 0x0078, 0x2b2c, 0x157e, 0x0d7e,
+	0x0e7e, 0x2069, 0xa413, 0x6810, 0x6914, 0xa10a, 0x00c8, 0x2db2,
+	0x2009, 0x0000, 0x6816, 0x2011, 0x0000, 0x2019, 0x0000, 0x20a9,
+	0x00ff, 0x2069, 0xa434, 0x2d04, 0xa075, 0x0040, 0x2dc7, 0x704c,
+	0x1078, 0x2dd1, 0xa210, 0x7080, 0x1078, 0x2dd1, 0xa318, 0x8d68,
+	0x00f0, 0x2dbb, 0x2300, 0xa218, 0x0e7f, 0x0d7f, 0x157f, 0x0078,
+	0x2b2c, 0x0f7e, 0x017e, 0xa07d, 0x0040, 0x2de0, 0x2001, 0x0000,
+	0x8000, 0x2f0c, 0x81ff, 0x0040, 0x2de0, 0x2178, 0x0078, 0x2dd8,
+	0x017f, 0x0f7f, 0x007c, 0x2069, 0xa413, 0x6910, 0x62a4, 0x0078,
+	0x2b2c, 0x81ff, 0x00c0, 0x2b56, 0x614c, 0xa190, 0x293f, 0x2214,
+	0xa294, 0x00ff, 0x606c, 0xa084, 0xff00, 0xa215, 0x6368, 0x67c8,
+	0xd79c, 0x0040, 0x2dff, 0x2031, 0x0001, 0x0078, 0x2e01, 0x2031,
+	0x0000, 0x7e3a, 0x7f3e, 0x0078, 0x2b2c, 0x613c, 0x6240, 0x2019,
+	0xa5a0, 0x231c, 0x0078, 0x2b2c, 0x127e, 0x2091, 0x8000, 0x6134,
+	0xa006, 0x2010, 0x2018, 0x127f, 0x0078, 0x2b2c, 0x1078, 0x3542,
+	0x0040, 0x2b5a, 0x6244, 0x6338, 0x0078, 0x2b2c, 0x613c, 0x6240,
+	0x7824, 0x603e, 0x7b28, 0x6342, 0x2069, 0xa351, 0x831f, 0xa305,
+	0x6816, 0x782c, 0x2069, 0xa5a0, 0x2d1c, 0x206a, 0x0078, 0x2b2c,
+	0x017e, 0x127e, 0x2091, 0x8000, 0x7824, 0x6036, 0xd094, 0x0040,
+	0x2e43, 0x7828, 0xa085, 0x0001, 0x2009, 0xa5a9, 0x200a, 0x2001,
+	0xffff, 0x1078, 0x5975, 0x127f, 0x017f, 0x0078, 0x2b2c, 0x1078,
+	0x3542, 0x0040, 0x2b5a, 0x7828, 0xa00d, 0x0040, 0x2b5a, 0x782c,
+	0xa005, 0x0040, 0x2b5a, 0x6244, 0x6146, 0x6338, 0x603a, 0x0078,
+	0x2b2c, 0x2001, 0xa300, 0x2004, 0xa086, 0x0003, 0x00c0, 0x2b56,
+	0x0c7e, 0x2061, 0x0100, 0x7924, 0x810f, 0xa18c, 0x00ff, 0xa196,
+	0x00ff, 0x00c0, 0x2e70, 0x6030, 0xa085, 0xff00, 0x0078, 0x2e7f,
+	0xa182, 0x007f, 0x00c8, 0x2ea9, 0xa188, 0x293f, 0x210c, 0xa18c,
+	0x00ff, 0x6030, 0xa116, 0x0040, 0x2ea9, 0x810f, 0xa105, 0x127e,
+	0x2091, 0x8000, 0x007e, 0x1078, 0x74d7, 0x007f, 0x0040, 0x2ea5,
+	0x601a, 0x600b, 0xbc09, 0x601f, 0x0001, 0x1078, 0x3518, 0x0040,
+	0x2eac, 0x6837, 0x0000, 0x7007, 0x0003, 0x6833, 0x0000, 0x6838,
+	0xc0fd, 0x683a, 0x701b, 0x2f07, 0x2d00, 0x6012, 0x2009, 0x0032,
+	0x1078, 0x756c, 0x127f, 0x0c7f, 0x007c, 0x127f, 0x0c7f, 0x0078,
+	0x2b56, 0x0c7f, 0x0078, 0x2b5a, 0x1078, 0x753d, 0x0078, 0x2ea5,
+	0x2001, 0xa300, 0x2004, 0xa086, 0x0003, 0x00c0, 0x2b56, 0x0c7e,
+	0x2061, 0x0100, 0x7924, 0x810f, 0xa18c, 0x00ff, 0xa196, 0x00ff,
+	0x00c0, 0x2ec7, 0x6030, 0xa085, 0xff00, 0x0078, 0x2ed6, 0xa182,
+	0x007f, 0x00c8, 0x2f00, 0xa188, 0x293f, 0x210c, 0xa18c, 0x00ff,
+	0x6030, 0xa116, 0x0040, 0x2f00, 0x810f, 0xa105, 0x127e, 0x2091,
+	0x8000, 0x007e, 0x1078, 0x74d7, 0x007f, 0x0040, 0x2efc, 0x601a,
+	0x600b, 0xbc05, 0x601f, 0x0001, 0x1078, 0x3518, 0x0040, 0x2f03,
+	0x6837, 0x0000, 0x7007, 0x0003, 0x6833, 0x0000, 0x6838, 0xc0fd,
+	0x683a, 0x701b, 0x2f07, 0x2d00, 0x6012, 0x2009, 0x0032, 0x1078,
+	0x756c, 0x127f, 0x0c7f, 0x007c, 0x127f, 0x0c7f, 0x0078, 0x2b56,
+	0x0c7f, 0x0078, 0x2b5a, 0x1078, 0x753d, 0x0078, 0x2efc, 0x6830,
+	0xa086, 0x0100, 0x0040, 0x2b56, 0x0078, 0x2b2c, 0x2061, 0xa62d,
+	0x127e, 0x2091, 0x8000, 0x6000, 0xd084, 0x0040, 0x2f1c, 0x6104,
+	0x6208, 0x127f, 0x0078, 0x2b2c, 0x127f, 0x0078, 0x2b5a, 0x81ff,
+	0x00c0, 0x2b56, 0x127e, 0x2091, 0x8000, 0x6244, 0x6060, 0xa202,
+	0x0048, 0x2f33, 0xa085, 0x0001, 0x1078, 0x2500, 0x1078, 0x3bf5,
+	0x127f, 0x0078, 0x2b2c, 0x127f, 0x0078, 0x2b5a, 0x127e, 0x2091,
+	0x8000, 0x20a9, 0x0011, 0x2001, 0xa340, 0x20a0, 0xa006, 0x40a4,
+	0x127f, 0x0078, 0x2b2c, 0x7d38, 0x7c3c, 0x0078, 0x2bde, 0x7824,
+	0xa09c, 0x00ff, 0xa39a, 0x0003, 0x00c8, 0x2b56, 0x624c, 0xa084,
+	0xff00, 0x8007, 0xa206, 0x00c0, 0x2f5f, 0x2001, 0xa340, 0x2009,
+	0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0078, 0x3566, 0x81ff,
+	0x00c0, 0x2b56, 0x1078, 0x3542, 0x0040, 0x2b5a, 0x6004, 0xa084,
+	0x00ff, 0xa086, 0x0006, 0x00c0, 0x2b56, 0x0c7e, 0x1078, 0x3518,
+	0x0c7f, 0x0040, 0x2b56, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a,
+	0x1078, 0x8b85, 0x0040, 0x2b56, 0x7007, 0x0003, 0x701b, 0x2f81,
+	0x007c, 0x6830, 0xa086, 0x0100, 0x0040, 0x2b56, 0xad80, 0x000e,
+	0x2009, 0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0078, 0x3566,
+	0x1078, 0x3518, 0x0040, 0x2b56, 0x1078, 0x421a, 0x2009, 0x001c,
+	0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078, 0x3562, 0x701b, 0x2fa1,
+	0x007c, 0xade8, 0x000d, 0x6800, 0xa005, 0x0040, 0x2b5a, 0x6804,
+	0xd0ac, 0x0040, 0x2fae, 0xd0a4, 0x0040, 0x2b5a, 0xd094, 0x0040,
+	0x2fb9, 0x0c7e, 0x2061, 0x0100, 0x6104, 0xa18c, 0xffdf, 0x6106,
+	0x0c7f, 0xd08c, 0x0040, 0x2fc4, 0x0c7e, 0x2061, 0x0100, 0x6104,
+	0xa18d, 0x0010, 0x6106, 0x0c7f, 0x2009, 0x0100, 0x210c, 0xa18a,
+	0x0002, 0x0048, 0x2fd9, 0xd084, 0x0040, 0x2fd9, 0x6a28, 0xa28a,
+	0x007f, 0x00c8, 0x2b5a, 0xa288, 0x293f, 0x210c, 0xa18c, 0x00ff,
+	0x6152, 0xd0dc, 0x0040, 0x2fe2, 0x6828, 0xa08a, 0x007f, 0x00c8,
+	0x2b5a, 0x604e, 0x6808, 0xa08a, 0x0100, 0x0048, 0x2b5a, 0xa08a,
+	0x0841, 0x00c8, 0x2b5a, 0xa084, 0x0007, 0x00c0, 0x2b5a, 0x680c,
+	0xa005, 0x0040, 0x2b5a, 0x6810, 0xa005, 0x0040, 0x2b5a, 0x6848,
+	0x6940, 0xa10a, 0x00c8, 0x2b5a, 0x8001, 0x0040, 0x2b5a, 0x684c,
+	0x6944, 0xa10a, 0x00c8, 0x2b5a, 0x8001, 0x0040, 0x2b5a, 0x6804,
+	0xd0fc, 0x0040, 0x3038, 0x1078, 0x3518, 0x0040, 0x2b56, 0x2009,
+	0x0014, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0xa290, 0x0038, 0xa399,
+	0x0000, 0x1078, 0x3562, 0x701b, 0x301e, 0x007c, 0xade8, 0x000d,
+	0x20a9, 0x0014, 0x2d98, 0x2069, 0xa36d, 0x2da0, 0x53a3, 0x7010,
+	0xa0e8, 0x000d, 0x2001, 0xa371, 0x200c, 0xd1e4, 0x0040, 0x3038,
+	0x0c7e, 0x2061, 0x0100, 0x6004, 0xa085, 0x0b00, 0x6006, 0x0c7f,
+	0x20a9, 0x001c, 0x2d98, 0x2069, 0xa351, 0x2da0, 0x53a3, 0x6814,
+	0xa08c, 0x00ff, 0x613e, 0x8007, 0xa084, 0x00ff, 0x6042, 0x1078,
+	0x4dbd, 0x1078, 0x48dd, 0x1078, 0x494d, 0x6000, 0xa086, 0x0000,
+	0x00c0, 0x30c3, 0x6808, 0x602a, 0x1078, 0x218b, 0x6818, 0x691c,
+	0x6a20, 0x6b24, 0x8007, 0x810f, 0x8217, 0x831f, 0x6016, 0x611a,
+	0x621e, 0x6322, 0x6c04, 0xd4f4, 0x0040, 0x3070, 0x6830, 0x6934,
+	0x6a38, 0x6b3c, 0x8007, 0x810f, 0x8217, 0x831f, 0x0078, 0x3072,
+	0xa084, 0xf0ff, 0x6006, 0x610a, 0x620e, 0x6312, 0x1078, 0x59a8,
+	0x6904, 0xd1fc, 0x0040, 0x30a5, 0x0c7e, 0x2009, 0x0000, 0x20a9,
+	0x0001, 0x6b70, 0xd384, 0x0040, 0x30a2, 0x0078, 0x308c, 0x839d,
+	0x00c8, 0x30a2, 0x3508, 0x8109, 0x1078, 0x5364, 0x6878, 0x6016,
+	0x6874, 0x2008, 0xa084, 0xff00, 0x8007, 0x600a, 0xa184, 0x00ff,
+	0x6006, 0x8108, 0x00c0, 0x30a0, 0x6003, 0x0003, 0x0078, 0x30a2,
+	0x6003, 0x0001, 0x00f0, 0x3087, 0x0c7f, 0x0c7e, 0x2061, 0x0100,
+	0x602f, 0x0040, 0x602f, 0x0000, 0x0c7f, 0x1078, 0x3784, 0x0040,
+	0x30b3, 0x1078, 0x2500, 0x60bc, 0xa005, 0x0040, 0x30bf, 0x6003,
+	0x0001, 0x2091, 0x301d, 0x1078, 0x4171, 0x0078, 0x30c3, 0x6003,
+	0x0004, 0x2091, 0x301d, 0x0078, 0x2b2c, 0x6000, 0xa086, 0x0000,
+	0x0040, 0x2b56, 0x2069, 0xa351, 0x7830, 0x6842, 0x7834, 0x6846,
+	0x6804, 0xd0fc, 0x0040, 0x30d8, 0x2009, 0x0030, 0x0078, 0x30da,
+	0x2009, 0x001c, 0x2d00, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0078,
+	0x3566, 0xa006, 0x1078, 0x2500, 0x81ff, 0x00c0, 0x2b56, 0x1078,
+	0x421a, 0x1078, 0x4171, 0x0078, 0x2b2c, 0x81ff, 0x00c0, 0x2b56,
+	0x6180, 0x81ff, 0x0040, 0x3107, 0x703f, 0x0000, 0x2001, 0xa9c0,
+	0x2009, 0x0040, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x127e, 0x2091,
+	0x8000, 0x1078, 0x3566, 0x701b, 0x2b29, 0x127f, 0x007c, 0x703f,
+	0x0001, 0x0d7e, 0x2069, 0xa9c0, 0x20a9, 0x0040, 0x20a1, 0xa9c0,
+	0x2019, 0xffff, 0x43a4, 0x654c, 0xa588, 0x293f, 0x210c, 0xa18c,
+	0x00ff, 0x216a, 0xa00e, 0x2011, 0x0002, 0x2100, 0xa506, 0x0040,
+	0x3139, 0x1078, 0x4501, 0x00c0, 0x3139, 0x6014, 0x821c, 0x0048,
+	0x3131, 0xa398, 0xa9c0, 0xa085, 0xff00, 0x8007, 0x201a, 0x0078,
+	0x3138, 0xa398, 0xa9c0, 0x2324, 0xa4a4, 0xff00, 0xa405, 0x201a,
+	0x8210, 0x8108, 0xa182, 0x0080, 0x00c8, 0x3140, 0x0078, 0x311d,
+	0x8201, 0x8007, 0x2d0c, 0xa105, 0x206a, 0x0d7f, 0x20a9, 0x0040,
+	0x20a1, 0xa9c0, 0x2099, 0xa9c0, 0x1078, 0x41be, 0x0078, 0x30f6,
+	0x1078, 0x3542, 0x0040, 0x2b5a, 0x0c7e, 0x1078, 0x3518, 0x0c7f,
+	0x00c0, 0x315e, 0x2009, 0x0002, 0x0078, 0x2b56, 0x2001, 0xa352,
+	0x2004, 0xd0b4, 0x0040, 0x3185, 0x6000, 0xd08c, 0x00c0, 0x3185,
+	0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x3185, 0x6837,
+	0x0000, 0x6838, 0xc0fd, 0x683a, 0x1078, 0x8bd9, 0x00c0, 0x317c,
+	0x2009, 0x0003, 0x0078, 0x2b56, 0x7007, 0x0003, 0x701b, 0x3181,
+	0x007c, 0x1078, 0x3542, 0x0040, 0x2b5a, 0x20a9, 0x002b, 0x2c98,
+	0xade8, 0x0002, 0x2da0, 0x53a3, 0x20a9, 0x0004, 0xac80, 0x0006,
+	0x2098, 0xad80, 0x0006, 0x20a0, 0x1078, 0x41be, 0x20a9, 0x0004,
+	0xac80, 0x000a, 0x2098, 0xad80, 0x000a, 0x20a0, 0x1078, 0x41be,
+	0x2d00, 0x2009, 0x002b, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0078,
+	0x3566, 0x81ff, 0x00c0, 0x2b56, 0x1078, 0x3530, 0x0040, 0x2b5a,
+	0x1078, 0x46ef, 0x0078, 0x2b2c, 0x81ff, 0x00c0, 0x2b56, 0x7828,
+	0xa08a, 0x1000, 0x00c8, 0x2b5a, 0x1078, 0x3542, 0x0040, 0x2b5a,
+	0x1078, 0x475f, 0x0040, 0x2b56, 0x2019, 0x0004, 0x1078, 0x4705,
+	0x7924, 0x810f, 0x7a28, 0x1078, 0x31cf, 0x0078, 0x2b2c, 0xa186,
+	0x00ff, 0x0040, 0x31d7, 0x1078, 0x31e7, 0x0078, 0x31e6, 0x2029,
+	0x007e, 0x2061, 0xa300, 0x644c, 0x2400, 0xa506, 0x0040, 0x31e3,
+	0x2508, 0x1078, 0x31e7, 0x8529, 0x00c8, 0x31dc, 0x007c, 0x1078,
+	0x4501, 0x00c0, 0x31f2, 0x2200, 0x8003, 0x800b, 0x810b, 0xa108,
+	0x1078, 0x58e1, 0x007c, 0x81ff, 0x00c0, 0x2b56, 0x1078, 0x3530,
+	0x0040, 0x2b5a, 0x1078, 0x45a7, 0x0040, 0x2b56, 0x1078, 0x46fa,
+	0x0078, 0x2b2c, 0x81ff, 0x00c0, 0x2b56, 0x1078, 0x3530, 0x0040,
+	0x2b5a, 0x1078, 0x45a7, 0x0040, 0x2b56, 0x1078, 0x46e4, 0x0078,
+	0x2b2c, 0x6100, 0x0078, 0x2b2c, 0x1078, 0x3542, 0x0040, 0x2b5a,
+	0x2001, 0xa300, 0x2004, 0xa086, 0x0003, 0x00c0, 0x2b56, 0x0d7e,
+	0xace8, 0x000a, 0x7924, 0xd184, 0x0040, 0x3228, 0xace8, 0x0006,
+	0x680c, 0x8007, 0x783e, 0x6808, 0x8007, 0x783a, 0x6b04, 0x831f,
+	0x6a00, 0x8217, 0x0d7f, 0x6100, 0xa18c, 0x0200, 0x0078, 0x2b2c,
+	0xa006, 0x1078, 0x2500, 0x7824, 0xa084, 0x00ff, 0xa086, 0x00ff,
+	0x0040, 0x3245, 0x81ff, 0x00c0, 0x2b56, 0x1078, 0x421a, 0x7828,
+	0xa08a, 0x1000, 0x00c8, 0x2b5a, 0x7924, 0xa18c, 0xff00, 0x810f,
+	0xa186, 0x00ff, 0x0040, 0x325b, 0xa182, 0x007f, 0x00c8, 0x2b5a,
+	0x2100, 0x1078, 0x24fa, 0x027e, 0x0c7e, 0x127e, 0x2091, 0x8000,
+	0x2061, 0xa5be, 0x601b, 0x0000, 0x601f, 0x0000, 0x2061, 0x0100,
+	0x6030, 0xa084, 0x00ff, 0x810f, 0xa105, 0x604a, 0x6043, 0x0090,
+	0x6043, 0x0010, 0x2009, 0x002d, 0x2011, 0x4196, 0x1078, 0x596c,
+	0x7924, 0xa18c, 0xff00, 0x810f, 0x7a28, 0x1078, 0x31cf, 0x127f,
+	0x0c7f, 0x027f, 0x0078, 0x2b2c, 0x7924, 0xa18c, 0xff00, 0x810f,
+	0x0c7e, 0x1078, 0x4499, 0x2c08, 0x0c7f, 0x00c0, 0x2b5a, 0x0078,
+	0x2b2c, 0x81ff, 0x0040, 0x3298, 0x2009, 0x0001, 0x0078, 0x2b56,
+	0x60c8, 0xd09c, 0x00c0, 0x32a0, 0x2009, 0x0005, 0x0078, 0x2b56,
+	0x1078, 0x3518, 0x00c0, 0x32a8, 0x2009, 0x0002, 0x0078, 0x2b56,
+	0x7924, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078, 0x3562, 0x701b,
+	0x32b2, 0x007c, 0x2009, 0x0080, 0x1078, 0x4501, 0x00c0, 0x32bf,
+	0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x0040, 0x32c3, 0x2021,
+	0x400a, 0x0078, 0x2b2e, 0x0d7e, 0xade8, 0x000d, 0x6900, 0x6a08,
+	0x6b0c, 0x6c10, 0x6d14, 0x6e18, 0x6820, 0xa0be, 0x0100, 0x0040,
+	0x3336, 0xa0be, 0x0112, 0x0040, 0x3336, 0xa0be, 0x0113, 0x0040,
+	0x3336, 0xa0be, 0x0114, 0x0040, 0x3336, 0xa0be, 0x0117, 0x0040,
+	0x3336, 0xa0be, 0x011a, 0x0040, 0x3336, 0xa0be, 0x0121, 0x0040,
+	0x332c, 0xa0be, 0x0131, 0x0040, 0x332c, 0xa0be, 0x0171, 0x0040,
+	0x3336, 0xa0be, 0x0173, 0x0040, 0x3336, 0xa0be, 0x01a1, 0x00c0,
+	0x32fe, 0x6830, 0x8007, 0x6832, 0x0078, 0x333c, 0xa0be, 0x0212,
+	0x0040, 0x3332, 0xa0be, 0x0213, 0x0040, 0x3332, 0xa0be, 0x0214,
+	0x0040, 0x3324, 0xa0be, 0x0217, 0x0040, 0x331e, 0xa0be, 0x021a,
+	0x00c0, 0x3317, 0x6838, 0x8007, 0x683a, 0x0078, 0x3336, 0xa0be,
+	0x0300, 0x0040, 0x3336, 0x0d7f, 0x0078, 0x2b5a, 0xad80, 0x0010,
+	0x20a9, 0x0007, 0x1078, 0x337e, 0xad80, 0x000e, 0x20a9, 0x0001,
+	0x1078, 0x337e, 0x0078, 0x3336, 0xad80, 0x000c, 0x1078, 0x338c,
+	0x0078, 0x333c, 0xad80, 0x000e, 0x1078, 0x338c, 0xad80, 0x000c,
+	0x20a9, 0x0001, 0x1078, 0x337e, 0x0c7e, 0x1078, 0x3518, 0x0040,
+	0x336f, 0x6838, 0xc0fd, 0x683a, 0x6837, 0x0119, 0x6853, 0x0000,
+	0x684f, 0x0020, 0x685b, 0x0001, 0x810b, 0x697e, 0x6883, 0x0000,
+	0x6a86, 0x6b8a, 0x6c8e, 0x6d92, 0x6996, 0x689b, 0x0000, 0x0c7f,
+	0x0d7f, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x6823, 0x0000,
+	0x6804, 0x2068, 0x1078, 0x8ba1, 0x00c0, 0x336a, 0x2009, 0x0003,
+	0x0078, 0x2b56, 0x7007, 0x0003, 0x701b, 0x3375, 0x007c, 0x0c7f,
+	0x0d7f, 0x2009, 0x0002, 0x0078, 0x2b56, 0x6820, 0xa086, 0x8001,
+	0x00c0, 0x2b2c, 0x2009, 0x0004, 0x0078, 0x2b56, 0x017e, 0x2008,
+	0x2044, 0x8000, 0x204c, 0x8000, 0x290a, 0x8108, 0x280a, 0x8108,
+	0x00f0, 0x3380, 0x017f, 0x007c, 0x017e, 0x0a7e, 0x0b7e, 0x2008,
+	0x2044, 0x8000, 0x204c, 0x8000, 0x2054, 0x8000, 0x205c, 0x2b0a,
+	0x8108, 0x2a0a, 0x8108, 0x290a, 0x8108, 0x280a, 0x0b7f, 0x0a7f,
+	0x017f, 0x007c, 0x81ff, 0x0040, 0x33a9, 0x2009, 0x0001, 0x0078,
+	0x2b56, 0x7924, 0x2140, 0xa18c, 0xff00, 0x810f, 0xa182, 0x0080,
+	0x0048, 0x2b5a, 0xa182, 0x00ff, 0x00c8, 0x2b5a, 0x7a2c, 0x7b28,
+	0x6068, 0xa306, 0x00c0, 0x33c4, 0x606c, 0xa24e, 0x0040, 0x2b5a,
+	0xa9cc, 0xff00, 0x0040, 0x2b5a, 0x0c7e, 0x1078, 0x346d, 0x2c68,
+	0x0c7f, 0x0040, 0x33fc, 0xa0c6, 0x4000, 0x00c0, 0x33e2, 0x0c7e,
+	0x007e, 0x2d60, 0x2009, 0x0000, 0x1078, 0x47cb, 0x00c0, 0x33d9,
+	0xc185, 0x6000, 0xd0bc, 0x0040, 0x33de, 0xc18d, 0x007f, 0x0c7f,
+	0x0078, 0x33f9, 0xa0c6, 0x4007, 0x00c0, 0x33e9, 0x2408, 0x0078,
+	0x33f9, 0xa0c6, 0x4008, 0x00c0, 0x33f1, 0x2708, 0x2610, 0x0078,
+	0x33f9, 0xa0c6, 0x4009, 0x00c0, 0x33f7, 0x0078, 0x33f9, 0x2001,
+	0x4006, 0x2020, 0x0078, 0x2b2e, 0x2d00, 0x7022, 0x017e, 0x0b7e,
+	0x0c7e, 0x0e7e, 0x2c70, 0x1078, 0x74d7, 0x0040, 0x3442, 0x2d00,
+	0x601a, 0x2001, 0xa356, 0x2004, 0xa084, 0x00ff, 0x6842, 0x2e58,
+	0x0e7f, 0x0e7e, 0x0c7e, 0x1078, 0x3518, 0x0c7f, 0x2b70, 0x00c0,
+	0x3423, 0x1078, 0x753d, 0x0e7f, 0x0c7f, 0x0b7f, 0x017f, 0x2009,
+	0x0002, 0x0078, 0x2b56, 0x6837, 0x0000, 0x2d00, 0x6012, 0x6833,
+	0x0000, 0x6838, 0xc0fd, 0x683a, 0x127e, 0x2091, 0x8000, 0x1078,
+	0x2813, 0x127f, 0x601f, 0x0001, 0x2001, 0x0000, 0x1078, 0x442b,
+	0x2001, 0x0002, 0x1078, 0x443f, 0x2009, 0x0002, 0x1078, 0x756c,
+	0xa085, 0x0001, 0x0e7f, 0x0c7f, 0x0b7f, 0x017f, 0x00c0, 0x344c,
+	0x2009, 0x0003, 0x0078, 0x2b56, 0x7007, 0x0003, 0x701b, 0x3451,
+	0x007c, 0x6830, 0xa086, 0x0100, 0x7020, 0x2060, 0x00c0, 0x345f,
+	0x2009, 0x0004, 0x6204, 0xa294, 0x00ff, 0x0078, 0x2b56, 0x2009,
+	0x0000, 0x1078, 0x47cb, 0x00c0, 0x3466, 0xc185, 0x6000, 0xd0bc,
+	0x0040, 0x346b, 0xc18d, 0x0078, 0x2b2c, 0x0e7e, 0x0d7e, 0x2029,
+	0x0000, 0x2021, 0x0080, 0x20a9, 0x007f, 0x2071, 0xa4b4, 0x2e04,
+	0xa005, 0x00c0, 0x3482, 0x2100, 0xa406, 0x00c0, 0x34b3, 0x2428,
+	0x0078, 0x34b3, 0x2068, 0x6f10, 0x2700, 0xa306, 0x00c0, 0x34a4,
+	0x6e14, 0x2600, 0xa206, 0x00c0, 0x34a4, 0x2400, 0xa106, 0x00c0,
+	0x34a0, 0x2d60, 0xd884, 0x0040, 0x34c8, 0x6004, 0xa084, 0x00ff,
+	0xa086, 0x0006, 0x00c0, 0x34c8, 0x2001, 0x4000, 0x0078, 0x34c9,
+	0x2001, 0x4007, 0x0078, 0x34c9, 0x2400, 0xa106, 0x00c0, 0x34b3,
+	0x6e14, 0x87ff, 0x00c0, 0x34af, 0x86ff, 0x0040, 0x347f, 0x2001,
+	0x4008, 0x0078, 0x34c9, 0x8420, 0x8e70, 0x00f0, 0x3477, 0x85ff,
+	0x00c0, 0x34c2, 0x2001, 0x4009, 0x0078, 0x34c9, 0x2001, 0x0001,
+	0x0078, 0x34c9, 0x1078, 0x4499, 0x00c0, 0x34be, 0x6312, 0x6216,
+	0xa006, 0xa005, 0x0d7f, 0x0e7f, 0x007c, 0x81ff, 0x00c0, 0x2b56,
+	0x1078, 0x3518, 0x0040, 0x2b56, 0x6837, 0x0000, 0x6838, 0xc0fd,
+	0x683a, 0x7824, 0xa005, 0x0040, 0x2b5a, 0xa096, 0x00ff, 0x0040,
+	0x34e5, 0xa092, 0x0004, 0x00c8, 0x2b5a, 0x2010, 0x2d18, 0x1078,
+	0x27c2, 0x0040, 0x2b56, 0x7007, 0x0003, 0x701b, 0x34f0, 0x007c,
+	0x6830, 0xa086, 0x0100, 0x0040, 0x2b56, 0x0078, 0x2b2c, 0x7924,
+	0xa18c, 0xff00, 0x810f, 0xa182, 0x0080, 0x0048, 0x2b5a, 0xa182,
+	0x00ff, 0x00c8, 0x2b5a, 0x127e, 0x2091, 0x8000, 0x1078, 0x8a89,
+	0x00c0, 0x3515, 0xa190, 0xa434, 0x2204, 0xa065, 0x0040, 0x3515,
+	0x1078, 0x4235, 0x127f, 0x0078, 0x2b2c, 0x127f, 0x0078, 0x2b56,
+	0x1078, 0x1381, 0x0040, 0x352f, 0xa006, 0x6802, 0x7010, 0xa005,
+	0x00c0, 0x3527, 0x2d00, 0x7012, 0x7016, 0x0078, 0x352d, 0x7014,
+	0x6802, 0x2060, 0x2d00, 0x6006, 0x7016, 0xad80, 0x000d, 0x007c,
+	0x7924, 0x810f, 0xa18c, 0x00ff, 0x1078, 0x4501, 0x00c0, 0x353f,
+	0x7e28, 0xa684, 0x3fff, 0xa082, 0x4000, 0x0048, 0x3540, 0xa066,
+	0x8cff, 0x007c, 0x7e24, 0x860f, 0xa18c, 0x00ff, 0x1078, 0x4501,
+	0x00c0, 0x3550, 0xa6b4, 0x00ff, 0xa682, 0x4000, 0x0048, 0x3551,
+	0xa066, 0x8cff, 0x007c, 0x017e, 0x7110, 0x81ff, 0x0040, 0x355e,
+	0x2168, 0x6904, 0x1078, 0x139a, 0x0078, 0x3555, 0x7112, 0x7116,
+	0x017f, 0x007c, 0x2031, 0x0001, 0x0078, 0x3568, 0x2031, 0x0000,
+	0x2061, 0xa3d1, 0x6606, 0x6112, 0x600e, 0x6226, 0x632a, 0x642e,
+	0x6532, 0x2c10, 0x1078, 0x13d1, 0x7007, 0x0002, 0x701b, 0x2b2c,
+	0x007c, 0x0f7e, 0x127e, 0x2091, 0x8000, 0x2079, 0x0000, 0x2001,
+	0xa38f, 0x2004, 0xa005, 0x00c0, 0x3594, 0x0068, 0x3594, 0x7818,
+	0xd084, 0x00c0, 0x3594, 0x7a22, 0x7b26, 0x7c2a, 0x781b, 0x0001,
+	0x2091, 0x4080, 0x0078, 0x35b9, 0x017e, 0x0c7e, 0x0e7e, 0x2071,
+	0xa381, 0x7138, 0xa182, 0x0008, 0x0048, 0x35a2, 0x7030, 0x2060,
+	0x0078, 0x35b3, 0x7030, 0xa0e0, 0x0008, 0xac82, 0xa3d1, 0x0048,
+	0x35ab, 0x2061, 0xa391, 0x2c00, 0x7032, 0x81ff, 0x00c0, 0x35b1,
+	0x7036, 0x8108, 0x713a, 0x2262, 0x6306, 0x640a, 0x0e7f, 0x0c7f,
+	0x017f, 0x127f, 0x0f7f, 0x007c, 0x0e7e, 0x2071, 0xa381, 0x7038,
+	0xa005, 0x0040, 0x35f5, 0x127e, 0x2091, 0x8000, 0x0068, 0x35f4,
+	0x0f7e, 0x2079, 0x0000, 0x7818, 0xd084, 0x00c0, 0x35f3, 0x0c7e,
+	0x7034, 0x2060, 0x2c04, 0x7822, 0x6004, 0x7826, 0x6008, 0x782a,
+	0x781b, 0x0001, 0x2091, 0x4080, 0x7038, 0x8001, 0x703a, 0xa005,
+	0x00c0, 0x35e9, 0x7033, 0xa391, 0x7037, 0xa391, 0x0c7f, 0x0078,
+	0x35f3, 0xac80, 0x0008, 0xa0fa, 0xa3d1, 0x0048, 0x35f1, 0x2001,
+	0xa391, 0x7036, 0x0c7f, 0x0f7f, 0x127f, 0x0e7f, 0x007c, 0x027e,
+	0x2001, 0xa352, 0x2004, 0xd0c4, 0x0040, 0x3602, 0x2011, 0x8014,
+	0x1078, 0x3579, 0x027f, 0x007c, 0x81ff, 0x00c0, 0x2b56, 0x127e,
+	0x2091, 0x8000, 0x6030, 0xc08d, 0xc085, 0xc0ac, 0x6032, 0x1078,
+	0x4171, 0x127f, 0x0078, 0x2b2c, 0x7824, 0x2008, 0xa18c, 0xfffd,
+	0x00c0, 0x361f, 0x61d4, 0xa10d, 0x61d6, 0x0078, 0x2b2c, 0x0078,
+	0x2b5a, 0x81ff, 0x00c0, 0x2b56, 0x6000, 0xa086, 0x0003, 0x00c0,
+	0x2b56, 0x2001, 0xa352, 0x2004, 0xd0ac, 0x00c0, 0x2b56, 0x1078,
+	0x3542, 0x0040, 0x2b5a, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006,
+	0x00c0, 0x363e, 0x7828, 0xa005, 0x0040, 0x2b2c, 0x0c7e, 0x1078,
+	0x3518, 0x0c7f, 0x0040, 0x2b56, 0x6837, 0x0000, 0x6833, 0x0000,
+	0x6838, 0xc0fd, 0x683a, 0x1078, 0x8c4d, 0x0040, 0x2b56, 0x7007,
+	0x0003, 0x701b, 0x3654, 0x007c, 0x6830, 0xa086, 0x0100, 0x0040,
+	0x2b56, 0x0078, 0x2b2c, 0x2001, 0xa300, 0x2004, 0xa086, 0x0003,
+	0x00c0, 0x2b56, 0x7f24, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078,
+	0x3518, 0x0040, 0x2b56, 0x2009, 0x0000, 0x2031, 0x0000, 0x7023,
+	0x0000, 0x702f, 0x0000, 0xad80, 0x0005, 0x7026, 0x20a0, 0x1078,
+	0x4501, 0x00c0, 0x36d8, 0x6004, 0xa0c4, 0x00ff, 0xa8c6, 0x0006,
+	0x0040, 0x3688, 0xa0c4, 0xff00, 0xa8c6, 0x0600, 0x00c0, 0x36d8,
+	0x2001, 0xa352, 0x2004, 0xd0ac, 0x00c0, 0x3695, 0x1078, 0x47cb,
+	0x00c0, 0x3695, 0xd79c, 0x0040, 0x36d8, 0xd794, 0x00c0, 0x369b,
+	0xd784, 0x0040, 0x36a7, 0xac80, 0x0006, 0x2098, 0x3400, 0x20a9,
+	0x0004, 0x53a3, 0x1078, 0x338c, 0xd794, 0x0040, 0x36b0, 0xac80,
+	0x000a, 0x2098, 0x3400, 0x20a9, 0x0004, 0x53a3, 0x1078, 0x338c,
+	0x21a2, 0xd794, 0x0040, 0x36d0, 0xac80, 0x0000, 0x2098, 0x94a0,
+	0x20a9, 0x0002, 0x53a3, 0xac80, 0x0003, 0x20a6, 0x94a0, 0xac80,
+	0x0004, 0x2098, 0x3400, 0x20a9, 0x0002, 0x53a3, 0x1078, 0x337e,
+	0xac80, 0x0026, 0x2098, 0x20a9, 0x0002, 0x53a3, 0x0078, 0x36d1,
+	0x94a0, 0xd794, 0x0040, 0x36d6, 0xa6b0, 0x000b, 0xa6b0, 0x0005,
+	0x8108, 0xd78c, 0x0040, 0x36e2, 0xa186, 0x0100, 0x0040, 0x36f3,
+	0x0078, 0x36e6, 0xa186, 0x007e, 0x0040, 0x36f3, 0xd794, 0x0040,
+	0x36ed, 0xa686, 0x0020, 0x0078, 0x36ef, 0xa686, 0x0028, 0x0040,
+	0x36fc, 0x0078, 0x3677, 0x86ff, 0x00c0, 0x36fa, 0x7120, 0x810b,
+	0x0078, 0x2b2c, 0x702f, 0x0001, 0x711e, 0x7020, 0xa600, 0x7022,
+	0x772a, 0x2061, 0xa3d1, 0x6007, 0x0000, 0x6612, 0x7024, 0x600e,
+	0x6226, 0x632a, 0x642e, 0x6532, 0x2c10, 0x1078, 0x13d1, 0x7007,
+	0x0002, 0x701b, 0x3714, 0x007c, 0x702c, 0xa005, 0x00c0, 0x3726,
+	0x711c, 0x7024, 0x20a0, 0x7728, 0x2031, 0x0000, 0x2061, 0xa3d1,
+	0x6224, 0x6328, 0x642c, 0x6530, 0x0078, 0x3677, 0x7120, 0x810b,
+	0x0078, 0x2b2c, 0x2029, 0x007e, 0x7924, 0x7a28, 0x7b2c, 0x7c38,
+	0xa184, 0xff00, 0x8007, 0xa0e2, 0x0020, 0x0048, 0x2b5a, 0xa502,
+	0x0048, 0x2b5a, 0xa184, 0x00ff, 0xa0e2, 0x0020, 0x0048, 0x2b5a,
+	0xa502, 0x0048, 0x2b5a, 0xa284, 0xff00, 0x8007, 0xa0e2, 0x0020,
+	0x0048, 0x2b5a, 0xa502, 0x0048, 0x2b5a, 0xa284, 0x00ff, 0xa0e2,
+	0x0020, 0x0048, 0x2b5a, 0xa502, 0x0048, 0x2b5a, 0xa384, 0xff00,
+	0x8007, 0xa0e2, 0x0020, 0x0048, 0x2b5a, 0xa502, 0x0048, 0x2b5a,
+	0xa384, 0x00ff, 0xa0e2, 0x0020, 0x0048, 0x2b5a, 0xa502, 0x0048,
+	0x2b5a, 0xa484, 0xff00, 0x8007, 0xa0e2, 0x0020, 0x0048, 0x2b5a,
+	0xa502, 0x0048, 0x2b5a, 0xa484, 0x00ff, 0xa0e2, 0x0020, 0x0048,
+	0x2b5a, 0xa502, 0x0048, 0x2b5a, 0x2061, 0xa5a3, 0x6102, 0x6206,
+	0x630a, 0x640e, 0x0078, 0x2b2c, 0x007e, 0x2001, 0xa352, 0x2004,
+	0xd0cc, 0x007f, 0x007c, 0x007e, 0x2001, 0xa371, 0x2004, 0xd0bc,
+	0x007f, 0x007c, 0x6160, 0x7a24, 0x6300, 0x82ff, 0x00c0, 0x379b,
+	0x7926, 0x0078, 0x2b2c, 0x83ff, 0x00c0, 0x2b5a, 0x2001, 0xfff0,
+	0xa200, 0x00c8, 0x2b5a, 0x2019, 0xffff, 0x6064, 0xa302, 0xa200,
+	0x0048, 0x2b5a, 0x7926, 0x6262, 0x0078, 0x2b2c, 0x2001, 0xa300,
+	0x2004, 0xa086, 0x0003, 0x00c0, 0x2b56, 0x7c28, 0x7d24, 0x7e38,
+	0x7f2c, 0x1078, 0x3518, 0x0040, 0x2b56, 0x2009, 0x0000, 0x2019,
+	0x0000, 0x7023, 0x0000, 0x702f, 0x0000, 0xad80, 0x0003, 0x7026,
+	0x20a0, 0xa1e0, 0xa434, 0x2c64, 0x8cff, 0x0040, 0x37e8, 0x6004,
+	0xa084, 0x00ff, 0xa086, 0x0006, 0x0040, 0x37dd, 0x6004, 0xa084,
+	0xff00, 0xa086, 0x0600, 0x00c0, 0x37e8, 0x6014, 0x20a2, 0x94a0,
+	0x6010, 0x8007, 0xa105, 0x8007, 0x20a2, 0x94a0, 0xa398, 0x0002,
+	0x8108, 0xa182, 0x00ff, 0x0040, 0x37f3, 0xa386, 0x002a, 0x0040,
+	0x37fc, 0x0078, 0x37c9, 0x83ff, 0x00c0, 0x37fa, 0x7120, 0x810c,
+	0x0078, 0x2b2c, 0x702f, 0x0001, 0x711e, 0x7020, 0xa300, 0x7022,
+	0x2061, 0xa3d1, 0x6007, 0x0000, 0x6312, 0x7024, 0x600e, 0x6426,
+	0x652a, 0x662e, 0x6732, 0x2c10, 0x1078, 0x13d1, 0x7007, 0x0002,
+	0x701b, 0x3813, 0x007c, 0x702c, 0xa005, 0x00c0, 0x3824, 0x711c,
+	0x7024, 0x20a0, 0x2019, 0x0000, 0x2061, 0xa3d1, 0x6424, 0x6528,
+	0x662c, 0x6730, 0x0078, 0x37c9, 0x7120, 0x810c, 0x0078, 0x2b2c,
+	0x81ff, 0x00c0, 0x2b56, 0x60c8, 0xd09c, 0x0040, 0x2b56, 0x1078,
+	0x3518, 0x0040, 0x2b56, 0x7924, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38,
+	0x1078, 0x3562, 0x701b, 0x383d, 0x007c, 0x0d7e, 0xade8, 0x000d,
+	0x6828, 0xa0be, 0x7000, 0x0040, 0x3850, 0xa0be, 0x7100, 0x0040,
+	0x3850, 0xa0be, 0x7200, 0x0040, 0x3850, 0x0d7f, 0x0078, 0x2b5a,
+	0x6820, 0x6924, 0x1078, 0x24e3, 0x00c0, 0x387b, 0x1078, 0x4499,
+	0x00c0, 0x387b, 0x7122, 0x6612, 0x6516, 0x6e18, 0x0c7e, 0x1078,
+	0x3518, 0x0040, 0x387b, 0x1078, 0x3518, 0x0040, 0x387b, 0x0c7f,
+	0x0d7f, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x6823, 0x0000,
+	0x6804, 0x2068, 0x1078, 0x8bbd, 0x0040, 0x2b56, 0x7007, 0x0003,
+	0x701b, 0x387e, 0x007c, 0x0d7f, 0x0078, 0x2b56, 0x7120, 0x1078,
+	0x2921, 0x6820, 0xa086, 0x8001, 0x0040, 0x2b56, 0x2d00, 0x701e,
+	0x6804, 0xa080, 0x0002, 0x007e, 0x20a9, 0x002a, 0x2098, 0x20a0,
+	0x1078, 0x41be, 0x007f, 0xade8, 0x000d, 0x6a08, 0x6b0c, 0x6c10,
+	0x6d14, 0x2061, 0xa3d1, 0x6007, 0x0000, 0x6e00, 0x6f28, 0xa7c6,
+	0x7000, 0x00c0, 0x38a5, 0x0078, 0x38a9, 0xa7c6, 0x7100, 0x00c0,
+	0x38b1, 0xa6c2, 0x0004, 0x0048, 0x2b5a, 0x2009, 0x0004, 0x0078,
+	0x3566, 0xa7c6, 0x7200, 0x00c0, 0x2b5a, 0xa6c2, 0x0054, 0x0048,
+	0x2b5a, 0x600e, 0x6013, 0x002a, 0x6226, 0x632a, 0x642e, 0x6532,
+	0x2c10, 0x1078, 0x13d1, 0x7007, 0x0002, 0x701b, 0x38c8, 0x007c,
+	0x701c, 0x2068, 0x6804, 0xa080, 0x0001, 0x2004, 0xa080, 0x0002,
+	0x007e, 0x20a9, 0x002a, 0x2098, 0x20a0, 0x1078, 0x41be, 0x007f,
+	0x2009, 0x002a, 0x2061, 0xa3d1, 0x6224, 0x6328, 0x642c, 0x6530,
+	0x0078, 0x3566, 0x81ff, 0x00c0, 0x2b56, 0x1078, 0x3530, 0x0040,
+	0x2b5a, 0x1078, 0x45a7, 0x0040, 0x2b56, 0x1078, 0x4710, 0x0078,
+	0x2b2c, 0x7824, 0xd084, 0x0040, 0x3150, 0x1078, 0x3542, 0x0040,
+	0x2b5a, 0x0c7e, 0x1078, 0x3518, 0x0c7f, 0x00c0, 0x3903, 0x2009,
+	0x0002, 0x0078, 0x2b56, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006,
+	0x0040, 0x3910, 0xa08e, 0x0004, 0x0040, 0x3910, 0xa08e, 0x0005,
+	0x00c0, 0x3934, 0x2001, 0xa352, 0x2004, 0xd0b4, 0x0040, 0x3185,
+	0x6000, 0xd08c, 0x00c0, 0x3185, 0x6837, 0x0000, 0x6838, 0xc0fd,
+	0x683a, 0x1078, 0x8bd9, 0x00c0, 0x3929, 0x2009, 0x0003, 0x0078,
+	0x2b56, 0x7007, 0x0003, 0x701b, 0x392e, 0x007c, 0x1078, 0x3542,
+	0x0040, 0x2b5a, 0x0078, 0x3185, 0x2009, 0xa32e, 0x210c, 0x81ff,
+	0x0040, 0x393e, 0x2009, 0x0001, 0x0078, 0x2b56, 0x2001, 0xa300,
+	0x2004, 0xa086, 0x0003, 0x0040, 0x3949, 0x2009, 0x0007, 0x0078,
+	0x2b56, 0x2001, 0xa352, 0x2004, 0xd0ac, 0x0040, 0x3953, 0x2009,
+	0x0008, 0x0078, 0x2b56, 0x609c, 0xd0a4, 0x00c0, 0x395a, 0xd0ac,
+	0x00c0, 0x3185, 0x6837, 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd,
+	0x683a, 0x1078, 0x8c4d, 0x00c0, 0x3969, 0x2009, 0x0003, 0x0078,
+	0x2b56, 0x7007, 0x0003, 0x701b, 0x396e, 0x007c, 0x6830, 0xa086,
+	0x0100, 0x00c0, 0x3977, 0x2009, 0x0004, 0x0078, 0x2b56, 0x1078,
+	0x3542, 0x0040, 0x2b5a, 0x0078, 0x3912, 0x81ff, 0x2009, 0x0001,
+	0x00c0, 0x2b56, 0x6000, 0xa086, 0x0003, 0x2009, 0x0007, 0x00c0,
+	0x2b56, 0x2001, 0xa352, 0x2004, 0xd0ac, 0x2009, 0x0008, 0x00c0,
+	0x2b56, 0x1078, 0x3542, 0x0040, 0x2b5a, 0x6004, 0xa084, 0x00ff,
+	0xa086, 0x0006, 0x2009, 0x0009, 0x00c0, 0x2b56, 0x0c7e, 0x1078,
+	0x3518, 0x0c7f, 0x2009, 0x0002, 0x0040, 0x2b56, 0x6837, 0x0000,
+	0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x7928, 0xa194, 0xff00,
+	0xa18c, 0x00ff, 0xa006, 0x82ff, 0x00c0, 0x39bc, 0xc0ed, 0x6952,
+	0x792c, 0x6956, 0x0078, 0x39c5, 0xa28e, 0x0100, 0x00c0, 0x2b5a,
+	0xc0e5, 0x6853, 0x0000, 0x6857, 0x0000, 0x683e, 0x1078, 0x8df6,
+	0x2009, 0x0003, 0x0040, 0x2b56, 0x7007, 0x0003, 0x701b, 0x39d1,
+	0x007c, 0x6830, 0xa086, 0x0100, 0x2009, 0x0004, 0x0040, 0x2b56,
+	0x0078, 0x2b2c, 0x81ff, 0x2009, 0x0001, 0x00c0, 0x2b56, 0x6000,
+	0xa086, 0x0003, 0x2009, 0x0007, 0x00c0, 0x2b56, 0x1078, 0x3542,
+	0x0040, 0x2b5a, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x2009,
+	0x0009, 0x00c0, 0x2b56, 0x0c7e, 0x1078, 0x3518, 0x0c7f, 0x2009,
+	0x0002, 0x0040, 0x2b56, 0xad80, 0x000f, 0x2009, 0x0008, 0x7a2c,
+	0x7b28, 0x7c3c, 0x7d38, 0x1078, 0x3562, 0x701b, 0x3a08, 0x007c,
+	0x0d7e, 0xade8, 0x000f, 0x6800, 0xa086, 0x0500, 0x00c0, 0x3a1b,
+	0x6804, 0xa005, 0x00c0, 0x3a1b, 0x6808, 0xa084, 0xff00, 0x00c0,
+	0x3a1b, 0x0078, 0x3a1e, 0x0d7f, 0x00c0, 0x2b5a, 0x0d7f, 0x6837,
+	0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x0c7e, 0x1078,
+	0x3542, 0x00c0, 0x3a2e, 0x0c7f, 0x0078, 0x2b5a, 0x1078, 0x8e52,
+	0x2009, 0x0003, 0x0c7f, 0x0040, 0x2b56, 0x7007, 0x0003, 0x701b,
+	0x3a3a, 0x007c, 0x6830, 0xa086, 0x0100, 0x2009, 0x0004, 0x0040,
+	0x2b56, 0x0078, 0x2b2c, 0x127e, 0x0c7e, 0x0e7e, 0x2061, 0x0100,
+	0x2071, 0xa300, 0x6044, 0xd0a4, 0x00c0, 0x3a6c, 0xd084, 0x0040,
+	0x3a55, 0x1078, 0x3bcc, 0x0078, 0x3a68, 0xd08c, 0x0040, 0x3a5c,
+	0x1078, 0x3ae3, 0x0078, 0x3a68, 0xd094, 0x0040, 0x3a63, 0x1078,
+	0x3ab7, 0x0078, 0x3a68, 0xd09c, 0x0040, 0x3a68, 0x1078, 0x3a76,
+	0x0e7f, 0x0c7f, 0x127f, 0x007c, 0x017e, 0x6128, 0xd19c, 0x00c0,
+	0x3a73, 0xc19d, 0x612a, 0x017f, 0x0078, 0x3a68, 0x624c, 0xa286,
+	0xf0f0, 0x00c0, 0x3a87, 0x6048, 0xa086, 0xf0f0, 0x0040, 0x3a87,
+	0x624a, 0x6043, 0x0090, 0x6043, 0x0010, 0x0078, 0x3ab6, 0xa294,
+	0xff00, 0xa296, 0xf700, 0x0040, 0x3a9c, 0x7134, 0xd1a4, 0x00c0,
+	0x3a9c, 0x6240, 0xa294, 0x0010, 0x0040, 0x3a9c, 0x2009, 0x00f7,
+	0x1078, 0x41de, 0x0078, 0x3ab6, 0x6043, 0x0040, 0x6043, 0x0000,
+	0x7073, 0x0000, 0x708b, 0x0001, 0x70af, 0x0000, 0x70cb, 0x0000,
+	0x2009, 0xa9c0, 0x200b, 0x0000, 0x7083, 0x0000, 0x7077, 0x000f,
+	0x2009, 0x000f, 0x2011, 0x4122, 0x1078, 0x596c, 0x007c, 0x157e,
+	0x7074, 0xa005, 0x00c0, 0x3ae1, 0x2011, 0x4122, 0x1078, 0x58d4,
+	0x6040, 0xa094, 0x0010, 0xa285, 0x0020, 0x6042, 0x20a9, 0x00c8,
+	0x6044, 0xd08c, 0x00c0, 0x3ada, 0x00f0, 0x3ac8, 0x6242, 0x7087,
+	0x0000, 0x6040, 0xa094, 0x0010, 0xa285, 0x0080, 0x6042, 0x6242,
+	0x0078, 0x3ae1, 0x6242, 0x7087, 0x0000, 0x707b, 0x0000, 0x0078,
+	0x3ae1, 0x157f, 0x007c, 0x7078, 0xa08a, 0x0003, 0x00c8, 0x3aec,
+	0x1079, 0x3aef, 0x0078, 0x3aee, 0x1078, 0x1328, 0x007c, 0x3af2,
+	0x3b41, 0x3bcb, 0x0f7e, 0x707b, 0x0001, 0x20e1, 0xa000, 0x20e1,
+	0x8700, 0x1078, 0x218b, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2079,
+	0xa800, 0x207b, 0x2200, 0x7807, 0x00ef, 0x780b, 0x0000, 0x780f,
+	0x00ef, 0x7813, 0x0138, 0x7817, 0x0000, 0x781b, 0x0000, 0x781f,
+	0x0000, 0x7823, 0xffff, 0x7827, 0xffff, 0x782b, 0x0000, 0x782f,
+	0x0000, 0x2079, 0xa80c, 0x207b, 0x1101, 0x7807, 0x0000, 0x2099,
+	0xa305, 0x20a1, 0xa80e, 0x20a9, 0x0004, 0x53a3, 0x2079, 0xa812,
+	0x207b, 0x0000, 0x7807, 0x0000, 0x2099, 0xa800, 0x20a1, 0x020b,
+	0x20a9, 0x0014, 0x53a6, 0x60c3, 0x000c, 0x600f, 0x0000, 0x1078,
+	0x4158, 0x0f7f, 0x707f, 0x0000, 0x6043, 0x0008, 0x6043, 0x0000,
+	0x007c, 0x0d7e, 0x707c, 0x707f, 0x0000, 0xa025, 0x0040, 0x3bb5,
+	0x6020, 0xd0b4, 0x00c0, 0x3bb3, 0x7188, 0x81ff, 0x0040, 0x3ba2,
+	0xa486, 0x000c, 0x00c0, 0x3bad, 0xa480, 0x0018, 0x8004, 0x20a8,
+	0x2011, 0xa880, 0x2019, 0xa800, 0x220c, 0x2304, 0xa106, 0x00c0,
+	0x3b79, 0x8210, 0x8318, 0x00f0, 0x3b5c, 0x6043, 0x0004, 0x608b,
+	0xbc94, 0x608f, 0xf0f0, 0x6043, 0x0006, 0x707b, 0x0002, 0x7087,
+	0x0002, 0x2009, 0x07d0, 0x2011, 0x4129, 0x1078, 0x596c, 0x0078,
+	0x3bb3, 0x2069, 0xa880, 0x6930, 0xa18e, 0x1101, 0x00c0, 0x3bad,
+	0x6834, 0xa005, 0x00c0, 0x3bad, 0x6900, 0xa18c, 0x00ff, 0x00c0,
+	0x3b8d, 0x6804, 0xa005, 0x0040, 0x3ba2, 0x2011, 0xa88e, 0x2019,
+	0xa305, 0x20a9, 0x0004, 0x220c, 0x2304, 0xa102, 0x0048, 0x3ba0,
+	0x00c0, 0x3bad, 0x8210, 0x8318, 0x00f0, 0x3b93, 0x0078, 0x3bad,
+	0x708b, 0x0000, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xa880,
+	0x20a1, 0x020b, 0x20a9, 0x0014, 0x53a6, 0x6043, 0x0008, 0x6043,
+	0x0000, 0x0078, 0x3bb5, 0x0d7f, 0x007c, 0x6020, 0xd0b4, 0x00c0,
+	0x3bb3, 0x60c3, 0x000c, 0x2011, 0xa5b5, 0x2013, 0x0000, 0x707f,
+	0x0000, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x1078,
+	0x6c38, 0x0078, 0x3bb3, 0x007c, 0x7084, 0xa08a, 0x001d, 0x00c8,
+	0x3bd5, 0x1079, 0x3bd8, 0x0078, 0x3bd7, 0x1078, 0x1328, 0x007c,
+	0x3c02, 0x3c11, 0x3c40, 0x3c59, 0x3c85, 0x3cb1, 0x3cdd, 0x3d13,
+	0x3d3f, 0x3d67, 0x3daa, 0x3dd4, 0x3df6, 0x3e0c, 0x3e32, 0x3e45,
+	0x3e4e, 0x3e7e, 0x3eaa, 0x3ed6, 0x3f02, 0x3f38, 0x3f7d, 0x3fac,
+	0x3fce, 0x4010, 0x4036, 0x404f, 0x4050, 0x0c7e, 0x2061, 0xa300,
+	0x6003, 0x0007, 0x2061, 0x0100, 0x6004, 0xa084, 0xfff9, 0x6006,
+	0x0c7f, 0x007c, 0x608b, 0xbc94, 0x608f, 0xf0f0, 0x6043, 0x0002,
+	0x7087, 0x0001, 0x2009, 0x07d0, 0x2011, 0x4129, 0x1078, 0x596c,
+	0x007c, 0x0f7e, 0x707c, 0xa086, 0x0014, 0x00c0, 0x3c3e, 0x6043,
+	0x0000, 0x6020, 0xd0b4, 0x00c0, 0x3c3e, 0x2079, 0xa880, 0x7a30,
+	0xa296, 0x1102, 0x00c0, 0x3c3c, 0x7834, 0xa005, 0x00c0, 0x3c3c,
+	0x7a38, 0xd2fc, 0x0040, 0x3c32, 0x70ac, 0xa005, 0x00c0, 0x3c32,
+	0x70af, 0x0001, 0x2011, 0x4129, 0x1078, 0x58d4, 0x7087, 0x0010,
+	0x1078, 0x3e4e, 0x0078, 0x3c3e, 0x1078, 0x4171, 0x0f7f, 0x007c,
+	0x7087, 0x0003, 0x6043, 0x0004, 0x2011, 0x4129, 0x1078, 0x58d4,
+	0x1078, 0x41c6, 0x20a3, 0x1102, 0x20a3, 0x0000, 0x20a9, 0x000a,
+	0x20a3, 0x0000, 0x00f0, 0x3c50, 0x60c3, 0x0014, 0x1078, 0x4158,
+	0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040, 0x3c83, 0x2011, 0x4129,
+	0x1078, 0x58d4, 0xa086, 0x0014, 0x00c0, 0x3c81, 0x2079, 0xa880,
+	0x7a30, 0xa296, 0x1102, 0x00c0, 0x3c81, 0x7834, 0xa005, 0x00c0,
+	0x3c81, 0x7a38, 0xd2fc, 0x0040, 0x3c7b, 0x70ac, 0xa005, 0x00c0,
+	0x3c7b, 0x70af, 0x0001, 0x7087, 0x0004, 0x1078, 0x3c85, 0x0078,
+	0x3c83, 0x1078, 0x4171, 0x0f7f, 0x007c, 0x7087, 0x0005, 0x1078,
+	0x41c6, 0x20a3, 0x1103, 0x20a3, 0x0000, 0x3430, 0x2011, 0xa88e,
+	0x1078, 0x4211, 0x00c0, 0x3ca3, 0x7070, 0xa005, 0x00c0, 0x3ca3,
+	0x714c, 0xa186, 0xffff, 0x0040, 0x3ca3, 0x1078, 0x40ea, 0x0040,
+	0x3ca3, 0x1078, 0x41f5, 0x20a9, 0x0008, 0x2298, 0x26a0, 0x53a6,
+	0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, 0x4158,
+	0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040, 0x3cdb, 0x2011, 0x4129,
+	0x1078, 0x58d4, 0xa086, 0x0014, 0x00c0, 0x3cd9, 0x2079, 0xa880,
+	0x7a30, 0xa296, 0x1103, 0x00c0, 0x3cd9, 0x7834, 0xa005, 0x00c0,
+	0x3cd9, 0x7a38, 0xd2fc, 0x0040, 0x3cd3, 0x70ac, 0xa005, 0x00c0,
+	0x3cd3, 0x70af, 0x0001, 0x7087, 0x0006, 0x1078, 0x3cdd, 0x0078,
+	0x3cdb, 0x1078, 0x4171, 0x0f7f, 0x007c, 0x7087, 0x0007, 0x1078,
+	0x41c6, 0x20a3, 0x1104, 0x20a3, 0x0000, 0x3430, 0x2011, 0xa88e,
+	0x1078, 0x4211, 0x00c0, 0x3d05, 0x7070, 0xa005, 0x00c0, 0x3d05,
+	0x7150, 0xa186, 0xffff, 0x0040, 0x3d05, 0xa180, 0x293f, 0x200c,
+	0xa18c, 0xff00, 0x810f, 0x1078, 0x40ea, 0x0040, 0x3d05, 0x1078,
+	0x378b, 0x0040, 0x3d05, 0x1078, 0x2500, 0x20a9, 0x0008, 0x2298,
+	0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014,
+	0x1078, 0x4158, 0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040, 0x3d3d,
+	0x2011, 0x4129, 0x1078, 0x58d4, 0xa086, 0x0014, 0x00c0, 0x3d3b,
+	0x2079, 0xa880, 0x7a30, 0xa296, 0x1104, 0x00c0, 0x3d3b, 0x7834,
+	0xa005, 0x00c0, 0x3d3b, 0x7a38, 0xd2fc, 0x0040, 0x3d35, 0x70ac,
+	0xa005, 0x00c0, 0x3d35, 0x70af, 0x0001, 0x7087, 0x0008, 0x1078,
+	0x3d3f, 0x0078, 0x3d3d, 0x1078, 0x4171, 0x0f7f, 0x007c, 0x7087,
+	0x0009, 0x1078, 0x41c6, 0x20a3, 0x1105, 0x20a3, 0x0100, 0x3430,
+	0x1078, 0x4211, 0x00c0, 0x3d58, 0x7070, 0xa005, 0x00c0, 0x3d58,
+	0x1078, 0x4051, 0x00c0, 0x3d62, 0xa085, 0x0001, 0x1078, 0x2500,
+	0x20a9, 0x0008, 0x2099, 0xa88e, 0x26a0, 0x53a6, 0x20a3, 0x0000,
+	0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, 0x4158, 0x007c, 0x0f7e,
+	0x707c, 0xa005, 0x0040, 0x3da8, 0x2011, 0x4129, 0x1078, 0x58d4,
+	0xa086, 0x0014, 0x00c0, 0x3da6, 0x2079, 0xa880, 0x7a30, 0xa296,
+	0x1105, 0x00c0, 0x3da6, 0x7834, 0x2011, 0x0100, 0xa21e, 0x00c0,
+	0x3d91, 0x7a38, 0xd2fc, 0x0040, 0x3d8b, 0x70ac, 0xa005, 0x00c0,
+	0x3d8b, 0x70af, 0x0001, 0x7087, 0x000a, 0x1078, 0x3daa, 0x0078,
+	0x3da8, 0xa005, 0x00c0, 0x3da6, 0x7a38, 0xd2fc, 0x0040, 0x3d9e,
+	0x70ac, 0xa005, 0x00c0, 0x3d9e, 0x70af, 0x0001, 0x7083, 0x0000,
+	0x7087, 0x000e, 0x1078, 0x3e32, 0x0078, 0x3da8, 0x1078, 0x4171,
+	0x0f7f, 0x007c, 0x7087, 0x000b, 0x2011, 0xa80e, 0x22a0, 0x20a9,
+	0x0040, 0x2019, 0xffff, 0x43a4, 0x20a9, 0x0002, 0x2009, 0x0000,
+	0x41a4, 0x1078, 0x41c6, 0x20a3, 0x1106, 0x20a3, 0x0000, 0x1078,
+	0x4211, 0x0040, 0x3dc7, 0x2013, 0x0000, 0x0078, 0x3dcb, 0x6030,
+	0xa085, 0x0100, 0x2012, 0x2298, 0x20a9, 0x0042, 0x53a6, 0x60c3,
+	0x0084, 0x1078, 0x4158, 0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040,
+	0x3df4, 0x2011, 0x4129, 0x1078, 0x58d4, 0xa086, 0x0084, 0x00c0,
+	0x3df2, 0x2079, 0xa880, 0x7a30, 0xa296, 0x1106, 0x00c0, 0x3df2,
+	0x7834, 0xa005, 0x00c0, 0x3df2, 0x7087, 0x000c, 0x1078, 0x3df6,
+	0x0078, 0x3df4, 0x1078, 0x4171, 0x0f7f, 0x007c, 0x7087, 0x000d,
+	0x1078, 0x41c6, 0x20a3, 0x1107, 0x20a3, 0x0000, 0x2099, 0xa88e,
+	0x20a9, 0x0040, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3,
+	0x0084, 0x1078, 0x4158, 0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040,
+	0x3e30, 0x2011, 0x4129, 0x1078, 0x58d4, 0xa086, 0x0084, 0x00c0,
+	0x3e2e, 0x2079, 0xa880, 0x7a30, 0xa296, 0x1107, 0x00c0, 0x3e2e,
+	0x7834, 0xa005, 0x00c0, 0x3e2e, 0x7083, 0x0001, 0x1078, 0x41b8,
+	0x7087, 0x000e, 0x1078, 0x3e32, 0x0078, 0x3e30, 0x1078, 0x4171,
+	0x0f7f, 0x007c, 0x7087, 0x000f, 0x707f, 0x0000, 0x608b, 0xbc85,
+	0x608f, 0xb5b5, 0x6043, 0x0005, 0x6043, 0x0004, 0x2009, 0x07d0,
+	0x2011, 0x4129, 0x1078, 0x58c7, 0x007c, 0x707c, 0xa005, 0x0040,
+	0x3e4d, 0x2011, 0x4129, 0x1078, 0x58d4, 0x007c, 0x7087, 0x0011,
+	0x1078, 0x4211, 0x00c0, 0x3e67, 0x7168, 0x81ff, 0x0040, 0x3e67,
+	0x2009, 0x0000, 0x706c, 0xa084, 0x00ff, 0x1078, 0x24e3, 0xa186,
+	0x0080, 0x0040, 0x3e67, 0x2011, 0xa88e, 0x1078, 0x40ea, 0x20e1,
+	0x9080, 0x20e1, 0x4000, 0x2099, 0xa880, 0x20a1, 0x020b, 0x747c,
+	0xa480, 0x0018, 0xa080, 0x0007, 0xa084, 0x03f8, 0x8004, 0x20a8,
+	0x53a6, 0x60c3, 0x0014, 0x1078, 0x4158, 0x007c, 0x0f7e, 0x707c,
+	0xa005, 0x0040, 0x3ea8, 0x2011, 0x4129, 0x1078, 0x58d4, 0xa086,
+	0x0014, 0x00c0, 0x3ea6, 0x2079, 0xa880, 0x7a30, 0xa296, 0x1103,
+	0x00c0, 0x3ea6, 0x7834, 0xa005, 0x00c0, 0x3ea6, 0x7a38, 0xd2fc,
+	0x0040, 0x3ea0, 0x70ac, 0xa005, 0x00c0, 0x3ea0, 0x70af, 0x0001,
+	0x7087, 0x0012, 0x1078, 0x3eaa, 0x0078, 0x3ea8, 0x1078, 0x4171,
+	0x0f7f, 0x007c, 0x7087, 0x0013, 0x1078, 0x41d2, 0x20a3, 0x1103,
+	0x20a3, 0x0000, 0x3430, 0x2011, 0xa88e, 0x1078, 0x4211, 0x00c0,
+	0x3ec8, 0x7070, 0xa005, 0x00c0, 0x3ec8, 0x714c, 0xa186, 0xffff,
+	0x0040, 0x3ec8, 0x1078, 0x40ea, 0x0040, 0x3ec8, 0x1078, 0x41f5,
+	0x20a9, 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3,
+	0x0000, 0x60c3, 0x0014, 0x1078, 0x4158, 0x007c, 0x0f7e, 0x707c,
+	0xa005, 0x0040, 0x3f00, 0x2011, 0x4129, 0x1078, 0x58d4, 0xa086,
+	0x0014, 0x00c0, 0x3efe, 0x2079, 0xa880, 0x7a30, 0xa296, 0x1104,
+	0x00c0, 0x3efe, 0x7834, 0xa005, 0x00c0, 0x3efe, 0x7a38, 0xd2fc,
+	0x0040, 0x3ef8, 0x70ac, 0xa005, 0x00c0, 0x3ef8, 0x70af, 0x0001,
+	0x7087, 0x0014, 0x1078, 0x3f02, 0x0078, 0x3f00, 0x1078, 0x4171,
+	0x0f7f, 0x007c, 0x7087, 0x0015, 0x1078, 0x41d2, 0x20a3, 0x1104,
+	0x20a3, 0x0000, 0x3430, 0x2011, 0xa88e, 0x1078, 0x4211, 0x00c0,
+	0x3f2a, 0x7070, 0xa005, 0x00c0, 0x3f2a, 0x7150, 0xa186, 0xffff,
+	0x0040, 0x3f2a, 0xa180, 0x293f, 0x200c, 0xa18c, 0xff00, 0x810f,
+	0x1078, 0x40ea, 0x0040, 0x3f2a, 0x1078, 0x378b, 0x0040, 0x3f2a,
+	0x1078, 0x2500, 0x20a9, 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3,
+	0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, 0x4158, 0x007c,
+	0x0f7e, 0x707c, 0xa005, 0x0040, 0x3f7b, 0x2011, 0x4129, 0x1078,
+	0x58d4, 0xa086, 0x0014, 0x00c0, 0x3f79, 0x2079, 0xa880, 0x7a30,
+	0xa296, 0x1105, 0x00c0, 0x3f79, 0x7834, 0x2011, 0x0100, 0xa21e,
+	0x00c0, 0x3f5e, 0x7a38, 0xd2fc, 0x0040, 0x3f5c, 0x70ac, 0xa005,
+	0x00c0, 0x3f5c, 0x70af, 0x0001, 0x0078, 0x3f6d, 0xa005, 0x00c0,
+	0x3f79, 0x7a38, 0xd2fc, 0x0040, 0x3f6b, 0x70ac, 0xa005, 0x00c0,
+	0x3f6b, 0x70af, 0x0001, 0x7083, 0x0000, 0x7a38, 0xd2f4, 0x0040,
+	0x3f73, 0x70cb, 0x0008, 0x7087, 0x0016, 0x1078, 0x3f7d, 0x0078,
+	0x3f7b, 0x1078, 0x4171, 0x0f7f, 0x007c, 0x20e1, 0x9080, 0x20e1,
+	0x4000, 0x2099, 0xa880, 0x20a1, 0x020b, 0x20a9, 0x000e, 0x53a6,
+	0x3430, 0x2011, 0xa88e, 0x7087, 0x0017, 0x1078, 0x4211, 0x00c0,
+	0x3f9d, 0x7070, 0xa005, 0x00c0, 0x3f9d, 0x1078, 0x4051, 0x00c0,
+	0x3fa7, 0xa085, 0x0001, 0x1078, 0x2500, 0x20a9, 0x0008, 0x2099,
+	0xa88e, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3,
+	0x0014, 0x1078, 0x4158, 0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040,
+	0x3fcc, 0x2011, 0x4129, 0x1078, 0x58d4, 0xa086, 0x0084, 0x00c0,
+	0x3fca, 0x2079, 0xa880, 0x7a30, 0xa296, 0x1106, 0x00c0, 0x3fca,
+	0x7834, 0xa005, 0x00c0, 0x3fca, 0x7087, 0x0018, 0x1078, 0x3fce,
+	0x0078, 0x3fcc, 0x1078, 0x4171, 0x0f7f, 0x007c, 0x7087, 0x0019,
+	0x1078, 0x41d2, 0x20a3, 0x1106, 0x20a3, 0x0000, 0x3430, 0x2099,
+	0xa88e, 0x2039, 0xa80e, 0x27a0, 0x20a9, 0x0040, 0x53a3, 0x1078,
+	0x4211, 0x00c0, 0x4002, 0x2728, 0x2514, 0x8207, 0xa084, 0x00ff,
+	0x8000, 0x2018, 0xa294, 0x00ff, 0x8007, 0xa205, 0x202a, 0x6030,
+	0x2310, 0x8214, 0xa2a0, 0xa80e, 0x2414, 0xa38c, 0x0001, 0x0040,
+	0x3ffd, 0xa294, 0xff00, 0x0078, 0x4000, 0xa294, 0x00ff, 0x8007,
+	0xa215, 0x2222, 0x2798, 0x26a0, 0x20a9, 0x0040, 0x53a6, 0x20a3,
+	0x0000, 0x20a3, 0x0000, 0x60c3, 0x0084, 0x1078, 0x4158, 0x007c,
+	0x0f7e, 0x707c, 0xa005, 0x0040, 0x4034, 0x2011, 0x4129, 0x1078,
+	0x58d4, 0xa086, 0x0084, 0x00c0, 0x4032, 0x2079, 0xa880, 0x7a30,
+	0xa296, 0x1107, 0x00c0, 0x4032, 0x7834, 0xa005, 0x00c0, 0x4032,
+	0x7083, 0x0001, 0x1078, 0x41b8, 0x7087, 0x001a, 0x1078, 0x4036,
+	0x0078, 0x4034, 0x1078, 0x4171, 0x0f7f, 0x007c, 0x7087, 0x001b,
+	0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xa880, 0x20a1, 0x020b,
+	0x747c, 0xa480, 0x0018, 0xa080, 0x0007, 0xa084, 0x03f8, 0x8004,
+	0x20a8, 0x53a6, 0x60c3, 0x0084, 0x1078, 0x4158, 0x007c, 0x007c,
+	0x007c, 0x087e, 0x097e, 0x2029, 0xa352, 0x252c, 0x20a9, 0x0008,
+	0x2041, 0xa80e, 0x28a0, 0x2099, 0xa88e, 0x53a3, 0x20a9, 0x0008,
+	0x2011, 0x0007, 0xd5d4, 0x0040, 0x4067, 0x2011, 0x0000, 0x2800,
+	0xa200, 0x200c, 0xa1a6, 0xffff, 0x00c0, 0x4079, 0xd5d4, 0x0040,
+	0x4074, 0x8210, 0x0078, 0x4075, 0x8211, 0x00f0, 0x4067, 0x0078,
+	0x40e1, 0x82ff, 0x00c0, 0x408b, 0xd5d4, 0x0040, 0x4085, 0xa1a6,
+	0x3fff, 0x0040, 0x4071, 0x0078, 0x4089, 0xa1a6, 0x3fff, 0x0040,
+	0x40e1, 0xa18d, 0xc000, 0x20a9, 0x0010, 0x2019, 0x0001, 0xd5d4,
+	0x0040, 0x4094, 0x2019, 0x0010, 0x2120, 0xd5d4, 0x0040, 0x409b,
+	0x8423, 0x0078, 0x409c, 0x8424, 0x00c8, 0x40a9, 0xd5d4, 0x0040,
+	0x40a4, 0x8319, 0x0078, 0x40a5, 0x8318, 0x00f0, 0x4095, 0x0078,
+	0x40e1, 0x23a8, 0x2021, 0x0001, 0x8426, 0x8425, 0x00f0, 0x40ad,
+	0x2328, 0x8529, 0xa2be, 0x0007, 0x0040, 0x40c1, 0x007e, 0x2039,
+	0x0007, 0x2200, 0xa73a, 0x007f, 0x27a8, 0xa5a8, 0x0010, 0x00f0,
+	0x40bd, 0x754e, 0xa5c8, 0x293f, 0x292c, 0xa5ac, 0x00ff, 0x6532,
+	0x60e7, 0x0000, 0x65ea, 0x706b, 0x0000, 0x756e, 0x2018, 0x2304,
+	0xa405, 0x201a, 0x7073, 0x0001, 0x26a0, 0x2898, 0x20a9, 0x0008,
+	0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0xa085, 0x0001, 0x0078,
+	0x40e7, 0xa006, 0x0078, 0x40e7, 0xa006, 0x1078, 0x1328, 0x097f,
+	0x087f, 0x007c, 0x2118, 0x2021, 0x0000, 0x2001, 0x0007, 0xa39a,
+	0x0010, 0x0048, 0x40f7, 0x8420, 0x8001, 0x0078, 0x40ef, 0x2118,
+	0x84ff, 0x0040, 0x4100, 0xa39a, 0x0010, 0x8421, 0x00c0, 0x40fb,
+	0x2021, 0x0001, 0x83ff, 0x0040, 0x4109, 0x8423, 0x8319, 0x00c0,
+	0x4105, 0xa238, 0x2704, 0xa42c, 0x00c0, 0x4121, 0xa405, 0x203a,
+	0x714e, 0xa1a0, 0x293f, 0x242c, 0xa5ac, 0x00ff, 0x6532, 0x60e7,
+	0x0000, 0x65ea, 0x706b, 0x0000, 0x756e, 0x7073, 0x0001, 0xa084,
+	0x0000, 0x007c, 0x0e7e, 0x2071, 0xa300, 0x7077, 0x0000, 0x0e7f,
+	0x007c, 0x0e7e, 0x0f7e, 0x2001, 0x0002, 0x1078, 0x5975, 0x2079,
+	0x0100, 0x2071, 0x0140, 0x1078, 0x6c41, 0x7004, 0xa084, 0x4000,
+	0x0040, 0x413e, 0x7003, 0x1000, 0x7003, 0x0000, 0x127e, 0x2091,
+	0x8000, 0x2071, 0xa321, 0x2073, 0x0000, 0x7840, 0x027e, 0x017e,
+	0x2009, 0x00f7, 0x1078, 0x41de, 0x017f, 0xa094, 0x0010, 0xa285,
+	0x0080, 0x7842, 0x7a42, 0x027f, 0x127f, 0x0f7f, 0x0e7f, 0x007c,
+	0x127e, 0x2091, 0x8000, 0x2011, 0xa5b5, 0x2013, 0x0000, 0x707f,
+	0x0000, 0x127f, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575,
+	0x1078, 0x6c38, 0x2009, 0x07d0, 0x2011, 0x4129, 0x1078, 0x596c,
+	0x007c, 0x017e, 0x027e, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x2009,
+	0x00f7, 0x1078, 0x41de, 0x2061, 0xa5be, 0x601b, 0x0000, 0x601f,
+	0x0000, 0x2061, 0xa300, 0x6003, 0x0001, 0x2061, 0x0100, 0x6043,
+	0x0090, 0x6043, 0x0010, 0x2009, 0x002d, 0x2011, 0x4196, 0x1078,
+	0x58c7, 0x127f, 0x0c7f, 0x027f, 0x017f, 0x007c, 0x0e7e, 0x007e,
+	0x127e, 0x2091, 0x8000, 0x2001, 0x0001, 0x1078, 0x5975, 0x2071,
+	0x0100, 0x1078, 0x6c41, 0x2071, 0x0140, 0x7004, 0xa084, 0x4000,
+	0x0040, 0x41ae, 0x7003, 0x1000, 0x7003, 0x0000, 0x2001, 0x0001,
+	0x1078, 0x2480, 0x1078, 0x4171, 0x127f, 0x007f, 0x0e7f, 0x007c,
+	0x20a9, 0x0040, 0x20a1, 0xa9c0, 0x2099, 0xa88e, 0x3304, 0x8007,
+	0x20a2, 0x9398, 0x94a0, 0x00f0, 0x41be, 0x007c, 0x20e1, 0x9080,
+	0x20e1, 0x4000, 0x2099, 0xa800, 0x20a1, 0x020b, 0x20a9, 0x000c,
+	0x53a6, 0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xa880,
+	0x20a1, 0x020b, 0x20a9, 0x000c, 0x53a6, 0x007c, 0x0c7e, 0x007e,
+	0x2061, 0x0100, 0x810f, 0x2001, 0xa32e, 0x2004, 0xa005, 0x00c0,
+	0x41ef, 0x6030, 0xa084, 0x00ff, 0xa105, 0x0078, 0x41f1, 0xa185,
+	0x00f7, 0x604a, 0x007f, 0x0c7f, 0x007c, 0x017e, 0x047e, 0x2001,
+	0xa352, 0x2004, 0xd0a4, 0x0040, 0x4208, 0xa006, 0x2020, 0x2009,
+	0x002a, 0x1078, 0x9ec0, 0x2001, 0xa30c, 0x200c, 0xc195, 0x2102,
+	0x2019, 0x002a, 0x2009, 0x0000, 0x1078, 0x27e2, 0x047f, 0x017f,
+	0x007c, 0x007e, 0x2001, 0xa30c, 0x2004, 0xd09c, 0x0040, 0x4218,
+	0x007f, 0x007c, 0x007e, 0x017e, 0x127e, 0x2091, 0x8000, 0x2001,
+	0x0101, 0x200c, 0xa18d, 0x0006, 0x2102, 0x127f, 0x017f, 0x007f,
+	0x007c, 0x157e, 0x20a9, 0x00ff, 0x2009, 0xa434, 0xa006, 0x200a,
+	0x8108, 0x00f0, 0x422f, 0x157f, 0x007c, 0x0d7e, 0x037e, 0x157e,
+	0x137e, 0x147e, 0x2069, 0xa351, 0xa006, 0x6002, 0x6007, 0x0707,
+	0x600a, 0x600e, 0x6012, 0xa198, 0x293f, 0x231c, 0xa39c, 0x00ff,
+	0x6316, 0x20a9, 0x0004, 0xac98, 0x0006, 0x23a0, 0x40a4, 0x20a9,
+	0x0004, 0xac98, 0x000a, 0x23a0, 0x40a4, 0x603e, 0x6042, 0x604e,
+	0x6052, 0x6056, 0x605a, 0x605e, 0x6062, 0x6066, 0x606a, 0x606e,
+	0x6072, 0x6076, 0x607a, 0x607e, 0x6082, 0x6086, 0x608a, 0x608e,
+	0x6092, 0x6096, 0x609a, 0x609e, 0x60ae, 0x61a2, 0x0d7e, 0x60a4,
+	0xa06d, 0x0040, 0x4275, 0x1078, 0x139a, 0x60a7, 0x0000, 0x60a8,
+	0xa06d, 0x0040, 0x427d, 0x1078, 0x139a, 0x60ab, 0x0000, 0x0d7f,
+	0xa006, 0x604a, 0x6810, 0x603a, 0x680c, 0x6046, 0x6814, 0xa084,
+	0x00ff, 0x6042, 0x147f, 0x137f, 0x157f, 0x037f, 0x0d7f, 0x007c,
+	0x127e, 0x2091, 0x8000, 0x6944, 0x6e48, 0xa684, 0x3fff, 0xa082,
+	0x4000, 0x00c8, 0x4361, 0xa18c, 0xff00, 0x810f, 0xa182, 0x00ff,
+	0x00c8, 0x4367, 0x2001, 0xa30c, 0x2004, 0xa084, 0x0003, 0x0040,
+	0x42c2, 0x2001, 0xa30c, 0x2004, 0xd084, 0x00c0, 0x4342, 0xa188,
+	0xa434, 0x2104, 0xa065, 0x0040, 0x4342, 0x6004, 0xa084, 0x00ff,
+	0xa08e, 0x0006, 0x00c0, 0x4342, 0x6000, 0xd0c4, 0x0040, 0x4342,
+	0x0078, 0x42cf, 0xa188, 0xa434, 0x2104, 0xa065, 0x0040, 0x4326,
+	0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, 0x00c0, 0x432c, 0x60a4,
+	0xa00d, 0x0040, 0x42d7, 0x1078, 0x4749, 0x0040, 0x4320, 0x60a8,
+	0xa00d, 0x0040, 0x42f1, 0x1078, 0x479a, 0x00c0, 0x42f1, 0x694c,
+	0xd1fc, 0x00c0, 0x42e7, 0x1078, 0x441c, 0x0078, 0x431b, 0x1078,
+	0x43d6, 0x694c, 0xd1ec, 0x00c0, 0x431b, 0x1078, 0x460a, 0x0078,
+	0x431b, 0x694c, 0xa184, 0xa000, 0x0040, 0x430b, 0xd1ec, 0x0040,
+	0x4304, 0xd1fc, 0x0040, 0x4300, 0x1078, 0x461b, 0x0078, 0x4307,
+	0x1078, 0x461b, 0x0078, 0x430b, 0xd1fc, 0x0040, 0x430b, 0x1078,
+	0x43d6, 0x0078, 0x431b, 0x6050, 0xa00d, 0x0040, 0x4316, 0x2d00,
+	0x200a, 0x6803, 0x0000, 0x6052, 0x0078, 0x431b, 0x2d00, 0x6052,
+	0x604e, 0x6803, 0x0000, 0x1078, 0x5c17, 0xa006, 0x127f, 0x007c,
+	0x2001, 0x0005, 0x2009, 0x0000, 0x0078, 0x436b, 0x2001, 0x0028,
+	0x2009, 0x0000, 0x0078, 0x436b, 0xa082, 0x0006, 0x00c8, 0x4342,
+	0x60a0, 0xd0bc, 0x00c0, 0x433e, 0x6100, 0xd1fc, 0x0040, 0x42cf,
+	0x2001, 0x0029, 0x2009, 0x1000, 0x0078, 0x436b, 0x2001, 0x0028,
+	0x0078, 0x435d, 0x2009, 0xa30c, 0x210c, 0xd18c, 0x0040, 0x434c,
+	0x2001, 0x0004, 0x0078, 0x435d, 0xd184, 0x0040, 0x4353, 0x2001,
+	0x0004, 0x0078, 0x435d, 0x2001, 0x0029, 0x6100, 0xd1fc, 0x0040,
+	0x435d, 0x2009, 0x1000, 0x0078, 0x436b, 0x2009, 0x0000, 0x0078,
+	0x436b, 0x2001, 0x0029, 0x2009, 0x0000, 0x0078, 0x436b, 0x2001,
+	0x0029, 0x2009, 0x0000, 0xa005, 0x127f, 0x007c, 0x6944, 0x6e48,
+	0xa684, 0x3fff, 0xa082, 0x4000, 0x00c8, 0x43bb, 0xa18c, 0xff00,
+	0x810f, 0xa182, 0x00ff, 0x00c8, 0x43a1, 0xa188, 0xa434, 0x2104,
+	0xa065, 0x0040, 0x43a1, 0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006,
+	0x00c0, 0x43a7, 0x684c, 0xd0ec, 0x0040, 0x4394, 0x1078, 0x461b,
+	0x1078, 0x43d6, 0x0078, 0x439c, 0x1078, 0x43d6, 0x684c, 0xd0fc,
+	0x0040, 0x439c, 0x1078, 0x460a, 0x1078, 0x4663, 0xa006, 0x0078,
+	0x43bf, 0x2001, 0x0028, 0x2009, 0x0000, 0x0078, 0x43bf, 0xa082,
+	0x0006, 0x00c8, 0x43b5, 0x6100, 0xd1fc, 0x0040, 0x438a, 0x2001,
+	0x0029, 0x2009, 0x1000, 0x0078, 0x43bf, 0x2001, 0x0029, 0x2009,
+	0x0000, 0x0078, 0x43bf, 0x2001, 0x0029, 0x2009, 0x0000, 0xa005,
+	0x007c, 0x127e, 0x2091, 0x8000, 0x6050, 0xa00d, 0x0040, 0x43cf,
+	0x2d00, 0x200a, 0x6803, 0x0000, 0x6052, 0x127f, 0x007c, 0x2d00,
+	0x6052, 0x604e, 0x6803, 0x0000, 0x0078, 0x43cd, 0x127e, 0x2091,
+	0x8000, 0x604c, 0xa005, 0x0040, 0x43ec, 0x0e7e, 0x2071, 0xa5ab,
+	0x7004, 0xa086, 0x0002, 0x0040, 0x43f3, 0x0e7f, 0x604c, 0x6802,
+	0x2d00, 0x604e, 0x127f, 0x007c, 0x2d00, 0x6052, 0x604e, 0x6803,
+	0x0000, 0x0078, 0x43ea, 0x701c, 0xac06, 0x00c0, 0x43e5, 0x604c,
+	0x2070, 0x7000, 0x6802, 0x2d00, 0x7002, 0x0e7f, 0x127f, 0x007c,
+	0x127e, 0x2091, 0x8000, 0x604c, 0xa06d, 0x0040, 0x440e, 0x6800,
+	0xa005, 0x00c0, 0x440c, 0x6052, 0x604e, 0xad05, 0x127f, 0x007c,
+	0x604c, 0xa06d, 0x0040, 0x441b, 0x6800, 0xa005, 0x00c0, 0x4419,
+	0x6052, 0x604e, 0xad05, 0x007c, 0x6803, 0x0000, 0x6084, 0xa00d,
+	0x0040, 0x4426, 0x2d00, 0x200a, 0x6086, 0x007c, 0x2d00, 0x6086,
+	0x6082, 0x0078, 0x4425, 0x127e, 0x0c7e, 0x027e, 0x2091, 0x8000,
+	0x6218, 0x2260, 0x6200, 0xa005, 0x0040, 0x4439, 0xc285, 0x0078,
+	0x443a, 0xc284, 0x6202, 0x027f, 0x0c7f, 0x127f, 0x007c, 0x127e,
+	0x0c7e, 0x2091, 0x8000, 0x6218, 0x2260, 0x6204, 0x007e, 0xa086,
+	0x0006, 0x00c0, 0x445e, 0x609c, 0xd0ac, 0x0040, 0x445e, 0x2001,
+	0xa352, 0x2004, 0xd0a4, 0x0040, 0x445e, 0xa284, 0xff00, 0x8007,
+	0xa086, 0x0007, 0x00c0, 0x445e, 0x2011, 0x0600, 0x007f, 0xa294,
+	0xff00, 0xa215, 0x6206, 0x007e, 0xa086, 0x0006, 0x00c0, 0x446e,
+	0x6290, 0x82ff, 0x00c0, 0x446e, 0x1078, 0x1328, 0x007f, 0x0c7f,
+	0x127f, 0x007c, 0x127e, 0x0c7e, 0x2091, 0x8000, 0x6218, 0x2260,
+	0x6204, 0x007e, 0xa086, 0x0006, 0x00c0, 0x4490, 0x609c, 0xd0a4,
+	0x0040, 0x4490, 0x2001, 0xa352, 0x2004, 0xd0ac, 0x00c0, 0x4490,
+	0xa284, 0x00ff, 0xa086, 0x0007, 0x00c0, 0x4490, 0x2011, 0x0006,
+	0x007f, 0xa294, 0x00ff, 0x8007, 0xa215, 0x6206, 0x0c7f, 0x127f,
+	0x007c, 0x027e, 0xa182, 0x00ff, 0x0048, 0x44a2, 0xa085, 0x0001,
+	0x0078, 0x44ba, 0xa190, 0xa434, 0x2204, 0xa065, 0x00c0, 0x44b9,
+	0x017e, 0x0d7e, 0x1078, 0x1366, 0x2d60, 0x0d7f, 0x017f, 0x0040,
+	0x449e, 0x2c00, 0x2012, 0x60a7, 0x0000, 0x60ab, 0x0000, 0x1078,
+	0x4235, 0xa006, 0x027f, 0x007c, 0x127e, 0x2091, 0x8000, 0x027e,
+	0xa182, 0x00ff, 0x0048, 0x44c8, 0xa085, 0x0001, 0x0078, 0x44fe,
+	0x0d7e, 0xa190, 0xa434, 0x2204, 0xa06d, 0x0040, 0x44fc, 0x2013,
+	0x0000, 0x0d7e, 0x0c7e, 0x2d60, 0x60a4, 0xa06d, 0x0040, 0x44da,
+	0x1078, 0x139a, 0x60a8, 0xa06d, 0x0040, 0x44e0, 0x1078, 0x139a,
+	0x0c7f, 0x0d7f, 0x0d7e, 0x0c7e, 0x68ac, 0x2060, 0x8cff, 0x0040,
+	0x44f8, 0x600c, 0x007e, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040,
+	0x44f3, 0x1078, 0x13aa, 0x1078, 0x753d, 0x0c7f, 0x0078, 0x44e6,
+	0x0c7f, 0x0d7f, 0x1078, 0x139a, 0x0d7f, 0xa006, 0x027f, 0x127f,
+	0x007c, 0x017e, 0xa182, 0x00ff, 0x0048, 0x450a, 0xa085, 0x0001,
+	0x0078, 0x4511, 0xa188, 0xa434, 0x2104, 0xa065, 0x0040, 0x4506,
+	0xa006, 0x017f, 0x007c, 0x0d7e, 0x157e, 0x137e, 0x147e, 0x600b,
+	0x0000, 0x600f, 0x0000, 0x6000, 0xc08c, 0x6002, 0x2069, 0xa88e,
+	0x6808, 0x605e, 0x6810, 0x6062, 0x6138, 0xa10a, 0x0048, 0x4529,
+	0x603a, 0x6814, 0x6066, 0x2099, 0xa896, 0xac88, 0x000a, 0x21a0,
+	0x20a9, 0x0004, 0x53a3, 0x2099, 0xa89a, 0xac88, 0x0006, 0x21a0,
+	0x20a9, 0x0004, 0x53a3, 0x2069, 0xa8ae, 0x6808, 0x606a, 0x690c,
+	0x616e, 0x6810, 0x6072, 0x6818, 0x6076, 0xa182, 0x0211, 0x00c8,
+	0x454d, 0x2009, 0x0008, 0x0078, 0x4577, 0xa182, 0x0259, 0x00c8,
+	0x4555, 0x2009, 0x0007, 0x0078, 0x4577, 0xa182, 0x02c1, 0x00c8,
+	0x455d, 0x2009, 0x0006, 0x0078, 0x4577, 0xa182, 0x0349, 0x00c8,
+	0x4565, 0x2009, 0x0005, 0x0078, 0x4577, 0xa182, 0x0421, 0x00c8,
+	0x456d, 0x2009, 0x0004, 0x0078, 0x4577, 0xa182, 0x0581, 0x00c8,
+	0x4575, 0x2009, 0x0003, 0x0078, 0x4577, 0x2009, 0x0002, 0x6192,
+	0x147f, 0x137f, 0x157f, 0x0d7f, 0x007c, 0x017e, 0x027e, 0x0e7e,
+	0x2071, 0xa88d, 0x2e04, 0x6896, 0x2071, 0xa88e, 0x7004, 0x689a,
+	0x701c, 0x689e, 0x6a00, 0x2009, 0xa371, 0x210c, 0xd0bc, 0x0040,
+	0x4597, 0xd1ec, 0x0040, 0x4597, 0xc2ad, 0x0078, 0x4598, 0xc2ac,
+	0xd0c4, 0x0040, 0x45a1, 0xd1e4, 0x0040, 0x45a1, 0xc2bd, 0x0078,
+	0x45a2, 0xc2bc, 0x6a02, 0x0e7f, 0x027f, 0x017f, 0x007c, 0x0d7e,
+	0x127e, 0x2091, 0x8000, 0x60a4, 0xa06d, 0x0040, 0x45cb, 0x6900,
+	0x81ff, 0x00c0, 0x45df, 0x6a04, 0xa282, 0x0010, 0x00c8, 0x45e4,
+	0xad88, 0x0004, 0x20a9, 0x0010, 0x2104, 0xa086, 0xffff, 0x0040,
+	0x45c6, 0x8108, 0x00f0, 0x45bc, 0x1078, 0x1328, 0x260a, 0x8210,
+	0x6a06, 0x0078, 0x45df, 0x1078, 0x1381, 0x0040, 0x45e4, 0x2d00,
+	0x60a6, 0x6803, 0x0000, 0xad88, 0x0004, 0x20a9, 0x0010, 0x200b,
+	0xffff, 0x8108, 0x00f0, 0x45d7, 0x6807, 0x0001, 0x6e12, 0xa085,
+	0x0001, 0x127f, 0x0d7f, 0x007c, 0xa006, 0x0078, 0x45e1, 0x127e,
+	0x2091, 0x8000, 0x0d7e, 0x60a4, 0xa00d, 0x0040, 0x4607, 0x2168,
+	0x6800, 0xa005, 0x00c0, 0x4603, 0x1078, 0x4749, 0x00c0, 0x4607,
+	0x200b, 0xffff, 0x6804, 0xa08a, 0x0002, 0x0048, 0x4603, 0x8001,
+	0x6806, 0x0078, 0x4607, 0x1078, 0x139a, 0x60a7, 0x0000, 0x0d7f,
+	0x127f, 0x007c, 0x127e, 0x2091, 0x8000, 0x1078, 0x47af, 0x0078,
+	0x4613, 0x1078, 0x43c1, 0x1078, 0x46a7, 0x00c0, 0x4611, 0x1078,
+	0x4663, 0x127f, 0x007c, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x60a8,
+	0xa06d, 0x0040, 0x463f, 0x6950, 0x81ff, 0x00c0, 0x4653, 0x6a54,
+	0xa282, 0x0010, 0x00c8, 0x4660, 0xad88, 0x0018, 0x20a9, 0x0010,
+	0x2104, 0xa086, 0xffff, 0x0040, 0x463a, 0x8108, 0x00f0, 0x4630,
+	0x1078, 0x1328, 0x260a, 0x8210, 0x6a56, 0x0078, 0x4653, 0x1078,
+	0x1381, 0x0040, 0x4660, 0x2d00, 0x60aa, 0x6853, 0x0000, 0xad88,
+	0x0018, 0x20a9, 0x0010, 0x200b, 0xffff, 0x8108, 0x00f0, 0x464b,
+	0x6857, 0x0001, 0x6e62, 0x0078, 0x4657, 0x1078, 0x441c, 0x1078,
+	0x466d, 0x00c0, 0x4655, 0xa085, 0x0001, 0x127f, 0x0d7f, 0x007c,
+	0xa006, 0x0078, 0x465d, 0x127e, 0x2091, 0x8000, 0x1078, 0x5c17,
+	0x127f, 0x007c, 0xa01e, 0x0078, 0x466f, 0x2019, 0x0001, 0xa00e,
+	0x127e, 0x2091, 0x8000, 0x604c, 0x2068, 0x6000, 0xd0dc, 0x00c0,
+	0x468d, 0x8dff, 0x0040, 0x46a2, 0x83ff, 0x0040, 0x4685, 0x6848,
+	0xa606, 0x0040, 0x4692, 0x0078, 0x468d, 0x683c, 0xa406, 0x00c0,
+	0x468d, 0x6840, 0xa506, 0x0040, 0x4692, 0x2d08, 0x6800, 0x2068,
+	0x0078, 0x4679, 0x6a00, 0x604c, 0xad06, 0x00c0, 0x469a, 0x624e,
+	0x0078, 0x469d, 0xa180, 0x0000, 0x2202, 0x82ff, 0x00c0, 0x46a2,
+	0x6152, 0x8dff, 0x127f, 0x007c, 0xa01e, 0x0078, 0x46a9, 0x2019,
+	0x0001, 0xa00e, 0x6080, 0x2068, 0x8dff, 0x0040, 0x46d5, 0x83ff,
+	0x0040, 0x46b8, 0x6848, 0xa606, 0x0040, 0x46c5, 0x0078, 0x46c0,
+	0x683c, 0xa406, 0x00c0, 0x46c0, 0x6840, 0xa506, 0x0040, 0x46c5,
+	0x2d08, 0x6800, 0x2068, 0x0078, 0x46ac, 0x6a00, 0x6080, 0xad06,
+	0x00c0, 0x46cd, 0x6282, 0x0078, 0x46d0, 0xa180, 0x0000, 0x2202,
+	0x82ff, 0x00c0, 0x46d5, 0x6186, 0x8dff, 0x007c, 0xa016, 0x1078,
+	0x4742, 0x00c0, 0x46dd, 0x2011, 0x0001, 0x1078, 0x4793, 0x00c0,
+	0x46e3, 0xa295, 0x0002, 0x007c, 0x1078, 0x47cb, 0x0040, 0x46ec,
+	0x1078, 0x8b12, 0x0078, 0x46ee, 0xa085, 0x0001, 0x007c, 0x1078,
+	0x47cb, 0x0040, 0x46f7, 0x1078, 0x8aaa, 0x0078, 0x46f9, 0xa085,
+	0x0001, 0x007c, 0x1078, 0x47cb, 0x0040, 0x4702, 0x1078, 0x8af4,
+	0x0078, 0x4704, 0xa085, 0x0001, 0x007c, 0x1078, 0x47cb, 0x0040,
+	0x470d, 0x1078, 0x8ac6, 0x0078, 0x470f, 0xa085, 0x0001, 0x007c,
+	0x1078, 0x47cb, 0x0040, 0x4718, 0x1078, 0x8b30, 0x0078, 0x471a,
+	0xa085, 0x0001, 0x007c, 0x127e, 0x007e, 0x0d7e, 0x2091, 0x8000,
+	0x6080, 0xa06d, 0x0040, 0x473a, 0x6800, 0x007e, 0x6837, 0x0103,
+	0x6b4a, 0x6847, 0x0000, 0x1078, 0x8cb8, 0x007e, 0x6000, 0xd0fc,
+	0x0040, 0x4734, 0x1078, 0xa18c, 0x007f, 0x1078, 0x4982, 0x007f,
+	0x0078, 0x4721, 0x6083, 0x0000, 0x6087, 0x0000, 0x0d7f, 0x007f,
+	0x127f, 0x007c, 0x60a4, 0xa00d, 0x00c0, 0x4749, 0xa085, 0x0001,
+	0x007c, 0x0e7e, 0x2170, 0x7000, 0xa005, 0x00c0, 0x475c, 0x20a9,
+	0x0010, 0xae88, 0x0004, 0x2104, 0xa606, 0x0040, 0x475c, 0x8108,
+	0x00f0, 0x4753, 0xa085, 0x0001, 0xa006, 0x0e7f, 0x007c, 0x0d7e,
+	0x127e, 0x2091, 0x8000, 0x60a4, 0xa06d, 0x00c0, 0x476d, 0x1078,
+	0x1381, 0x0040, 0x477f, 0x2d00, 0x60a6, 0x6803, 0x0001, 0x6807,
+	0x0000, 0xad88, 0x0004, 0x20a9, 0x0010, 0x200b, 0xffff, 0x8108,
+	0x00f0, 0x4775, 0xa085, 0x0001, 0x127f, 0x0d7f, 0x007c, 0xa006,
+	0x0078, 0x477c, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x60a4, 0xa06d,
+	0x0040, 0x4790, 0x60a7, 0x0000, 0x1078, 0x139a, 0xa085, 0x0001,
+	0x127f, 0x0d7f, 0x007c, 0x60a8, 0xa00d, 0x00c0, 0x479a, 0xa085,
+	0x0001, 0x007c, 0x0e7e, 0x2170, 0x7050, 0xa005, 0x00c0, 0x47ad,
+	0x20a9, 0x0010, 0xae88, 0x0018, 0x2104, 0xa606, 0x0040, 0x47ad,
+	0x8108, 0x00f0, 0x47a4, 0xa085, 0x0001, 0x0e7f, 0x007c, 0x127e,
+	0x2091, 0x8000, 0x1078, 0x4793, 0x00c0, 0x47c9, 0x200b, 0xffff,
+	0x0d7e, 0x60a8, 0x2068, 0x6854, 0xa08a, 0x0002, 0x0048, 0x47c4,
+	0x8001, 0x6856, 0x0078, 0x47c8, 0x1078, 0x139a, 0x60ab, 0x0000,
+	0x0d7f, 0x127f, 0x007c, 0x609c, 0xd0a4, 0x007c, 0x0f7e, 0x71ac,
+	0x81ff, 0x00c0, 0x47e9, 0x71c8, 0xd19c, 0x0040, 0x47e9, 0x2001,
+	0x007e, 0xa080, 0xa434, 0x2004, 0xa07d, 0x0040, 0x47e9, 0x7804,
+	0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x47e9, 0x7800, 0xc0ed,
+	0x7802, 0x2079, 0xa351, 0x7804, 0xd0a4, 0x0040, 0x480f, 0x157e,
+	0x0c7e, 0x20a9, 0x007f, 0x2009, 0x0000, 0x017e, 0x1078, 0x4501,
+	0x00c0, 0x4809, 0x6004, 0xa084, 0xff00, 0x8007, 0xa096, 0x0004,
+	0x0040, 0x4806, 0xa086, 0x0006, 0x00c0, 0x4809, 0x6000, 0xc0ed,
+	0x6002, 0x017f, 0x8108, 0x00f0, 0x47f5, 0x0c7f, 0x157f, 0x1078,
+	0x4897, 0x0040, 0x4818, 0x2001, 0xa59f, 0x200c, 0x0078, 0x4820,
+	0x2079, 0xa351, 0x7804, 0xd0a4, 0x0040, 0x4824, 0x2009, 0x07d0,
+	0x2011, 0x4826, 0x1078, 0x596c, 0x0f7f, 0x007c, 0x2011, 0x4826,
+	0x1078, 0x58d4, 0x1078, 0x4897, 0x0040, 0x484e, 0x2001, 0xa4b2,
+	0x2004, 0xa080, 0x0000, 0x200c, 0xc1ec, 0x2102, 0x2001, 0xa352,
+	0x2004, 0xd0a4, 0x0040, 0x4842, 0x2009, 0x07d0, 0x2011, 0x4826,
+	0x1078, 0x596c, 0x0e7e, 0x2071, 0xa300, 0x706b, 0x0000, 0x706f,
+	0x0000, 0x1078, 0x260d, 0x0e7f, 0x0078, 0x4886, 0x157e, 0x0c7e,
+	0x20a9, 0x007f, 0x2009, 0x0000, 0x017e, 0x1078, 0x4501, 0x00c0,
+	0x4880, 0x6000, 0xd0ec, 0x0040, 0x4880, 0x047e, 0x62a0, 0xa294,
+	0x00ff, 0x8227, 0xa006, 0x2009, 0x0029, 0x1078, 0x9ec0, 0x6000,
+	0xc0e5, 0xc0ec, 0x6002, 0x6004, 0xa084, 0x00ff, 0xa085, 0x0700,
+	0x6006, 0x2019, 0x0029, 0x1078, 0x5d53, 0x077e, 0x2039, 0x0000,
+	0x1078, 0x5c78, 0x2009, 0x0000, 0x1078, 0x9c38, 0x077f, 0x047f,
+	0x017f, 0x8108, 0x00f0, 0x4854, 0x0c7f, 0x157f, 0x007c, 0x0c7e,
+	0x6018, 0x2060, 0x6000, 0xc0ec, 0x6002, 0x0c7f, 0x007c, 0x7818,
+	0x2004, 0xd0ac, 0x007c, 0x7818, 0x2004, 0xd0bc, 0x007c, 0x0f7e,
+	0x2001, 0xa4b2, 0x2004, 0xa07d, 0x0040, 0x48a0, 0x7800, 0xd0ec,
+	0x0f7f, 0x007c, 0x127e, 0x027e, 0x2091, 0x8000, 0x6200, 0xa005,
+	0x0040, 0x48ad, 0xc2fd, 0x0078, 0x48ae, 0xc2fc, 0x6202, 0x027f,
+	0x127f, 0x007c, 0x2071, 0xa413, 0x7003, 0x0001, 0x7007, 0x0000,
+	0x7013, 0x0000, 0x7017, 0x0000, 0x701b, 0x0000, 0x701f, 0x0000,
+	0x700b, 0x0000, 0x704b, 0x0001, 0x704f, 0x0000, 0x705b, 0x0020,
+	0x705f, 0x0040, 0x707f, 0x0000, 0x2071, 0xa57c, 0x7003, 0xa413,
+	0x7007, 0x0000, 0x700b, 0x0000, 0x700f, 0xa55c, 0x7013, 0x0020,
+	0x7017, 0x0040, 0x7037, 0x0000, 0x007c, 0x017e, 0x0e7e, 0x2071,
+	0xa534, 0xa00e, 0x7186, 0x718a, 0x7097, 0x0001, 0x2001, 0xa352,
+	0x2004, 0xd0fc, 0x00c0, 0x48f7, 0x2001, 0xa352, 0x2004, 0xa00e,
+	0xd09c, 0x0040, 0x48f4, 0x8108, 0x7102, 0x0078, 0x494a, 0x2001,
+	0xa371, 0x200c, 0xa184, 0x000f, 0x2009, 0xa372, 0x210c, 0x0079,
+	0x4901, 0x48ec, 0x4922, 0x492a, 0x4935, 0x493b, 0x48ec, 0x48ec,
+	0x48ec, 0x4911, 0x48ec, 0x48ec, 0x48ec, 0x48ec, 0x48ec, 0x48ec,
+	0x48ec, 0x7003, 0x0004, 0x137e, 0x147e, 0x157e, 0x2099, 0xa375,
+	0x20a1, 0xa585, 0x20a9, 0x0004, 0x53a3, 0x157f, 0x147f, 0x137f,
+	0x0078, 0x494a, 0x708f, 0x0005, 0x7007, 0x0122, 0x2001, 0x0002,
+	0x0078, 0x4930, 0x708f, 0x0002, 0x7007, 0x0121, 0x2001, 0x0003,
+	0x7002, 0x7097, 0x0001, 0x0078, 0x4947, 0x7007, 0x0122, 0x2001,
+	0x0002, 0x0078, 0x493f, 0x7007, 0x0121, 0x2001, 0x0003, 0x7002,
+	0xa006, 0x7096, 0x708e, 0xa184, 0xff00, 0x8007, 0x709a, 0xa184,
+	0x00ff, 0x7092, 0x0e7f, 0x017f, 0x007c, 0x0e7e, 0x2071, 0xa413,
+	0x684c, 0xa005, 0x00c0, 0x495b, 0x7028, 0xc085, 0x702a, 0xa085,
+	0x0001, 0x0078, 0x4980, 0x6a60, 0x7236, 0x6b64, 0x733a, 0x6868,
+	0x703e, 0x7076, 0x686c, 0x7042, 0x707a, 0x684c, 0x702e, 0x6844,
+	0x7032, 0x2009, 0x000d, 0x200a, 0x700b, 0x0000, 0x8007, 0x8006,
+	0x8006, 0xa08c, 0x003f, 0xa084, 0xffc0, 0xa210, 0x2100, 0xa319,
+	0x726e, 0x7372, 0x7028, 0xc084, 0x702a, 0x7007, 0x0001, 0xa006,
+	0x0e7f, 0x007c, 0x0e7e, 0x027e, 0x6838, 0xd0fc, 0x00c0, 0x49d8,
+	0x6804, 0xa00d, 0x0040, 0x499e, 0x0d7e, 0x2071, 0xa300, 0xa016,
+	0x702c, 0x2168, 0x6904, 0x206a, 0x8210, 0x2d00, 0x81ff, 0x00c0,
+	0x4991, 0x702e, 0x70a8, 0xa200, 0x70aa, 0x0d7f, 0x2071, 0xa413,
+	0x701c, 0xa005, 0x00c0, 0x49ea, 0x0068, 0x49e8, 0x2071, 0xa534,
+	0x7200, 0x82ff, 0x0040, 0x49e8, 0x6934, 0xa186, 0x0103, 0x00c0,
+	0x49fb, 0x6948, 0x6844, 0xa105, 0x00c0, 0x49db, 0x2009, 0x8020,
+	0x2200, 0x0079, 0x49bb, 0x49e8, 0x49c0, 0x4a18, 0x4a26, 0x49e8,
+	0x2071, 0x0000, 0x7018, 0xd084, 0x00c0, 0x49e8, 0x7122, 0x683c,
+	0x7026, 0x6840, 0x702a, 0x701b, 0x0001, 0x2091, 0x4080, 0x2071,
+	0xa300, 0x702c, 0x206a, 0x2d00, 0x702e, 0x70a8, 0x8000, 0x70aa,
+	0x027f, 0x0e7f, 0x007c, 0x6844, 0xa086, 0x0100, 0x00c0, 0x49e8,
+	0x6868, 0xa005, 0x00c0, 0x49e8, 0x2009, 0x8020, 0x0078, 0x49b8,
+	0x2071, 0xa413, 0x2d08, 0x206b, 0x0000, 0x7010, 0x8000, 0x7012,
+	0x7018, 0xa06d, 0x711a, 0x0040, 0x49f8, 0x6902, 0x0078, 0x49f9,
+	0x711e, 0x0078, 0x49d8, 0xa18c, 0x00ff, 0xa186, 0x0017, 0x0040,
+	0x4a09, 0xa186, 0x001e, 0x0040, 0x4a09, 0xa18e, 0x001f, 0x00c0,
+	0x49e8, 0x684c, 0xd0cc, 0x0040, 0x49e8, 0x6850, 0xa084, 0x00ff,
+	0xa086, 0x0001, 0x00c0, 0x49e8, 0x2009, 0x8021, 0x0078, 0x49b8,
+	0x7084, 0x8008, 0xa092, 0x001e, 0x00c8, 0x49e8, 0x7186, 0xae90,
+	0x0003, 0xa210, 0x683c, 0x2012, 0x0078, 0x4a36, 0x7084, 0x8008,
+	0xa092, 0x000f, 0x00c8, 0x49e8, 0x7186, 0xae90, 0x0003, 0x8003,
+	0xa210, 0x683c, 0x2012, 0x8210, 0x6840, 0x2012, 0x7088, 0xa10a,
+	0x0048, 0x49cf, 0x718c, 0x7084, 0xa10a, 0x0048, 0x49cf, 0x2071,
+	0x0000, 0x7018, 0xd084, 0x00c0, 0x49cf, 0x2071, 0xa534, 0x7000,
+	0xa086, 0x0002, 0x00c0, 0x4a56, 0x1078, 0x4cd2, 0x2071, 0x0000,
+	0x701b, 0x0001, 0x2091, 0x4080, 0x0078, 0x49cf, 0x1078, 0x4cfd,
+	0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0078, 0x49cf,
+	0x007e, 0x684c, 0x007e, 0x6837, 0x0103, 0x20a9, 0x001c, 0xad80,
+	0x0011, 0x20a0, 0x2001, 0x0000, 0x40a4, 0x007f, 0xa084, 0x00ff,
+	0x684e, 0x007f, 0x684a, 0x6952, 0x007c, 0x2071, 0xa413, 0x7004,
+	0x0079, 0x4a7a, 0x4a84, 0x4a95, 0x4ca3, 0x4ca4, 0x4ccb, 0x4cd1,
+	0x4a85, 0x4c91, 0x4c32, 0x4cb4, 0x007c, 0x127e, 0x2091, 0x8000,
+	0x0068, 0x4a94, 0x2009, 0x000d, 0x7030, 0x200a, 0x2091, 0x4080,
+	0x7007, 0x0001, 0x700b, 0x0000, 0x127f, 0x2069, 0xa5be, 0x6844,
+	0xa005, 0x0050, 0x4abd, 0x00c0, 0x4abd, 0x127e, 0x2091, 0x8000,
+	0x2069, 0x0000, 0x6934, 0x2001, 0xa41f, 0x2004, 0xa10a, 0x0040,
+	0x4ab8, 0x0068, 0x4abc, 0x2069, 0x0000, 0x6818, 0xd084, 0x00c0,
+	0x4abc, 0x2009, 0x8040, 0x6922, 0x681b, 0x0001, 0x2091, 0x4080,
+	0x2069, 0xa5be, 0x6847, 0xffff, 0x127f, 0x2069, 0xa300, 0x6844,
+	0x6960, 0xa102, 0x2069, 0xa534, 0x688a, 0x6984, 0x701c, 0xa06d,
+	0x0040, 0x4acf, 0x81ff, 0x0040, 0x4b17, 0x0078, 0x4ae5, 0x81ff,
+	0x0040, 0x4be9, 0x2071, 0xa534, 0x7184, 0x7088, 0xa10a, 0x00c8,
+	0x4ae5, 0x7190, 0x2071, 0xa5be, 0x7040, 0xa005, 0x0040, 0x4ae5,
+	0x00d0, 0x4be9, 0x7142, 0x0078, 0x4be9, 0x2071, 0xa534, 0x718c,
+	0x127e, 0x2091, 0x8000, 0x7084, 0xa10a, 0x0048, 0x4c06, 0x0068,
+	0x4b9b, 0x2071, 0x0000, 0x7018, 0xd084, 0x00c0, 0x4b9b, 0x2001,
+	0xffff, 0x2071, 0xa5be, 0x7042, 0x2071, 0xa534, 0x7000, 0xa086,
+	0x0002, 0x00c0, 0x4b0d, 0x1078, 0x4cd2, 0x2071, 0x0000, 0x701b,
+	0x0001, 0x2091, 0x4080, 0x0078, 0x4b9b, 0x1078, 0x4cfd, 0x2071,
+	0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0078, 0x4b9b, 0x2071,
+	0xa534, 0x7000, 0xa005, 0x0040, 0x4bc8, 0x6934, 0xa186, 0x0103,
+	0x00c0, 0x4b9e, 0x684c, 0xd0bc, 0x00c0, 0x4bc8, 0x6948, 0x6844,
+	0xa105, 0x00c0, 0x4bbb, 0x2009, 0x8020, 0x2071, 0xa534, 0x7000,
+	0x0079, 0x4b32, 0x4bc8, 0x4b80, 0x4b58, 0x4b6a, 0x4b37, 0x137e,
+	0x147e, 0x157e, 0x2099, 0xa375, 0x20a1, 0xa585, 0x20a9, 0x0004,
+	0x53a3, 0x157f, 0x147f, 0x137f, 0x2071, 0xa57c, 0xad80, 0x000f,
+	0x700e, 0x7013, 0x0002, 0x7007, 0x0002, 0x700b, 0x0000, 0x2e10,
+	0x1078, 0x13d1, 0x2071, 0xa413, 0x7007, 0x0009, 0x0078, 0x4be9,
+	0x7084, 0x8008, 0xa092, 0x001e, 0x00c8, 0x4be9, 0xae90, 0x0003,
+	0xa210, 0x683c, 0x2012, 0x7186, 0x2071, 0xa413, 0x1078, 0x4d5b,
+	0x0078, 0x4be9, 0x7084, 0x8008, 0xa092, 0x000f, 0x00c8, 0x4be9,
+	0xae90, 0x0003, 0x8003, 0xa210, 0x683c, 0x2012, 0x8210, 0x6840,
+	0x2012, 0x7186, 0x2071, 0xa413, 0x1078, 0x4d5b, 0x0078, 0x4be9,
+	0x127e, 0x2091, 0x8000, 0x0068, 0x4b9b, 0x2071, 0x0000, 0x7018,
+	0xd084, 0x00c0, 0x4b9b, 0x7122, 0x683c, 0x7026, 0x6840, 0x702a,
+	0x701b, 0x0001, 0x2091, 0x4080, 0x127f, 0x2071, 0xa413, 0x1078,
+	0x4d5b, 0x0078, 0x4be9, 0x127f, 0x0078, 0x4be9, 0xa18c, 0x00ff,
+	0xa186, 0x0017, 0x0040, 0x4bac, 0xa186, 0x001e, 0x0040, 0x4bac,
+	0xa18e, 0x001f, 0x00c0, 0x4bc8, 0x684c, 0xd0cc, 0x0040, 0x4bc8,
+	0x6850, 0xa084, 0x00ff, 0xa086, 0x0001, 0x00c0, 0x4bc8, 0x2009,
+	0x8021, 0x0078, 0x4b2d, 0x6844, 0xa086, 0x0100, 0x00c0, 0x4bc8,
+	0x6868, 0xa005, 0x00c0, 0x4bc8, 0x2009, 0x8020, 0x0078, 0x4b2d,
+	0x2071, 0xa413, 0x1078, 0x4d6f, 0x0040, 0x4be9, 0x2071, 0xa413,
+	0x700f, 0x0001, 0x6934, 0xa184, 0x00ff, 0xa086, 0x0003, 0x00c0,
+	0x4be0, 0x810f, 0xa18c, 0x00ff, 0x8101, 0x0040, 0x4be0, 0x710e,
+	0x7007, 0x0003, 0x1078, 0x4d8f, 0x7050, 0xa086, 0x0100, 0x0040,
+	0x4ca4, 0x127e, 0x2091, 0x8000, 0x2071, 0xa413, 0x7008, 0xa086,
+	0x0001, 0x00c0, 0x4c04, 0x0068, 0x4c04, 0x2009, 0x000d, 0x7030,
+	0x200a, 0x2091, 0x4080, 0x700b, 0x0000, 0x7004, 0xa086, 0x0006,
+	0x00c0, 0x4c04, 0x7007, 0x0001, 0x127f, 0x007c, 0x2071, 0xa413,
+	0x1078, 0x4d6f, 0x0040, 0x4c2f, 0x2071, 0xa534, 0x7084, 0x700a,
+	0x20a9, 0x0020, 0x2099, 0xa535, 0x20a1, 0xa55c, 0x53a3, 0x7087,
+	0x0000, 0x2071, 0xa413, 0x2069, 0xa57c, 0x706c, 0x6826, 0x7070,
+	0x682a, 0x7074, 0x682e, 0x7078, 0x6832, 0x2d10, 0x1078, 0x13d1,
+	0x7007, 0x0008, 0x2001, 0xffff, 0x2071, 0xa5be, 0x7042, 0x127f,
+	0x0078, 0x4be9, 0x2069, 0xa57c, 0x6808, 0xa08e, 0x0000, 0x0040,
+	0x4c90, 0xa08e, 0x0200, 0x0040, 0x4c8e, 0xa08e, 0x0100, 0x00c0,
+	0x4c90, 0x127e, 0x2091, 0x8000, 0x0068, 0x4c8b, 0x2069, 0x0000,
+	0x6818, 0xd084, 0x00c0, 0x4c8b, 0x702c, 0x7130, 0x8108, 0xa102,
+	0x0048, 0x4c59, 0xa00e, 0x7034, 0x706e, 0x7038, 0x7072, 0x0078,
+	0x4c63, 0x706c, 0xa080, 0x0040, 0x706e, 0x00c8, 0x4c63, 0x7070,
+	0xa081, 0x0000, 0x7072, 0x7132, 0x6936, 0x700b, 0x0000, 0x2001,
+	0xa559, 0x2004, 0xa005, 0x00c0, 0x4c82, 0x6934, 0x2069, 0xa534,
+	0x689c, 0x699e, 0x2069, 0xa5be, 0xa102, 0x00c0, 0x4c7b, 0x6844,
+	0xa005, 0x00d0, 0x4c89, 0x2001, 0xa55a, 0x200c, 0x810d, 0x6946,
+	0x0078, 0x4c89, 0x2009, 0x8040, 0x6922, 0x681b, 0x0001, 0x2091,
+	0x4080, 0x7007, 0x0001, 0x127f, 0x0078, 0x4c90, 0x7007, 0x0005,
+	0x007c, 0x701c, 0xa06d, 0x0040, 0x4ca2, 0x1078, 0x4d6f, 0x0040,
+	0x4ca2, 0x7007, 0x0003, 0x1078, 0x4d8f, 0x7050, 0xa086, 0x0100,
+	0x0040, 0x4ca4, 0x007c, 0x007c, 0x7050, 0xa09e, 0x0100, 0x00c0,
+	0x4cad, 0x7007, 0x0004, 0x0078, 0x4ccb, 0xa086, 0x0200, 0x00c0,
+	0x4cb3, 0x7007, 0x0005, 0x007c, 0x2001, 0xa57e, 0x2004, 0xa08e,
+	0x0100, 0x00c0, 0x4cc0, 0x7007, 0x0001, 0x1078, 0x4d5b, 0x007c,
+	0xa08e, 0x0000, 0x0040, 0x4cbf, 0xa08e, 0x0200, 0x00c0, 0x4cbf,
+	0x7007, 0x0005, 0x007c, 0x1078, 0x4d25, 0x7006, 0x1078, 0x4d5b,
+	0x007c, 0x007c, 0x0e7e, 0x157e, 0x2071, 0xa534, 0x7184, 0x81ff,
+	0x0040, 0x4cfa, 0xa006, 0x7086, 0xae80, 0x0003, 0x2071, 0x0000,
+	0x21a8, 0x2014, 0x7226, 0x8000, 0x0070, 0x4cf7, 0x2014, 0x722a,
+	0x8000, 0x0070, 0x4cf7, 0x2014, 0x722e, 0x8000, 0x0070, 0x4cf7,
+	0x2014, 0x723a, 0x8000, 0x0070, 0x4cf7, 0x2014, 0x723e, 0xa180,
+	0x8030, 0x7022, 0x157f, 0x0e7f, 0x007c, 0x0e7e, 0x157e, 0x2071,
+	0xa534, 0x7184, 0x81ff, 0x0040, 0x4d22, 0xa006, 0x7086, 0xae80,
+	0x0003, 0x2071, 0x0000, 0x21a8, 0x2014, 0x7226, 0x8000, 0x2014,
+	0x722a, 0x8000, 0x0070, 0x4d1b, 0x2014, 0x723a, 0x8000, 0x2014,
+	0x723e, 0x0078, 0x4d1f, 0x2001, 0x8020, 0x0078, 0x4d21, 0x2001,
+	0x8042, 0x7022, 0x157f, 0x0e7f, 0x007c, 0x702c, 0x7130, 0x8108,
+	0xa102, 0x0048, 0x4d32, 0xa00e, 0x7034, 0x706e, 0x7038, 0x7072,
+	0x0078, 0x4d3c, 0x706c, 0xa080, 0x0040, 0x706e, 0x00c8, 0x4d3c,
+	0x7070, 0xa081, 0x0000, 0x7072, 0x7132, 0x700c, 0x8001, 0x700e,
+	0x00c0, 0x4d52, 0x127e, 0x2091, 0x8000, 0x0068, 0x4d55, 0x2001,
+	0x000d, 0x2102, 0x2091, 0x4080, 0x2001, 0x0001, 0x700b, 0x0000,
+	0x127f, 0x007c, 0x2001, 0x0007, 0x007c, 0x2001, 0x0006, 0x700b,
+	0x0001, 0x127f, 0x007c, 0x701c, 0xa06d, 0x0040, 0x4d6e, 0x127e,
+	0x2091, 0x8000, 0x7010, 0x8001, 0x7012, 0x2d04, 0x701e, 0xa005,
+	0x00c0, 0x4d6b, 0x701a, 0x127f, 0x1078, 0x139a, 0x007c, 0x2019,
+	0x000d, 0x2304, 0x230c, 0xa10e, 0x0040, 0x4d7e, 0x2304, 0x230c,
+	0xa10e, 0x0040, 0x4d7e, 0xa006, 0x0078, 0x4d8e, 0x732c, 0x8319,
+	0x7130, 0xa102, 0x00c0, 0x4d88, 0x2300, 0xa005, 0x0078, 0x4d8e,
+	0x0048, 0x4d8d, 0xa302, 0x0078, 0x4d8e, 0x8002, 0x007c, 0x2d00,
+	0x7026, 0xa080, 0x000d, 0x7056, 0x7053, 0x0000, 0x127e, 0x2091,
+	0x8000, 0x2009, 0xa5d0, 0x2104, 0xc08d, 0x200a, 0x127f, 0x1078,
+	0x13eb, 0x007c, 0x2071, 0xa3e1, 0x7003, 0x0000, 0x7007, 0x0000,
+	0x700f, 0x0000, 0x702b, 0x0001, 0x704f, 0x0000, 0x7053, 0x0001,
+	0x705f, 0x0020, 0x7063, 0x0040, 0x7083, 0x0000, 0x708b, 0x0000,
+	0x708f, 0x0001, 0x70bf, 0x0000, 0x007c, 0x0e7e, 0x2071, 0xa3e1,
+	0x6848, 0xa005, 0x00c0, 0x4dcb, 0x7028, 0xc085, 0x702a, 0xa085,
+	0x0001, 0x0078, 0x4df0, 0x6a50, 0x7236, 0x6b54, 0x733a, 0x6858,
+	0x703e, 0x707a, 0x685c, 0x7042, 0x707e, 0x6848, 0x702e, 0x6840,
+	0x7032, 0x2009, 0x000c, 0x200a, 0x8007, 0x8006, 0x8006, 0xa08c,
+	0x003f, 0xa084, 0xffc0, 0xa210, 0x2100, 0xa319, 0x7272, 0x7376,
+	0x7028, 0xc084, 0x702a, 0x7007, 0x0001, 0x700f, 0x0000, 0xa006,
+	0x0e7f, 0x007c, 0x2b78, 0x2071, 0xa3e1, 0x7004, 0x1079, 0x4e50,
+	0x700c, 0x0079, 0x4dfb, 0x4e00, 0x4df5, 0x4df5, 0x4df5, 0x4df5,
+	0x007c, 0x700c, 0x0079, 0x4e04, 0x4e09, 0x4e4e, 0x4e4e, 0x4e4f,
+	0x4e4f, 0x7830, 0x7930, 0xa106, 0x0040, 0x4e13, 0x7830, 0x7930,
+	0xa106, 0x00c0, 0x4e39, 0x7030, 0xa10a, 0x0040, 0x4e39, 0x00c8,
+	0x4e1b, 0x712c, 0xa10a, 0xa18a, 0x0002, 0x00c8, 0x4e3a, 0x1078,
+	0x1366, 0x0040, 0x4e39, 0x2d00, 0x705a, 0x7063, 0x0040, 0x2001,
+	0x0003, 0x7057, 0x0000, 0x127e, 0x007e, 0x2091, 0x8000, 0x2009,
+	0xa5d0, 0x2104, 0xc085, 0x200a, 0x007f, 0x700e, 0x127f, 0x1078,
+	0x13eb, 0x007c, 0x1078, 0x1366, 0x0040, 0x4e39, 0x2d00, 0x705a,
+	0x1078, 0x1366, 0x00c0, 0x4e46, 0x0078, 0x4e25, 0x2d00, 0x7086,
+	0x7063, 0x0080, 0x2001, 0x0004, 0x0078, 0x4e29, 0x007c, 0x007c,
+	0x4e61, 0x4e62, 0x4e99, 0x4e9a, 0x4e4e, 0x4ed0, 0x4ed5, 0x4f0c,
+	0x4f0d, 0x4f28, 0x4f29, 0x4f2a, 0x4f2b, 0x4f2c, 0x4f2d, 0x4fad,
+	0x4fd7, 0x007c, 0x700c, 0x0079, 0x4e65, 0x4e6a, 0x4e6d, 0x4e7d,
+	0x4e98, 0x4e98, 0x1078, 0x4e01, 0x007c, 0x127e, 0x8001, 0x700e,
+	0x7058, 0x007e, 0x1078, 0x5348, 0x0040, 0x4e7a, 0x2091, 0x8000,
+	0x1078, 0x4e01, 0x0d7f, 0x0078, 0x4e86, 0x127e, 0x8001, 0x700e,
+	0x1078, 0x5348, 0x7058, 0x2068, 0x7084, 0x705a, 0x6803, 0x0000,
+	0x6807, 0x0000, 0x6834, 0xa084, 0x00ff, 0xa08a, 0x0020, 0x00c8,
+	0x4e95, 0x1079, 0x4eb0, 0x127f, 0x007c, 0x127f, 0x1078, 0x4f2e,
+	0x007c, 0x007c, 0x007c, 0x0e7e, 0x2071, 0xa3e1, 0x700c, 0x0079,
+	0x4ea1, 0x4ea6, 0x4ea6, 0x4ea6, 0x4ea8, 0x4eac, 0x0e7f, 0x007c,
+	0x700f, 0x0001, 0x0078, 0x4eae, 0x700f, 0x0002, 0x0e7f, 0x007c,
+	0x4f2e, 0x4f2e, 0x4f4a, 0x4f2e, 0x5080, 0x4f2e, 0x4f2e, 0x4f2e,
+	0x4f2e, 0x4f2e, 0x4f4a, 0x50ca, 0x5117, 0x5170, 0x5186, 0x4f2e,
+	0x4f2e, 0x4f66, 0x4f4a, 0x4f2e, 0x4f2e, 0x4f87, 0x5245, 0x5263,
+	0x4f2e, 0x4f66, 0x4f2e, 0x4f2e, 0x4f2e, 0x4f2e, 0x4f7c, 0x5263,
+	0x7020, 0x2068, 0x1078, 0x139a, 0x007c, 0x700c, 0x0079, 0x4ed8,
+	0x4edd, 0x4ee0, 0x4ef0, 0x4f0b, 0x4f0b, 0x1078, 0x4e01, 0x007c,
+	0x127e, 0x8001, 0x700e, 0x7058, 0x007e, 0x1078, 0x5348, 0x0040,
+	0x4eed, 0x2091, 0x8000, 0x1078, 0x4e01, 0x0d7f, 0x0078, 0x4ef9,
+	0x127e, 0x8001, 0x700e, 0x1078, 0x5348, 0x7058, 0x2068, 0x7084,
+	0x705a, 0x6803, 0x0000, 0x6807, 0x0000, 0x6834, 0xa084, 0x00ff,
+	0xa08a, 0x001a, 0x00c8, 0x4f08, 0x1079, 0x4f0e, 0x127f, 0x007c,
+	0x127f, 0x1078, 0x4f2e, 0x007c, 0x007c, 0x007c, 0x4f2e, 0x4f4a,
+	0x506a, 0x4f2e, 0x4f4a, 0x4f2e, 0x4f4a, 0x4f4a, 0x4f2e, 0x4f4a,
+	0x506a, 0x4f4a, 0x4f4a, 0x4f4a, 0x4f4a, 0x4f4a, 0x4f2e, 0x4f4a,
+	0x506a, 0x4f2e, 0x4f2e, 0x4f4a, 0x4f2e, 0x4f2e, 0x4f2e, 0x4f4a,
+	0x007c, 0x007c, 0x007c, 0x007c, 0x007c, 0x007c, 0x7007, 0x0001,
+	0x6838, 0xa084, 0x00ff, 0xc0d5, 0x683a, 0x127e, 0x2091, 0x8000,
+	0x1078, 0x4982, 0x127f, 0x007c, 0x7007, 0x0001, 0x6838, 0xa084,
+	0x00ff, 0xc0e5, 0x683a, 0x127e, 0x2091, 0x8000, 0x1078, 0x4982,
+	0x127f, 0x007c, 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0ed,
+	0x683a, 0x127e, 0x2091, 0x8000, 0x1078, 0x4982, 0x127f, 0x007c,
+	0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0dd, 0x683a, 0x127e,
+	0x2091, 0x8000, 0x1078, 0x4982, 0x127f, 0x007c, 0x6834, 0x8007,
+	0xa084, 0x00ff, 0x0040, 0x4f3c, 0x8001, 0x00c0, 0x4f73, 0x7007,
+	0x0001, 0x0078, 0x5049, 0x7007, 0x0006, 0x7012, 0x2d00, 0x7016,
+	0x701a, 0x704b, 0x5049, 0x007c, 0x684c, 0xa084, 0x00c0, 0xa086,
+	0x00c0, 0x00c0, 0x4f87, 0x7007, 0x0001, 0x0078, 0x5280, 0x2d00,
+	0x7016, 0x701a, 0x20a9, 0x0004, 0xa080, 0x0024, 0x2098, 0x20a1,
+	0xa40c, 0x53a3, 0x6858, 0x7012, 0xa082, 0x0401, 0x00c8, 0x4f58,
+	0x6884, 0xa08a, 0x0002, 0x00c8, 0x4f58, 0x82ff, 0x00c0, 0x4fa9,
+	0x6888, 0x698c, 0xa105, 0x0040, 0x4fa9, 0x2001, 0x5019, 0x0078,
+	0x4fac, 0xa280, 0x500f, 0x2004, 0x70c6, 0x7010, 0xa015, 0x0040,
+	0x4ff7, 0x1078, 0x1366, 0x00c0, 0x4fb8, 0x7007, 0x000f, 0x007c,
+	0x2d00, 0x7022, 0x70c4, 0x2060, 0x6000, 0x6836, 0x6004, 0xad00,
+	0x7096, 0x6008, 0xa20a, 0x00c8, 0x4fc7, 0xa00e, 0x2200, 0x7112,
+	0x620c, 0x8003, 0x800b, 0xa296, 0x0004, 0x0040, 0x4fd0, 0xa108,
+	0x719a, 0x810b, 0x719e, 0xae90, 0x0022, 0x1078, 0x13d1, 0x7090,
+	0xa08e, 0x0100, 0x0040, 0x4feb, 0xa086, 0x0200, 0x0040, 0x4fe3,
+	0x7007, 0x0010, 0x007c, 0x7020, 0x2068, 0x1078, 0x139a, 0x7014,
+	0x2068, 0x0078, 0x4f58, 0x7020, 0x2068, 0x7018, 0x6802, 0x6807,
+	0x0000, 0x2d08, 0x2068, 0x6906, 0x711a, 0x0078, 0x4fad, 0x7014,
+	0x2068, 0x7007, 0x0001, 0x6884, 0xa005, 0x00c0, 0x5006, 0x6888,
+	0x698c, 0xa105, 0x0040, 0x5006, 0x1078, 0x501d, 0x6834, 0xa084,
+	0x00ff, 0xa086, 0x001e, 0x0040, 0x5280, 0x0078, 0x5049, 0x5011,
+	0x5015, 0x0002, 0x0011, 0x0007, 0x0004, 0x000a, 0x000f, 0x0005,
+	0x0006, 0x000a, 0x0011, 0x0005, 0x0004, 0x0f7e, 0x0e7e, 0x0c7e,
+	0x077e, 0x067e, 0x6f88, 0x6e8c, 0x6804, 0x2060, 0xacf0, 0x0021,
+	0xacf8, 0x0027, 0x2009, 0x0005, 0x700c, 0x7816, 0x7008, 0x7812,
+	0x7004, 0x7806, 0x7000, 0x7802, 0x7e0e, 0x7f0a, 0x8109, 0x0040,
+	0x503f, 0xaef2, 0x0004, 0xaffa, 0x0006, 0x0078, 0x502c, 0x6004,
+	0xa065, 0x00c0, 0x5026, 0x067f, 0x077f, 0x0c7f, 0x0e7f, 0x0f7f,
+	0x007c, 0x2009, 0xa32e, 0x210c, 0x81ff, 0x00c0, 0x5064, 0x6838,
+	0xa084, 0x00ff, 0x683a, 0x1078, 0x4290, 0x00c0, 0x5058, 0x007c,
+	0x1078, 0x4a60, 0x127e, 0x2091, 0x8000, 0x1078, 0x8cb8, 0x1078,
+	0x4982, 0x127f, 0x0078, 0x5057, 0x2001, 0x0028, 0x2009, 0x0000,
+	0x0078, 0x5058, 0x7018, 0x6802, 0x2d08, 0x2068, 0x6906, 0x711a,
+	0x7010, 0x8001, 0x7012, 0x0040, 0x5079, 0x7007, 0x0006, 0x0078,
+	0x507f, 0x7014, 0x2068, 0x7007, 0x0001, 0x7048, 0x107a, 0x007c,
+	0x7007, 0x0001, 0x6944, 0x810f, 0xa18c, 0x00ff, 0x6848, 0xa084,
+	0x00ff, 0x20a9, 0x0001, 0xa096, 0x0001, 0x0040, 0x50a9, 0x2009,
+	0x0000, 0x20a9, 0x00ff, 0xa096, 0x0002, 0x0040, 0x50a9, 0xa005,
+	0x00c0, 0x50bc, 0x6944, 0x810f, 0xa18c, 0x00ff, 0x1078, 0x4501,
+	0x00c0, 0x50bc, 0x067e, 0x6e50, 0x1078, 0x45e7, 0x067f, 0x0078,
+	0x50bc, 0x047e, 0x2011, 0xa30c, 0x2224, 0xc484, 0xc48c, 0x2412,
+	0x047f, 0x0c7e, 0x1078, 0x4501, 0x00c0, 0x50b8, 0x1078, 0x4782,
+	0x8108, 0x00f0, 0x50b2, 0x0c7f, 0x684c, 0xd084, 0x00c0, 0x50c3,
+	0x1078, 0x139a, 0x007c, 0x127e, 0x2091, 0x8000, 0x1078, 0x4982,
+	0x127f, 0x007c, 0x127e, 0x2091, 0x8000, 0x7007, 0x0001, 0x2001,
+	0xa352, 0x2004, 0xd0a4, 0x0040, 0x510e, 0x2061, 0xa62d, 0x6100,
+	0xd184, 0x0040, 0x50ee, 0x6858, 0xa084, 0x00ff, 0x00c0, 0x5111,
+	0x6000, 0xd084, 0x0040, 0x510e, 0x6004, 0xa005, 0x00c0, 0x5114,
+	0x6003, 0x0000, 0x600b, 0x0000, 0x0078, 0x510b, 0x2011, 0x0001,
+	0x6860, 0xa005, 0x00c0, 0x50f6, 0x2001, 0x001e, 0x8000, 0x6016,
+	0x6858, 0xa084, 0x00ff, 0x0040, 0x510e, 0x6006, 0x6858, 0x8007,
+	0xa084, 0x00ff, 0x0040, 0x510e, 0x600a, 0x6858, 0x8000, 0x00c0,
+	0x510a, 0xc28d, 0x6202, 0x127f, 0x0078, 0x5337, 0x127f, 0x0078,
+	0x532f, 0x127f, 0x0078, 0x5327, 0x127f, 0x0078, 0x532b, 0x127e,
+	0x2091, 0x8000, 0x7007, 0x0001, 0x2001, 0xa352, 0x2004, 0xd0a4,
+	0x0040, 0x516d, 0x2061, 0xa62d, 0x6000, 0xd084, 0x0040, 0x516d,
+	0x6204, 0x6308, 0xd08c, 0x00c0, 0x515f, 0x6c48, 0xa484, 0x0003,
+	0x0040, 0x5145, 0x6958, 0xa18c, 0x00ff, 0x8001, 0x00c0, 0x513e,
+	0x2100, 0xa210, 0x0048, 0x516a, 0x0078, 0x5145, 0x8001, 0x00c0,
+	0x516a, 0x2100, 0xa212, 0x0048, 0x516a, 0xa484, 0x000c, 0x0040,
+	0x515f, 0x6958, 0x810f, 0xa18c, 0x00ff, 0xa082, 0x0004, 0x00c0,
+	0x5157, 0x2100, 0xa318, 0x0048, 0x516a, 0x0078, 0x515f, 0xa082,
+	0x0004, 0x00c0, 0x516a, 0x2100, 0xa31a, 0x0048, 0x516a, 0x6860,
+	0xa005, 0x0040, 0x5165, 0x8000, 0x6016, 0x6206, 0x630a, 0x127f,
+	0x0078, 0x5337, 0x127f, 0x0078, 0x5333, 0x127f, 0x0078, 0x532f,
+	0x127e, 0x2091, 0x8000, 0x7007, 0x0001, 0x2061, 0xa62d, 0x6300,
+	0xd38c, 0x00c0, 0x5180, 0x6308, 0x8318, 0x0048, 0x5183, 0x630a,
+	0x127f, 0x0078, 0x5345, 0x127f, 0x0078, 0x5333, 0x127e, 0x0c7e,
+	0x2091, 0x8000, 0x7007, 0x0001, 0x684c, 0xd0ac, 0x0040, 0x519a,
+	0x0c7e, 0x2061, 0xa62d, 0x6000, 0xa084, 0xfcff, 0x6002, 0x0c7f,
+	0x0078, 0x51c9, 0x6858, 0xa005, 0x0040, 0x51e0, 0x685c, 0xa065,
+	0x0040, 0x51dc, 0x2001, 0xa32e, 0x2004, 0xa005, 0x0040, 0x51ac,
+	0x1078, 0x8c01, 0x0078, 0x51ba, 0x6013, 0x0400, 0x6037, 0x0000,
+	0x694c, 0xd1a4, 0x0040, 0x51b6, 0x6950, 0x6136, 0x2009, 0x0041,
+	0x1078, 0x756c, 0x6958, 0xa18c, 0xff00, 0xa186, 0x2000, 0x00c0,
+	0x51c9, 0x027e, 0x2009, 0x0000, 0x2011, 0xfdff, 0x1078, 0x5a6d,
+	0x027f, 0x684c, 0xd0c4, 0x0040, 0x51d8, 0x2061, 0xa62d, 0x6000,
+	0xd08c, 0x00c0, 0x51d8, 0x6008, 0x8000, 0x0048, 0x51dc, 0x600a,
+	0x0c7f, 0x127f, 0x0078, 0x5337, 0x0c7f, 0x127f, 0x0078, 0x532f,
+	0x6954, 0xa186, 0x0045, 0x0040, 0x5213, 0xa186, 0x002a, 0x00c0,
+	0x51f0, 0x2001, 0xa30c, 0x200c, 0xc194, 0x2102, 0x0078, 0x51c9,
+	0xa186, 0x0020, 0x0040, 0x5209, 0xa186, 0x0029, 0x0040, 0x51fc,
+	0xa186, 0x002d, 0x00c0, 0x51dc, 0x6944, 0xa18c, 0xff00, 0x810f,
+	0x1078, 0x4501, 0x00c0, 0x51c9, 0x6000, 0xc0e4, 0x6002, 0x0078,
+	0x51c9, 0x685c, 0xa065, 0x0040, 0x51dc, 0x2001, 0xa5a1, 0x2004,
+	0x6016, 0x0078, 0x51c9, 0x685c, 0xa065, 0x0040, 0x51dc, 0x0e7e,
+	0x6860, 0xa075, 0x2001, 0xa32e, 0x2004, 0xa005, 0x0040, 0x522b,
+	0x1078, 0x8c01, 0x8eff, 0x0040, 0x5228, 0x2e60, 0x1078, 0x8c01,
+	0x0e7f, 0x0078, 0x51c9, 0x6024, 0xc0dc, 0xc0d5, 0x6026, 0x2e60,
+	0x6007, 0x003a, 0x6870, 0xa005, 0x0040, 0x523c, 0x6007, 0x003b,
+	0x6874, 0x602a, 0x6878, 0x6012, 0x6003, 0x0001, 0x1078, 0x5bf8,
+	0x1078, 0x6109, 0x0e7f, 0x0078, 0x51c9, 0x2061, 0xa62d, 0x6000,
+	0xd084, 0x0040, 0x525f, 0xd08c, 0x00c0, 0x5345, 0x2091, 0x8000,
+	0x6204, 0x8210, 0x0048, 0x5259, 0x6206, 0x2091, 0x8001, 0x0078,
+	0x5345, 0x2091, 0x8001, 0x6853, 0x0016, 0x0078, 0x533e, 0x6853,
+	0x0007, 0x0078, 0x533e, 0x6834, 0x8007, 0xa084, 0x00ff, 0x00c0,
+	0x526d, 0x1078, 0x4f3c, 0x0078, 0x527f, 0x2030, 0x8001, 0x00c0,
+	0x5277, 0x7007, 0x0001, 0x1078, 0x5280, 0x0078, 0x527f, 0x7007,
+	0x0006, 0x7012, 0x2d00, 0x7016, 0x701a, 0x704b, 0x5280, 0x007c,
+	0x0e7e, 0x127e, 0x2091, 0x8000, 0x2009, 0xa32e, 0x210c, 0x81ff,
+	0x00c0, 0x530b, 0x2009, 0xa30c, 0x210c, 0xd194, 0x00c0, 0x5315,
+	0x6848, 0x2070, 0xae82, 0xaa00, 0x0048, 0x52fb, 0x2001, 0xa315,
+	0x2004, 0xae02, 0x00c8, 0x52fb, 0x2061, 0xa62d, 0x6100, 0xa184,
+	0x0301, 0xa086, 0x0001, 0x00c0, 0x52de, 0x711c, 0xa186, 0x0006,
+	0x00c0, 0x52e6, 0x7018, 0xa005, 0x0040, 0x530b, 0x2004, 0xd0e4,
+	0x00c0, 0x530f, 0x7024, 0xd0dc, 0x00c0, 0x5319, 0x6853, 0x0000,
+	0x6803, 0x0000, 0x2d08, 0x7010, 0xa005, 0x00c0, 0x52ca, 0x7112,
+	0x684c, 0xd0f4, 0x00c0, 0x531d, 0x2e60, 0x1078, 0x59b6, 0x127f,
+	0x0e7f, 0x007c, 0x2068, 0x6800, 0xa005, 0x00c0, 0x52ca, 0x6902,
+	0x2168, 0x684c, 0xd0f4, 0x00c0, 0x531d, 0x127f, 0x0e7f, 0x007c,
+	0x127f, 0x0e7f, 0x6853, 0x0006, 0x0078, 0x533e, 0xd184, 0x0040,
+	0x52d8, 0xd1c4, 0x00c0, 0x52ff, 0x0078, 0x5303, 0x6944, 0xa18c,
+	0xff00, 0x810f, 0x1078, 0x4501, 0x00c0, 0x530f, 0x6000, 0xd0e4,
+	0x00c0, 0x530f, 0x711c, 0xa186, 0x0007, 0x00c0, 0x52fb, 0x6853,
+	0x0002, 0x0078, 0x5311, 0x6853, 0x0008, 0x0078, 0x5311, 0x6853,
+	0x000e, 0x0078, 0x5311, 0x6853, 0x0017, 0x0078, 0x5311, 0x6853,
+	0x0035, 0x0078, 0x5311, 0x6853, 0x0028, 0x0078, 0x5311, 0x6853,
+	0x0029, 0x127f, 0x0e7f, 0x0078, 0x533e, 0x6853, 0x002a, 0x0078,
+	0x5311, 0x6853, 0x0045, 0x0078, 0x5311, 0x2e60, 0x2019, 0x0002,
+	0x6017, 0x0014, 0x1078, 0x9a6a, 0x127f, 0x0e7f, 0x007c, 0x2009,
+	0x003e, 0x0078, 0x5339, 0x2009, 0x0004, 0x0078, 0x5339, 0x2009,
+	0x0006, 0x0078, 0x5339, 0x2009, 0x0016, 0x0078, 0x5339, 0x2009,
+	0x0001, 0x6854, 0xa084, 0xff00, 0xa105, 0x6856, 0x2091, 0x8000,
+	0x1078, 0x4982, 0x2091, 0x8001, 0x007c, 0x1078, 0x139a, 0x007c,
+	0x702c, 0x7130, 0x8108, 0xa102, 0x0048, 0x5355, 0xa00e, 0x7034,
+	0x7072, 0x7038, 0x7076, 0x0078, 0x5361, 0x7070, 0xa080, 0x0040,
+	0x7072, 0x00c8, 0x5361, 0x7074, 0xa081, 0x0000, 0x7076, 0xa085,
+	0x0001, 0x7932, 0x7132, 0x007c, 0x0d7e, 0x1078, 0x59ad, 0x0d7f,
+	0x007c, 0x0d7e, 0x2011, 0x0004, 0x2204, 0xa085, 0x8002, 0x2012,
+	0x0d7f, 0x007c, 0x20e1, 0x0002, 0x3d08, 0x20e1, 0x2000, 0x3d00,
+	0xa084, 0x7000, 0x0040, 0x5380, 0xa086, 0x1000, 0x00c0, 0x53ac,
+	0x20e1, 0x0000, 0x3d00, 0xa094, 0xff00, 0x8217, 0xa084, 0xf000,
+	0xa086, 0x3000, 0x00c0, 0x5390, 0x1078, 0x5570, 0x0078, 0x53a7,
+	0x20e1, 0x0004, 0x3d60, 0xd1bc, 0x00c0, 0x5397, 0x3e60, 0xac84,
+	0x000f, 0x00c0, 0x53ac, 0xac82, 0xaa00, 0x0048, 0x53ac, 0x6854,
+	0xac02, 0x00c8, 0x53ac, 0x2009, 0x0047, 0x1078, 0x756c, 0x7a1c,
+	0xd284, 0x00c0, 0x5372, 0x007c, 0xa016, 0x1078, 0x15ec, 0x0078,
+	0x53a7, 0x0078, 0x53ac, 0x781c, 0xd08c, 0x0040, 0x53db, 0x157e,
+	0x137e, 0x147e, 0x20e1, 0x3000, 0x3d20, 0x3e28, 0xa584, 0x0076,
+	0x00c0, 0x53f1, 0xa484, 0x7000, 0xa086, 0x1000, 0x00c0, 0x53e0,
+	0x1078, 0x540c, 0x0040, 0x53f1, 0x20e1, 0x3000, 0x7828, 0x7828,
+	0x1078, 0x542a, 0x147f, 0x137f, 0x157f, 0x2009, 0xa5b3, 0x2104,
+	0xa005, 0x00c0, 0x53dc, 0x007c, 0x1078, 0x6109, 0x0078, 0x53db,
+	0xa484, 0x7000, 0x00c0, 0x53f1, 0x1078, 0x540c, 0x0040, 0x5403,
+	0x7000, 0xa084, 0xff00, 0xa086, 0x8100, 0x0040, 0x53cc, 0x0078,
+	0x5403, 0x1078, 0xa1ee, 0xd5a4, 0x0040, 0x53ff, 0x1078, 0x1af7,
+	0x20e1, 0x9010, 0x2001, 0x0138, 0x2202, 0x0078, 0x5407, 0x1078,
+	0x540c, 0x687f, 0x0000, 0x20e1, 0x3000, 0x7828, 0x7828, 0x147f,
+	0x137f, 0x157f, 0x0078, 0x53db, 0xa484, 0x01ff, 0x687e, 0xa005,
+	0x0040, 0x541e, 0xa080, 0x001f, 0xa084, 0x03f8, 0x80ac, 0x20e1,
+	0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5, 0x007c, 0x20a9, 0x000c,
+	0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5, 0xa085, 0x0001,
+	0x0078, 0x541d, 0x7000, 0xa084, 0xff00, 0xa08c, 0xf000, 0x8007,
+	0xa196, 0x0000, 0x00c0, 0x5437, 0x0078, 0x567c, 0x007c, 0xa196,
+	0x2000, 0x00c0, 0x5448, 0x6900, 0xa18e, 0x0001, 0x00c0, 0x5444,
+	0x1078, 0x3a43, 0x0078, 0x5436, 0x1078, 0x5450, 0x0078, 0x5436,
+	0xa196, 0x8000, 0x00c0, 0x5436, 0x1078, 0x570c, 0x0078, 0x5436,
+	0x0c7e, 0x7110, 0xa18c, 0xff00, 0x810f, 0xa196, 0x0001, 0x0040,
+	0x545d, 0xa196, 0x0023, 0x00c0, 0x5568, 0xa08e, 0x0023, 0x00c0,
+	0x5492, 0x1078, 0x57b2, 0x0040, 0x5568, 0x7124, 0x610a, 0x7030,
+	0xa08e, 0x0200, 0x00c0, 0x5476, 0x7034, 0xa005, 0x00c0, 0x5568,
+	0x2009, 0x0015, 0x1078, 0x756c, 0x0078, 0x5568, 0xa08e, 0x0214,
+	0x0040, 0x547e, 0xa08e, 0x0210, 0x00c0, 0x5484, 0x2009, 0x0015,
+	0x1078, 0x756c, 0x0078, 0x5568, 0xa08e, 0x0100, 0x00c0, 0x5568,
+	0x7034, 0xa005, 0x00c0, 0x5568, 0x2009, 0x0016, 0x1078, 0x756c,
+	0x0078, 0x5568, 0xa08e, 0x0022, 0x00c0, 0x5568, 0x7030, 0xa08e,
+	0x0300, 0x00c0, 0x54a3, 0x7034, 0xa005, 0x00c0, 0x5568, 0x2009,
+	0x0017, 0x0078, 0x5534, 0xa08e, 0x0500, 0x00c0, 0x54af, 0x7034,
+	0xa005, 0x00c0, 0x5568, 0x2009, 0x0018, 0x0078, 0x5534, 0xa08e,
+	0x2010, 0x00c0, 0x54b7, 0x2009, 0x0019, 0x0078, 0x5534, 0xa08e,
+	0x2110, 0x00c0, 0x54bf, 0x2009, 0x001a, 0x0078, 0x5534, 0xa08e,
+	0x5200, 0x00c0, 0x54cb, 0x7034, 0xa005, 0x00c0, 0x5568, 0x2009,
+	0x001b, 0x0078, 0x5534, 0xa08e, 0x5000, 0x00c0, 0x54d7, 0x7034,
+	0xa005, 0x00c0, 0x5568, 0x2009, 0x001c, 0x0078, 0x5534, 0xa08e,
+	0x1300, 0x00c0, 0x54df, 0x2009, 0x0034, 0x0078, 0x5534, 0xa08e,
+	0x1200, 0x00c0, 0x54eb, 0x7034, 0xa005, 0x00c0, 0x5568, 0x2009,
+	0x0024, 0x0078, 0x5534, 0xa08c, 0xff00, 0xa18e, 0x2400, 0x00c0,
+	0x54f5, 0x2009, 0x002d, 0x0078, 0x5534, 0xa08c, 0xff00, 0xa18e,
+	0x5300, 0x00c0, 0x54ff, 0x2009, 0x002a, 0x0078, 0x5534, 0xa08e,
+	0x0f00, 0x00c0, 0x5507, 0x2009, 0x0020, 0x0078, 0x5534, 0xa08e,
+	0x5300, 0x00c0, 0x550d, 0x0078, 0x552a, 0xa08e, 0x6104, 0x00c0,
+	0x552a, 0x2011, 0xa88d, 0x8208, 0x2204, 0xa082, 0x0004, 0x20a8,
+	0x95ac, 0x95ac, 0x2011, 0x8015, 0x211c, 0x8108, 0x047e, 0x2124,
+	0x1078, 0x3579, 0x047f, 0x8108, 0x00f0, 0x551a, 0x2009, 0x0023,
+	0x0078, 0x5534, 0xa08e, 0x6000, 0x00c0, 0x5532, 0x2009, 0x003f,
+	0x0078, 0x5534, 0x2009, 0x001d, 0x017e, 0x2011, 0xa883, 0x2204,
+	0x8211, 0x220c, 0x1078, 0x24e3, 0x00c0, 0x556a, 0x1078, 0x4499,
+	0x00c0, 0x556a, 0x6612, 0x6516, 0x86ff, 0x0040, 0x555a, 0x017f,
+	0x017e, 0xa186, 0x0017, 0x00c0, 0x555a, 0x6868, 0xa606, 0x00c0,
+	0x555a, 0x686c, 0xa506, 0xa084, 0xff00, 0x00c0, 0x555a, 0x6000,
+	0xc0f5, 0x6002, 0x0c7e, 0x1078, 0x74d7, 0x0040, 0x556d, 0x017f,
+	0x611a, 0x601f, 0x0004, 0x7120, 0x610a, 0x017f, 0x1078, 0x756c,
+	0x0c7f, 0x007c, 0x017f, 0x0078, 0x5568, 0x0c7f, 0x0078, 0x556a,
+	0x0c7e, 0x1078, 0x55d4, 0x00c0, 0x55d2, 0xa184, 0xff00, 0x8007,
+	0xa086, 0x0008, 0x00c0, 0x55d2, 0xa28e, 0x0033, 0x00c0, 0x55a3,
+	0x1078, 0x57b2, 0x0040, 0x55d2, 0x7124, 0x610a, 0x7030, 0xa08e,
+	0x0200, 0x00c0, 0x5595, 0x7034, 0xa005, 0x00c0, 0x55d2, 0x2009,
+	0x0015, 0x1078, 0x756c, 0x0078, 0x55d2, 0xa08e, 0x0100, 0x00c0,
+	0x55d2, 0x7034, 0xa005, 0x00c0, 0x55d2, 0x2009, 0x0016, 0x1078,
+	0x756c, 0x0078, 0x55d2, 0xa28e, 0x0032, 0x00c0, 0x55d2, 0x7030,
+	0xa08e, 0x1400, 0x00c0, 0x55d2, 0x2009, 0x0038, 0x017e, 0x2011,
+	0xa883, 0x2204, 0x8211, 0x220c, 0x1078, 0x24e3, 0x00c0, 0x55d1,
+	0x1078, 0x4499, 0x00c0, 0x55d1, 0x6612, 0x6516, 0x0c7e, 0x1078,
+	0x74d7, 0x0040, 0x55d0, 0x017f, 0x611a, 0x601f, 0x0004, 0x7120,
+	0x610a, 0x017f, 0x1078, 0x756c, 0x1078, 0x6109, 0x0078, 0x55d2,
+	0x0c7f, 0x017f, 0x0c7f, 0x007c, 0x0f7e, 0x0d7e, 0x027e, 0x017e,
+	0x137e, 0x147e, 0x157e, 0x3c00, 0x007e, 0x2079, 0x0030, 0x2069,
+	0x0200, 0x1078, 0x1c25, 0x00c0, 0x5615, 0x1078, 0x1b15, 0x0040,
+	0x561f, 0x7908, 0xa18c, 0x1fff, 0xa182, 0x0011, 0x00c8, 0x561f,
+	0x20a9, 0x000c, 0x20e1, 0x0000, 0x2ea0, 0x2099, 0x020a, 0x53a5,
+	0x20e1, 0x2000, 0x2001, 0x020a, 0x2004, 0x7a0c, 0x7808, 0xa080,
+	0x0007, 0xa084, 0x1ff8, 0xa08a, 0x0140, 0x10c8, 0x1328, 0x80ac,
+	0x20e1, 0x6000, 0x2099, 0x020a, 0x53a5, 0x20e1, 0x7000, 0x6828,
+	0x6828, 0x7803, 0x0004, 0xa294, 0x0070, 0x007f, 0x20e0, 0x157f,
+	0x147f, 0x137f, 0x017f, 0x027f, 0x0d7f, 0x0f7f, 0x007c, 0xa085,
+	0x0001, 0x0078, 0x5615, 0x047e, 0x0e7e, 0x0d7e, 0x2028, 0x2130,
+	0xa696, 0x00ff, 0x00c0, 0x5644, 0xa596, 0xfffd, 0x00c0, 0x5634,
+	0x2009, 0x007f, 0x0078, 0x5677, 0xa596, 0xfffe, 0x00c0, 0x563c,
+	0x2009, 0x007e, 0x0078, 0x5677, 0xa596, 0xfffc, 0x00c0, 0x5644,
+	0x2009, 0x0080, 0x0078, 0x5677, 0x2011, 0x0000, 0x2021, 0x0081,
+	0x20a9, 0x007e, 0x2071, 0xa4b5, 0x2e1c, 0x83ff, 0x00c0, 0x5656,
+	0x82ff, 0x00c0, 0x566b, 0x2410, 0x0078, 0x566b, 0x2368, 0x6f10,
+	0x007e, 0x2100, 0xa706, 0x007f, 0x6b14, 0x00c0, 0x5665, 0xa346,
+	0x00c0, 0x5665, 0x2408, 0x0078, 0x5677, 0x87ff, 0x00c0, 0x566b,
+	0x83ff, 0x0040, 0x5650, 0x8420, 0x8e70, 0x00f0, 0x564c, 0x82ff,
+	0x00c0, 0x5676, 0xa085, 0x0001, 0x0078, 0x5678, 0x2208, 0xa006,
+	0x0d7f, 0x0e7f, 0x047f, 0x007c, 0xa084, 0x0007, 0x0079, 0x5681,
+	0x007c, 0x5689, 0x5689, 0x5689, 0x57c8, 0x5689, 0x568a, 0x56a3,
+	0x56f3, 0x007c, 0x7110, 0xd1bc, 0x0040, 0x56a2, 0x7120, 0x2160,
+	0xac8c, 0x000f, 0x00c0, 0x56a2, 0xac8a, 0xaa00, 0x0048, 0x56a2,
+	0x6854, 0xac02, 0x00c8, 0x56a2, 0x7124, 0x610a, 0x2009, 0x0046,
+	0x1078, 0x756c, 0x007c, 0x0c7e, 0x7110, 0xd1bc, 0x00c0, 0x56f1,
+	0x2011, 0xa883, 0x2204, 0x8211, 0x220c, 0x1078, 0x24e3, 0x00c0,
+	0x56f1, 0x1078, 0x4499, 0x00c0, 0x56f1, 0x6612, 0x6516, 0x6000,
+	0xd0ec, 0x00c0, 0x56f1, 0x6204, 0xa294, 0xff00, 0x8217, 0xa286,
+	0x0006, 0x00c0, 0x56d6, 0x0c7e, 0x1078, 0x74d7, 0x017f, 0x0040,
+	0x56f1, 0x611a, 0x601f, 0x0006, 0x7120, 0x610a, 0x7130, 0x6122,
+	0x2009, 0x0044, 0x1078, 0x756c, 0x0078, 0x56f1, 0x0c7e, 0x1078,
+	0x74d7, 0x017f, 0x0040, 0x56f1, 0x611a, 0x601f, 0x0004, 0x7120,
+	0x610a, 0xa286, 0x0004, 0x00c0, 0x56e9, 0x6007, 0x0005, 0x0078,
+	0x56eb, 0x6007, 0x0001, 0x6003, 0x0001, 0x1078, 0x5c45, 0x1078,
+	0x6109, 0x0c7f, 0x007c, 0x7110, 0xd1bc, 0x0040, 0x570b, 0x7020,
+	0x2060, 0xac84, 0x000f, 0x00c0, 0x570b, 0xac82, 0xaa00, 0x0048,
+	0x570b, 0x6854, 0xac02, 0x00c8, 0x570b, 0x7124, 0x610a, 0x2009,
+	0x0045, 0x1078, 0x756c, 0x007c, 0x7110, 0xa18c, 0xff00, 0x810f,
+	0xa18e, 0x0000, 0x00c0, 0x571c, 0xa084, 0x000f, 0xa08a, 0x0006,
+	0x00c8, 0x571c, 0x1079, 0x571d, 0x007c, 0x5723, 0x5724, 0x5723,
+	0x5723, 0x5794, 0x57a3, 0x007c, 0x7110, 0xd1bc, 0x0040, 0x572c,
+	0x702c, 0xd084, 0x0040, 0x5793, 0x700c, 0x7108, 0x1078, 0x24e3,
+	0x00c0, 0x5793, 0x1078, 0x4499, 0x00c0, 0x5793, 0x6612, 0x6516,
+	0x6204, 0x7110, 0xd1bc, 0x0040, 0x575e, 0xa28c, 0x00ff, 0xa186,
+	0x0004, 0x0040, 0x5747, 0xa186, 0x0006, 0x00c0, 0x5784, 0x0c7e,
+	0x1078, 0x57b2, 0x0c7f, 0x0040, 0x5793, 0x0c7e, 0x1078, 0x74d7,
+	0x017f, 0x0040, 0x5793, 0x611a, 0x601f, 0x0002, 0x7120, 0x610a,
+	0x2009, 0x0088, 0x1078, 0x756c, 0x0078, 0x5793, 0xa28c, 0x00ff,
+	0xa186, 0x0006, 0x0040, 0x5773, 0xa186, 0x0004, 0x0040, 0x5773,
+	0xa294, 0xff00, 0x8217, 0xa286, 0x0004, 0x0040, 0x5773, 0xa286,
+	0x0006, 0x00c0, 0x5784, 0x0c7e, 0x1078, 0x74d7, 0x017f, 0x0040,
+	0x5793, 0x611a, 0x601f, 0x0005, 0x7120, 0x610a, 0x2009, 0x0088,
+	0x1078, 0x756c, 0x0078, 0x5793, 0x0c7e, 0x1078, 0x74d7, 0x017f,
+	0x0040, 0x5793, 0x611a, 0x601f, 0x0004, 0x7120, 0x610a, 0x2009,
+	0x0001, 0x1078, 0x756c, 0x007c, 0x7110, 0xd1bc, 0x0040, 0x57a2,
+	0x1078, 0x57b2, 0x0040, 0x57a2, 0x7124, 0x610a, 0x2009, 0x0089,
+	0x1078, 0x756c, 0x007c, 0x7110, 0xd1bc, 0x0040, 0x57b1, 0x1078,
+	0x57b2, 0x0040, 0x57b1, 0x7124, 0x610a, 0x2009, 0x008a, 0x1078,
+	0x756c, 0x007c, 0x7020, 0x2060, 0xac84, 0x000f, 0x00c0, 0x57c5,
+	0xac82, 0xaa00, 0x0048, 0x57c5, 0x2001, 0xa315, 0x2004, 0xac02,
+	0x00c8, 0x57c5, 0xa085, 0x0001, 0x007c, 0xa006, 0x0078, 0x57c4,
+	0x7110, 0xd1bc, 0x00c0, 0x57de, 0x7024, 0x2060, 0xac84, 0x000f,
+	0x00c0, 0x57de, 0xac82, 0xaa00, 0x0048, 0x57de, 0x6854, 0xac02,
+	0x00c8, 0x57de, 0x2009, 0x0051, 0x1078, 0x756c, 0x007c, 0x2071,
+	0xa5be, 0x7003, 0x0003, 0x700f, 0x0361, 0xa006, 0x701a, 0x7012,
+	0x7017, 0xaa00, 0x7007, 0x0000, 0x7026, 0x702b, 0x6c4e, 0x7032,
+	0x7037, 0x6ca0, 0x703b, 0x0002, 0x703f, 0x0000, 0x7043, 0xffff,
+	0x7047, 0xffff, 0x007c, 0x2071, 0xa5be, 0x00e0, 0x58c1, 0x2091,
+	0x6000, 0x700c, 0x8001, 0x700e, 0x00c0, 0x5873, 0x700f, 0x0361,
+	0x7007, 0x0001, 0x127e, 0x2091, 0x8000, 0x7138, 0x8109, 0x713a,
+	0x00c0, 0x5871, 0x703b, 0x0002, 0x2009, 0x0100, 0x2104, 0xa082,
+	0x0003, 0x00c8, 0x5871, 0x703c, 0xa086, 0x0001, 0x00c0, 0x584e,
+	0x0d7e, 0x2069, 0x0140, 0x6804, 0xa084, 0x4000, 0x0040, 0x582c,
+	0x6803, 0x1000, 0x0078, 0x5833, 0x6804, 0xa084, 0x1000, 0x0040,
+	0x5833, 0x6803, 0x0100, 0x6803, 0x0000, 0x703f, 0x0000, 0x2069,
+	0xa5ab, 0x6804, 0xa082, 0x0006, 0x00c0, 0x5840, 0x6807, 0x0000,
+	0x6830, 0xa082, 0x0003, 0x00c0, 0x5847, 0x6833, 0x0000, 0x1078,
+	0x6109, 0x1078, 0x61d3, 0x0d7f, 0x0078, 0x5871, 0x0d7e, 0x2069,
+	0xa300, 0x6944, 0x6860, 0xa102, 0x00c8, 0x5870, 0x2069, 0xa5ab,
+	0x6804, 0xa086, 0x0000, 0x00c0, 0x5870, 0x6830, 0xa086, 0x0000,
+	0x00c0, 0x5870, 0x703f, 0x0001, 0x6807, 0x0006, 0x6833, 0x0003,
+	0x2069, 0x0100, 0x6830, 0x689e, 0x2069, 0x0140, 0x6803, 0x0600,
+	0x0d7f, 0x0078, 0x5876, 0x127e, 0x2091, 0x8000, 0x7024, 0xa00d,
+	0x0040, 0x588e, 0x7020, 0x8001, 0x7022, 0x00c0, 0x588e, 0x7023,
+	0x0009, 0x8109, 0x7126, 0xa186, 0x03e8, 0x00c0, 0x5889, 0x7028,
+	0x107a, 0x81ff, 0x00c0, 0x588e, 0x7028, 0x107a, 0x7030, 0xa00d,
+	0x0040, 0x589f, 0x702c, 0x8001, 0x702e, 0x00c0, 0x589f, 0x702f,
+	0x0009, 0x8109, 0x7132, 0x00c0, 0x589f, 0x7034, 0x107a, 0x7040,
+	0xa005, 0x0040, 0x58a7, 0x0050, 0x58a7, 0x8001, 0x7042, 0x7044,
+	0xa005, 0x0040, 0x58af, 0x0050, 0x58af, 0x8001, 0x7046, 0x7018,
+	0xa00d, 0x0040, 0x58c0, 0x7008, 0x8001, 0x700a, 0x00c0, 0x58c0,
+	0x700b, 0x0009, 0x8109, 0x711a, 0x00c0, 0x58c0, 0x701c, 0x107a,
+	0x127f, 0x7004, 0x0079, 0x58c4, 0x58eb, 0x58ec, 0x5908, 0x0e7e,
+	0x2071, 0xa5be, 0x7018, 0xa005, 0x00c0, 0x58d2, 0x711a, 0x721e,
+	0x700b, 0x0009, 0x0e7f, 0x007c, 0x0e7e, 0x007e, 0x2071, 0xa5be,
+	0x701c, 0xa206, 0x00c0, 0x58de, 0x701a, 0x701e, 0x007f, 0x0e7f,
+	0x007c, 0x0e7e, 0x2071, 0xa5be, 0x6088, 0xa102, 0x0048, 0x58e9,
+	0x618a, 0x0e7f, 0x007c, 0x007c, 0x7110, 0x1078, 0x4501, 0x00c0,
+	0x58fe, 0x6088, 0x8001, 0x0048, 0x58fe, 0x608a, 0x00c0, 0x58fe,
+	0x127e, 0x2091, 0x8000, 0x1078, 0x6109, 0x127f, 0x8108, 0xa182,
+	0x00ff, 0x0048, 0x5906, 0xa00e, 0x7007, 0x0002, 0x7112, 0x007c,
+	0x7014, 0x2060, 0x127e, 0x2091, 0x8000, 0x603c, 0xa005, 0x0040,
+	0x5917, 0x8001, 0x603e, 0x00c0, 0x5917, 0x1078, 0x8cd7, 0x6014,
+	0xa005, 0x0040, 0x5941, 0x8001, 0x6016, 0x00c0, 0x5941, 0x611c,
+	0xa186, 0x0003, 0x0040, 0x5928, 0xa186, 0x0006, 0x00c0, 0x593f,
+	0x6010, 0x2068, 0x6854, 0xa08a, 0x199a, 0x0048, 0x593f, 0xa082,
+	0x1999, 0x6856, 0xa08a, 0x199a, 0x0048, 0x5938, 0x2001, 0x1999,
+	0x8003, 0x800b, 0x810b, 0xa108, 0x6116, 0x0078, 0x5941, 0x1078,
+	0x8810, 0x127f, 0xac88, 0x0010, 0x7116, 0x2001, 0xca00, 0xa102,
+	0x0048, 0x594e, 0x7017, 0xaa00, 0x7007, 0x0000, 0x007c, 0x0e7e,
+	0x2071, 0xa5be, 0x7027, 0x07d0, 0x7023, 0x0009, 0x703b, 0x0002,
+	0x0e7f, 0x007c, 0x2001, 0xa5c7, 0x2003, 0x0000, 0x007c, 0x0e7e,
+	0x2071, 0xa5be, 0x7132, 0x702f, 0x0009, 0x0e7f, 0x007c, 0x2011,
+	0xa5ca, 0x2013, 0x0000, 0x007c, 0x0e7e, 0x2071, 0xa5be, 0x711a,
+	0x721e, 0x700b, 0x0009, 0x0e7f, 0x007c, 0x027e, 0x0e7e, 0x0f7e,
+	0x2079, 0xa300, 0x7a34, 0xd294, 0x0040, 0x59a4, 0x2071, 0xa5aa,
+	0x2e14, 0xa0fe, 0x0000, 0x0040, 0x5991, 0xa0fe, 0x0001, 0x0040,
+	0x5995, 0xa0fe, 0x0002, 0x00c0, 0x59a0, 0xa292, 0x0085, 0x0078,
+	0x5997, 0xa292, 0x0005, 0x0078, 0x5997, 0xa292, 0x0002, 0x2272,
+	0x0040, 0x599c, 0x00c8, 0x59a4, 0x2011, 0x8037, 0x1078, 0x3579,
+	0x2011, 0xa5a9, 0x2204, 0x2072, 0x0f7f, 0x0e7f, 0x027f, 0x007c,
+	0x0c7e, 0x2061, 0xa62d, 0x0c7f, 0x007c, 0xa184, 0x000f, 0x8003,
+	0x8003, 0x8003, 0xa080, 0xa62d, 0x2060, 0x007c, 0x6854, 0xa08a,
+	0x199a, 0x0048, 0x59bd, 0x2001, 0x1999, 0xa005, 0x00c0, 0x59cc,
+	0x0c7e, 0x2061, 0xa62d, 0x6014, 0x0c7f, 0xa005, 0x00c0, 0x59d1,
+	0x2001, 0x001e, 0x0078, 0x59d1, 0xa08e, 0xffff, 0x00c0, 0x59d1,
+	0xa006, 0x8003, 0x800b, 0x810b, 0xa108, 0x6116, 0x684c, 0xa08c,
+	0x00c0, 0xa18e, 0x00c0, 0x0040, 0x5a24, 0xd0b4, 0x00c0, 0x59e8,
+	0xd0bc, 0x00c0, 0x5a14, 0x2009, 0x0006, 0x1078, 0x5a43, 0x007c,
+	0xd0fc, 0x0040, 0x59f3, 0xa084, 0x0003, 0x0040, 0x59f3, 0xa086,
+	0x0003, 0x00c0, 0x5a3c, 0x6024, 0xd0d4, 0x0040, 0x59fd, 0xc0d4,
+	0x6026, 0x6860, 0x602a, 0x685c, 0x602e, 0x2009, 0xa373, 0x2104,
+	0xd084, 0x0040, 0x5a0f, 0x6118, 0xa188, 0x0027, 0x2104, 0xd08c,
+	0x00c0, 0x5a0f, 0x2009, 0x0042, 0x1078, 0x756c, 0x007c, 0x2009,
+	0x0043, 0x1078, 0x756c, 0x007c, 0xd0fc, 0x0040, 0x5a1f, 0xa084,
+	0x0003, 0x0040, 0x5a1f, 0xa086, 0x0003, 0x00c0, 0x5a3c, 0x2009,
+	0x0042, 0x1078, 0x756c, 0x007c, 0xd0fc, 0x0040, 0x5a32, 0xa084,
+	0x0003, 0xa08e, 0x0002, 0x0040, 0x5a36, 0x2009, 0x0041, 0x1078,
+	0x756c, 0x007c, 0x1078, 0x5a41, 0x0078, 0x5a31, 0x2009, 0x0043,
+	0x1078, 0x756c, 0x0078, 0x5a31, 0x2009, 0x0004, 0x1078, 0x5a43,
+	0x007c, 0x2009, 0x0001, 0x0d7e, 0x6010, 0xa0ec, 0xf000, 0x0040,
+	0x5a6b, 0x2068, 0x6952, 0x6800, 0x6012, 0xa186, 0x0001, 0x00c0,
+	0x5a65, 0x694c, 0xa18c, 0x8100, 0xa18e, 0x8100, 0x00c0, 0x5a65,
+	0x0c7e, 0x2061, 0xa62d, 0x6200, 0xd28c, 0x00c0, 0x5a64, 0x6204,
+	0x8210, 0x0048, 0x5a64, 0x6206, 0x0c7f, 0x1078, 0x4982, 0x6010,
+	0xa06d, 0x10c0, 0x59b6, 0x0d7f, 0x007c, 0x157e, 0x0c7e, 0x2061,
+	0xa62d, 0x6000, 0x81ff, 0x0040, 0x5a78, 0xa205, 0x0078, 0x5a79,
+	0xa204, 0x6002, 0x0c7f, 0x157f, 0x007c, 0x6800, 0xd08c, 0x00c0,
+	0x5a89, 0x6808, 0xa005, 0x0040, 0x5a89, 0x8001, 0x680a, 0xa085,
+	0x0001, 0x007c, 0x20a9, 0x0010, 0xa006, 0x8004, 0x8086, 0x818e,
+	0x00c8, 0x5a93, 0xa200, 0x00f0, 0x5a8e, 0x8086, 0x818e, 0x007c,
+	0x157e, 0x20a9, 0x0010, 0xa005, 0x0040, 0x5ab9, 0xa11a, 0x00c8,
+	0x5ab9, 0x8213, 0x818d, 0x0048, 0x5aac, 0xa11a, 0x00c8, 0x5aad,
+	0x00f0, 0x5aa1, 0x0078, 0x5ab1, 0xa11a, 0x2308, 0x8210, 0x00f0,
+	0x5aa1, 0x007e, 0x3200, 0xa084, 0xf7ff, 0x2080, 0x007f, 0x157f,
+	0x007c, 0x007e, 0x3200, 0xa085, 0x0800, 0x0078, 0x5ab5, 0x127e,
+	0x2091, 0x2200, 0x2079, 0xa5ab, 0x127f, 0x0d7e, 0x2069, 0xa5ab,
+	0x6803, 0x0005, 0x2069, 0x0004, 0x2d04, 0xa085, 0x8001, 0x206a,
+	0x0d7f, 0x007c, 0x0c7e, 0x6027, 0x0001, 0x7804, 0xa084, 0x0007,
+	0x0079, 0x5ada, 0x5ae4, 0x5b09, 0x5b64, 0x5aea, 0x5b09, 0x5ae4,
+	0x5ae2, 0x5ae2, 0x1078, 0x1328, 0x1078, 0x595a, 0x1078, 0x6109,
+	0x0c7f, 0x007c, 0x62c0, 0x82ff, 0x00c0, 0x5af0, 0x0c7f, 0x007c,
+	0x2011, 0x4129, 0x1078, 0x58d4, 0x7828, 0xa092, 0x00c8, 0x00c8,
+	0x5aff, 0x8000, 0x782a, 0x1078, 0x4168, 0x0078, 0x5aee, 0x1078,
+	0x4129, 0x7807, 0x0003, 0x7827, 0x0000, 0x782b, 0x0000, 0x0078,
+	0x5aee, 0x1078, 0x595a, 0x3c00, 0x007e, 0x2011, 0x0209, 0x20e1,
+	0x4000, 0x2214, 0x007f, 0x20e0, 0x82ff, 0x0040, 0x5b27, 0x62c0,
+	0x82ff, 0x00c0, 0x5b27, 0x782b, 0x0000, 0x7824, 0xa065, 0x1040,
+	0x1328, 0x2009, 0x0013, 0x1078, 0x756c, 0x0c7f, 0x007c, 0x3900,
+	0xa082, 0xa6cd, 0x00c8, 0x5b2e, 0x1078, 0x728a, 0x0c7e, 0x7824,
+	0xa065, 0x1040, 0x1328, 0x7804, 0xa086, 0x0004, 0x0040, 0x5ba9,
+	0x7828, 0xa092, 0x2710, 0x00c8, 0x5b44, 0x8000, 0x782a, 0x0c7f,
+	0x1078, 0x6c33, 0x0078, 0x5b25, 0x6104, 0xa186, 0x0003, 0x00c0,
+	0x5b5b, 0x0e7e, 0x2071, 0xa300, 0x70d4, 0x0e7f, 0xd08c, 0x0040,
+	0x5b5b, 0x0c7e, 0x0e7e, 0x2061, 0x0100, 0x2071, 0xa300, 0x1078,
+	0x4171, 0x0e7f, 0x0c7f, 0x1078, 0xa241, 0x2009, 0x0014, 0x1078,
+	0x756c, 0x0c7f, 0x0078, 0x5b25, 0x2001, 0xa5c7, 0x2003, 0x0000,
+	0x62c0, 0x82ff, 0x00c0, 0x5b78, 0x782b, 0x0000, 0x7824, 0xa065,
+	0x1040, 0x1328, 0x2009, 0x0013, 0x1078, 0x75c3, 0x0c7f, 0x007c,
+	0x0c7e, 0x0d7e, 0x3900, 0xa082, 0xa6cd, 0x00c8, 0x5b81, 0x1078,
+	0x728a, 0x7824, 0xa005, 0x1040, 0x1328, 0x781c, 0xa06d, 0x1040,
+	0x1328, 0x6800, 0xc0dc, 0x6802, 0x7924, 0x2160, 0x1078, 0x753d,
+	0x693c, 0x81ff, 0x1040, 0x1328, 0x8109, 0x693e, 0x6854, 0xa015,
+	0x0040, 0x5b9d, 0x7a1e, 0x0078, 0x5b9f, 0x7918, 0x791e, 0x7807,
+	0x0000, 0x7827, 0x0000, 0x0d7f, 0x0c7f, 0x1078, 0x6109, 0x0078,
+	0x5b76, 0x6104, 0xa186, 0x0002, 0x0040, 0x5bb4, 0xa186, 0x0004,
+	0x0040, 0x5bb4, 0x0078, 0x5b38, 0x7808, 0xac06, 0x0040, 0x5b38,
+	0x1078, 0x6010, 0x1078, 0x5c45, 0x0c7f, 0x1078, 0x6109, 0x0078,
+	0x5b25, 0x0c7e, 0x6027, 0x0002, 0x62c8, 0x82ff, 0x00c0, 0x5bdb,
+	0x62c4, 0x82ff, 0x00c0, 0x5bdb, 0x793c, 0xa1e5, 0x0000, 0x0040,
+	0x5bd5, 0x2009, 0x0049, 0x1078, 0x756c, 0x2011, 0xa5ca, 0x2013,
+	0x0000, 0x0c7f, 0x007c, 0x3908, 0xa192, 0xa6cd, 0x00c8, 0x5be2,
+	0x1078, 0x728a, 0x6017, 0x0010, 0x793c, 0x81ff, 0x0040, 0x5bd5,
+	0x793c, 0xa188, 0x0007, 0x210c, 0xa18e, 0x0006, 0x00c0, 0x5bf4,
+	0x6017, 0x0012, 0x0078, 0x5bd9, 0x6017, 0x0016, 0x0078, 0x5bd9,
+	0x007e, 0x017e, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x600f, 0x0000,
+	0x2c08, 0x2061, 0xa5ab, 0x6020, 0x8000, 0x6022, 0x6010, 0xa005,
+	0x0040, 0x5c13, 0xa080, 0x0003, 0x2102, 0x6112, 0x127f, 0x0c7f,
+	0x017f, 0x007f, 0x007c, 0x6116, 0x6112, 0x0078, 0x5c0e, 0x0d7e,
+	0x2069, 0xa5ab, 0x6000, 0xd0d4, 0x0040, 0x5c2c, 0x6820, 0x8000,
+	0x6822, 0xa086, 0x0001, 0x00c0, 0x5c27, 0x2c00, 0x681e, 0x6804,
+	0xa084, 0x0007, 0x0079, 0x6111, 0xc0d5, 0x6002, 0x6818, 0xa005,
+	0x0040, 0x5c3e, 0x6056, 0x605b, 0x0000, 0x007e, 0x2c00, 0x681a,
+	0x0d7f, 0x685a, 0x2069, 0xa5ab, 0x0078, 0x5c1e, 0x6056, 0x605a,
+	0x2c00, 0x681a, 0x681e, 0x0078, 0x5c1e, 0x007e, 0x017e, 0x0c7e,
+	0x127e, 0x2091, 0x8000, 0x600f, 0x0000, 0x2c08, 0x2061, 0xa5ab,
+	0x6020, 0x8000, 0x6022, 0x6008, 0xa005, 0x0040, 0x5c60, 0xa080,
+	0x0003, 0x2102, 0x610a, 0x127f, 0x0c7f, 0x017f, 0x007f, 0x007c,
+	0x610e, 0x610a, 0x0078, 0x5c5b, 0x0c7e, 0x600f, 0x0000, 0x2c08,
+	0x2061, 0xa5ab, 0x6034, 0xa005, 0x0040, 0x5c74, 0xa080, 0x0003,
+	0x2102, 0x6136, 0x0c7f, 0x007c, 0x613a, 0x6136, 0x0078, 0x5c72,
+	0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x027e, 0x017e, 0x007e,
+	0x127e, 0x2071, 0xa5ab, 0x7638, 0x2660, 0x2678, 0x2091, 0x8000,
+	0x8cff, 0x0040, 0x5ced, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206,
+	0x00c0, 0x5ce8, 0x87ff, 0x0040, 0x5c99, 0x6020, 0xa106, 0x00c0,
+	0x5ce8, 0x703c, 0xac06, 0x00c0, 0x5cab, 0x037e, 0x2019, 0x0001,
+	0x1078, 0x6e6c, 0x7033, 0x0000, 0x703f, 0x0000, 0x7043, 0x0000,
+	0x7047, 0x0000, 0x037f, 0x7038, 0xac36, 0x00c0, 0x5cb1, 0x660c,
+	0x763a, 0x7034, 0xac36, 0x00c0, 0x5cbf, 0x2c00, 0xaf36, 0x0040,
+	0x5cbd, 0x2f00, 0x7036, 0x0078, 0x5cbf, 0x7037, 0x0000, 0x660c,
+	0x067e, 0x2c00, 0xaf06, 0x0040, 0x5cc8, 0x7e0e, 0x0078, 0x5cc9,
+	0x2678, 0x600f, 0x0000, 0x1078, 0x8a44, 0x0040, 0x5ce3, 0x6010,
+	0x2068, 0x601c, 0xa086, 0x0003, 0x00c0, 0x5cf7, 0x6837, 0x0103,
+	0x6b4a, 0x6847, 0x0000, 0x1078, 0x8cb8, 0x1078, 0xa181, 0x1078,
+	0x4982, 0x1078, 0x8bf4, 0x1078, 0x8c01, 0x0c7f, 0x0078, 0x5c88,
+	0x2c78, 0x600c, 0x2060, 0x0078, 0x5c88, 0x127f, 0x007f, 0x017f,
+	0x027f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x601c,
+	0xa086, 0x0006, 0x00c0, 0x5cd6, 0x1078, 0xa181, 0x1078, 0x9e70,
+	0x0078, 0x5ce3, 0x007e, 0x067e, 0x0c7e, 0x0d7e, 0x0f7e, 0x2031,
+	0x0000, 0x127e, 0x2091, 0x8000, 0x2079, 0xa5ab, 0x7838, 0xa065,
+	0x0040, 0x5d41, 0x600c, 0x007e, 0x600f, 0x0000, 0x783c, 0xac06,
+	0x00c0, 0x5d28, 0x037e, 0x2019, 0x0001, 0x1078, 0x6e6c, 0x7833,
+	0x0000, 0x783f, 0x0000, 0x7843, 0x0000, 0x7847, 0x0000, 0x037f,
+	0x1078, 0x8a44, 0x0040, 0x5d3c, 0x6010, 0x2068, 0x601c, 0xa086,
+	0x0003, 0x00c0, 0x5d4a, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000,
+	0x1078, 0x4982, 0x1078, 0x8bf4, 0x1078, 0x8c01, 0x007f, 0x0078,
+	0x5d0f, 0x7e3a, 0x7e36, 0x127f, 0x0f7f, 0x0d7f, 0x0c7f, 0x067f,
+	0x007f, 0x007c, 0x601c, 0xa086, 0x0006, 0x00c0, 0x5d33, 0x1078,
+	0x9e70, 0x0078, 0x5d3c, 0x017e, 0x027e, 0x087e, 0x2041, 0x0000,
+	0x1078, 0x5d6d, 0x1078, 0x5e21, 0x087f, 0x027f, 0x017f, 0x007c,
+	0x0f7e, 0x127e, 0x2079, 0xa5ab, 0x2091, 0x8000, 0x1078, 0x5ebc,
+	0x1078, 0x5f32, 0x127f, 0x0f7f, 0x007c, 0x0f7e, 0x0e7e, 0x0d7e,
+	0x0c7e, 0x067e, 0x017e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071,
+	0xa5ab, 0x7614, 0x2660, 0x2678, 0x8cff, 0x0040, 0x5e01, 0x6018,
+	0xa080, 0x0028, 0x2004, 0xa206, 0x00c0, 0x5dfc, 0x88ff, 0x0040,
+	0x5d8d, 0x6020, 0xa106, 0x00c0, 0x5dfc, 0x7024, 0xac06, 0x00c0,
+	0x5dbd, 0x2069, 0x0100, 0x68c0, 0xa005, 0x0040, 0x5db8, 0x1078,
+	0x595a, 0x1078, 0x6c41, 0x68c3, 0x0000, 0x1078, 0x7188, 0x7027,
+	0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0040,
+	0x5dad, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824,
+	0xd084, 0x0040, 0x5db5, 0x6827, 0x0001, 0x037f, 0x0078, 0x5dbd,
+	0x6003, 0x0009, 0x630a, 0x0078, 0x5dfc, 0x7014, 0xac36, 0x00c0,
+	0x5dc3, 0x660c, 0x7616, 0x7010, 0xac36, 0x00c0, 0x5dd1, 0x2c00,
+	0xaf36, 0x0040, 0x5dcf, 0x2f00, 0x7012, 0x0078, 0x5dd1, 0x7013,
+	0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06, 0x0040, 0x5dda, 0x7e0e,
+	0x0078, 0x5ddb, 0x2678, 0x600f, 0x0000, 0x6010, 0x2068, 0x1078,
+	0x8a44, 0x0040, 0x5df5, 0x601c, 0xa086, 0x0003, 0x00c0, 0x5e0a,
+	0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x8cb8, 0x1078,
+	0xa181, 0x1078, 0x4982, 0x1078, 0x8bf4, 0x1078, 0x8c01, 0x1078,
+	0x7045, 0x0c7f, 0x0078, 0x5d7c, 0x2c78, 0x600c, 0x2060, 0x0078,
+	0x5d7c, 0x127f, 0x007f, 0x017f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f,
+	0x0f7f, 0x007c, 0x601c, 0xa086, 0x0006, 0x00c0, 0x5e15, 0x1078,
+	0xa181, 0x1078, 0x9e70, 0x0078, 0x5df5, 0x601c, 0xa086, 0x0002,
+	0x00c0, 0x5df5, 0x6004, 0xa086, 0x0085, 0x0040, 0x5de8, 0x0078,
+	0x5df5, 0x0c7e, 0x007e, 0x127e, 0x2091, 0x8000, 0xa280, 0xa434,
+	0x2004, 0xa065, 0x0040, 0x5eb8, 0x0f7e, 0x0e7e, 0x0d7e, 0x067e,
+	0x2071, 0xa5ab, 0x6654, 0x7018, 0xac06, 0x00c0, 0x5e38, 0x761a,
+	0x701c, 0xac06, 0x00c0, 0x5e44, 0x86ff, 0x00c0, 0x5e43, 0x7018,
+	0x701e, 0x0078, 0x5e44, 0x761e, 0x6058, 0xa07d, 0x0040, 0x5e49,
+	0x7e56, 0xa6ed, 0x0000, 0x0040, 0x5e4f, 0x2f00, 0x685a, 0x6057,
+	0x0000, 0x605b, 0x0000, 0x6000, 0xc0d4, 0xc0dc, 0x6002, 0x1078,
+	0x4410, 0x0040, 0x5eb4, 0x7624, 0x86ff, 0x0040, 0x5ea2, 0xa680,
+	0x0004, 0x2004, 0xad06, 0x00c0, 0x5ea2, 0x0d7e, 0x2069, 0x0100,
+	0x68c0, 0xa005, 0x0040, 0x5e99, 0x1078, 0x595a, 0x1078, 0x6c41,
+	0x68c3, 0x0000, 0x1078, 0x7188, 0x7027, 0x0000, 0x037e, 0x2069,
+	0x0140, 0x6b04, 0xa384, 0x1000, 0x0040, 0x5e82, 0x6803, 0x0100,
+	0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0040, 0x5e8a,
+	0x6827, 0x0001, 0x037f, 0x0d7f, 0x0c7e, 0x603c, 0xa005, 0x0040,
+	0x5e93, 0x8001, 0x603e, 0x2660, 0x1078, 0x8c01, 0x0c7f, 0x0078,
+	0x5ea2, 0x0d7f, 0x0c7e, 0x2660, 0x6003, 0x0009, 0x630a, 0x0c7f,
+	0x0078, 0x5e57, 0x8dff, 0x0040, 0x5eb0, 0x6837, 0x0103, 0x6b4a,
+	0x6847, 0x0000, 0x1078, 0x8cb8, 0x1078, 0xa181, 0x1078, 0x4982,
+	0x1078, 0x7045, 0x0078, 0x5e57, 0x067f, 0x0d7f, 0x0e7f, 0x0f7f,
+	0x127f, 0x007f, 0x0c7f, 0x007c, 0x007e, 0x067e, 0x0c7e, 0x0d7e,
+	0x2031, 0x0000, 0x7814, 0xa065, 0x0040, 0x5f16, 0x600c, 0x007e,
+	0x600f, 0x0000, 0x7824, 0xac06, 0x00c0, 0x5efb, 0x2069, 0x0100,
+	0x68c0, 0xa005, 0x0040, 0x5ef5, 0x1078, 0x595a, 0x1078, 0x6c41,
+	0x68c3, 0x0000, 0x1078, 0x7188, 0x7827, 0x0000, 0x037e, 0x2069,
+	0x0140, 0x6b04, 0xa384, 0x1000, 0x0040, 0x5eea, 0x6803, 0x0100,
+	0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0040, 0x5ef2,
+	0x6827, 0x0001, 0x037f, 0x0078, 0x5efb, 0x6003, 0x0009, 0x630a,
+	0x2c30, 0x0078, 0x5f13, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040,
+	0x5f0f, 0x601c, 0xa086, 0x0003, 0x00c0, 0x5f1d, 0x6837, 0x0103,
+	0x6b4a, 0x6847, 0x0000, 0x1078, 0x4982, 0x1078, 0x8bf4, 0x1078,
+	0x8c01, 0x1078, 0x7045, 0x007f, 0x0078, 0x5ec3, 0x7e16, 0x7e12,
+	0x0d7f, 0x0c7f, 0x067f, 0x007f, 0x007c, 0x601c, 0xa086, 0x0006,
+	0x00c0, 0x5f26, 0x1078, 0x9e70, 0x0078, 0x5f0f, 0x601c, 0xa086,
+	0x0002, 0x00c0, 0x5f0f, 0x6004, 0xa086, 0x0085, 0x0040, 0x5f06,
+	0x0078, 0x5f0f, 0x007e, 0x067e, 0x0c7e, 0x0d7e, 0x7818, 0xa065,
+	0x0040, 0x5fa0, 0x6054, 0x007e, 0x6057, 0x0000, 0x605b, 0x0000,
+	0x6000, 0xc0d4, 0xc0dc, 0x6002, 0x1078, 0x4410, 0x0040, 0x5f9d,
+	0x7e24, 0x86ff, 0x0040, 0x5f8f, 0xa680, 0x0004, 0x2004, 0xad06,
+	0x00c0, 0x5f8f, 0x0d7e, 0x2069, 0x0100, 0x68c0, 0xa005, 0x0040,
+	0x5f86, 0x1078, 0x595a, 0x1078, 0x6c41, 0x68c3, 0x0000, 0x1078,
+	0x7188, 0x7827, 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384,
+	0x1000, 0x0040, 0x5f6f, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069,
+	0x0100, 0x6824, 0xd084, 0x0040, 0x5f77, 0x6827, 0x0001, 0x037f,
+	0x0d7f, 0x0c7e, 0x603c, 0xa005, 0x0040, 0x5f80, 0x8001, 0x603e,
+	0x2660, 0x1078, 0x8c01, 0x0c7f, 0x0078, 0x5f8f, 0x0d7f, 0x0c7e,
+	0x2660, 0x6003, 0x0009, 0x630a, 0x0c7f, 0x0078, 0x5f44, 0x8dff,
+	0x0040, 0x5f99, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078,
+	0x4982, 0x1078, 0x7045, 0x0078, 0x5f44, 0x007f, 0x0078, 0x5f37,
+	0x781e, 0x781a, 0x0d7f, 0x0c7f, 0x067f, 0x007f, 0x007c, 0x0e7e,
+	0x0d7e, 0x067e, 0x6000, 0xd0dc, 0x0040, 0x5fc4, 0x604c, 0xa06d,
+	0x0040, 0x5fc4, 0x6848, 0xa606, 0x00c0, 0x5fc4, 0x2071, 0xa5ab,
+	0x7024, 0xa035, 0x0040, 0x5fc4, 0xa080, 0x0004, 0x2004, 0xad06,
+	0x00c0, 0x5fc4, 0x1078, 0x5fc8, 0x067f, 0x0d7f, 0x0e7f, 0x007c,
+	0x0f7e, 0x2079, 0x0100, 0x78c0, 0xa005, 0x00c0, 0x5fd7, 0x0c7e,
+	0x2660, 0x6003, 0x0009, 0x630a, 0x0c7f, 0x0078, 0x600e, 0x1078,
+	0x6c41, 0x78c3, 0x0000, 0x1078, 0x7188, 0x7027, 0x0000, 0x037e,
+	0x2079, 0x0140, 0x7b04, 0xa384, 0x1000, 0x0040, 0x5feb, 0x7803,
+	0x0100, 0x7803, 0x0000, 0x2079, 0x0100, 0x7824, 0xd084, 0x0040,
+	0x5ff3, 0x7827, 0x0001, 0x1078, 0x7188, 0x037f, 0x1078, 0x4410,
+	0x0c7e, 0x603c, 0xa005, 0x0040, 0x5fff, 0x8001, 0x603e, 0x2660,
+	0x1078, 0x753d, 0x0c7f, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000,
+	0x1078, 0x8cb8, 0x1078, 0x4982, 0x1078, 0x7045, 0x0f7f, 0x007c,
+	0x0e7e, 0x0c7e, 0x2071, 0xa5ab, 0x7004, 0xa084, 0x0007, 0x0079,
+	0x6019, 0x6023, 0x6026, 0x603f, 0x605b, 0x60a0, 0x6023, 0x6023,
+	0x6021, 0x1078, 0x1328, 0x0c7f, 0x0e7f, 0x007c, 0x7024, 0xa065,
+	0x0040, 0x6034, 0x7020, 0x8001, 0x7022, 0x600c, 0xa015, 0x0040,
+	0x603b, 0x7216, 0x600f, 0x0000, 0x7007, 0x0000, 0x7027, 0x0000,
+	0x0c7f, 0x0e7f, 0x007c, 0x7216, 0x7212, 0x0078, 0x6034, 0x6018,
+	0x2060, 0x1078, 0x4410, 0x6000, 0xc0dc, 0x6002, 0x7020, 0x8001,
+	0x7022, 0x0040, 0x6050, 0x6054, 0xa015, 0x0040, 0x6057, 0x721e,
+	0x7007, 0x0000, 0x7027, 0x0000, 0x0c7f, 0x0e7f, 0x007c, 0x7218,
+	0x721e, 0x0078, 0x6050, 0x7024, 0xa065, 0x0040, 0x609d, 0x700c,
+	0xac06, 0x00c0, 0x6072, 0x1078, 0x7045, 0x600c, 0xa015, 0x0040,
+	0x606e, 0x720e, 0x600f, 0x0000, 0x0078, 0x609b, 0x720e, 0x720a,
+	0x0078, 0x609b, 0x7014, 0xac06, 0x00c0, 0x6085, 0x1078, 0x7045,
+	0x600c, 0xa015, 0x0040, 0x6081, 0x7216, 0x600f, 0x0000, 0x0078,
+	0x609b, 0x7216, 0x7212, 0x0078, 0x609b, 0x6018, 0x2060, 0x1078,
+	0x4410, 0x6000, 0xc0dc, 0x6002, 0x1078, 0x7045, 0x701c, 0xa065,
+	0x0040, 0x609b, 0x6054, 0xa015, 0x0040, 0x6099, 0x721e, 0x0078,
+	0x609b, 0x7218, 0x721e, 0x7027, 0x0000, 0x0c7f, 0x0e7f, 0x007c,
+	0x7024, 0xa065, 0x0040, 0x60ad, 0x1078, 0x7045, 0x600c, 0xa015,
+	0x0040, 0x60b4, 0x720e, 0x600f, 0x0000, 0x1078, 0x7188, 0x7027,
+	0x0000, 0x0c7f, 0x0e7f, 0x007c, 0x720e, 0x720a, 0x0078, 0x60ad,
+	0x0d7e, 0x2069, 0xa5ab, 0x6830, 0xa084, 0x0003, 0x0079, 0x60c0,
+	0x60c6, 0x60c8, 0x60ee, 0x60c6, 0x1078, 0x1328, 0x0d7f, 0x007c,
+	0x0c7e, 0x6840, 0xa086, 0x0001, 0x0040, 0x60e4, 0x683c, 0xa065,
+	0x0040, 0x60d9, 0x600c, 0xa015, 0x0040, 0x60e0, 0x6a3a, 0x600f,
+	0x0000, 0x6833, 0x0000, 0x683f, 0x0000, 0x0c7f, 0x0d7f, 0x007c,
+	0x683a, 0x6836, 0x0078, 0x60d9, 0x6843, 0x0000, 0x6838, 0xa065,
+	0x0040, 0x60d9, 0x6003, 0x0003, 0x0078, 0x60d9, 0x0c7e, 0x6843,
+	0x0000, 0x6847, 0x0000, 0x683c, 0xa065, 0x0040, 0x6106, 0x600c,
+	0xa015, 0x0040, 0x6102, 0x6a3a, 0x600f, 0x0000, 0x683f, 0x0000,
+	0x0078, 0x6106, 0x683f, 0x0000, 0x683a, 0x6836, 0x0c7f, 0x0d7f,
+	0x007c, 0x0d7e, 0x2069, 0xa5ab, 0x6804, 0xa084, 0x0007, 0x0079,
+	0x6111, 0x611b, 0x61c2, 0x61c2, 0x61c2, 0x61c2, 0x61c4, 0x61c2,
+	0x6119, 0x1078, 0x1328, 0x6820, 0xa005, 0x00c0, 0x6121, 0x0d7f,
+	0x007c, 0x0c7e, 0x680c, 0xa065, 0x0040, 0x6130, 0x6807, 0x0004,
+	0x6826, 0x682b, 0x0000, 0x1078, 0x620a, 0x0c7f, 0x0d7f, 0x007c,
+	0x6814, 0xa065, 0x0040, 0x613e, 0x6807, 0x0001, 0x6826, 0x682b,
+	0x0000, 0x1078, 0x620a, 0x0c7f, 0x0d7f, 0x007c, 0x0e7e, 0x037e,
+	0x6a1c, 0xa2f5, 0x0000, 0x0040, 0x61bd, 0x704c, 0xa00d, 0x0040,
+	0x614d, 0x7088, 0xa005, 0x0040, 0x6165, 0x7054, 0xa075, 0x0040,
+	0x6156, 0xa20e, 0x0040, 0x61bd, 0x0078, 0x615b, 0x6818, 0xa20e,
+	0x0040, 0x61bd, 0x2070, 0x704c, 0xa00d, 0x0040, 0x614d, 0x7088,
+	0xa005, 0x00c0, 0x614d, 0x2e00, 0x681e, 0x733c, 0x7038, 0xa302,
+	0x00c8, 0x614d, 0x1078, 0x750c, 0x0040, 0x61bd, 0x8318, 0x733e,
+	0x6112, 0x2e10, 0x621a, 0xa180, 0x0014, 0x2004, 0xa084, 0x00ff,
+	0x6032, 0xa180, 0x0014, 0x2003, 0x0000, 0xa180, 0x0015, 0x2004,
+	0xa08a, 0x199a, 0x0048, 0x6186, 0x2001, 0x1999, 0x8003, 0x801b,
+	0x831b, 0xa318, 0x6316, 0x037f, 0x0f7e, 0x2c78, 0x71a0, 0xd1bc,
+	0x0040, 0x619f, 0x7100, 0xd1f4, 0x0040, 0x619b, 0x7114, 0xa18c,
+	0x00ff, 0x0078, 0x61a4, 0x2009, 0x0000, 0x0078, 0x61a4, 0xa1e0,
+	0x293f, 0x2c0c, 0xa18c, 0x00ff, 0x2061, 0x0100, 0x619a, 0x1078,
+	0x679b, 0x7300, 0xc3dd, 0x7302, 0x6807, 0x0002, 0x2f18, 0x6b26,
+	0x682b, 0x0000, 0x781f, 0x0003, 0x7803, 0x0001, 0x7807, 0x0040,
+	0x0f7f, 0x0e7f, 0x0c7f, 0x0d7f, 0x007c, 0x037f, 0x0e7f, 0x0c7f,
+	0x0078, 0x61bb, 0x0d7f, 0x007c, 0x0c7e, 0x680c, 0xa065, 0x0040,
+	0x61d0, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, 0x1078, 0x620a,
+	0x0c7f, 0x0d7f, 0x007c, 0x0f7e, 0x0d7e, 0x2069, 0xa5ab, 0x6830,
+	0xa086, 0x0000, 0x00c0, 0x61f1, 0x6838, 0xa07d, 0x0040, 0x61f1,
+	0x6833, 0x0001, 0x683e, 0x6847, 0x0000, 0x127e, 0x0f7e, 0x2091,
+	0x2200, 0x027f, 0x1078, 0x1d28, 0x00c0, 0x61f4, 0x127f, 0x1078,
+	0x6ae5, 0x0d7f, 0x0f7f, 0x007c, 0x127f, 0x6843, 0x0000, 0x7803,
+	0x0002, 0x780c, 0xa015, 0x0040, 0x6206, 0x6a3a, 0x780f, 0x0000,
+	0x6833, 0x0000, 0x683f, 0x0000, 0x0078, 0x61f1, 0x683a, 0x6836,
+	0x0078, 0x6200, 0x601c, 0xa084, 0x000f, 0x1079, 0x6210, 0x007c,
+	0x6219, 0x621e, 0x663f, 0x6758, 0x621e, 0x663f, 0x6758, 0x6219,
+	0x621e, 0x1078, 0x6010, 0x1078, 0x6109, 0x007c, 0x157e, 0x137e,
+	0x147e, 0x0c7e, 0x0f7e, 0x6004, 0xa08a, 0x0044, 0x10c8, 0x1328,
+	0x6118, 0x2178, 0x79a0, 0xd1bc, 0x0040, 0x623b, 0x7900, 0xd1f4,
+	0x0040, 0x6237, 0x7914, 0xa18c, 0x00ff, 0x0078, 0x6240, 0x2009,
+	0x0000, 0x0078, 0x6240, 0xa1f8, 0x293f, 0x2f0c, 0xa18c, 0x00ff,
+	0x2c78, 0x2061, 0x0100, 0x619a, 0xa08a, 0x0040, 0x00c8, 0x6292,
+	0x1079, 0x6250, 0x0f7f, 0x0c7f, 0x147f, 0x137f, 0x157f, 0x007c,
+	0x62f8, 0x6340, 0x6368, 0x6403, 0x6433, 0x643b, 0x6462, 0x6473,
+	0x6484, 0x648c, 0x64a4, 0x648c, 0x650f, 0x6473, 0x6530, 0x6538,
+	0x6484, 0x6538, 0x6549, 0x6290, 0x6290, 0x6290, 0x6290, 0x6290,
+	0x6290, 0x6290, 0x6290, 0x6290, 0x6290, 0x6290, 0x6d05, 0x6d2a,
+	0x6d3f, 0x6d62, 0x6d83, 0x6462, 0x6290, 0x6462, 0x648c, 0x6290,
+	0x6368, 0x6403, 0x6290, 0x72ac, 0x648c, 0x6290, 0x72cc, 0x648c,
+	0x6290, 0x6290, 0x62f3, 0x62a1, 0x6290, 0x72f1, 0x7368, 0x7450,
+	0x6290, 0x7461, 0x645c, 0x747d, 0x6290, 0x6d98, 0x6290, 0x6290,
+	0x1078, 0x1328, 0x2100, 0x1079, 0x629b, 0x0f7f, 0x0c7f, 0x147f,
+	0x137f, 0x157f, 0x007c, 0x629f, 0x629f, 0x629f, 0x62d5, 0x1078,
+	0x1328, 0x0d7e, 0x20a1, 0x020b, 0x1078, 0x6567, 0x7810, 0x2068,
+	0x20a3, 0x2414, 0x20a3, 0x0018, 0x20a3, 0x0800, 0x683c, 0x20a2,
+	0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000,
+	0x6850, 0x20a2, 0x6854, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000,
+	0x60c3, 0x0018, 0x1078, 0x6c2d, 0x0d7f, 0x007c, 0x0d7e, 0x7818,
+	0x2068, 0x68a0, 0xa082, 0x007e, 0x0048, 0x62d2, 0xa085, 0x0001,
+	0x0d7f, 0x007c, 0xa006, 0x0078, 0x62d0, 0x0d7e, 0x20a1, 0x020b,
+	0x1078, 0x6567, 0x20a3, 0x0500, 0x20a3, 0x0000, 0x7810, 0xa0e8,
+	0x000f, 0x6808, 0x20a2, 0x680c, 0x20a2, 0x6810, 0x20a2, 0x6814,
+	0x20a2, 0x6818, 0x20a2, 0x681c, 0x20a2, 0x60c3, 0x0010, 0x1078,
+	0x6c2d, 0x0d7f, 0x007c, 0x6030, 0x609a, 0x1078, 0x6c2d, 0x007c,
+	0x20a1, 0x020b, 0x1078, 0x6567, 0x20a3, 0x5200, 0x20a3, 0x0000,
+	0x0d7e, 0x2069, 0xa351, 0x6804, 0xd084, 0x0040, 0x6312, 0x6828,
+	0x20a3, 0x0000, 0x017e, 0x1078, 0x24fa, 0x21a2, 0x017f, 0x0d7f,
+	0x0078, 0x6317, 0x0d7f, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a9,
+	0x0004, 0x2099, 0xa305, 0x53a6, 0x20a9, 0x0004, 0x2099, 0xa301,
+	0x53a6, 0x7818, 0xa080, 0x0028, 0x2004, 0xa082, 0x007f, 0x0048,
+	0x6331, 0x2001, 0xa31a, 0x20a6, 0x2001, 0xa31b, 0x20a6, 0x0078,
+	0x6337, 0x20a3, 0x0000, 0x6030, 0xa084, 0x00ff, 0x20a2, 0x20a3,
+	0x0000, 0x20a3, 0x0000, 0x60c3, 0x001c, 0x1078, 0x6c2d, 0x007c,
+	0x20a1, 0x020b, 0x1078, 0x6567, 0x20a3, 0x0500, 0x20a3, 0x0000,
+	0x7818, 0xa080, 0x0028, 0x2004, 0xa082, 0x007f, 0x0048, 0x6358,
+	0x2001, 0xa31a, 0x20a6, 0x2001, 0xa31b, 0x20a6, 0x0078, 0x635e,
+	0x20a3, 0x0000, 0x6030, 0xa084, 0x00ff, 0x20a2, 0x20a9, 0x0004,
+	0x2099, 0xa305, 0x53a6, 0x60c3, 0x0010, 0x1078, 0x6c2d, 0x007c,
+	0x20a1, 0x020b, 0x1078, 0x6567, 0x0c7e, 0x7818, 0x2060, 0x2001,
+	0x0000, 0x1078, 0x48a2, 0x0c7f, 0x7818, 0xa080, 0x0028, 0x2004,
+	0xa086, 0x007e, 0x00c0, 0x6383, 0x20a3, 0x0400, 0x620c, 0xc2b4,
+	0x620e, 0x0078, 0x6385, 0x20a3, 0x0300, 0x20a3, 0x0000, 0x7818,
+	0xa080, 0x0028, 0x2004, 0xa086, 0x007e, 0x00c0, 0x63d2, 0x2099,
+	0xa58c, 0x33a6, 0x9398, 0x33a6, 0x9398, 0x3304, 0xa084, 0x3fff,
+	0x20a2, 0x9398, 0x33a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+	0x0000, 0x20a3, 0x0000, 0x20a9, 0x0004, 0x2099, 0xa305, 0x53a6,
+	0x20a9, 0x0004, 0x2099, 0xa301, 0x53a6, 0x20a9, 0x0010, 0x20a3,
+	0x0000, 0x00f0, 0x63af, 0x2099, 0xa594, 0x3304, 0xc0dd, 0x20a2,
+	0x2001, 0xa371, 0x2004, 0xd0e4, 0x0040, 0x63ca, 0x20a3, 0x0000,
+	0x20a3, 0x0000, 0x9398, 0x9398, 0x9398, 0x33a6, 0x20a9, 0x0004,
+	0x0078, 0x63cc, 0x20a9, 0x0007, 0x20a3, 0x0000, 0x00f0, 0x63cc,
+	0x0078, 0x63f2, 0x2099, 0xa58c, 0x20a9, 0x0008, 0x53a6, 0x20a9,
+	0x0004, 0x2099, 0xa305, 0x53a6, 0x20a9, 0x0004, 0x2099, 0xa301,
+	0x53a6, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x00f0, 0x63e3, 0x20a9,
+	0x0008, 0x20a3, 0x0000, 0x00f0, 0x63e9, 0x2099, 0xa594, 0x20a9,
+	0x0008, 0x53a6, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x00f0, 0x63f4,
+	0x20a9, 0x000a, 0x20a3, 0x0000, 0x00f0, 0x63fa, 0x60c3, 0x0074,
+	0x1078, 0x6c2d, 0x007c, 0x20a1, 0x020b, 0x1078, 0x6567, 0x20a3,
+	0x2010, 0x20a3, 0x0014, 0x20a3, 0x0800, 0x20a3, 0x2000, 0xa006,
+	0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x0f7e, 0x2079, 0xa351,
+	0x7904, 0x0f7f, 0xd1ac, 0x00c0, 0x641f, 0xa085, 0x0020, 0xd1a4,
+	0x0040, 0x6424, 0xa085, 0x0010, 0xa085, 0x0002, 0x0d7e, 0x0078,
+	0x64ed, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014,
+	0x1078, 0x6c2d, 0x007c, 0x20a1, 0x020b, 0x1078, 0x6567, 0x20a3,
+	0x5000, 0x0078, 0x6385, 0x20a1, 0x020b, 0x1078, 0x6567, 0x20a3,
+	0x2110, 0x20a3, 0x0014, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+	0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+	0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3,
+	0x0014, 0x1078, 0x6c2d, 0x007c, 0x20a1, 0x020b, 0x1078, 0x65ef,
+	0x0078, 0x6466, 0x20a1, 0x020b, 0x1078, 0x65f8, 0x20a3, 0x0200,
+	0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0004,
+	0x1078, 0x6c2d, 0x007c, 0x20a1, 0x020b, 0x1078, 0x65f8, 0x20a3,
+	0x0100, 0x20a3, 0x0000, 0x20a3, 0x0003, 0x20a3, 0x2a00, 0x60c3,
+	0x0008, 0x1078, 0x6c2d, 0x007c, 0x20a1, 0x020b, 0x1078, 0x65f8,
+	0x20a3, 0x0200, 0x0078, 0x6385, 0x20a1, 0x020b, 0x1078, 0x65f8,
+	0x20a3, 0x0100, 0x20a3, 0x0000, 0x7828, 0xa005, 0x0040, 0x649b,
+	0x20a2, 0x0078, 0x649d, 0x20a3, 0x0003, 0x7810, 0x20a2, 0x60c3,
+	0x0008, 0x1078, 0x6c2d, 0x007c, 0x0d7e, 0x20a1, 0x020b, 0x1078,
+	0x65f8, 0x20a3, 0x0210, 0x20a3, 0x0014, 0x20a3, 0x0800, 0x7818,
+	0x2068, 0x6894, 0xa086, 0x0014, 0x00c0, 0x64ca, 0x6998, 0xa184,
+	0xc000, 0x00c0, 0x64c6, 0xd1ec, 0x0040, 0x64c2, 0x20a3, 0x2100,
+	0x0078, 0x64cc, 0x20a3, 0x0100, 0x0078, 0x64cc, 0x20a3, 0x0400,
+	0x0078, 0x64cc, 0x20a3, 0x0700, 0xa006, 0x20a2, 0x20a2, 0x20a2,
+	0x20a2, 0x20a2, 0x0f7e, 0x2079, 0xa351, 0x7904, 0x0f7f, 0xd1ac,
+	0x00c0, 0x64dc, 0xa085, 0x0020, 0xd1a4, 0x0040, 0x64e1, 0xa085,
+	0x0010, 0x2009, 0xa373, 0x210c, 0xd184, 0x0040, 0x64eb, 0x699c,
+	0xd18c, 0x0040, 0x64ed, 0xa085, 0x0002, 0x027e, 0x2009, 0xa371,
+	0x210c, 0xd1e4, 0x0040, 0x64fb, 0xc0c5, 0xa094, 0x0030, 0xa296,
+	0x0010, 0x0040, 0x6505, 0xd1ec, 0x0040, 0x6505, 0xa094, 0x0030,
+	0xa296, 0x0010, 0x0040, 0x6505, 0xc0bd, 0x027f, 0x20a2, 0x20a2,
+	0x20a2, 0x60c3, 0x0014, 0x1078, 0x6c2d, 0x0d7f, 0x007c, 0x20a1,
+	0x020b, 0x1078, 0x65f8, 0x20a3, 0x0210, 0x20a3, 0x0014, 0x20a3,
+	0x0000, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+	0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+	0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, 0x6c2d, 0x007c,
+	0x20a1, 0x020b, 0x1078, 0x65f8, 0x20a3, 0x0200, 0x0078, 0x62fe,
+	0x20a1, 0x020b, 0x1078, 0x65f8, 0x20a3, 0x0100, 0x20a3, 0x0000,
+	0x20a3, 0x0003, 0x20a3, 0x2a00, 0x60c3, 0x0008, 0x1078, 0x6c2d,
+	0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a1, 0x020b, 0x1078,
+	0x65f8, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x000b, 0x20a3,
+	0x0000, 0x60c3, 0x0008, 0x1078, 0x6c2d, 0x007c, 0x027e, 0x037e,
+	0x047e, 0x2019, 0x3200, 0x2021, 0x0800, 0x0078, 0x656e, 0x027e,
+	0x037e, 0x047e, 0x2019, 0x2200, 0x2021, 0x0100, 0x20e1, 0x9080,
+	0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2014, 0xa286, 0x007e,
+	0x00c0, 0x6581, 0xa385, 0x00ff, 0x20a2, 0x20a3, 0xfffe, 0x0078,
+	0x65b6, 0xa286, 0x007f, 0x00c0, 0x658d, 0x0d7e, 0xa385, 0x00ff,
+	0x20a2, 0x20a3, 0xfffd, 0x0078, 0x65a4, 0xd2bc, 0x0040, 0x65ac,
+	0xa286, 0x0080, 0x0d7e, 0x00c0, 0x659c, 0xa385, 0x00ff, 0x20a2,
+	0x20a3, 0xfffc, 0x0078, 0x65a4, 0xa2e8, 0xa434, 0x2d6c, 0x6810,
+	0xa305, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa31a, 0x2da6, 0x8d68,
+	0x2da6, 0x0d7f, 0x0078, 0x65ba, 0x0d7e, 0xa2e8, 0xa434, 0x2d6c,
+	0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000,
+	0x6230, 0x22a2, 0xa485, 0x0029, 0x20a2, 0x047f, 0x037f, 0x20a3,
+	0x0000, 0x1078, 0x6c1c, 0x22a2, 0x20a3, 0x0000, 0x2fa2, 0x20a3,
+	0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f, 0x007c, 0x027e,
+	0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a3, 0x02ff, 0x2011, 0xfffc,
+	0x22a2, 0x0d7e, 0x2069, 0xa31a, 0x2da6, 0x8d68, 0x2da6, 0x0d7f,
+	0x20a3, 0x2029, 0x20a3, 0x0000, 0x0078, 0x65c1, 0x20a3, 0x0100,
+	0x20a3, 0x0000, 0x20a3, 0xfc02, 0x20a3, 0x0000, 0x007c, 0x027e,
+	0x037e, 0x047e, 0x2019, 0x3300, 0x2021, 0x0800, 0x0078, 0x65ff,
+	0x027e, 0x037e, 0x047e, 0x2019, 0x2300, 0x2021, 0x0100, 0x20e1,
+	0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0xa092,
+	0x007e, 0x0048, 0x661c, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810,
+	0xa305, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa31a, 0x2da6, 0x8d68,
+	0x2da6, 0x0d7f, 0x0078, 0x662a, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c,
+	0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000,
+	0x6230, 0x22a2, 0xa485, 0x0098, 0x20a2, 0x20a3, 0x0000, 0x047f,
+	0x037f, 0x1078, 0x6c1c, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2,
+	0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f, 0x007c, 0x0c7e,
+	0x0f7e, 0x6004, 0xa08a, 0x0085, 0x1048, 0x1328, 0xa08a, 0x008c,
+	0x10c8, 0x1328, 0x6118, 0x2178, 0x79a0, 0xd1bc, 0x0040, 0x665d,
+	0x7900, 0xd1f4, 0x0040, 0x6659, 0x7914, 0xa18c, 0x00ff, 0x0078,
+	0x6662, 0x2009, 0x0000, 0x0078, 0x6662, 0xa1f8, 0x293f, 0x2f0c,
+	0xa18c, 0x00ff, 0x2c78, 0x2061, 0x0100, 0x619a, 0xa082, 0x0085,
+	0x1079, 0x666d, 0x0f7f, 0x0c7f, 0x007c, 0x6676, 0x6681, 0x669c,
+	0x6674, 0x6674, 0x6674, 0x6676, 0x1078, 0x1328, 0x147e, 0x20a1,
+	0x020b, 0x1078, 0x66af, 0x60c3, 0x0000, 0x1078, 0x6c2d, 0x147f,
+	0x007c, 0x147e, 0x20a1, 0x020b, 0x1078, 0x66e3, 0x20a3, 0x0000,
+	0x20a3, 0x0000, 0x7808, 0x20a2, 0x7810, 0x20a2, 0x20a3, 0x0000,
+	0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x000c,
+	0x1078, 0x6c2d, 0x147f, 0x007c, 0x147e, 0x20a1, 0x020b, 0x1078,
+	0x6724, 0x20a3, 0x0003, 0x20a3, 0x0300, 0x20a3, 0x0000, 0x20a3,
+	0x0000, 0x60c3, 0x0004, 0x1078, 0x6c2d, 0x147f, 0x007c, 0x027e,
+	0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004,
+	0xa092, 0x007e, 0x0048, 0x66ce, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c,
+	0x6810, 0xa085, 0x8100, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa31a,
+	0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x66dd, 0x0d7e, 0xa0e8,
+	0xa434, 0x2d6c, 0x6810, 0xa085, 0x8100, 0x20a2, 0x6814, 0x20a2,
+	0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0009, 0x20a3,
+	0x0000, 0x0078, 0x65c1, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000,
+	0x7818, 0xa080, 0x0028, 0x2004, 0xa092, 0x007e, 0x0048, 0x6702,
+	0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085, 0x8400, 0x20a2,
+	0x6814, 0x20a2, 0x2069, 0xa31a, 0x2da6, 0x8d68, 0x2da6, 0x0d7f,
+	0x0078, 0x6711, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085,
+	0x8400, 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, 0x6230,
+	0x22a2, 0x20a3, 0x0099, 0x20a3, 0x0000, 0x1078, 0x6c1c, 0x22a2,
+	0x20a3, 0x0000, 0x7a08, 0x22a2, 0x7a10, 0x22a2, 0x20a3, 0x0000,
+	0x20a3, 0x0000, 0x027f, 0x007c, 0x027e, 0x20e1, 0x9080, 0x20e1,
+	0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0xa092, 0x007e, 0x0048,
+	0x6743, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085, 0x8500,
+	0x20a2, 0x6814, 0x20a2, 0x2069, 0xa31a, 0x2da6, 0x8d68, 0x2da6,
+	0x0d7f, 0x0078, 0x6752, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810,
+	0xa085, 0x8500, 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000,
+	0x6230, 0x22a2, 0x20a3, 0x0099, 0x20a3, 0x0000, 0x0078, 0x6715,
+	0x0c7e, 0x0f7e, 0x2c78, 0x7804, 0xa08a, 0x0040, 0x1048, 0x1328,
+	0xa08a, 0x0053, 0x10c8, 0x1328, 0x7918, 0x2160, 0x61a0, 0xd1bc,
+	0x0040, 0x6777, 0x6100, 0xd1f4, 0x0040, 0x6773, 0x6114, 0xa18c,
+	0x00ff, 0x0078, 0x677c, 0x2009, 0x0000, 0x0078, 0x677c, 0xa1e0,
+	0x293f, 0x2c0c, 0xa18c, 0x00ff, 0x2061, 0x0100, 0x619a, 0xa082,
+	0x0040, 0x1079, 0x6786, 0x0f7f, 0x0c7f, 0x007c, 0x679b, 0x68a9,
+	0x684a, 0x6a59, 0x6799, 0x6799, 0x6799, 0x6799, 0x6799, 0x6799,
+	0x6799, 0x6f5e, 0x6f6f, 0x6f80, 0x6f91, 0x6799, 0x748e, 0x6799,
+	0x6f4d, 0x1078, 0x1328, 0x0d7e, 0x157e, 0x147e, 0x780b, 0xffff,
+	0x20a1, 0x020b, 0x1078, 0x6806, 0x7910, 0x2168, 0x6948, 0x7922,
+	0x21a2, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x694c, 0xa184, 0x000f,
+	0x00c0, 0x67b6, 0x2001, 0x0005, 0x0078, 0x67c0, 0xd184, 0x0040,
+	0x67bd, 0x2001, 0x0004, 0x0078, 0x67c0, 0xa084, 0x0006, 0x8004,
+	0x017e, 0x2008, 0x7830, 0xa084, 0x00ff, 0x8007, 0xa105, 0x017f,
+	0x20a2, 0xd1ac, 0x0040, 0x67d0, 0x20a3, 0x0002, 0x0078, 0x67dc,
+	0xd1b4, 0x0040, 0x67d7, 0x20a3, 0x0001, 0x0078, 0x67dc, 0x20a3,
+	0x0000, 0x2230, 0x0078, 0x67de, 0x6a80, 0x6e7c, 0x20a9, 0x0008,
+	0xad80, 0x0017, 0x200c, 0x810f, 0x21a2, 0x8000, 0x00f0, 0x67e2,
+	0x22a2, 0x26a2, 0x60c3, 0x0020, 0x20e1, 0x9080, 0x6014, 0xa084,
+	0x0004, 0xa085, 0x0009, 0x6016, 0x2001, 0xa5c7, 0x2003, 0x07d0,
+	0x2001, 0xa5c6, 0x2003, 0x0009, 0x2001, 0xa5cc, 0x2003, 0x0002,
+	0x1078, 0x157e, 0x147f, 0x157f, 0x0d7f, 0x007c, 0x20e1, 0x9080,
+	0x20e1, 0x4000, 0x7a18, 0xa280, 0x0023, 0x2014, 0x8210, 0xa294,
+	0x00ff, 0x2202, 0x8217, 0x7818, 0xa080, 0x0028, 0x2004, 0xd0bc,
+	0x0040, 0x682c, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085,
+	0x0600, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa31a, 0x2da6, 0x8d68,
+	0x2da6, 0x0d7f, 0x0078, 0x683b, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c,
+	0x6810, 0xa085, 0x0600, 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3,
+	0x0000, 0x6130, 0x21a2, 0x20a3, 0x0829, 0x20a3, 0x0000, 0x22a2,
+	0x20a3, 0x0000, 0x2fa2, 0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3,
+	0x0000, 0x007c, 0x0d7e, 0x157e, 0x137e, 0x147e, 0x20a1, 0x020b,
+	0x1078, 0x686a, 0x7810, 0x2068, 0x6860, 0x20a2, 0x685c, 0x20a2,
+	0x6880, 0x20a2, 0x687c, 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2,
+	0x20a2, 0x60c3, 0x000c, 0x1078, 0x6c2d, 0x147f, 0x137f, 0x157f,
+	0x0d7f, 0x007c, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818,
+	0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040, 0x6888, 0x0d7e, 0xa0e8,
+	0xa434, 0x2d6c, 0x6810, 0xa085, 0x0500, 0x20a2, 0x6814, 0x20a2,
+	0x2069, 0xa31a, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x6897,
+	0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085, 0x0500, 0x20a2,
+	0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3,
+	0x0889, 0x20a3, 0x0000, 0x1078, 0x6c1c, 0x22a2, 0x20a3, 0x0000,
+	0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f,
+	0x007c, 0x0d7e, 0x157e, 0x137e, 0x147e, 0x7810, 0xa06d, 0x1078,
+	0x488f, 0x0040, 0x68bd, 0x684c, 0xa084, 0x2020, 0xa086, 0x2020,
+	0x00c0, 0x68bd, 0x7824, 0xc0cd, 0x7826, 0x20a1, 0x020b, 0x1078,
+	0x6a12, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x7810,
+	0xa084, 0xf000, 0x00c0, 0x68d4, 0x7810, 0xa084, 0x0700, 0x8007,
+	0x1079, 0x68dc, 0x0078, 0x68d7, 0xa006, 0x1079, 0x68dc, 0x147f,
+	0x137f, 0x157f, 0x0d7f, 0x007c, 0x68e6, 0x697e, 0x6989, 0x69b3,
+	0x69c7, 0x69e3, 0x69ee, 0x68e4, 0x1078, 0x1328, 0x017e, 0x037e,
+	0x694c, 0xa18c, 0x0003, 0x0040, 0x68f1, 0xa186, 0x0003, 0x00c0,
+	0x6900, 0x6b78, 0x7824, 0xd0cc, 0x0040, 0x68f7, 0xc3e5, 0x23a2,
+	0x6868, 0x20a2, 0x6864, 0x20a2, 0x037f, 0x017f, 0x0078, 0x69be,
+	0xa186, 0x0001, 0x10c0, 0x1328, 0x6b78, 0x7824, 0xd0cc, 0x0040,
+	0x690a, 0xc3e5, 0x23a2, 0x6868, 0x20a2, 0x6864, 0x20a2, 0x22a2,
+	0x6874, 0x20a2, 0x22a2, 0x687c, 0x20a2, 0x2009, 0x0018, 0xa384,
+	0x0300, 0x0040, 0x6978, 0xd3c4, 0x0040, 0x6920, 0x687c, 0xa108,
+	0xd3cc, 0x0040, 0x6925, 0x6874, 0xa108, 0x157e, 0x20a9, 0x000d,
+	0xad80, 0x0020, 0x201c, 0x831f, 0x23a2, 0x8000, 0x00f0, 0x692a,
+	0x157f, 0x22a2, 0x22a2, 0x22a2, 0xa184, 0x0003, 0x0040, 0x6978,
+	0x20a1, 0x020b, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x007e, 0x7818,
+	0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040, 0x6958, 0x0d7e, 0xa0e8,
+	0xa434, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2,
+	0x2069, 0xa31a, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x6967,
+	0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2,
+	0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x007f,
+	0x7b24, 0xd3cc, 0x0040, 0x6970, 0x20a3, 0x0889, 0x0078, 0x6972,
+	0x20a3, 0x0898, 0x20a2, 0x1078, 0x6c1c, 0x22a2, 0x20a3, 0x0000,
+	0x61c2, 0x037f, 0x017f, 0x1078, 0x6c2d, 0x007c, 0x2011, 0x0008,
+	0x7824, 0xd0cc, 0x0040, 0x6985, 0xc2e5, 0x22a2, 0xa016, 0x0078,
+	0x69bc, 0x2011, 0x0302, 0x7824, 0xd0cc, 0x0040, 0x6990, 0xc2e5,
+	0x22a2, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x20a3, 0x0012, 0x22a2,
+	0x20a3, 0x0008, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x20a3, 0x7000,
+	0x20a3, 0x0500, 0x22a2, 0x20a3, 0x000a, 0x22a2, 0x22a2, 0x20a3,
+	0x2500, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0032,
+	0x1078, 0x6c2d, 0x007c, 0x2011, 0x0028, 0x7824, 0xd0cc, 0x0040,
+	0x69ba, 0xc2e5, 0x22a2, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x22a2,
+	0x22a2, 0x22a2, 0x60c3, 0x0018, 0x1078, 0x6c2d, 0x007c, 0x2011,
+	0x0100, 0x7824, 0xd0cc, 0x0040, 0x69ce, 0xc2e5, 0x22a2, 0xa016,
+	0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x20a3, 0x0008, 0x22a2,
+	0x7834, 0xa084, 0x00ff, 0x20a2, 0x22a2, 0x22a2, 0x60c3, 0x0020,
+	0x1078, 0x6c2d, 0x007c, 0x2011, 0x0008, 0x7824, 0xd0cc, 0x0040,
+	0x69ea, 0xc2e5, 0x22a2, 0xa016, 0x0078, 0x69bc, 0x037e, 0x7b10,
+	0xa384, 0xff00, 0x7812, 0xa384, 0x00ff, 0x8001, 0x00c0, 0x6a01,
+	0x7824, 0xd0cc, 0x0040, 0x69fd, 0xc2e5, 0x22a2, 0x037f, 0x0078,
+	0x69bc, 0x047e, 0x2021, 0x0800, 0x007e, 0x7824, 0xd0cc, 0x007f,
+	0x0040, 0x6a0b, 0xc4e5, 0x24a2, 0x047f, 0x22a2, 0x20a2, 0x037f,
+	0x0078, 0x69be, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818,
+	0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040, 0x6a30, 0x0d7e, 0xa0e8,
+	0xa434, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2,
+	0x2069, 0xa31a, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x6a3f,
+	0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2,
+	0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x7824,
+	0xd0cc, 0x0040, 0x6a47, 0x20a3, 0x0889, 0x0078, 0x6a49, 0x20a3,
+	0x0898, 0x20a3, 0x0000, 0x1078, 0x6c1c, 0x22a2, 0x20a3, 0x0000,
+	0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f,
+	0x007c, 0x0d7e, 0x157e, 0x137e, 0x147e, 0x017e, 0x037e, 0x7810,
+	0xa084, 0x0700, 0x8007, 0x1079, 0x6a6c, 0x037f, 0x017f, 0x147f,
+	0x137f, 0x157f, 0x0d7f, 0x007c, 0x6a74, 0x6a74, 0x6a76, 0x6a74,
+	0x6a74, 0x6a74, 0x6a9b, 0x6a74, 0x1078, 0x1328, 0x7910, 0xa18c,
+	0xf8ff, 0xa18d, 0x0600, 0x7912, 0x20a1, 0x020b, 0x2009, 0x0003,
+	0x1078, 0x6aa5, 0x0d7e, 0x2069, 0xa351, 0x6804, 0xd0bc, 0x0040,
+	0x6a90, 0x682c, 0xa084, 0x00ff, 0x8007, 0x20a2, 0x0078, 0x6a92,
+	0x20a3, 0x3f00, 0x0d7f, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0001,
+	0x1078, 0x6c2d, 0x007c, 0x20a1, 0x020b, 0x2009, 0x0003, 0x1078,
+	0x6aa5, 0x20a3, 0x7f00, 0x0078, 0x6a93, 0x027e, 0x20e1, 0x9080,
+	0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040,
+	0x6ac3, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085, 0x0100,
+	0x20a2, 0x6814, 0x20a2, 0x2069, 0xa31a, 0x2da6, 0x8d68, 0x2da6,
+	0x0d7f, 0x0078, 0x6ad2, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810,
+	0xa085, 0x0100, 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000,
+	0x6230, 0x22a2, 0x20a3, 0x0888, 0xa18d, 0x0008, 0x21a2, 0x1078,
+	0x6c1c, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3,
+	0x0000, 0x20a3, 0x0000, 0x027f, 0x007c, 0x0e7e, 0x0d7e, 0x0c7e,
+	0x057e, 0x047e, 0x037e, 0x2061, 0x0100, 0x2071, 0xa300, 0x6130,
+	0x7818, 0x2068, 0x68a0, 0x2028, 0xd0bc, 0x00c0, 0x6afc, 0x6910,
+	0x6a14, 0x6430, 0x0078, 0x6b00, 0x6910, 0x6a14, 0x7368, 0x746c,
+	0x781c, 0xa086, 0x0006, 0x0040, 0x6b5f, 0xd5bc, 0x0040, 0x6b10,
+	0xa185, 0x0100, 0x6062, 0x6266, 0x636a, 0x646e, 0x0078, 0x6b17,
+	0xa185, 0x0100, 0x6062, 0x6266, 0x606b, 0x0000, 0x646e, 0x6073,
+	0x0809, 0x6077, 0x0008, 0x688c, 0x8000, 0xa084, 0x00ff, 0x688e,
+	0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6082, 0x7808, 0x6086,
+	0x7810, 0x2070, 0x7014, 0x608a, 0x7010, 0x608e, 0x700c, 0x60c6,
+	0x7008, 0x60ca, 0x686c, 0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5,
+	0x60d7, 0x0000, 0xa582, 0x0080, 0x0048, 0x6b49, 0x6a00, 0xd2f4,
+	0x0040, 0x6b47, 0x6a14, 0xa294, 0x00ff, 0x0078, 0x6b49, 0x2011,
+	0x0000, 0x629e, 0x6017, 0x0016, 0x2009, 0x07d0, 0x60c4, 0xa084,
+	0xfff0, 0xa005, 0x0040, 0x6b56, 0x2009, 0x1b58, 0x1078, 0x595f,
+	0x037f, 0x047f, 0x057f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0x7810,
+	0x2070, 0x704c, 0xa084, 0x0003, 0xa086, 0x0002, 0x0040, 0x6bb7,
+	0xd5bc, 0x0040, 0x6b73, 0xa185, 0x0100, 0x6062, 0x6266, 0x636a,
+	0x646e, 0x0078, 0x6b7a, 0xa185, 0x0100, 0x6062, 0x6266, 0x606b,
+	0x0000, 0x646e, 0x6073, 0x0880, 0x6077, 0x0008, 0x688c, 0x8000,
+	0xa084, 0x00ff, 0x688e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00,
+	0x6086, 0x7808, 0x6082, 0x7060, 0x608a, 0x705c, 0x608e, 0x7080,
+	0x60c6, 0x707c, 0x60ca, 0x707c, 0x792c, 0xa108, 0x792e, 0x7080,
+	0x7928, 0xa109, 0x792a, 0x686c, 0x60ce, 0x60ab, 0x0036, 0x60af,
+	0x95d5, 0x60d7, 0x0000, 0xa582, 0x0080, 0x0048, 0x6bb2, 0x6a00,
+	0xd2f4, 0x0040, 0x6bb0, 0x6a14, 0xa294, 0x00ff, 0x0078, 0x6bb2,
+	0x2011, 0x0000, 0x629e, 0x6017, 0x0012, 0x0078, 0x6b4c, 0xd5bc,
+	0x0040, 0x6bc2, 0xa185, 0x0700, 0x6062, 0x6266, 0x636a, 0x646e,
+	0x0078, 0x6bc9, 0xa185, 0x0700, 0x6062, 0x6266, 0x606b, 0x0000,
+	0x646e, 0x1078, 0x488f, 0x0040, 0x6bdf, 0x0d7e, 0x7810, 0xa06d,
+	0x684c, 0x0d7f, 0xa084, 0x2020, 0xa086, 0x2020, 0x00c0, 0x6bdf,
+	0x7824, 0xc0cd, 0x7826, 0x6073, 0x0889, 0x0078, 0x6be1, 0x6073,
+	0x0898, 0x6077, 0x0000, 0x688c, 0x8000, 0xa084, 0x00ff, 0x688e,
+	0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6086, 0x7808, 0x6082,
+	0x7014, 0x608a, 0x7010, 0x608e, 0x700c, 0x60c6, 0x7008, 0x60ca,
+	0x686c, 0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5, 0x60d7, 0x0000,
+	0xa582, 0x0080, 0x0048, 0x6c0f, 0x6a00, 0xd2f4, 0x0040, 0x6c0d,
+	0x6a14, 0xa294, 0x00ff, 0x0078, 0x6c0f, 0x2011, 0x0000, 0x629e,
+	0x7824, 0xd0cc, 0x0040, 0x6c18, 0x6017, 0x0016, 0x0078, 0x6b4c,
+	0x6017, 0x0012, 0x0078, 0x6b4c, 0x7a18, 0xa280, 0x0023, 0x2014,
+	0x8210, 0xa294, 0x00ff, 0x2202, 0x8217, 0x007c, 0x0d7e, 0x2069,
+	0xa5ab, 0x6843, 0x0001, 0x0d7f, 0x007c, 0x20e1, 0x9080, 0x60a3,
+	0x0056, 0x60a7, 0x9575, 0x1078, 0x6c38, 0x1078, 0x594f, 0x007c,
+	0x007e, 0x6014, 0xa084, 0x0004, 0xa085, 0x0009, 0x6016, 0x007f,
+	0x007c, 0x007e, 0x0c7e, 0x2061, 0x0100, 0x6014, 0xa084, 0x0004,
+	0xa085, 0x0008, 0x6016, 0x0c7f, 0x007f, 0x007c, 0x0c7e, 0x0d7e,
+	0x017e, 0x027e, 0x2061, 0x0100, 0x2069, 0x0140, 0x6904, 0xa194,
+	0x4000, 0x0040, 0x6c89, 0x1078, 0x6c41, 0x6803, 0x1000, 0x6803,
+	0x0000, 0x0c7e, 0x2061, 0xa5ab, 0x6128, 0xa192, 0x00c8, 0x00c8,
+	0x6c76, 0x8108, 0x612a, 0x6124, 0x0c7f, 0x81ff, 0x0040, 0x6c84,
+	0x1078, 0x594f, 0x1078, 0x6c38, 0x0078, 0x6c84, 0x6124, 0xa1e5,
+	0x0000, 0x0040, 0x6c81, 0x1078, 0xa241, 0x2009, 0x0014, 0x1078,
+	0x756c, 0x0c7f, 0x0078, 0x6c84, 0x027f, 0x017f, 0x0d7f, 0x0c7f,
+	0x007c, 0x2001, 0xa5c7, 0x2004, 0xa005, 0x00c0, 0x6c84, 0x0c7e,
+	0x2061, 0xa5ab, 0x6128, 0xa192, 0x0003, 0x00c8, 0x6c76, 0x8108,
+	0x612a, 0x0c7f, 0x1078, 0x594f, 0x1078, 0x4171, 0x0078, 0x6c84,
+	0x0c7e, 0x0d7e, 0x0e7e, 0x017e, 0x027e, 0x1078, 0x5967, 0x2071,
+	0xa5ab, 0x713c, 0x81ff, 0x0040, 0x6cca, 0x2061, 0x0100, 0x2069,
+	0x0140, 0x6904, 0xa194, 0x4000, 0x0040, 0x6cd0, 0x6803, 0x1000,
+	0x6803, 0x0000, 0x037e, 0x2019, 0x0001, 0x1078, 0x6e6c, 0x037f,
+	0x713c, 0x2160, 0x1078, 0xa241, 0x2009, 0x004a, 0x1078, 0x756c,
+	0x0078, 0x6cca, 0x027f, 0x017f, 0x0e7f, 0x0d7f, 0x0c7f, 0x007c,
+	0x0078, 0x6cba, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x057e, 0x047e,
+	0x007e, 0x127e, 0x2091, 0x8000, 0x6018, 0x2068, 0x6ca0, 0x2071,
+	0xa5ab, 0x7018, 0x2068, 0x8dff, 0x0040, 0x6cfc, 0x68a0, 0xa406,
+	0x0040, 0x6cee, 0x6854, 0x2068, 0x0078, 0x6ce3, 0x6010, 0x2060,
+	0x643c, 0x6540, 0x6e48, 0x2d60, 0x1078, 0x466a, 0x0040, 0x6cfc,
+	0x1078, 0x7045, 0xa085, 0x0001, 0x127f, 0x007f, 0x047f, 0x057f,
+	0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0x20a1, 0x020b, 0x1078,
+	0x6567, 0x20a3, 0x1200, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x781c,
+	0xa086, 0x0004, 0x00c0, 0x6d17, 0x6098, 0x0078, 0x6d18, 0x6030,
+	0x20a2, 0x7834, 0x20a2, 0x7838, 0x20a2, 0x20a9, 0x0010, 0xa006,
+	0x20a2, 0x00f0, 0x6d20, 0x20a2, 0x20a2, 0x60c3, 0x002c, 0x1078,
+	0x6c2d, 0x007c, 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078, 0x6567,
+	0x20a3, 0x0f00, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808, 0x20a2,
+	0x60c3, 0x0008, 0x1078, 0x6c2d, 0x147f, 0x157f, 0x007c, 0x157e,
+	0x147e, 0x20a1, 0x020b, 0x1078, 0x65f8, 0x20a3, 0x0200, 0x20a3,
+	0x0000, 0x20a9, 0x0006, 0x2011, 0xa340, 0x2019, 0xa341, 0x23a6,
+	0x22a6, 0xa398, 0x0002, 0xa290, 0x0002, 0x00f0, 0x6d4f, 0x20a3,
+	0x0000, 0x20a3, 0x0000, 0x60c3, 0x001c, 0x1078, 0x6c2d, 0x147f,
+	0x157f, 0x007c, 0x157e, 0x147e, 0x017e, 0x027e, 0x20a1, 0x020b,
+	0x1078, 0x65cf, 0x1078, 0x65e6, 0x7810, 0xa080, 0x0000, 0x2004,
+	0xa080, 0x0015, 0x2098, 0x7808, 0xa088, 0x0002, 0x21a8, 0x53a6,
+	0xa080, 0x0004, 0x8003, 0x60c2, 0x1078, 0x6c2d, 0x027f, 0x017f,
+	0x147f, 0x157f, 0x007c, 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078,
+	0x6567, 0x20a3, 0x6200, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808,
+	0x20a2, 0x60c3, 0x0008, 0x1078, 0x6c2d, 0x147f, 0x157f, 0x007c,
+	0x157e, 0x147e, 0x017e, 0x027e, 0x20a1, 0x020b, 0x1078, 0x6567,
+	0x7810, 0xa080, 0x0000, 0x2004, 0xa080, 0x0017, 0x2098, 0x7808,
+	0xa088, 0x0002, 0x21a8, 0x53a6, 0x8003, 0x60c2, 0x1078, 0x6c2d,
+	0x027f, 0x017f, 0x147f, 0x157f, 0x007c, 0x0e7e, 0x0c7e, 0x007e,
+	0x127e, 0x2091, 0x8000, 0x2071, 0xa5ab, 0x700c, 0x2060, 0x8cff,
+	0x0040, 0x6dd1, 0x1078, 0x8c3b, 0x00c0, 0x6dc8, 0x1078, 0x7a05,
+	0x600c, 0x007e, 0x1078, 0x753d, 0x1078, 0x7045, 0x0c7f, 0x0078,
+	0x6dbf, 0x700f, 0x0000, 0x700b, 0x0000, 0x127f, 0x007f, 0x0c7f,
+	0x0e7f, 0x007c, 0x127e, 0x157e, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e,
+	0x027e, 0x017e, 0x007e, 0x2091, 0x8000, 0x2069, 0x0100, 0x2079,
+	0x0140, 0x2071, 0xa5ab, 0x7024, 0x2060, 0x8cff, 0x0040, 0x6e2a,
+	0x1078, 0x6c41, 0x68c3, 0x0000, 0x1078, 0x595a, 0x2009, 0x0013,
+	0x1078, 0x756c, 0x20a9, 0x01f4, 0x6824, 0xd094, 0x0040, 0x6e0d,
+	0x6827, 0x0004, 0x7804, 0xa084, 0x4000, 0x0040, 0x6e1f, 0x7803,
+	0x1000, 0x7803, 0x0000, 0x0078, 0x6e1f, 0xd084, 0x0040, 0x6e14,
+	0x6827, 0x0001, 0x0078, 0x6e16, 0x00f0, 0x6dfc, 0x7804, 0xa084,
+	0x1000, 0x0040, 0x6e1f, 0x7803, 0x0100, 0x7803, 0x0000, 0x6824,
+	0x007f, 0x017f, 0x027f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x157f,
+	0x127f, 0x007c, 0x2001, 0xa300, 0x2004, 0xa096, 0x0001, 0x0040,
+	0x6e62, 0xa096, 0x0004, 0x0040, 0x6e62, 0x6817, 0x0008, 0x68c3,
+	0x0000, 0x2011, 0x4129, 0x1078, 0x58d4, 0x20a9, 0x01f4, 0x6824,
+	0xd094, 0x0040, 0x6e50, 0x6827, 0x0004, 0x7804, 0xa084, 0x4000,
+	0x0040, 0x6e62, 0x7803, 0x1000, 0x7803, 0x0000, 0x0078, 0x6e62,
+	0xd084, 0x0040, 0x6e57, 0x6827, 0x0001, 0x0078, 0x6e59, 0x00f0,
+	0x6e3f, 0x7804, 0xa084, 0x1000, 0x0040, 0x6e62, 0x7803, 0x0100,
+	0x7803, 0x0000, 0x007f, 0x017f, 0x027f, 0x0c7f, 0x0d7f, 0x0e7f,
+	0x0f7f, 0x157f, 0x127f, 0x007c, 0x127e, 0x157e, 0x0f7e, 0x0e7e,
+	0x0d7e, 0x0c7e, 0x027e, 0x017e, 0x007e, 0x2091, 0x8000, 0x2069,
+	0x0100, 0x2079, 0x0140, 0x2071, 0xa5ab, 0x703c, 0x2060, 0x8cff,
+	0x0040, 0x6ee8, 0x6817, 0x0010, 0x2009, 0x00fa, 0x8109, 0x00c0,
+	0x6e86, 0x68c7, 0x0000, 0x68cb, 0x0008, 0x1078, 0x5967, 0x1078,
+	0x1f31, 0x047e, 0x057e, 0x2009, 0x017f, 0x212c, 0x200b, 0x00a5,
+	0x2021, 0x0169, 0x2404, 0xa084, 0x000f, 0xa086, 0x0004, 0x00c0,
+	0x6eb7, 0x68c7, 0x0000, 0x68cb, 0x0008, 0x0e7e, 0x0f7e, 0x2079,
+	0x0020, 0x2071, 0xa602, 0x6814, 0xa084, 0x0004, 0xa085, 0x0012,
+	0x6816, 0x7803, 0x0008, 0x7003, 0x0000, 0x0f7f, 0x0e7f, 0x250a,
+	0x057f, 0x047f, 0xa39d, 0x0000, 0x00c0, 0x6ec2, 0x2009, 0x0049,
+	0x1078, 0x756c, 0x20a9, 0x03e8, 0x6824, 0xd094, 0x0040, 0x6ed5,
+	0x6827, 0x0004, 0x7804, 0xa084, 0x4000, 0x0040, 0x6ee7, 0x7803,
+	0x1000, 0x7803, 0x0000, 0x0078, 0x6ee7, 0xd08c, 0x0040, 0x6edc,
+	0x6827, 0x0002, 0x0078, 0x6ede, 0x00f0, 0x6ec4, 0x7804, 0xa084,
+	0x1000, 0x0040, 0x6ee7, 0x7803, 0x0100, 0x7803, 0x0000, 0x6824,
+	0x007f, 0x017f, 0x027f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x157f,
+	0x127f, 0x007c, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x2069, 0xa5ab,
+	0x6a06, 0x127f, 0x0d7f, 0x007c, 0x0d7e, 0x127e, 0x2091, 0x8000,
+	0x2069, 0xa5ab, 0x6a32, 0x127f, 0x0d7f, 0x007c, 0x0f7e, 0x0e7e,
+	0x0c7e, 0x067e, 0x007e, 0x127e, 0x2071, 0xa5ab, 0x7614, 0x2660,
+	0x2678, 0x2091, 0x8000, 0x8cff, 0x0040, 0x6f46, 0x601c, 0xa206,
+	0x00c0, 0x6f41, 0x7014, 0xac36, 0x00c0, 0x6f20, 0x660c, 0x7616,
+	0x7010, 0xac36, 0x00c0, 0x6f2e, 0x2c00, 0xaf36, 0x0040, 0x6f2c,
+	0x2f00, 0x7012, 0x0078, 0x6f2e, 0x7013, 0x0000, 0x660c, 0x067e,
+	0x2c00, 0xaf06, 0x0040, 0x6f37, 0x7e0e, 0x0078, 0x6f38, 0x2678,
+	0x600f, 0x0000, 0x1078, 0x8c01, 0x1078, 0x7045, 0x0c7f, 0x0078,
+	0x6f13, 0x2c78, 0x600c, 0x2060, 0x0078, 0x6f13, 0x127f, 0x007f,
+	0x067f, 0x0c7f, 0x0e7f, 0x0f7f, 0x007c, 0x157e, 0x147e, 0x20a1,
+	0x020b, 0x1078, 0x6806, 0x7810, 0x20a2, 0xa006, 0x20a2, 0x20a2,
+	0x20a2, 0x20a2, 0x20a3, 0x1000, 0x0078, 0x6fa0, 0x157e, 0x147e,
+	0x20a1, 0x020b, 0x1078, 0x6806, 0x7810, 0x20a2, 0xa006, 0x20a2,
+	0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x4000, 0x0078, 0x6fa0, 0x157e,
+	0x147e, 0x20a1, 0x020b, 0x1078, 0x6806, 0x7810, 0x20a2, 0xa006,
+	0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x2000, 0x0078, 0x6fa0,
+	0x157e, 0x147e, 0x20a1, 0x020b, 0x1078, 0x6806, 0x7810, 0x20a2,
+	0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0400, 0x0078,
+	0x6fa0, 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078, 0x6806, 0x7810,
+	0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0200,
+	0x1078, 0x7050, 0x60c3, 0x0020, 0x1078, 0x6c2d, 0x147f, 0x157f,
+	0x007c, 0x127e, 0x0c7e, 0x2091, 0x8000, 0x2061, 0x0100, 0x6120,
+	0xd1b4, 0x00c0, 0x6fb8, 0xd1bc, 0x00c0, 0x7002, 0x0078, 0x7042,
+	0x2009, 0x017f, 0x200b, 0x00a1, 0x157e, 0x007e, 0x0d7e, 0x2069,
+	0x0140, 0x20a9, 0x001e, 0x2009, 0x0169, 0x6804, 0xa084, 0x4000,
+	0x0040, 0x6ff9, 0x6020, 0xd0b4, 0x0040, 0x6ff9, 0x6024, 0xd094,
+	0x00c0, 0x6ff9, 0x2104, 0xa084, 0x000f, 0xa086, 0x0004, 0x00c0,
+	0x6ff9, 0x00f0, 0x6fc5, 0x027e, 0x6198, 0xa18c, 0x00ff, 0x8107,
+	0x6130, 0xa18c, 0x00ff, 0xa10d, 0x6088, 0x628c, 0x618e, 0x608b,
+	0xbc91, 0x6043, 0x0001, 0x6043, 0x0000, 0x608a, 0x628e, 0x6024,
+	0xd094, 0x00c0, 0x6ff8, 0x6a04, 0xa294, 0x4000, 0x00c0, 0x6fef,
+	0x027f, 0x0d7f, 0x007f, 0x157f, 0x2009, 0x017f, 0x200b, 0x0000,
+	0x0078, 0x7042, 0x2009, 0x017f, 0x200b, 0x00a1, 0x157e, 0x007e,
+	0x0d7e, 0x2069, 0x0140, 0x20a9, 0x001e, 0x2009, 0x0169, 0x6804,
+	0xa084, 0x4000, 0x0040, 0x703b, 0x6020, 0xd0bc, 0x0040, 0x703b,
+	0x2104, 0xa084, 0x000f, 0xa086, 0x0004, 0x00c0, 0x703b, 0x00f0,
+	0x700f, 0x027e, 0x6164, 0xa18c, 0x00ff, 0x8107, 0x6130, 0xa18c,
+	0x00ff, 0xa10d, 0x6088, 0x628c, 0x608b, 0xbc91, 0x618e, 0x6043,
+	0x0001, 0x6043, 0x0000, 0x608a, 0x628e, 0x6a04, 0xa294, 0x4000,
+	0x00c0, 0x7035, 0x027f, 0x0d7f, 0x007f, 0x157f, 0x2009, 0x017f,
+	0x200b, 0x0000, 0x0c7f, 0x127f, 0x007c, 0x0e7e, 0x2071, 0xa5ab,
+	0x7020, 0xa005, 0x0040, 0x704e, 0x8001, 0x7022, 0x0e7f, 0x007c,
+	0x20a9, 0x0008, 0x20a2, 0x00f0, 0x7052, 0x20a2, 0x20a2, 0x007c,
+	0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x077e, 0x067e, 0x007e, 0x127e,
+	0x2091, 0x8000, 0x2071, 0xa5ab, 0x7614, 0x2660, 0x2678, 0x2039,
+	0x0001, 0x87ff, 0x0040, 0x70f4, 0x8cff, 0x0040, 0x70f4, 0x601c,
+	0xa086, 0x0006, 0x00c0, 0x70ef, 0x88ff, 0x0040, 0x707f, 0x2800,
+	0xac06, 0x00c0, 0x70ef, 0x2039, 0x0000, 0x0078, 0x708a, 0x6018,
+	0xa206, 0x00c0, 0x70ef, 0x85ff, 0x0040, 0x708a, 0x6020, 0xa106,
+	0x00c0, 0x70ef, 0x7024, 0xac06, 0x00c0, 0x70ba, 0x2069, 0x0100,
+	0x68c0, 0xa005, 0x0040, 0x70b5, 0x1078, 0x595a, 0x6817, 0x0008,
+	0x68c3, 0x0000, 0x1078, 0x7188, 0x7027, 0x0000, 0x037e, 0x2069,
+	0x0140, 0x6b04, 0xa384, 0x1000, 0x0040, 0x70aa, 0x6803, 0x0100,
+	0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0040, 0x70b2,
+	0x6827, 0x0001, 0x037f, 0x0078, 0x70ba, 0x6003, 0x0009, 0x630a,
+	0x0078, 0x70ef, 0x7014, 0xac36, 0x00c0, 0x70c0, 0x660c, 0x7616,
+	0x7010, 0xac36, 0x00c0, 0x70ce, 0x2c00, 0xaf36, 0x0040, 0x70cc,
+	0x2f00, 0x7012, 0x0078, 0x70ce, 0x7013, 0x0000, 0x660c, 0x067e,
+	0x2c00, 0xaf06, 0x0040, 0x70d7, 0x7e0e, 0x0078, 0x70d8, 0x2678,
+	0x89ff, 0x00c0, 0x70e7, 0x600f, 0x0000, 0x6010, 0x2068, 0x1078,
+	0x8a44, 0x0040, 0x70e5, 0x1078, 0x9e70, 0x1078, 0x8c01, 0x1078,
+	0x7045, 0x88ff, 0x00c0, 0x70fe, 0x0c7f, 0x0078, 0x7069, 0x2c78,
+	0x600c, 0x2060, 0x0078, 0x7069, 0xa006, 0x127f, 0x007f, 0x067f,
+	0x077f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x6017, 0x0000,
+	0x0c7f, 0xa8c5, 0x0001, 0x0078, 0x70f5, 0x0f7e, 0x0e7e, 0x0d7e,
+	0x0c7e, 0x067e, 0x027e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071,
+	0xa5ab, 0x7638, 0x2660, 0x2678, 0x8cff, 0x0040, 0x7177, 0x601c,
+	0xa086, 0x0006, 0x00c0, 0x7172, 0x87ff, 0x0040, 0x7125, 0x2700,
+	0xac06, 0x00c0, 0x7172, 0x0078, 0x7130, 0x6018, 0xa206, 0x00c0,
+	0x7172, 0x85ff, 0x0040, 0x7130, 0x6020, 0xa106, 0x00c0, 0x7172,
+	0x703c, 0xac06, 0x00c0, 0x7142, 0x037e, 0x2019, 0x0001, 0x1078,
+	0x6e6c, 0x7033, 0x0000, 0x703f, 0x0000, 0x7043, 0x0000, 0x7047,
+	0x0000, 0x037f, 0x7038, 0xac36, 0x00c0, 0x7148, 0x660c, 0x763a,
+	0x7034, 0xac36, 0x00c0, 0x7156, 0x2c00, 0xaf36, 0x0040, 0x7154,
+	0x2f00, 0x7036, 0x0078, 0x7156, 0x7037, 0x0000, 0x660c, 0x067e,
+	0x2c00, 0xaf06, 0x0040, 0x715f, 0x7e0e, 0x0078, 0x7160, 0x2678,
+	0x600f, 0x0000, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040, 0x716a,
+	0x1078, 0x9e70, 0x1078, 0x8c01, 0x87ff, 0x00c0, 0x7181, 0x0c7f,
+	0x0078, 0x7114, 0x2c78, 0x600c, 0x2060, 0x0078, 0x7114, 0xa006,
+	0x127f, 0x007f, 0x027f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f,
+	0x007c, 0x6017, 0x0000, 0x0c7f, 0xa7bd, 0x0001, 0x0078, 0x7178,
+	0x0e7e, 0x2071, 0xa5ab, 0x2001, 0xa300, 0x2004, 0xa086, 0x0002,
+	0x00c0, 0x7196, 0x7007, 0x0005, 0x0078, 0x7198, 0x7007, 0x0000,
+	0x0e7f, 0x007c, 0x0f7e, 0x0e7e, 0x0c7e, 0x067e, 0x027e, 0x007e,
+	0x127e, 0x2091, 0x8000, 0x2071, 0xa5ab, 0x2c10, 0x7638, 0x2660,
+	0x2678, 0x8cff, 0x0040, 0x71d8, 0x2200, 0xac06, 0x00c0, 0x71d3,
+	0x7038, 0xac36, 0x00c0, 0x71b6, 0x660c, 0x763a, 0x7034, 0xac36,
+	0x00c0, 0x71c4, 0x2c00, 0xaf36, 0x0040, 0x71c2, 0x2f00, 0x7036,
+	0x0078, 0x71c4, 0x7037, 0x0000, 0x660c, 0x2c00, 0xaf06, 0x0040,
+	0x71cc, 0x7e0e, 0x0078, 0x71cd, 0x2678, 0x600f, 0x0000, 0xa085,
+	0x0001, 0x0078, 0x71d8, 0x2c78, 0x600c, 0x2060, 0x0078, 0x71a9,
+	0x127f, 0x007f, 0x027f, 0x067f, 0x0c7f, 0x0e7f, 0x0f7f, 0x007c,
+	0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x007e, 0x127e, 0x2091,
+	0x8000, 0x2071, 0xa5ab, 0x760c, 0x2660, 0x2678, 0x8cff, 0x0040,
+	0x7279, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x00c0, 0x7274,
+	0x7024, 0xac06, 0x00c0, 0x721f, 0x2069, 0x0100, 0x68c0, 0xa005,
+	0x0040, 0x724d, 0x1078, 0x6c41, 0x68c3, 0x0000, 0x1078, 0x7188,
+	0x7027, 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000,
+	0x0040, 0x7216, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100,
+	0x6824, 0xd084, 0x0040, 0x721e, 0x6827, 0x0001, 0x037f, 0x700c,
+	0xac36, 0x00c0, 0x7225, 0x660c, 0x760e, 0x7008, 0xac36, 0x00c0,
+	0x7233, 0x2c00, 0xaf36, 0x0040, 0x7231, 0x2f00, 0x700a, 0x0078,
+	0x7233, 0x700b, 0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06, 0x0040,
+	0x723c, 0x7e0e, 0x0078, 0x723d, 0x2678, 0x600f, 0x0000, 0x1078,
+	0x8c27, 0x00c0, 0x7251, 0x1078, 0x2839, 0x1078, 0x8c3b, 0x00c0,
+	0x726d, 0x1078, 0x7a05, 0x0078, 0x726d, 0x1078, 0x7188, 0x0078,
+	0x721f, 0x1078, 0x8c3b, 0x00c0, 0x7259, 0x1078, 0x7a05, 0x0078,
+	0x726d, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040, 0x726d, 0x601c,
+	0xa086, 0x0003, 0x00c0, 0x7281, 0x6837, 0x0103, 0x6b4a, 0x6847,
+	0x0000, 0x1078, 0x4982, 0x1078, 0x8bf4, 0x1078, 0x8c01, 0x1078,
+	0x7045, 0x0c7f, 0x0078, 0x71ee, 0x2c78, 0x600c, 0x2060, 0x0078,
+	0x71ee, 0x127f, 0x007f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f,
+	0x007c, 0x601c, 0xa086, 0x0006, 0x00c0, 0x726d, 0x1078, 0x9e70,
+	0x0078, 0x726d, 0x037e, 0x157e, 0x137e, 0x147e, 0x3908, 0xa006,
+	0xa190, 0x0020, 0x221c, 0xa39e, 0x260c, 0x00c0, 0x729b, 0x8210,
+	0x8000, 0x0078, 0x7292, 0xa005, 0x0040, 0x72a7, 0x20a9, 0x0020,
+	0x2198, 0x8211, 0xa282, 0x0020, 0x20c8, 0x20a0, 0x53a3, 0x147f,
+	0x137f, 0x157f, 0x037f, 0x007c, 0x0d7e, 0x20a1, 0x020b, 0x1078,
+	0x65f8, 0x20a3, 0x0200, 0x20a3, 0x0014, 0x60c3, 0x0014, 0x20a3,
+	0x0000, 0x20a3, 0x0000, 0x2099, 0xa5a3, 0x20a9, 0x0004, 0x53a6,
+	0x20a3, 0x0004, 0x20a3, 0x7878, 0x20a3, 0x0000, 0x20a3, 0x0000,
+	0x1078, 0x6c2d, 0x0d7f, 0x007c, 0x20a1, 0x020b, 0x1078, 0x65f8,
+	0x20a3, 0x0214, 0x20a3, 0x0018, 0x20a3, 0x0800, 0x7810, 0xa084,
+	0xff00, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000,
+	0x20a3, 0x0000, 0x7810, 0xa084, 0x00ff, 0x20a2, 0x7828, 0x20a2,
+	0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0018, 0x1078, 0x6c2d,
+	0x007c, 0x0d7e, 0x017e, 0x2f68, 0x2009, 0x0035, 0x1078, 0x8ef5,
+	0x00c0, 0x7361, 0x20a1, 0x020b, 0x1078, 0x6567, 0x20a3, 0x1300,
+	0x20a3, 0x0000, 0x7828, 0x2068, 0x681c, 0xa086, 0x0003, 0x0040,
+	0x733d, 0x7818, 0xa080, 0x0028, 0x2014, 0xa286, 0x007e, 0x00c0,
+	0x7317, 0x20a3, 0x00ff, 0x20a3, 0xfffe, 0x0078, 0x7352, 0xa286,
+	0x007f, 0x00c0, 0x7321, 0x20a3, 0x00ff, 0x20a3, 0xfffd, 0x0078,
+	0x7352, 0xd2bc, 0x0040, 0x7337, 0xa286, 0x0080, 0x00c0, 0x732e,
+	0x20a3, 0x00ff, 0x20a3, 0xfffc, 0x0078, 0x7352, 0xa2e8, 0xa434,
+	0x2d6c, 0x6810, 0x20a2, 0x6814, 0x20a2, 0x0078, 0x7352, 0x20a3,
+	0x0000, 0x6098, 0x20a2, 0x0078, 0x7352, 0x7818, 0xa080, 0x0028,
+	0x2004, 0xa082, 0x007e, 0x0048, 0x734e, 0x0d7e, 0x2069, 0xa31a,
+	0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x7352, 0x20a3, 0x0000,
+	0x6030, 0x20a2, 0x7834, 0x20a2, 0x7838, 0x20a2, 0x20a3, 0x0000,
+	0x20a3, 0x0000, 0x60c3, 0x000c, 0x1078, 0x6c2d, 0x017f, 0x0d7f,
+	0x007c, 0x7817, 0x0001, 0x7803, 0x0006, 0x017f, 0x0d7f, 0x007c,
+	0x0d7e, 0x027e, 0x7928, 0x2168, 0x691c, 0xa186, 0x0006, 0x0040,
+	0x738a, 0xa186, 0x0003, 0x0040, 0x73e5, 0xa186, 0x0005, 0x0040,
+	0x73c8, 0xa186, 0x0004, 0x0040, 0x73b8, 0xa186, 0x0008, 0x0040,
+	0x73d2, 0x7807, 0x0037, 0x7813, 0x1700, 0x1078, 0x7450, 0x027f,
+	0x0d7f, 0x007c, 0x1078, 0x740d, 0x2009, 0x4000, 0x6800, 0x0079,
+	0x7391, 0x73a4, 0x73b2, 0x73a6, 0x73b2, 0x73ad, 0x73a4, 0x73a4,
+	0x73b2, 0x73b2, 0x73b2, 0x73b2, 0x73a4, 0x73a4, 0x73a4, 0x73a4,
+	0x73a4, 0x73b2, 0x73a4, 0x73b2, 0x1078, 0x1328, 0x6824, 0xd0e4,
+	0x0040, 0x73ad, 0xd0cc, 0x0040, 0x73b0, 0xa00e, 0x0078, 0x73b2,
+	0x2009, 0x2000, 0x6828, 0x20a2, 0x682c, 0x20a2, 0x0078, 0x7403,
+	0x1078, 0x740d, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x2009, 0x4000,
+	0x6a00, 0xa286, 0x0002, 0x00c0, 0x73c6, 0xa00e, 0x0078, 0x7403,
+	0x1078, 0x740d, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x2009, 0x4000,
+	0x0078, 0x7403, 0x1078, 0x740d, 0x20a3, 0x0000, 0x20a3, 0x0000,
+	0x2009, 0x4000, 0xa286, 0x0005, 0x0040, 0x73e2, 0xa286, 0x0002,
+	0x00c0, 0x73e3, 0xa00e, 0x0078, 0x7403, 0x1078, 0x740d, 0x6810,
+	0x2068, 0x697c, 0x6810, 0xa112, 0x6980, 0x6814, 0xa103, 0x20a2,
+	0x22a2, 0x7928, 0xa180, 0x0000, 0x2004, 0xa08e, 0x0002, 0x0040,
+	0x7401, 0xa08e, 0x0004, 0x0040, 0x7401, 0x2009, 0x4000, 0x0078,
+	0x7403, 0x2009, 0x0000, 0x21a2, 0x20a3, 0x0000, 0x60c3, 0x0018,
+	0x1078, 0x6c2d, 0x027f, 0x0d7f, 0x007c, 0x037e, 0x047e, 0x057e,
+	0x067e, 0x20a1, 0x020b, 0x1078, 0x65f8, 0xa006, 0x20a3, 0x0200,
+	0x20a2, 0x7934, 0x21a2, 0x7938, 0x21a2, 0x7818, 0xa080, 0x0028,
+	0x2004, 0xa092, 0x007e, 0x0048, 0x7433, 0x0d7e, 0x2069, 0xa31a,
+	0x2d2c, 0x8d68, 0x2d34, 0xa0e8, 0xa434, 0x2d6c, 0x6b10, 0x6c14,
+	0x0d7f, 0x0078, 0x7439, 0x2019, 0x0000, 0x6498, 0x2029, 0x0000,
+	0x6630, 0x7828, 0xa080, 0x0007, 0x2004, 0xa086, 0x0003, 0x00c0,
+	0x7447, 0x25a2, 0x26a2, 0x23a2, 0x24a2, 0x0078, 0x744b, 0x23a2,
+	0x24a2, 0x25a2, 0x26a2, 0x067f, 0x057f, 0x047f, 0x037f, 0x007c,
+	0x20a1, 0x020b, 0x1078, 0x65f8, 0x20a3, 0x0100, 0x20a3, 0x0000,
+	0x20a3, 0x0009, 0x7810, 0x20a2, 0x60c3, 0x0008, 0x1078, 0x6c2d,
+	0x007c, 0x20a1, 0x020b, 0x1078, 0x655e, 0x20a3, 0x1400, 0x20a3,
+	0x0000, 0x7834, 0x20a2, 0x7838, 0x20a2, 0x7828, 0x20a2, 0x782c,
+	0x20a2, 0x7830, 0xa084, 0x00ff, 0x8007, 0x20a2, 0x20a3, 0x0000,
+	0x60c3, 0x0010, 0x1078, 0x6c2d, 0x007c, 0x20a1, 0x020b, 0x1078,
+	0x65ef, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x7828, 0x20a2, 0x7810,
+	0x20a2, 0x60c3, 0x0008, 0x1078, 0x6c2d, 0x007c, 0x147e, 0x20a1,
+	0x020b, 0x1078, 0x7499, 0x60c3, 0x0000, 0x1078, 0x6c2d, 0x147f,
+	0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028,
+	0x2004, 0xd0bc, 0x0040, 0x74b6, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c,
+	0x6810, 0xa085, 0x0300, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa31a,
+	0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x74be, 0x20a3, 0x0300,
+	0x6298, 0x22a2, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0819,
+	0x20a3, 0x0000, 0x1078, 0x6c1c, 0x22a2, 0x20a3, 0x0000, 0x2fa2,
+	0x7a08, 0x22a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x007c, 0x2061,
+	0xaa00, 0x2a70, 0x7060, 0x7046, 0x704b, 0xaa00, 0x007c, 0x0e7e,
+	0x127e, 0x2071, 0xa300, 0x2091, 0x8000, 0x7544, 0xa582, 0x0010,
+	0x0048, 0x7509, 0x7048, 0x2060, 0x6000, 0xa086, 0x0000, 0x0040,
+	0x74f5, 0xace0, 0x0010, 0x7054, 0xac02, 0x00c8, 0x74f1, 0x0078,
+	0x74e4, 0x2061, 0xaa00, 0x0078, 0x74e4, 0x6003, 0x0008, 0x8529,
+	0x7546, 0xaca8, 0x0010, 0x7054, 0xa502, 0x00c8, 0x7505, 0x754a,
+	0xa085, 0x0001, 0x127f, 0x0e7f, 0x007c, 0x704b, 0xaa00, 0x0078,
+	0x7500, 0xa006, 0x0078, 0x7502, 0x0e7e, 0x2071, 0xa300, 0x7544,
+	0xa582, 0x0010, 0x0048, 0x753a, 0x7048, 0x2060, 0x6000, 0xa086,
+	0x0000, 0x0040, 0x7527, 0xace0, 0x0010, 0x7054, 0xac02, 0x00c8,
+	0x7523, 0x0078, 0x7516, 0x2061, 0xaa00, 0x0078, 0x7516, 0x6003,
+	0x0008, 0x8529, 0x7546, 0xaca8, 0x0010, 0x7054, 0xa502, 0x00c8,
+	0x7536, 0x754a, 0xa085, 0x0001, 0x0e7f, 0x007c, 0x704b, 0xaa00,
+	0x0078, 0x7532, 0xa006, 0x0078, 0x7534, 0xac82, 0xaa00, 0x1048,
+	0x1328, 0x2001, 0xa315, 0x2004, 0xac02, 0x10c8, 0x1328, 0xa006,
+	0x6006, 0x600a, 0x600e, 0x6012, 0x6016, 0x601a, 0x601f, 0x0000,
+	0x6003, 0x0000, 0x6022, 0x6026, 0x602a, 0x602e, 0x6032, 0x6036,
+	0x603a, 0x603e, 0x2061, 0xa300, 0x6044, 0x8000, 0x6046, 0xa086,
+	0x0001, 0x0040, 0x7564, 0x007c, 0x127e, 0x2091, 0x8000, 0x1078,
+	0x6109, 0x127f, 0x0078, 0x7563, 0x601c, 0xa084, 0x000f, 0x0079,
+	0x7571, 0x757a, 0x758b, 0x75a7, 0x75c3, 0x8f2d, 0x8f49, 0x8f65,
+	0x757a, 0x758b, 0xa186, 0x0013, 0x00c0, 0x7583, 0x1078, 0x6010,
+	0x1078, 0x6109, 0x007c, 0xa18e, 0x0047, 0x00c0, 0x758a, 0xa016,
+	0x1078, 0x15ec, 0x007c, 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8,
+	0x1328, 0x1079, 0x7595, 0x067f, 0x007c, 0x75a5, 0x7891, 0x7a34,
+	0x75a5, 0x7ab8, 0x75df, 0x75a5, 0x75a5, 0x7823, 0x7e6d, 0x75a5,
+	0x75a5, 0x75a5, 0x75a5, 0x75a5, 0x75a5, 0x1078, 0x1328, 0x067e,
+	0x6000, 0xa0b2, 0x0010, 0x10c8, 0x1328, 0x1079, 0x75b1, 0x067f,
+	0x007c, 0x75c1, 0x8522, 0x75c1, 0x75c1, 0x75c1, 0x75c1, 0x75c1,
+	0x75c1, 0x84c5, 0x86a8, 0x75c1, 0x8552, 0x85d8, 0x8552, 0x85d8,
+	0x75c1, 0x1078, 0x1328, 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8,
+	0x1328, 0x1079, 0x75cd, 0x067f, 0x007c, 0x75dd, 0x7eb4, 0x7f81,
+	0x80c6, 0x8242, 0x75dd, 0x75dd, 0x75dd, 0x7e8d, 0x846d, 0x8471,
+	0x75dd, 0x75dd, 0x75dd, 0x75dd, 0x84a1, 0x1078, 0x1328, 0xa1b6,
+	0x0015, 0x00c0, 0x75e7, 0x1078, 0x753d, 0x0078, 0x75ed, 0xa1b6,
+	0x0016, 0x10c0, 0x1328, 0x1078, 0x753d, 0x007c, 0x20a9, 0x000e,
+	0x2e98, 0x6010, 0x20a0, 0x53a3, 0x20a9, 0x0006, 0x3310, 0x3420,
+	0x9398, 0x94a0, 0x3318, 0x3428, 0x222e, 0x2326, 0xa290, 0x0002,
+	0xa5a8, 0x0002, 0xa398, 0x0002, 0xa4a0, 0x0002, 0x00f0, 0x75fc,
+	0x0e7e, 0x1078, 0x8a44, 0x0040, 0x7613, 0x6010, 0x2070, 0x7007,
+	0x0000, 0x7037, 0x0103, 0x0e7f, 0x1078, 0x753d, 0x007c, 0x0d7e,
+	0x037e, 0x7330, 0xa386, 0x0200, 0x00c0, 0x7624, 0x6018, 0x2068,
+	0x6813, 0x00ff, 0x6817, 0xfffd, 0x6010, 0xa005, 0x0040, 0x762e,
+	0x2068, 0x6807, 0x0000, 0x6837, 0x0103, 0x6b32, 0x1078, 0x753d,
+	0x037f, 0x0d7f, 0x007c, 0x017e, 0x20a9, 0x002a, 0xae80, 0x000c,
+	0x2098, 0x6010, 0xa080, 0x0002, 0x20a0, 0x53a3, 0x20a9, 0x002a,
+	0x6010, 0xa080, 0x0001, 0x2004, 0xa080, 0x0002, 0x20a0, 0x53a3,
+	0x0e7e, 0x6010, 0x2004, 0x2070, 0x7037, 0x0103, 0x0e7f, 0x1078,
+	0x753d, 0x017f, 0x007c, 0x0e7e, 0x0d7e, 0x603f, 0x0000, 0x2c68,
+	0x017e, 0x2009, 0x0035, 0x1078, 0x8ef5, 0x017f, 0x00c0, 0x766f,
+	0x027e, 0x6228, 0x2268, 0x027f, 0x2071, 0xa88c, 0x6b1c, 0xa386,
+	0x0003, 0x0040, 0x7673, 0xa386, 0x0006, 0x0040, 0x7677, 0x1078,
+	0x753d, 0x0078, 0x7679, 0x1078, 0x767c, 0x0078, 0x7679, 0x1078,
+	0x771e, 0x0d7f, 0x0e7f, 0x007c, 0x0f7e, 0x6810, 0x2078, 0xa186,
+	0x0015, 0x0040, 0x7705, 0xa18e, 0x0016, 0x00c0, 0x771c, 0x700c,
+	0xa084, 0xff00, 0xa086, 0x1700, 0x00c0, 0x76e0, 0x8fff, 0x0040,
+	0x771a, 0x6808, 0xa086, 0xffff, 0x00c0, 0x7709, 0x784c, 0xa084,
+	0x0060, 0xa086, 0x0020, 0x00c0, 0x76a7, 0x797c, 0x7810, 0xa106,
+	0x00c0, 0x7709, 0x7980, 0x7814, 0xa106, 0x00c0, 0x7709, 0x1078,
+	0x8bf4, 0x6830, 0x7852, 0x784c, 0xc0dc, 0xc0f4, 0xc0d4, 0x784e,
+	0x027e, 0xa00e, 0x6a14, 0x2001, 0x000a, 0x1078, 0x5a98, 0x7854,
+	0xa20a, 0x0048, 0x76bc, 0x8011, 0x7a56, 0x82ff, 0x027f, 0x00c0,
+	0x76c8, 0x0c7e, 0x2d60, 0x1078, 0x8832, 0x0c7f, 0x0078, 0x771a,
+	0x0c7e, 0x0d7e, 0x2f68, 0x6838, 0xd0fc, 0x00c0, 0x76d3, 0x1078,
+	0x4290, 0x0078, 0x76d5, 0x1078, 0x436e, 0x0d7f, 0x0c7f, 0x00c0,
+	0x7709, 0x0c7e, 0x2d60, 0x1078, 0x753d, 0x0c7f, 0x0078, 0x771a,
+	0x7008, 0xa086, 0x000b, 0x00c0, 0x76fa, 0x6018, 0x200c, 0xc1bc,
+	0x2102, 0x0c7e, 0x2d60, 0x7853, 0x0003, 0x6007, 0x0085, 0x6003,
+	0x000b, 0x601f, 0x0002, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x0c7f,
+	0x0078, 0x771a, 0x700c, 0xa086, 0x2a00, 0x00c0, 0x7709, 0x2001,
+	0xa5a2, 0x2004, 0x683e, 0x0078, 0x771a, 0x1078, 0x7739, 0x0078,
+	0x771c, 0x8fff, 0x1040, 0x1328, 0x0c7e, 0x0d7e, 0x2d60, 0x2f68,
+	0x684b, 0x0003, 0x1078, 0x8726, 0x1078, 0x8bf4, 0x1078, 0x8c01,
+	0x0d7f, 0x0c7f, 0x1078, 0x753d, 0x0f7f, 0x007c, 0xa186, 0x0015,
+	0x00c0, 0x7728, 0x2001, 0xa5a2, 0x2004, 0x683e, 0x0078, 0x7736,
+	0xa18e, 0x0016, 0x00c0, 0x7738, 0x0c7e, 0x2d00, 0x2060, 0x1078,
+	0xa134, 0x1078, 0x5a41, 0x1078, 0x753d, 0x0c7f, 0x1078, 0x753d,
+	0x007c, 0x027e, 0x037e, 0x047e, 0x7228, 0x7c80, 0x7b7c, 0xd2f4,
+	0x0040, 0x7748, 0x2001, 0xa5a2, 0x2004, 0x683e, 0x0078, 0x77ac,
+	0x0c7e, 0x2d60, 0x1078, 0x874a, 0x0c7f, 0x6804, 0xa086, 0x0050,
+	0x00c0, 0x7760, 0x0c7e, 0x2d00, 0x2060, 0x6003, 0x0001, 0x6007,
+	0x0050, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x0c7f, 0x0078, 0x77ac,
+	0x6800, 0xa086, 0x000f, 0x0040, 0x7782, 0x8fff, 0x1040, 0x1328,
+	0x6824, 0xd0dc, 0x00c0, 0x7782, 0x6800, 0xa086, 0x0004, 0x00c0,
+	0x7787, 0x784c, 0xd0ac, 0x0040, 0x7787, 0x784c, 0xc0dc, 0xc0f4,
+	0x784e, 0x7850, 0xc0f4, 0xc0fc, 0x7852, 0x2001, 0x0001, 0x682e,
+	0x0078, 0x77a6, 0x2001, 0x0007, 0x682e, 0x0078, 0x77a6, 0x784c,
+	0xd0b4, 0x00c0, 0x7794, 0xd0ac, 0x0040, 0x7782, 0x784c, 0xd0f4,
+	0x00c0, 0x7782, 0x0078, 0x7775, 0xd2ec, 0x00c0, 0x7782, 0x7024,
+	0xa306, 0x00c0, 0x779f, 0x7020, 0xa406, 0x0040, 0x7782, 0x7020,
+	0x6836, 0x7024, 0x683a, 0x2001, 0x0005, 0x682e, 0x1078, 0x8d2b,
+	0x1078, 0x6109, 0x0078, 0x77ae, 0x1078, 0x753d, 0x047f, 0x037f,
+	0x027f, 0x007c, 0x0e7e, 0x0d7e, 0x027e, 0x6034, 0x2068, 0x6a1c,
+	0xa286, 0x0007, 0x0040, 0x7806, 0xa286, 0x0002, 0x0040, 0x7806,
+	0xa286, 0x0000, 0x0040, 0x7806, 0x6808, 0x6338, 0xa306, 0x00c0,
+	0x7806, 0x2071, 0xa88c, 0xa186, 0x0015, 0x0040, 0x7800, 0xa18e,
+	0x0016, 0x00c0, 0x77e8, 0x6030, 0xa084, 0x00ff, 0xa086, 0x0001,
+	0x00c0, 0x77e8, 0x700c, 0xa086, 0x2a00, 0x00c0, 0x77e8, 0x6034,
+	0xa080, 0x0009, 0x200c, 0xc1dd, 0xc1f5, 0x2102, 0x0078, 0x7800,
+	0x0c7e, 0x6034, 0x2060, 0x6010, 0x2068, 0x1078, 0x8a44, 0x1040,
+	0x1328, 0x6853, 0x0003, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f,
+	0x0002, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x0c7f, 0x0078, 0x7806,
+	0x6034, 0x2068, 0x2001, 0xa5a2, 0x2004, 0x683e, 0x1078, 0x753d,
+	0x027f, 0x0d7f, 0x0e7f, 0x007c, 0x0d7e, 0x20a9, 0x000e, 0x2e98,
+	0x6010, 0x20a0, 0x53a3, 0xa1b6, 0x0015, 0x00c0, 0x7820, 0x6018,
+	0x2068, 0x7038, 0x680a, 0x703c, 0x680e, 0x6800, 0xc08d, 0x6802,
+	0x0d7f, 0x0078, 0x7608, 0x2100, 0xa1b2, 0x0044, 0x10c8, 0x1328,
+	0xa1b2, 0x0040, 0x00c8, 0x7888, 0x0079, 0x782e, 0x787c, 0x7870,
+	0x787c, 0x787c, 0x787c, 0x787c, 0x786e, 0x786e, 0x786e, 0x786e,
+	0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e,
+	0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e,
+	0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x787c, 0x786e, 0x787c,
+	0x787c, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x787c, 0x786e,
+	0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e,
+	0x787c, 0x787c, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e,
+	0x786e, 0x786e, 0x786e, 0x787c, 0x786e, 0x786e, 0x1078, 0x1328,
+	0x6003, 0x0001, 0x6106, 0x1078, 0x5c45, 0x127e, 0x2091, 0x8000,
+	0x1078, 0x6109, 0x127f, 0x007c, 0x6003, 0x0001, 0x6106, 0x1078,
+	0x5c45, 0x127e, 0x2091, 0x8000, 0x1078, 0x6109, 0x127f, 0x007c,
+	0x2600, 0x0079, 0x788b, 0x788f, 0x788f, 0x788f, 0x787c, 0x1078,
+	0x1328, 0x6004, 0xa0b2, 0x0044, 0x10c8, 0x1328, 0xa1b6, 0x0013,
+	0x00c0, 0x78a1, 0xa0b2, 0x0040, 0x00c8, 0x79fb, 0x2008, 0x0079,
+	0x7941, 0xa1b6, 0x0027, 0x00c0, 0x78fe, 0x1078, 0x6010, 0x6004,
+	0x1078, 0x8c27, 0x0040, 0x78be, 0x1078, 0x8c3b, 0x0040, 0x78f6,
+	0xa08e, 0x0021, 0x0040, 0x78fa, 0xa08e, 0x0022, 0x0040, 0x78f6,
+	0xa08e, 0x003d, 0x0040, 0x78fa, 0x0078, 0x78f1, 0x1078, 0x2839,
+	0x2001, 0x0007, 0x1078, 0x443f, 0x6018, 0xa080, 0x0028, 0x200c,
+	0x1078, 0x7a05, 0xa186, 0x007e, 0x00c0, 0x78d3, 0x2001, 0xa332,
+	0x2014, 0xc285, 0x2202, 0x017e, 0x027e, 0x037e, 0x2110, 0x2019,
+	0x0028, 0x1078, 0x5d53, 0x077e, 0x2039, 0x0000, 0x1078, 0x5c78,
+	0x0c7e, 0x6018, 0xa065, 0x0040, 0x78e7, 0x1078, 0x471b, 0x0c7f,
+	0x2c08, 0x1078, 0x9c38, 0x077f, 0x037f, 0x027f, 0x017f, 0x1078,
+	0x44bc, 0x1078, 0x753d, 0x1078, 0x6109, 0x007c, 0x1078, 0x7a05,
+	0x0078, 0x78f1, 0x1078, 0x7a28, 0x0078, 0x78f1, 0xa186, 0x0014,
+	0x00c0, 0x78f5, 0x1078, 0x6010, 0x1078, 0x2813, 0x1078, 0x8c27,
+	0x00c0, 0x791d, 0x1078, 0x2839, 0x6018, 0xa080, 0x0028, 0x200c,
+	0x1078, 0x7a05, 0xa186, 0x007e, 0x00c0, 0x791b, 0x2001, 0xa332,
+	0x200c, 0xc185, 0x2102, 0x0078, 0x78f1, 0x1078, 0x8c3b, 0x00c0,
+	0x7925, 0x1078, 0x7a05, 0x0078, 0x78f1, 0x6004, 0xa08e, 0x0032,
+	0x00c0, 0x7936, 0x0e7e, 0x0f7e, 0x2071, 0xa381, 0x2079, 0x0000,
+	0x1078, 0x2b56, 0x0f7f, 0x0e7f, 0x0078, 0x78f1, 0x6004, 0xa08e,
+	0x0021, 0x0040, 0x7921, 0xa08e, 0x0022, 0x1040, 0x7a05, 0x0078,
+	0x78f1, 0x7983, 0x7985, 0x7989, 0x798d, 0x7991, 0x7995, 0x7981,
+	0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981,
+	0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981,
+	0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7999,
+	0x79ab, 0x7981, 0x79ad, 0x79ab, 0x7981, 0x7981, 0x7981, 0x7981,
+	0x7981, 0x79ab, 0x79ab, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981,
+	0x7981, 0x7981, 0x7981, 0x79de, 0x79ab, 0x7981, 0x79a5, 0x7981,
+	0x7981, 0x7981, 0x79a7, 0x7981, 0x7981, 0x7981, 0x79ab, 0x7981,
+	0x7981, 0x1078, 0x1328, 0x0078, 0x79ab, 0x2001, 0x000b, 0x0078,
+	0x79b8, 0x2001, 0x0003, 0x0078, 0x79b8, 0x2001, 0x0005, 0x0078,
+	0x79b8, 0x2001, 0x0001, 0x0078, 0x79b8, 0x2001, 0x0009, 0x0078,
+	0x79b8, 0x1078, 0x6010, 0x6003, 0x0005, 0x2001, 0xa5a2, 0x2004,
+	0x603e, 0x1078, 0x6109, 0x0078, 0x79b7, 0x0078, 0x79ab, 0x0078,
+	0x79ab, 0x1078, 0x443f, 0x0078, 0x79f0, 0x1078, 0x6010, 0x6003,
+	0x0004, 0x2001, 0xa5a0, 0x2004, 0x6016, 0x1078, 0x6109, 0x007c,
+	0x1078, 0x443f, 0x1078, 0x6010, 0x2001, 0xa5a2, 0x2004, 0x603e,
+	0x6003, 0x0002, 0x037e, 0x2019, 0xa35c, 0x2304, 0xa084, 0xff00,
+	0x00c0, 0x79cf, 0x2019, 0xa5a0, 0x231c, 0x0078, 0x79d8, 0x8007,
+	0xa09a, 0x0004, 0x0048, 0x79ca, 0x8003, 0x801b, 0x831b, 0xa318,
+	0x6316, 0x037f, 0x1078, 0x6109, 0x0078, 0x79b7, 0x0e7e, 0x0f7e,
+	0x2071, 0xa381, 0x2079, 0x0000, 0x1078, 0x2b56, 0x0f7f, 0x0e7f,
+	0x1078, 0x6010, 0x1078, 0x753d, 0x1078, 0x6109, 0x0078, 0x79b7,
+	0x1078, 0x6010, 0x6003, 0x0002, 0x2001, 0xa5a0, 0x2004, 0x6016,
+	0x1078, 0x6109, 0x007c, 0x2600, 0x2008, 0x0079, 0x79ff, 0x7a03,
+	0x7a03, 0x7a03, 0x79f0, 0x1078, 0x1328, 0x0e7e, 0x1078, 0x8a44,
+	0x0040, 0x7a21, 0x6010, 0x2070, 0x7038, 0xd0fc, 0x0040, 0x7a21,
+	0x7007, 0x0000, 0x017e, 0x6004, 0xa08e, 0x0021, 0x0040, 0x7a23,
+	0xa08e, 0x003d, 0x0040, 0x7a23, 0x017f, 0x7037, 0x0103, 0x7033,
+	0x0100, 0x0e7f, 0x007c, 0x017f, 0x1078, 0x7a28, 0x0078, 0x7a21,
+	0x0e7e, 0xacf0, 0x0004, 0x2e74, 0x7000, 0x2070, 0x7037, 0x0103,
+	0x7023, 0x8001, 0x0e7f, 0x007c, 0x0d7e, 0x6618, 0x2668, 0x6804,
+	0xa084, 0x00ff, 0x0d7f, 0xa0b2, 0x000c, 0x10c8, 0x1328, 0x6604,
+	0xa6b6, 0x0043, 0x00c0, 0x7a48, 0x1078, 0x8e6d, 0x0078, 0x7aa7,
+	0x6604, 0xa6b6, 0x0033, 0x00c0, 0x7a51, 0x1078, 0x8e11, 0x0078,
+	0x7aa7, 0x6604, 0xa6b6, 0x0028, 0x00c0, 0x7a5a, 0x1078, 0x8c6a,
+	0x0078, 0x7aa7, 0x6604, 0xa6b6, 0x0029, 0x00c0, 0x7a63, 0x1078,
+	0x8c84, 0x0078, 0x7aa7, 0x6604, 0xa6b6, 0x001f, 0x00c0, 0x7a6c,
+	0x1078, 0x75ee, 0x0078, 0x7aa7, 0x6604, 0xa6b6, 0x0000, 0x00c0,
+	0x7a75, 0x1078, 0x780c, 0x0078, 0x7aa7, 0x6604, 0xa6b6, 0x0022,
+	0x00c0, 0x7a7e, 0x1078, 0x7617, 0x0078, 0x7aa7, 0x6604, 0xa6b6,
+	0x0035, 0x00c0, 0x7a87, 0x1078, 0x7653, 0x0078, 0x7aa7, 0x6604,
+	0xa6b6, 0x0039, 0x00c0, 0x7a90, 0x1078, 0x77b2, 0x0078, 0x7aa7,
+	0x6604, 0xa6b6, 0x003d, 0x00c0, 0x7a99, 0x1078, 0x7633, 0x0078,
+	0x7aa7, 0xa1b6, 0x0015, 0x00c0, 0x7aa1, 0x1079, 0x7aac, 0x0078,
+	0x7aa7, 0xa1b6, 0x0016, 0x00c0, 0x7aa8, 0x1079, 0x7bfd, 0x007c,
+	0x1078, 0x7583, 0x0078, 0x7aa7, 0x7ad0, 0x7ad3, 0x7ad0, 0x7b1e,
+	0x7ad0, 0x7b91, 0x7c09, 0x7ad0, 0x7ad0, 0x7bd5, 0x7ad0, 0x7beb,
+	0xa1b6, 0x0048, 0x0040, 0x7ac4, 0x20e1, 0x0005, 0x3d18, 0x3e20,
+	0x2c10, 0x1078, 0x15ec, 0x007c, 0x0e7e, 0xacf0, 0x0004, 0x2e74,
+	0x7000, 0x2070, 0x7037, 0x0103, 0x0e7f, 0x1078, 0x753d, 0x007c,
+	0x0005, 0x0005, 0x007c, 0x0e7e, 0x2071, 0xa300, 0x707c, 0xa086,
+	0x0074, 0x00c0, 0x7b07, 0x1078, 0x9c0c, 0x00c0, 0x7af9, 0x0d7e,
+	0x6018, 0x2068, 0x7030, 0xd08c, 0x0040, 0x7aec, 0x6800, 0xd0bc,
+	0x0040, 0x7aec, 0xc0c5, 0x6802, 0x1078, 0x7b0b, 0x0d7f, 0x2001,
+	0x0006, 0x1078, 0x443f, 0x1078, 0x2839, 0x1078, 0x753d, 0x0078,
+	0x7b09, 0x2001, 0x000a, 0x1078, 0x443f, 0x1078, 0x2839, 0x6003,
+	0x0001, 0x6007, 0x0001, 0x1078, 0x5c45, 0x0078, 0x7b09, 0x1078,
+	0x7b81, 0x0e7f, 0x007c, 0x6800, 0xd084, 0x0040, 0x7b1d, 0x2001,
+	0x0000, 0x1078, 0x442b, 0x2069, 0xa351, 0x6804, 0xd0a4, 0x0040,
+	0x7b1d, 0x2001, 0x0006, 0x1078, 0x4472, 0x007c, 0x0d7e, 0x2011,
+	0xa31f, 0x2204, 0xa086, 0x0074, 0x00c0, 0x7b7d, 0x6018, 0x2068,
+	0x6aa0, 0xa286, 0x007e, 0x00c0, 0x7b31, 0x1078, 0x7d17, 0x0078,
+	0x7b7f, 0x1078, 0x7d0d, 0x6018, 0x2068, 0xa080, 0x0028, 0x2014,
+	0xa286, 0x0080, 0x00c0, 0x7b55, 0x6813, 0x00ff, 0x6817, 0xfffc,
+	0x6010, 0xa005, 0x0040, 0x7b4b, 0x2068, 0x6807, 0x0000, 0x6837,
+	0x0103, 0x6833, 0x0200, 0x2001, 0x0006, 0x1078, 0x443f, 0x1078,
+	0x2839, 0x1078, 0x753d, 0x0078, 0x7b7f, 0x0e7e, 0x2071, 0xa332,
+	0x2e04, 0xd09c, 0x0040, 0x7b70, 0x2071, 0xa880, 0x7108, 0x720c,
+	0xa18c, 0x00ff, 0x00c0, 0x7b68, 0xa284, 0xff00, 0x0040, 0x7b70,
+	0x6018, 0x2070, 0x70a0, 0xd0bc, 0x00c0, 0x7b70, 0x7112, 0x7216,
+	0x0e7f, 0x2001, 0x0004, 0x1078, 0x443f, 0x6003, 0x0001, 0x6007,
+	0x0003, 0x1078, 0x5c45, 0x0078, 0x7b7f, 0x1078, 0x7b81, 0x0d7f,
+	0x007c, 0x2001, 0xa300, 0x2004, 0xa086, 0x0003, 0x0040, 0x7b8c,
+	0x2001, 0x0007, 0x1078, 0x443f, 0x1078, 0x2839, 0x1078, 0x753d,
+	0x007c, 0x0e7e, 0x2071, 0xa300, 0x707c, 0xa086, 0x0014, 0x00c0,
+	0x7bcf, 0x7000, 0xa086, 0x0003, 0x00c0, 0x7ba4, 0x6010, 0xa005,
+	0x00c0, 0x7ba4, 0x1078, 0x35f7, 0x0d7e, 0x6018, 0x2068, 0x1078,
+	0x457d, 0x1078, 0x7b0b, 0x0d7f, 0x1078, 0x7dba, 0x00c0, 0x7bcf,
+	0x0d7e, 0x6018, 0x2068, 0x6890, 0x0d7f, 0xa005, 0x0040, 0x7bcf,
+	0x2001, 0x0006, 0x1078, 0x443f, 0x0e7e, 0x6010, 0xa005, 0x0040,
+	0x7bc8, 0x2070, 0x7007, 0x0000, 0x7037, 0x0103, 0x7033, 0x0200,
+	0x0e7f, 0x1078, 0x2839, 0x1078, 0x753d, 0x0078, 0x7bd3, 0x1078,
+	0x7a05, 0x1078, 0x7b81, 0x0e7f, 0x007c, 0x2011, 0xa31f, 0x2204,
+	0xa086, 0x0014, 0x00c0, 0x7be8, 0x2001, 0x0002, 0x1078, 0x443f,
+	0x6003, 0x0001, 0x6007, 0x0001, 0x1078, 0x5c45, 0x0078, 0x7bea,
+	0x1078, 0x7b81, 0x007c, 0x2011, 0xa31f, 0x2204, 0xa086, 0x0004,
+	0x00c0, 0x7bfa, 0x2001, 0x0007, 0x1078, 0x443f, 0x1078, 0x753d,
+	0x0078, 0x7bfc, 0x1078, 0x7b81, 0x007c, 0x7ad0, 0x7c11, 0x7ad0,
+	0x7c4e, 0x7ad0, 0x7cc0, 0x7c09, 0x7ad0, 0x7ad0, 0x7cd5, 0x7ad0,
+	0x7ce8, 0x6604, 0xa6b6, 0x001e, 0x00c0, 0x7c10, 0x1078, 0x753d,
+	0x007c, 0x0d7e, 0x0c7e, 0x1078, 0x7cfb, 0x00c0, 0x7c27, 0x2001,
+	0x0000, 0x1078, 0x442b, 0x2001, 0x0002, 0x1078, 0x443f, 0x6003,
+	0x0001, 0x6007, 0x0002, 0x1078, 0x5c45, 0x0078, 0x7c4b, 0x2009,
+	0xa88e, 0x2104, 0xa086, 0x0009, 0x00c0, 0x7c3c, 0x6018, 0x2068,
+	0x6840, 0xa084, 0x00ff, 0xa005, 0x0040, 0x7c49, 0x8001, 0x6842,
+	0x6017, 0x000a, 0x0078, 0x7c4b, 0x2009, 0xa88f, 0x2104, 0xa084,
+	0xff00, 0xa086, 0x1900, 0x00c0, 0x7c49, 0x1078, 0x753d, 0x0078,
+	0x7c4b, 0x1078, 0x7b81, 0x0c7f, 0x0d7f, 0x007c, 0x1078, 0x7d0a,
+	0x00c0, 0x7c62, 0x2001, 0x0000, 0x1078, 0x442b, 0x2001, 0x0002,
+	0x1078, 0x443f, 0x6003, 0x0001, 0x6007, 0x0002, 0x1078, 0x5c45,
+	0x0078, 0x7c8e, 0x1078, 0x7a05, 0x2009, 0xa88e, 0x2134, 0xa6b4,
+	0x00ff, 0xa686, 0x0005, 0x0040, 0x7c8f, 0xa686, 0x000b, 0x0040,
+	0x7c8c, 0x2009, 0xa88f, 0x2104, 0xa084, 0xff00, 0x00c0, 0x7c7c,
+	0xa686, 0x0009, 0x0040, 0x7c8f, 0xa086, 0x1900, 0x00c0, 0x7c8c,
+	0xa686, 0x0009, 0x0040, 0x7c8f, 0x2001, 0x0004, 0x1078, 0x443f,
+	0x1078, 0x753d, 0x0078, 0x7c8e, 0x1078, 0x7b81, 0x007c, 0x0d7e,
+	0x6010, 0x2068, 0x1078, 0x8a44, 0x0040, 0x7c9d, 0x6838, 0xd0fc,
+	0x0040, 0x7c9d, 0x0d7f, 0x0078, 0x7c8c, 0x6018, 0x2068, 0x6840,
+	0xa084, 0x00ff, 0xa005, 0x0040, 0x7cae, 0x8001, 0x6842, 0x6017,
+	0x000a, 0x6007, 0x0016, 0x0d7f, 0x0078, 0x7c8e, 0x68a0, 0xa086,
+	0x007e, 0x00c0, 0x7cbb, 0x0e7e, 0x2071, 0xa300, 0x1078, 0x41f5,
+	0x0e7f, 0x0078, 0x7cbd, 0x1078, 0x2813, 0x0d7f, 0x0078, 0x7c8c,
+	0x1078, 0x7d0a, 0x00c0, 0x7cd0, 0x2001, 0x0004, 0x1078, 0x443f,
+	0x6003, 0x0001, 0x6007, 0x0003, 0x1078, 0x5c45, 0x0078, 0x7cd4,
+	0x1078, 0x7a05, 0x1078, 0x7b81, 0x007c, 0x1078, 0x7d0a, 0x00c0,
+	0x7ce5, 0x2001, 0x0008, 0x1078, 0x443f, 0x6003, 0x0001, 0x6007,
+	0x0005, 0x1078, 0x5c45, 0x0078, 0x7ce7, 0x1078, 0x7b81, 0x007c,
+	0x1078, 0x7d0a, 0x00c0, 0x7cf8, 0x2001, 0x000a, 0x1078, 0x443f,
+	0x6003, 0x0001, 0x6007, 0x0001, 0x1078, 0x5c45, 0x0078, 0x7cfa,
+	0x1078, 0x7b81, 0x007c, 0x2009, 0xa88e, 0x2104, 0xa086, 0x0003,
+	0x00c0, 0x7d09, 0x2009, 0xa88f, 0x2104, 0xa084, 0xff00, 0xa086,
+	0x2a00, 0x007c, 0xa085, 0x0001, 0x007c, 0x0c7e, 0x017e, 0xac88,
+	0x0006, 0x2164, 0x1078, 0x4513, 0x017f, 0x0c7f, 0x007c, 0x0f7e,
+	0x0e7e, 0x0d7e, 0x037e, 0x017e, 0x6018, 0x2068, 0x2071, 0xa332,
+	0x2e04, 0xa085, 0x0003, 0x2072, 0x1078, 0x7d8b, 0x0040, 0x7d50,
+	0x2001, 0xa352, 0x2004, 0xd0a4, 0x0040, 0x7d39, 0xa006, 0x2020,
+	0x2009, 0x002a, 0x1078, 0x9ec0, 0x2001, 0xa30c, 0x200c, 0xc195,
+	0x2102, 0x2019, 0x002a, 0x2009, 0x0001, 0x1078, 0x27e2, 0x2071,
+	0xa300, 0x1078, 0x260d, 0x0c7e, 0x157e, 0x20a9, 0x0081, 0x2009,
+	0x007f, 0x1078, 0x2921, 0x8108, 0x00f0, 0x7d49, 0x157f, 0x0c7f,
+	0x1078, 0x7d0d, 0x6813, 0x00ff, 0x6817, 0xfffe, 0x2071, 0xa880,
+	0x2079, 0x0100, 0x2e04, 0xa084, 0x00ff, 0x2069, 0xa31a, 0x206a,
+	0x78e6, 0x007e, 0x8e70, 0x2e04, 0x2069, 0xa31b, 0x206a, 0x78ea,
+	0xa084, 0xff00, 0x017f, 0xa105, 0x2009, 0xa325, 0x200a, 0x2069,
+	0xa88e, 0x2071, 0xa59c, 0x6810, 0x2072, 0x6814, 0x7006, 0x6818,
+	0x700a, 0x681c, 0x700e, 0x1078, 0x8da9, 0x2001, 0x0006, 0x1078,
+	0x443f, 0x1078, 0x2839, 0x1078, 0x753d, 0x017f, 0x037f, 0x0d7f,
+	0x0e7f, 0x0f7f, 0x007c, 0x027e, 0x037e, 0x0e7e, 0x157e, 0x2019,
+	0xa325, 0x231c, 0x83ff, 0x0040, 0x7db5, 0x2071, 0xa880, 0x2e14,
+	0xa294, 0x00ff, 0x7004, 0xa084, 0xff00, 0xa205, 0xa306, 0x00c0,
+	0x7db5, 0x2011, 0xa896, 0xad98, 0x000a, 0x20a9, 0x0004, 0x1078,
+	0x7e55, 0x00c0, 0x7db5, 0x2011, 0xa89a, 0xad98, 0x0006, 0x20a9,
+	0x0004, 0x1078, 0x7e55, 0x00c0, 0x7db5, 0x157f, 0x0e7f, 0x037f,
+	0x027f, 0x007c, 0x0e7e, 0x2071, 0xa88c, 0x7004, 0xa086, 0x0014,
+	0x00c0, 0x7ddd, 0x7008, 0xa086, 0x0800, 0x00c0, 0x7ddd, 0x700c,
+	0xd0ec, 0x0040, 0x7ddb, 0xa084, 0x0f00, 0xa086, 0x0100, 0x00c0,
+	0x7ddb, 0x7024, 0xd0a4, 0x00c0, 0x7dd8, 0xd0ac, 0x0040, 0x7ddb,
+	0xa006, 0x0078, 0x7ddd, 0xa085, 0x0001, 0x0e7f, 0x007c, 0x0e7e,
+	0x0d7e, 0x0c7e, 0x077e, 0x057e, 0x047e, 0x027e, 0x007e, 0x127e,
+	0x2091, 0x8000, 0x2029, 0xa5b4, 0x252c, 0x2021, 0xa5ba, 0x2424,
+	0x2061, 0xaa00, 0x2071, 0xa300, 0x7244, 0x7060, 0xa202, 0x00c8,
+	0x7e43, 0x1078, 0x9ee5, 0x0040, 0x7e3b, 0x671c, 0xa786, 0x0001,
+	0x0040, 0x7e3b, 0xa786, 0x0007, 0x0040, 0x7e3b, 0x2500, 0xac06,
+	0x0040, 0x7e3b, 0x2400, 0xac06, 0x0040, 0x7e3b, 0x0c7e, 0x6000,
+	0xa086, 0x0004, 0x00c0, 0x7e16, 0x1078, 0x1749, 0xa786, 0x0008,
+	0x00c0, 0x7e25, 0x1078, 0x8c3b, 0x00c0, 0x7e25, 0x0c7f, 0x1078,
+	0x7a05, 0x1078, 0x8c01, 0x0078, 0x7e3b, 0x6010, 0x2068, 0x1078,
+	0x8a44, 0x0040, 0x7e38, 0xa786, 0x0003, 0x00c0, 0x7e4d, 0x6837,
+	0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x4982, 0x1078, 0x8bf4,
+	0x1078, 0x8c01, 0x0c7f, 0xace0, 0x0010, 0x7054, 0xac02, 0x00c8,
+	0x7e43, 0x0078, 0x7df4, 0x127f, 0x007f, 0x027f, 0x047f, 0x057f,
+	0x077f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0xa786, 0x0006, 0x00c0,
+	0x7e2f, 0x1078, 0x9e70, 0x0078, 0x7e38, 0x220c, 0x2304, 0xa106,
+	0x00c0, 0x7e60, 0x8210, 0x8318, 0x00f0, 0x7e55, 0xa006, 0x007c,
+	0x2304, 0xa102, 0x0048, 0x7e68, 0x2001, 0x0001, 0x0078, 0x7e6a,
+	0x2001, 0x0000, 0xa18d, 0x0001, 0x007c, 0x6004, 0xa08a, 0x0044,
+	0x10c8, 0x1328, 0x1078, 0x8c27, 0x0040, 0x7e7c, 0x1078, 0x8c3b,
+	0x0040, 0x7e89, 0x0078, 0x7e82, 0x1078, 0x2839, 0x1078, 0x8c3b,
+	0x0040, 0x7e89, 0x1078, 0x6010, 0x1078, 0x753d, 0x1078, 0x6109,
+	0x007c, 0x1078, 0x7a05, 0x0078, 0x7e82, 0xa182, 0x0040, 0x0079,
+	0x7e91, 0x7ea4, 0x7ea4, 0x7ea4, 0x7ea4, 0x7ea4, 0x7ea4, 0x7ea4,
+	0x7ea4, 0x7ea4, 0x7ea4, 0x7ea4, 0x7ea6, 0x7ea6, 0x7ea6, 0x7ea6,
+	0x7ea4, 0x7ea4, 0x7ea4, 0x7ea6, 0x1078, 0x1328, 0x600b, 0xffff,
+	0x6003, 0x0001, 0x6106, 0x1078, 0x5bf8, 0x127e, 0x2091, 0x8000,
+	0x1078, 0x6109, 0x127f, 0x007c, 0xa186, 0x0013, 0x00c0, 0x7ebd,
+	0x6004, 0xa082, 0x0040, 0x0079, 0x7f48, 0xa186, 0x0027, 0x00c0,
+	0x7edf, 0x1078, 0x6010, 0x1078, 0x2813, 0x0d7e, 0x6110, 0x2168,
+	0x1078, 0x8a44, 0x0040, 0x7ed9, 0x6837, 0x0103, 0x684b, 0x0029,
+	0x6847, 0x0000, 0x694c, 0xc1c5, 0x694e, 0x1078, 0x4982, 0x1078,
+	0x8bf4, 0x0d7f, 0x1078, 0x753d, 0x1078, 0x6109, 0x007c, 0xa186,
+	0x0014, 0x00c0, 0x7ee8, 0x6004, 0xa082, 0x0040, 0x0079, 0x7f10,
+	0xa186, 0x0046, 0x0040, 0x7ef4, 0xa186, 0x0045, 0x0040, 0x7ef4,
+	0xa186, 0x0047, 0x10c0, 0x1328, 0x2001, 0x0109, 0x2004, 0xd084,
+	0x0040, 0x7f0d, 0x127e, 0x2091, 0x2200, 0x007e, 0x017e, 0x027e,
+	0x1078, 0x5ad2, 0x027f, 0x017f, 0x007f, 0x127f, 0x6000, 0xa086,
+	0x0002, 0x00c0, 0x7f0d, 0x0078, 0x7f81, 0x1078, 0x7583, 0x007c,
+	0x7f25, 0x7f23, 0x7f23, 0x7f23, 0x7f23, 0x7f23, 0x7f23, 0x7f23,
+	0x7f23, 0x7f23, 0x7f23, 0x7f41, 0x7f41, 0x7f41, 0x7f41, 0x7f23,
+	0x7f41, 0x7f23, 0x7f41, 0x1078, 0x1328, 0x1078, 0x6010, 0x0d7e,
+	0x6110, 0x2168, 0x1078, 0x8a44, 0x0040, 0x7f3b, 0x6837, 0x0103,
+	0x684b, 0x0006, 0x6847, 0x0000, 0x6850, 0xc0ec, 0x6852, 0x1078,
+	0x4982, 0x1078, 0x8bf4, 0x0d7f, 0x1078, 0x753d, 0x1078, 0x6109,
+	0x007c, 0x1078, 0x6010, 0x1078, 0x753d, 0x1078, 0x6109, 0x007c,
+	0x7f5d, 0x7f5b, 0x7f5b, 0x7f5b, 0x7f5b, 0x7f5b, 0x7f5b, 0x7f5b,
+	0x7f5b, 0x7f5b, 0x7f5b, 0x7f6f, 0x7f6f, 0x7f6f, 0x7f6f, 0x7f5b,
+	0x7f7a, 0x7f5b, 0x7f6f, 0x1078, 0x1328, 0x1078, 0x6010, 0x2001,
+	0xa5a2, 0x2004, 0x603e, 0x6003, 0x0002, 0x1078, 0x6109, 0x6010,
+	0xa088, 0x0013, 0x2104, 0xa085, 0x0400, 0x200a, 0x007c, 0x1078,
+	0x6010, 0x2001, 0xa5a2, 0x2004, 0x603e, 0x6003, 0x000f, 0x1078,
+	0x6109, 0x007c, 0x1078, 0x6010, 0x1078, 0x753d, 0x1078, 0x6109,
+	0x007c, 0xa182, 0x0040, 0x0079, 0x7f85, 0x7f98, 0x7f98, 0x7f98,
+	0x7f98, 0x7f98, 0x7f9a, 0x8095, 0x80b7, 0x7f98, 0x7f98, 0x7f98,
+	0x7f98, 0x7f98, 0x7f98, 0x7f98, 0x7f98, 0x7f98, 0x7f98, 0x7f98,
+	0x1078, 0x1328, 0x0e7e, 0x0d7e, 0x603f, 0x0000, 0x2071, 0xa880,
+	0x7124, 0x610a, 0x2071, 0xa88c, 0x6110, 0x2168, 0x7614, 0xa6b4,
+	0x0fff, 0x86ff, 0x0040, 0x8058, 0xa68c, 0x0c00, 0x0040, 0x7fd1,
+	0x0f7e, 0x2c78, 0x1078, 0x4893, 0x0f7f, 0x0040, 0x7fcd, 0x684c,
+	0xd0ac, 0x0040, 0x7fcd, 0x6024, 0xd0dc, 0x00c0, 0x7fcd, 0x6850,
+	0xd0bc, 0x00c0, 0x7fcd, 0x7318, 0x6814, 0xa306, 0x00c0, 0x806f,
+	0x731c, 0x6810, 0xa306, 0x00c0, 0x806f, 0x7318, 0x6b62, 0x731c,
+	0x6b5e, 0xa68c, 0x00ff, 0xa186, 0x0002, 0x0040, 0x8004, 0xa186,
+	0x0028, 0x00c0, 0x7fe1, 0x1078, 0x8c15, 0x684b, 0x001c, 0x0078,
+	0x8006, 0xd6dc, 0x0040, 0x7ffd, 0x684b, 0x0015, 0x684c, 0xd0ac,
+	0x0040, 0x7ffb, 0x6914, 0x6a10, 0x2100, 0xa205, 0x0040, 0x7ffb,
+	0x7018, 0xa106, 0x00c0, 0x7ff8, 0x701c, 0xa206, 0x0040, 0x7ffb,
+	0x6962, 0x6a5e, 0xc6dc, 0x0078, 0x8006, 0xd6d4, 0x0040, 0x8004,
+	0x684b, 0x0007, 0x0078, 0x8006, 0x684b, 0x0000, 0x6837, 0x0103,
+	0x6e46, 0xa01e, 0xd6c4, 0x0040, 0x802f, 0xa686, 0x0100, 0x00c0,
+	0x801a, 0x2001, 0xa899, 0x2004, 0xa005, 0x00c0, 0x801a, 0xc6c4,
+	0x0078, 0x7fa9, 0x7328, 0x732c, 0x6b56, 0x83ff, 0x0040, 0x802f,
+	0xa38a, 0x0009, 0x0048, 0x8026, 0x2019, 0x0008, 0x037e, 0x2308,
+	0x2019, 0xa898, 0xad90, 0x0019, 0x1078, 0x8739, 0x037f, 0xd6cc,
+	0x0040, 0x8085, 0x7124, 0x695a, 0x81ff, 0x0040, 0x8085, 0xa192,
+	0x0021, 0x00c8, 0x8046, 0x2071, 0xa898, 0x831c, 0x2300, 0xae18,
+	0xad90, 0x001d, 0x1078, 0x8739, 0x0078, 0x8085, 0x6838, 0xd0fc,
+	0x0040, 0x804f, 0x2009, 0x0020, 0x695a, 0x0078, 0x803b, 0x0f7e,
+	0x2d78, 0x1078, 0x86d1, 0x0f7f, 0x1078, 0x8726, 0x0078, 0x8087,
+	0x0f7e, 0x2c78, 0x1078, 0x4893, 0x0f7f, 0x0040, 0x8075, 0x684c,
+	0xd0ac, 0x0040, 0x8075, 0x6024, 0xd0dc, 0x00c0, 0x8075, 0x6850,
+	0xd0bc, 0x00c0, 0x8075, 0x684c, 0xd0f4, 0x00c0, 0x8075, 0x1078,
+	0x8cfa, 0x0d7f, 0x0e7f, 0x0078, 0x8094, 0x684b, 0x0000, 0x6837,
+	0x0103, 0x6e46, 0x684c, 0xd0ac, 0x0040, 0x8085, 0x6810, 0x6914,
+	0xa115, 0x0040, 0x8085, 0x1078, 0x8233, 0x1078, 0x4982, 0x6218,
+	0x2268, 0x6a3c, 0x8211, 0x6a3e, 0x1078, 0x8cc4, 0x0d7f, 0x0e7f,
+	0x00c0, 0x8094, 0x1078, 0x753d, 0x007c, 0x0f7e, 0x6003, 0x0003,
+	0x2079, 0xa88c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08, 0x6010, 0x2078,
+	0x784c, 0xd0ac, 0x0040, 0x80a8, 0x6003, 0x0002, 0x0f7f, 0x007c,
+	0x7c12, 0x7b16, 0x7e0a, 0x7d0e, 0x0f7f, 0x603f, 0x0000, 0x2c10,
+	0x1078, 0x1cab, 0x1078, 0x5c64, 0x1078, 0x61d3, 0x007c, 0x2001,
+	0xa5a2, 0x2004, 0x603e, 0x6003, 0x0004, 0x6110, 0x20e1, 0x0005,
+	0x3d18, 0x3e20, 0x2c10, 0x1078, 0x15ec, 0x007c, 0xa182, 0x0040,
+	0x0079, 0x80ca, 0x80dd, 0x80dd, 0x80dd, 0x80dd, 0x80dd, 0x80df,
+	0x8182, 0x80dd, 0x80dd, 0x8198, 0x8209, 0x80dd, 0x80dd, 0x80dd,
+	0x80dd, 0x8218, 0x80dd, 0x80dd, 0x80dd, 0x1078, 0x1328, 0x077e,
+	0x0f7e, 0x0e7e, 0x0d7e, 0x2071, 0xa88c, 0x6110, 0x2178, 0x7614,
+	0xa6b4, 0x0fff, 0x7e46, 0x7f4c, 0xc7e5, 0x7f4e, 0x6218, 0x2268,
+	0x6a3c, 0x8211, 0x6a3e, 0x86ff, 0x0040, 0x817d, 0xa694, 0xff00,
+	0xa284, 0x0c00, 0x0040, 0x8100, 0x7018, 0x7862, 0x701c, 0x785e,
+	0xa284, 0x0300, 0x0040, 0x817d, 0x1078, 0x1381, 0x1040, 0x1328,
+	0x2d00, 0x784a, 0x7f4c, 0xc7cd, 0x7f4e, 0x6837, 0x0103, 0x7838,
+	0x683a, 0x783c, 0x683e, 0x7840, 0x6842, 0x6e46, 0xa68c, 0x0c00,
+	0x0040, 0x811e, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff,
+	0xa186, 0x0002, 0x0040, 0x813a, 0xa186, 0x0028, 0x00c0, 0x812c,
+	0x684b, 0x001c, 0x0078, 0x813c, 0xd6dc, 0x0040, 0x8133, 0x684b,
+	0x0015, 0x0078, 0x813c, 0xd6d4, 0x0040, 0x813a, 0x684b, 0x0007,
+	0x0078, 0x813c, 0x684b, 0x0000, 0x6f4e, 0x7850, 0x6852, 0x7854,
+	0x6856, 0xa01e, 0xd6c4, 0x0040, 0x815a, 0x7328, 0x732c, 0x6b56,
+	0x83ff, 0x0040, 0x815a, 0xa38a, 0x0009, 0x0048, 0x8151, 0x2019,
+	0x0008, 0x037e, 0x2308, 0x2019, 0xa898, 0xad90, 0x0019, 0x1078,
+	0x8739, 0x037f, 0xd6cc, 0x0040, 0x817d, 0x7124, 0x695a, 0x81ff,
+	0x0040, 0x817d, 0xa192, 0x0021, 0x00c8, 0x8171, 0x2071, 0xa898,
+	0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x1078, 0x8739, 0x0078,
+	0x817d, 0x7838, 0xd0fc, 0x0040, 0x817a, 0x2009, 0x0020, 0x695a,
+	0x0078, 0x8166, 0x2d78, 0x1078, 0x86d1, 0x0d7f, 0x0e7f, 0x0f7f,
+	0x077f, 0x007c, 0x0f7e, 0x6003, 0x0003, 0x2079, 0xa88c, 0x7c04,
+	0x7b00, 0x7e0c, 0x7d08, 0x6010, 0x2078, 0x7c12, 0x7b16, 0x7e0a,
+	0x7d0e, 0x0f7f, 0x2c10, 0x1078, 0x1cab, 0x1078, 0x6c26, 0x007c,
+	0x0d7e, 0x0f7e, 0x2c78, 0x1078, 0x4893, 0x0f7f, 0x0040, 0x81a4,
+	0x2001, 0xa5a2, 0x2004, 0x603e, 0x6003, 0x0002, 0x1078, 0x60b8,
+	0x1078, 0x61d3, 0x6110, 0x2168, 0x694c, 0xd1e4, 0x0040, 0x8207,
+	0xd1cc, 0x0040, 0x81de, 0x6948, 0x6838, 0xd0fc, 0x0040, 0x81d6,
+	0x017e, 0x684c, 0x007e, 0x6850, 0x007e, 0xad90, 0x000d, 0xa198,
+	0x000d, 0x2009, 0x0020, 0x157e, 0x21a8, 0x2304, 0x2012, 0x8318,
+	0x8210, 0x00f0, 0x81c5, 0x157f, 0x007f, 0x6852, 0x007f, 0x684e,
+	0x017f, 0x2168, 0x1078, 0x13aa, 0x0078, 0x8201, 0x017e, 0x1078,
+	0x13aa, 0x0d7f, 0x1078, 0x8726, 0x0078, 0x8201, 0x6837, 0x0103,
+	0x6944, 0xa184, 0x00ff, 0xa0b6, 0x0002, 0x0040, 0x81fd, 0xa086,
+	0x0028, 0x00c0, 0x81ef, 0x684b, 0x001c, 0x0078, 0x81ff, 0xd1dc,
+	0x0040, 0x81f6, 0x684b, 0x0015, 0x0078, 0x81ff, 0xd1d4, 0x0040,
+	0x81fd, 0x684b, 0x0007, 0x0078, 0x81ff, 0x684b, 0x0000, 0x1078,
+	0x4982, 0x1078, 0x8cc4, 0x00c0, 0x8207, 0x1078, 0x753d, 0x0d7f,
+	0x007c, 0x2019, 0x0001, 0x1078, 0x6e6c, 0x6003, 0x0002, 0x2001,
+	0xa5a2, 0x2004, 0x603e, 0x1078, 0x60b8, 0x1078, 0x61d3, 0x007c,
+	0x1078, 0x60b8, 0x1078, 0x2813, 0x0d7e, 0x6110, 0x2168, 0x1078,
+	0x8a44, 0x0040, 0x822d, 0x6837, 0x0103, 0x684b, 0x0029, 0x6847,
+	0x0000, 0x1078, 0x4982, 0x1078, 0x8bf4, 0x0d7f, 0x1078, 0x753d,
+	0x1078, 0x61d3, 0x007c, 0x684b, 0x0015, 0xd1fc, 0x0040, 0x823f,
+	0x684b, 0x0007, 0x8002, 0x8000, 0x810a, 0xa189, 0x0000, 0x6962,
+	0x685e, 0x007c, 0xa182, 0x0040, 0x0079, 0x8246, 0x8259, 0x8259,
+	0x8259, 0x8259, 0x8259, 0x825b, 0x8259, 0x8333, 0x833f, 0x8259,
+	0x8259, 0x8259, 0x8259, 0x8259, 0x8259, 0x8259, 0x8259, 0x8259,
+	0x8259, 0x1078, 0x1328, 0x077e, 0x0f7e, 0x0e7e, 0x0d7e, 0x2071,
+	0xa88c, 0x6110, 0x2178, 0x7614, 0xa6b4, 0x0fff, 0x0f7e, 0x2c78,
+	0x1078, 0x4893, 0x0f7f, 0x0040, 0x827e, 0xa684, 0x00ff, 0x00c0,
+	0x827e, 0x6024, 0xd0f4, 0x00c0, 0x827a, 0x7808, 0xa086, 0x0000,
+	0x00c0, 0x827e, 0x1078, 0x8cfa, 0x0078, 0x832e, 0x7e46, 0x7f4c,
+	0xc7e5, 0x7f4e, 0x6218, 0x2268, 0x6a3c, 0x8211, 0x6a3e, 0x86ff,
+	0x0040, 0x8323, 0xa694, 0xff00, 0xa284, 0x0c00, 0x0040, 0x8294,
+	0x7018, 0x7862, 0x701c, 0x785e, 0xa284, 0x0300, 0x0040, 0x8320,
+	0xa686, 0x0100, 0x00c0, 0x82a6, 0x2001, 0xa899, 0x2004, 0xa005,
+	0x00c0, 0x82a6, 0xc6c4, 0x7e46, 0x0078, 0x8287, 0x1078, 0x1381,
+	0x1040, 0x1328, 0x2d00, 0x784a, 0x7f4c, 0xa7bd, 0x0200, 0x7f4e,
+	0x6837, 0x0103, 0x7838, 0x683a, 0x783c, 0x683e, 0x7840, 0x6842,
+	0x6e46, 0xa68c, 0x0c00, 0x0040, 0x82c1, 0x7318, 0x6b62, 0x731c,
+	0x6b5e, 0xa68c, 0x00ff, 0xa186, 0x0002, 0x0040, 0x82dd, 0xa186,
+	0x0028, 0x00c0, 0x82cf, 0x684b, 0x001c, 0x0078, 0x82df, 0xd6dc,
+	0x0040, 0x82d6, 0x684b, 0x0015, 0x0078, 0x82df, 0xd6d4, 0x0040,
+	0x82dd, 0x684b, 0x0007, 0x0078, 0x82df, 0x684b, 0x0000, 0x6f4e,
+	0x7850, 0x6852, 0x7854, 0x6856, 0xa01e, 0xd6c4, 0x0040, 0x82fd,
+	0x7328, 0x732c, 0x6b56, 0x83ff, 0x0040, 0x82fd, 0xa38a, 0x0009,
+	0x0048, 0x82f4, 0x2019, 0x0008, 0x037e, 0x2308, 0x2019, 0xa898,
+	0xad90, 0x0019, 0x1078, 0x8739, 0x037f, 0xd6cc, 0x0040, 0x8320,
+	0x7124, 0x695a, 0x81ff, 0x0040, 0x8320, 0xa192, 0x0021, 0x00c8,
+	0x8314, 0x2071, 0xa898, 0x831c, 0x2300, 0xae18, 0xad90, 0x001d,
+	0x1078, 0x8739, 0x0078, 0x8320, 0x7838, 0xd0fc, 0x0040, 0x831d,
+	0x2009, 0x0020, 0x695a, 0x0078, 0x8309, 0x2d78, 0x1078, 0x86d1,
+	0xd6dc, 0x00c0, 0x8326, 0xa006, 0x0078, 0x832c, 0x2001, 0x0001,
+	0x2071, 0xa88c, 0x7218, 0x731c, 0x1078, 0x1645, 0x0d7f, 0x0e7f,
+	0x0f7f, 0x077f, 0x007c, 0x2001, 0xa5a2, 0x2004, 0x603e, 0x20e1,
+	0x0005, 0x3d18, 0x3e20, 0x2c10, 0x1078, 0x15ec, 0x007c, 0x2001,
+	0xa5a2, 0x2004, 0x603e, 0x0d7e, 0x6003, 0x0002, 0x6110, 0x2168,
+	0x694c, 0xd1e4, 0x0040, 0x846b, 0x603f, 0x0000, 0x0f7e, 0x2c78,
+	0x1078, 0x4893, 0x0f7f, 0x0040, 0x8385, 0x6814, 0x6910, 0xa115,
+	0x0040, 0x8385, 0x6a60, 0xa206, 0x00c0, 0x8362, 0x685c, 0xa106,
+	0x0040, 0x8385, 0x684c, 0xc0e4, 0x684e, 0x6847, 0x0000, 0x6863,
+	0x0000, 0x685f, 0x0000, 0x6024, 0xd0f4, 0x00c0, 0x837a, 0x697c,
+	0x6810, 0xa102, 0x603a, 0x6980, 0x6814, 0xa103, 0x6036, 0x6024,
+	0xc0f5, 0x6026, 0x0d7e, 0x6018, 0x2068, 0x683c, 0x8000, 0x683e,
+	0x0d7f, 0x1078, 0x8cfa, 0x0078, 0x846b, 0x694c, 0xd1cc, 0x0040,
+	0x8430, 0x6948, 0x6838, 0xd0fc, 0x0040, 0x83ea, 0x017e, 0x684c,
+	0x007e, 0x6850, 0x007e, 0x0f7e, 0x2178, 0x7944, 0xa184, 0x00ff,
+	0xa0b6, 0x0002, 0x0040, 0x83bf, 0xa086, 0x0028, 0x00c0, 0x83a6,
+	0x684b, 0x001c, 0x784b, 0x001c, 0x0078, 0x83ca, 0xd1dc, 0x0040,
+	0x83b6, 0x684b, 0x0015, 0x784b, 0x0015, 0x1078, 0x8ea5, 0x0040,
+	0x83b4, 0x7944, 0xc1dc, 0x7946, 0x0078, 0x83ca, 0xd1d4, 0x0040,
+	0x83bf, 0x684b, 0x0007, 0x784b, 0x0007, 0x0078, 0x83ca, 0x684c,
+	0xd0ac, 0x0040, 0x83ca, 0x6810, 0x6914, 0xa115, 0x0040, 0x83ca,
+	0x1078, 0x8233, 0x6848, 0x784a, 0x6860, 0x7862, 0x685c, 0x785e,
+	0xad90, 0x000d, 0xaf98, 0x000d, 0x2009, 0x0020, 0x157e, 0x21a8,
+	0x2304, 0x2012, 0x8318, 0x8210, 0x00f0, 0x83d8, 0x157f, 0x0f7f,
+	0x007f, 0x6852, 0x007f, 0x684e, 0x017f, 0x2168, 0x1078, 0x13aa,
+	0x0078, 0x8465, 0x017e, 0x0f7e, 0x2178, 0x7944, 0xa184, 0x00ff,
+	0xa0b6, 0x0002, 0x0040, 0x8417, 0xa086, 0x0028, 0x00c0, 0x83fe,
+	0x684b, 0x001c, 0x784b, 0x001c, 0x0078, 0x8422, 0xd1dc, 0x0040,
+	0x840e, 0x684b, 0x0015, 0x784b, 0x0015, 0x1078, 0x8ea5, 0x0040,
+	0x840c, 0x7944, 0xc1dc, 0x7946, 0x0078, 0x8422, 0xd1d4, 0x0040,
+	0x8417, 0x684b, 0x0007, 0x784b, 0x0007, 0x0078, 0x8422, 0x684c,
+	0xd0ac, 0x0040, 0x8422, 0x6810, 0x6914, 0xa115, 0x0040, 0x8422,
+	0x1078, 0x8233, 0x6860, 0x7862, 0x685c, 0x785e, 0x684c, 0x784e,
+	0x0f7f, 0x1078, 0x13aa, 0x0d7f, 0x1078, 0x8726, 0x0078, 0x8465,
+	0x6837, 0x0103, 0x6944, 0xa184, 0x00ff, 0xa0b6, 0x0002, 0x0040,
+	0x8456, 0xa086, 0x0028, 0x00c0, 0x8441, 0x684b, 0x001c, 0x0078,
+	0x8463, 0xd1dc, 0x0040, 0x844f, 0x684b, 0x0015, 0x1078, 0x8ea5,
+	0x0040, 0x844d, 0x6944, 0xc1dc, 0x6946, 0x0078, 0x8463, 0xd1d4,
+	0x0040, 0x8456, 0x684b, 0x0007, 0x0078, 0x8463, 0x684b, 0x0000,
+	0x684c, 0xd0ac, 0x0040, 0x8463, 0x6810, 0x6914, 0xa115, 0x0040,
+	0x8463, 0x1078, 0x8233, 0x1078, 0x4982, 0x1078, 0x8cc4, 0x00c0,
+	0x846b, 0x1078, 0x753d, 0x0d7f, 0x007c, 0x1078, 0x6010, 0x0078,
+	0x8473, 0x1078, 0x60b8, 0x1078, 0x8a44, 0x0040, 0x8492, 0x0d7e,
+	0x6110, 0x2168, 0x6837, 0x0103, 0x2009, 0xa30c, 0x210c, 0xd18c,
+	0x00c0, 0x849d, 0xd184, 0x00c0, 0x8499, 0x6108, 0x694a, 0xa18e,
+	0x0029, 0x00c0, 0x848d, 0x1078, 0xa181, 0x6847, 0x0000, 0x1078,
+	0x4982, 0x0d7f, 0x1078, 0x753d, 0x1078, 0x6109, 0x1078, 0x61d3,
+	0x007c, 0x684b, 0x0004, 0x0078, 0x848d, 0x684b, 0x0004, 0x0078,
+	0x848d, 0xa182, 0x0040, 0x0079, 0x84a5, 0x84b8, 0x84b8, 0x84b8,
+	0x84b8, 0x84b8, 0x84ba, 0x84b8, 0x84bd, 0x84b8, 0x84b8, 0x84b8,
+	0x84b8, 0x84b8, 0x84b8, 0x84b8, 0x84b8, 0x84b8, 0x84b8, 0x84b8,
+	0x1078, 0x1328, 0x1078, 0x753d, 0x007c, 0x007e, 0x027e, 0xa016,
+	0x1078, 0x15ec, 0x027f, 0x007f, 0x007c, 0xa182, 0x0085, 0x0079,
+	0x84c9, 0x84d2, 0x84d0, 0x84d0, 0x84de, 0x84d0, 0x84d0, 0x84d0,
+	0x1078, 0x1328, 0x6003, 0x0001, 0x6106, 0x1078, 0x5bf8, 0x127e,
+	0x2091, 0x8000, 0x1078, 0x6109, 0x127f, 0x007c, 0x027e, 0x057e,
+	0x0d7e, 0x0e7e, 0x2071, 0xa880, 0x7224, 0x6212, 0x7220, 0x1078,
+	0x8a30, 0x0040, 0x8503, 0x2268, 0x6800, 0xa086, 0x0000, 0x0040,
+	0x8503, 0x6018, 0x6d18, 0xa52e, 0x00c0, 0x8503, 0x0c7e, 0x2d60,
+	0x1078, 0x874a, 0x0c7f, 0x0040, 0x8503, 0x6803, 0x0002, 0x6007,
+	0x0086, 0x0078, 0x8505, 0x6007, 0x0087, 0x6003, 0x0001, 0x1078,
+	0x5bf8, 0x1078, 0x6109, 0x0f7e, 0x2278, 0x1078, 0x4893, 0x0f7f,
+	0x0040, 0x851d, 0x6824, 0xd0ec, 0x0040, 0x851d, 0x0c7e, 0x2260,
+	0x603f, 0x0000, 0x1078, 0x8cfa, 0x0c7f, 0x0e7f, 0x0d7f, 0x057f,
+	0x027f, 0x007c, 0xa186, 0x0013, 0x00c0, 0x8533, 0x6004, 0xa08a,
+	0x0085, 0x1048, 0x1328, 0xa08a, 0x008c, 0x10c8, 0x1328, 0xa082,
+	0x0085, 0x0079, 0x8542, 0xa186, 0x0027, 0x0040, 0x853b, 0xa186,
+	0x0014, 0x10c0, 0x1328, 0x1078, 0x6010, 0x1078, 0x8c01, 0x1078,
+	0x6109, 0x007c, 0x8549, 0x854b, 0x854b, 0x8549, 0x8549, 0x8549,
+	0x8549, 0x1078, 0x1328, 0x1078, 0x6010, 0x1078, 0x8c01, 0x1078,
+	0x6109, 0x007c, 0xa186, 0x0013, 0x00c0, 0x855c, 0x6004, 0xa082,
+	0x0085, 0x2008, 0x0078, 0x8597, 0xa186, 0x0027, 0x00c0, 0x857f,
+	0x1078, 0x6010, 0x1078, 0x2813, 0x0d7e, 0x6010, 0x2068, 0x1078,
+	0x8a44, 0x0040, 0x8575, 0x6837, 0x0103, 0x6847, 0x0000, 0x684b,
+	0x0029, 0x1078, 0x4982, 0x1078, 0x8bf4, 0x0d7f, 0x1078, 0x753d,
+	0x1078, 0x6109, 0x007c, 0x1078, 0x7583, 0x0078, 0x857a, 0xa186,
+	0x0014, 0x00c0, 0x857b, 0x1078, 0x6010, 0x0d7e, 0x6010, 0x2068,
+	0x1078, 0x8a44, 0x0040, 0x8575, 0x6837, 0x0103, 0x6847, 0x0000,
+	0x684b, 0x0006, 0x6850, 0xc0ec, 0x6852, 0x0078, 0x8571, 0x0079,
+	0x8599, 0x85a2, 0x85a0, 0x85a0, 0x85a0, 0x85a0, 0x85a0, 0x85bd,
+	0x1078, 0x1328, 0x1078, 0x6010, 0x6030, 0xa08c, 0xff00, 0x810f,
+	0xa186, 0x0039, 0x0040, 0x85b0, 0xa186, 0x0035, 0x00c0, 0x85b4,
+	0x2001, 0xa5a0, 0x0078, 0x85b6, 0x2001, 0xa5a1, 0x2004, 0x6016,
+	0x6003, 0x000c, 0x1078, 0x6109, 0x007c, 0x1078, 0x6010, 0x6030,
+	0xa08c, 0xff00, 0x810f, 0xa186, 0x0039, 0x0040, 0x85cb, 0xa186,
+	0x0035, 0x00c0, 0x85cf, 0x2001, 0xa5a0, 0x0078, 0x85d1, 0x2001,
+	0xa5a1, 0x2004, 0x6016, 0x6003, 0x000e, 0x1078, 0x6109, 0x007c,
+	0xa182, 0x008c, 0x00c8, 0x85e2, 0xa182, 0x0085, 0x0048, 0x85e2,
+	0x0079, 0x85e5, 0x1078, 0x7583, 0x007c, 0x85ec, 0x85ec, 0x85ec,
+	0x85ec, 0x85ee, 0x8643, 0x85ec, 0x1078, 0x1328, 0x0f7e, 0x2c78,
+	0x1078, 0x4893, 0x0f7f, 0x0040, 0x8601, 0x6030, 0xa08c, 0xff00,
+	0x810f, 0xa186, 0x0039, 0x0040, 0x865a, 0xa186, 0x0035, 0x0040,
+	0x865a, 0x0d7e, 0x1078, 0x8bf4, 0x1078, 0x8a44, 0x0040, 0x8625,
+	0x6010, 0x2068, 0x6837, 0x0103, 0x6850, 0xd0b4, 0x0040, 0x8616,
+	0x684b, 0x0006, 0xc0ec, 0x6852, 0x0078, 0x8621, 0xd0bc, 0x0040,
+	0x861d, 0x684b, 0x0002, 0x0078, 0x8621, 0x684b, 0x0005, 0x1078,
+	0x8cc0, 0x6847, 0x0000, 0x1078, 0x4982, 0x2c68, 0x1078, 0x74d7,
+	0x0040, 0x863e, 0x6003, 0x0001, 0x6007, 0x001e, 0x2009, 0xa88e,
+	0x210c, 0x6136, 0x2009, 0xa88f, 0x210c, 0x613a, 0x6918, 0x611a,
+	0x6920, 0x6122, 0x601f, 0x0001, 0x1078, 0x5bf8, 0x2d60, 0x1078,
+	0x753d, 0x0d7f, 0x007c, 0x0f7e, 0x2c78, 0x1078, 0x4893, 0x0f7f,
+	0x0040, 0x8680, 0x6030, 0xa08c, 0xff00, 0x810f, 0xa186, 0x0035,
+	0x0040, 0x865a, 0xa186, 0x001e, 0x0040, 0x865a, 0xa186, 0x0039,
+	0x00c0, 0x8680, 0x0d7e, 0x2c68, 0x1078, 0x8ef5, 0x00c0, 0x86a4,
+	0x1078, 0x74d7, 0x0040, 0x867d, 0x6106, 0x6003, 0x0001, 0x601f,
+	0x0001, 0x6918, 0x611a, 0x6928, 0x612a, 0x692c, 0x612e, 0x6930,
+	0xa18c, 0x00ff, 0x6132, 0x6934, 0x6136, 0x6938, 0x613a, 0x6920,
+	0x6122, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x2d60, 0x0078, 0x86a4,
+	0x0d7e, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040, 0x86a4, 0x6837,
+	0x0103, 0x6850, 0xd0b4, 0x0040, 0x8693, 0xc0ec, 0x6852, 0x684b,
+	0x0006, 0x0078, 0x869e, 0xd0bc, 0x0040, 0x869a, 0x684b, 0x0002,
+	0x0078, 0x869e, 0x684b, 0x0005, 0x1078, 0x8cc0, 0x6847, 0x0000,
+	0x1078, 0x4982, 0x1078, 0x8bf4, 0x0d7f, 0x1078, 0x753d, 0x007c,
+	0x017e, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040, 0x86b8,
+	0x6837, 0x0103, 0x684b, 0x0028, 0x6847, 0x0000, 0x1078, 0x4982,
+	0x0d7f, 0x017f, 0xa186, 0x0013, 0x0040, 0x86ca, 0xa186, 0x0014,
+	0x0040, 0x86ca, 0xa186, 0x0027, 0x0040, 0x86ca, 0x1078, 0x7583,
+	0x0078, 0x86d0, 0x1078, 0x6010, 0x1078, 0x8c01, 0x1078, 0x6109,
+	0x007c, 0x057e, 0x067e, 0x0d7e, 0x0f7e, 0x2029, 0x0001, 0xa182,
+	0x0101, 0x00c8, 0x86dd, 0x0078, 0x86df, 0x2009, 0x0100, 0x2130,
+	0x2069, 0xa898, 0x831c, 0x2300, 0xad18, 0x2009, 0x0020, 0xaf90,
+	0x001d, 0x1078, 0x8739, 0xa6b2, 0x0020, 0x7804, 0xa06d, 0x0040,
+	0x86f3, 0x1078, 0x13aa, 0x1078, 0x1381, 0x0040, 0x871d, 0x8528,
+	0x6837, 0x0110, 0x683b, 0x0000, 0x2d20, 0x7c06, 0xa68a, 0x003d,
+	0x00c8, 0x8709, 0x2608, 0xad90, 0x000f, 0x1078, 0x8739, 0x0078,
+	0x871d, 0xa6b2, 0x003c, 0x2009, 0x003c, 0x2d78, 0xad90, 0x000f,
+	0x1078, 0x8739, 0x0078, 0x86f3, 0x0f7f, 0x852f, 0xa5ad, 0x0003,
+	0x7d36, 0xa5ac, 0x0000, 0x0078, 0x8722, 0x0f7f, 0x852f, 0xa5ad,
+	0x0003, 0x7d36, 0x0d7f, 0x067f, 0x057f, 0x007c, 0x0f7e, 0x8dff,
+	0x0040, 0x8737, 0x6804, 0xa07d, 0x0040, 0x8735, 0x6807, 0x0000,
+	0x1078, 0x4982, 0x2f68, 0x0078, 0x872a, 0x1078, 0x4982, 0x0f7f,
+	0x007c, 0x157e, 0xa184, 0x0001, 0x0040, 0x873f, 0x8108, 0x810c,
+	0x21a8, 0x2304, 0x8007, 0x2012, 0x8318, 0x8210, 0x00f0, 0x8741,
+	0x157f, 0x007c, 0x067e, 0x127e, 0x2091, 0x8000, 0x2031, 0x0001,
+	0x601c, 0xa084, 0x000f, 0x1079, 0x8766, 0x127f, 0x067f, 0x007c,
+	0x127e, 0x2091, 0x8000, 0x067e, 0x2031, 0x0000, 0x601c, 0xa084,
+	0x000f, 0x1079, 0x8766, 0x067f, 0x127f, 0x007c, 0x8780, 0x876e,
+	0x877b, 0x879c, 0x876e, 0x877b, 0x879c, 0x877b, 0x1078, 0x1328,
+	0x037e, 0x2019, 0x0010, 0x1078, 0x9a6a, 0x601f, 0x0006, 0x6003,
+	0x0007, 0x037f, 0x007c, 0xa006, 0x007c, 0xa085, 0x0001, 0x007c,
+	0x0d7e, 0x86ff, 0x00c0, 0x8797, 0x6010, 0x2068, 0x1078, 0x8a44,
+	0x0040, 0x8799, 0xa00e, 0x2001, 0x0005, 0x1078, 0x4a60, 0x1078,
+	0x8cc0, 0x1078, 0x4982, 0x1078, 0x753d, 0xa085, 0x0001, 0x0d7f,
+	0x007c, 0xa006, 0x0078, 0x8797, 0x6000, 0xa08a, 0x0010, 0x10c8,
+	0x1328, 0x1079, 0x87a4, 0x007c, 0x87b4, 0x87d4, 0x87b6, 0x87f7,
+	0x87d0, 0x87b4, 0x877b, 0x8780, 0x8780, 0x877b, 0x877b, 0x877b,
+	0x877b, 0x877b, 0x877b, 0x877b, 0x1078, 0x1328, 0x86ff, 0x00c0,
+	0x87cd, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040, 0x87c2,
+	0x1078, 0x8cc0, 0x0d7f, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f,
+	0x0002, 0x1078, 0x5bf8, 0x1078, 0x6109, 0xa085, 0x0001, 0x007c,
+	0x1078, 0x1749, 0x0078, 0x87b6, 0x0e7e, 0x2071, 0xa5ab, 0x7024,
+	0xac06, 0x00c0, 0x87dd, 0x1078, 0x6dda, 0x601c, 0xa084, 0x000f,
+	0xa086, 0x0006, 0x00c0, 0x87ef, 0x087e, 0x097e, 0x2049, 0x0001,
+	0x2c40, 0x1078, 0x7058, 0x097f, 0x087f, 0x0078, 0x87f1, 0x1078,
+	0x6cd2, 0x0e7f, 0x00c0, 0x87b6, 0x1078, 0x877b, 0x007c, 0x037e,
+	0x0e7e, 0x2071, 0xa5ab, 0x703c, 0xac06, 0x00c0, 0x8807, 0x2019,
+	0x0000, 0x1078, 0x6e6c, 0x0e7f, 0x037f, 0x0078, 0x87b6, 0x1078,
+	0x719a, 0x0e7f, 0x037f, 0x00c0, 0x87b6, 0x1078, 0x877b, 0x007c,
+	0x0c7e, 0x601c, 0xa084, 0x000f, 0x1079, 0x8818, 0x0c7f, 0x007c,
+	0x8827, 0x8895, 0x89cd, 0x8832, 0x8c01, 0x8827, 0x9a5b, 0x753d,
+	0x8895, 0x1078, 0x8c3b, 0x00c0, 0x8827, 0x1078, 0x7a05, 0x007c,
+	0x1078, 0x6010, 0x1078, 0x6109, 0x1078, 0x753d, 0x007c, 0x6017,
+	0x0001, 0x007c, 0x6010, 0xa080, 0x0019, 0x2c02, 0x6000, 0xa08a,
+	0x0010, 0x10c8, 0x1328, 0x1079, 0x883e, 0x007c, 0x884e, 0x8850,
+	0x8872, 0x8884, 0x8891, 0x884e, 0x8827, 0x8827, 0x8827, 0x8884,
+	0x8884, 0x884e, 0x884e, 0x884e, 0x884e, 0x888e, 0x1078, 0x1328,
+	0x0e7e, 0x6010, 0x2070, 0x7050, 0xc0b5, 0x7052, 0x2071, 0xa5ab,
+	0x7024, 0xac06, 0x0040, 0x886e, 0x1078, 0x6cd2, 0x6007, 0x0085,
+	0x6003, 0x000b, 0x601f, 0x0002, 0x2001, 0xa5a1, 0x2004, 0x6016,
+	0x1078, 0x5bf8, 0x1078, 0x6109, 0x0e7f, 0x007c, 0x6017, 0x0001,
+	0x0078, 0x886c, 0x0d7e, 0x6010, 0x2068, 0x6850, 0xc0b5, 0x6852,
+	0x0d7f, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x1078,
+	0x5bf8, 0x1078, 0x6109, 0x007c, 0x0d7e, 0x6017, 0x0001, 0x6010,
+	0x2068, 0x6850, 0xc0b5, 0x6852, 0x0d7f, 0x007c, 0x1078, 0x753d,
+	0x007c, 0x1078, 0x1749, 0x0078, 0x8872, 0x6000, 0xa08a, 0x0010,
+	0x10c8, 0x1328, 0x1079, 0x889d, 0x007c, 0x88ad, 0x882f, 0x88af,
+	0x88ad, 0x88af, 0x88af, 0x8828, 0x88ad, 0x8821, 0x8821, 0x88ad,
+	0x88ad, 0x88ad, 0x88ad, 0x88ad, 0x88ad, 0x1078, 0x1328, 0x0d7e,
+	0x6018, 0x2068, 0x6804, 0xa084, 0x00ff, 0x0d7f, 0xa08a, 0x000c,
+	0x10c8, 0x1328, 0x1079, 0x88bd, 0x007c, 0x88c9, 0x8971, 0x88cb,
+	0x890b, 0x88cb, 0x890b, 0x88cb, 0x88d8, 0x88c9, 0x890b, 0x88c9,
+	0x88f5, 0x1078, 0x1328, 0x6004, 0xa08e, 0x0016, 0x0040, 0x8906,
+	0xa08e, 0x0004, 0x0040, 0x8906, 0xa08e, 0x0002, 0x0040, 0x8906,
+	0x6004, 0x1078, 0x8c3b, 0x0040, 0x898c, 0xa08e, 0x0021, 0x0040,
+	0x8990, 0xa08e, 0x0022, 0x0040, 0x898c, 0xa08e, 0x003d, 0x0040,
+	0x8990, 0xa08e, 0x0039, 0x0040, 0x8994, 0xa08e, 0x0035, 0x0040,
+	0x8994, 0xa08e, 0x001e, 0x0040, 0x8908, 0xa08e, 0x0001, 0x00c0,
+	0x8904, 0x0d7e, 0x6018, 0x2068, 0x6804, 0xa084, 0x00ff, 0x0d7f,
+	0xa086, 0x0006, 0x0040, 0x8906, 0x1078, 0x2813, 0x1078, 0x7a05,
+	0x1078, 0x8c01, 0x007c, 0x0c7e, 0x0d7e, 0x6104, 0xa186, 0x0016,
+	0x0040, 0x8961, 0xa186, 0x0002, 0x00c0, 0x8934, 0x6018, 0x2068,
+	0x68a0, 0xd0bc, 0x00c0, 0x89b8, 0x6840, 0xa084, 0x00ff, 0xa005,
+	0x0040, 0x8934, 0x8001, 0x6842, 0x6013, 0x0000, 0x601f, 0x0007,
+	0x6017, 0x0398, 0x1078, 0x74d7, 0x0040, 0x8934, 0x2d00, 0x601a,
+	0x601f, 0x0001, 0x0078, 0x8961, 0x0d7f, 0x0c7f, 0x6004, 0xa08e,
+	0x0002, 0x00c0, 0x8952, 0x6018, 0xa080, 0x0028, 0x2004, 0xa086,
+	0x007e, 0x00c0, 0x8952, 0x2009, 0xa332, 0x2104, 0xc085, 0x200a,
+	0x0e7e, 0x2071, 0xa300, 0x1078, 0x41f5, 0x0e7f, 0x1078, 0x7a05,
+	0x0078, 0x8956, 0x1078, 0x7a05, 0x1078, 0x2813, 0x0e7e, 0x127e,
+	0x2091, 0x8000, 0x1078, 0x2839, 0x127f, 0x0e7f, 0x1078, 0x8c01,
+	0x007c, 0x2001, 0x0002, 0x1078, 0x443f, 0x6003, 0x0001, 0x6007,
+	0x0002, 0x1078, 0x5c45, 0x1078, 0x6109, 0x0d7f, 0x0c7f, 0x0078,
+	0x8960, 0x0c7e, 0x0d7e, 0x6104, 0xa186, 0x0016, 0x0040, 0x8961,
+	0x6018, 0x2068, 0x6840, 0xa084, 0x00ff, 0xa005, 0x0040, 0x8934,
+	0x8001, 0x6842, 0x6003, 0x0001, 0x1078, 0x5c45, 0x1078, 0x6109,
+	0x0d7f, 0x0c7f, 0x0078, 0x8960, 0x1078, 0x7a05, 0x0078, 0x8908,
+	0x1078, 0x7a28, 0x0078, 0x8908, 0x0d7e, 0x2c68, 0x6104, 0x1078,
+	0x8ef5, 0x0d7f, 0x0040, 0x89a0, 0x1078, 0x753d, 0x0078, 0x89b7,
+	0x6004, 0x8007, 0x6130, 0xa18c, 0x00ff, 0xa105, 0x6032, 0x6007,
+	0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x6038, 0x600a, 0x2001,
+	0xa5a1, 0x2004, 0x6016, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x007c,
+	0x0d7f, 0x0c7f, 0x1078, 0x7a05, 0x1078, 0x2813, 0x0e7e, 0x127e,
+	0x2091, 0x8000, 0x1078, 0x2839, 0x6013, 0x0000, 0x601f, 0x0007,
+	0x6017, 0x0398, 0x127f, 0x0e7f, 0x007c, 0x6000, 0xa08a, 0x0010,
+	0x10c8, 0x1328, 0x1079, 0x89d5, 0x007c, 0x89e5, 0x89e5, 0x89e5,
+	0x89e5, 0x89e5, 0x89e5, 0x89e5, 0x89e5, 0x89e5, 0x8827, 0x89e5,
+	0x882f, 0x89e7, 0x882f, 0x89f5, 0x89e5, 0x1078, 0x1328, 0x6004,
+	0xa086, 0x008b, 0x0040, 0x89f5, 0x6007, 0x008b, 0x6003, 0x000d,
+	0x1078, 0x5bf8, 0x1078, 0x6109, 0x007c, 0x1078, 0x8bf4, 0x1078,
+	0x8a44, 0x0040, 0x8a2d, 0x1078, 0x2813, 0x0d7e, 0x1078, 0x8a44,
+	0x0040, 0x8a0f, 0x6010, 0x2068, 0x6837, 0x0103, 0x684b, 0x0006,
+	0x6847, 0x0000, 0x6850, 0xc0ed, 0x6852, 0x1078, 0x4982, 0x2c68,
+	0x1078, 0x74d7, 0x0040, 0x8a1d, 0x6818, 0x601a, 0x0c7e, 0x2d60,
+	0x1078, 0x8c01, 0x0c7f, 0x0078, 0x8a1e, 0x2d60, 0x0d7f, 0x6013,
+	0x0000, 0x601f, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x1078,
+	0x5c45, 0x1078, 0x6109, 0x0078, 0x8a2f, 0x1078, 0x8c01, 0x007c,
+	0xa284, 0x000f, 0x00c0, 0x8a41, 0xa282, 0xaa00, 0x0048, 0x8a41,
+	0x2001, 0xa315, 0x2004, 0xa202, 0x00c8, 0x8a41, 0xa085, 0x0001,
+	0x007c, 0xa006, 0x0078, 0x8a40, 0x027e, 0x0e7e, 0x2071, 0xa300,
+	0x6210, 0x7058, 0xa202, 0x0048, 0x8a56, 0x705c, 0xa202, 0x00c8,
+	0x8a56, 0xa085, 0x0001, 0x0e7f, 0x027f, 0x007c, 0xa006, 0x0078,
+	0x8a53, 0x0e7e, 0x0c7e, 0x037e, 0x007e, 0x127e, 0x2091, 0x8000,
+	0x2061, 0xaa00, 0x2071, 0xa300, 0x7344, 0x7060, 0xa302, 0x00c8,
+	0x8a83, 0x601c, 0xa206, 0x00c0, 0x8a7b, 0x1078, 0x8d66, 0x0040,
+	0x8a7b, 0x1078, 0x8c3b, 0x00c0, 0x8a77, 0x1078, 0x7a05, 0x0c7e,
+	0x1078, 0x753d, 0x0c7f, 0xace0, 0x0010, 0x7054, 0xac02, 0x00c8,
+	0x8a83, 0x0078, 0x8a64, 0x127f, 0x007f, 0x037f, 0x0c7f, 0x0e7f,
+	0x007c, 0x0e7e, 0x0c7e, 0x017e, 0xa188, 0xa434, 0x210c, 0x81ff,
+	0x0040, 0x8aa1, 0x2061, 0xaa00, 0x2071, 0xa300, 0x017e, 0x1078,
+	0x74d7, 0x017f, 0x0040, 0x8aa4, 0x611a, 0x1078, 0x2813, 0x1078,
+	0x753d, 0xa006, 0x0078, 0x8aa6, 0xa085, 0x0001, 0x017f, 0x0c7f,
+	0x0e7f, 0x007c, 0x0c7e, 0x057e, 0x127e, 0x2091, 0x8000, 0x0c7e,
+	0x1078, 0x74d7, 0x057f, 0x0040, 0x8ac3, 0x6612, 0x651a, 0x601f,
+	0x0003, 0x2009, 0x004b, 0x1078, 0x756c, 0xa085, 0x0001, 0x127f,
+	0x057f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x8abf, 0x0c7e, 0x057e,
+	0x127e, 0x2091, 0x8000, 0x62a0, 0x0c7e, 0x1078, 0x74d7, 0x057f,
+	0x0040, 0x8af1, 0x6013, 0x0000, 0x651a, 0x601f, 0x0003, 0x0c7e,
+	0x2560, 0x1078, 0x471b, 0x0c7f, 0x1078, 0x5d53, 0x077e, 0x2039,
+	0x0000, 0x1078, 0x5c78, 0x2c08, 0x1078, 0x9c38, 0x077f, 0x2009,
+	0x004c, 0x1078, 0x756c, 0xa085, 0x0001, 0x127f, 0x057f, 0x0c7f,
+	0x007c, 0xa006, 0x0078, 0x8aed, 0x0f7e, 0x0c7e, 0x047e, 0x0c7e,
+	0x1078, 0x74d7, 0x2c78, 0x0c7f, 0x0040, 0x8b0e, 0x7e12, 0x2c00,
+	0x781a, 0x781f, 0x0003, 0x2021, 0x0005, 0x1078, 0x8b4e, 0x2f60,
+	0x2009, 0x004d, 0x1078, 0x756c, 0xa085, 0x0001, 0x047f, 0x0c7f,
+	0x0f7f, 0x007c, 0x0f7e, 0x0c7e, 0x047e, 0x0c7e, 0x1078, 0x74d7,
+	0x2c78, 0x0c7f, 0x0040, 0x8b2c, 0x7e12, 0x2c00, 0x781a, 0x781f,
+	0x0003, 0x2021, 0x0005, 0x1078, 0x8b4e, 0x2f60, 0x2009, 0x004e,
+	0x1078, 0x756c, 0xa085, 0x0001, 0x047f, 0x0c7f, 0x0f7f, 0x007c,
+	0x0f7e, 0x0c7e, 0x047e, 0x0c7e, 0x1078, 0x74d7, 0x2c78, 0x0c7f,
+	0x0040, 0x8b4a, 0x7e12, 0x2c00, 0x781a, 0x781f, 0x0003, 0x2021,
+	0x0004, 0x1078, 0x8b4e, 0x2f60, 0x2009, 0x0052, 0x1078, 0x756c,
+	0xa085, 0x0001, 0x047f, 0x0c7f, 0x0f7f, 0x007c, 0x097e, 0x077e,
+	0x127e, 0x2091, 0x8000, 0x1078, 0x46a7, 0x0040, 0x8b5b, 0x2001,
+	0x8b53, 0x0078, 0x8b61, 0x1078, 0x466d, 0x0040, 0x8b6a, 0x2001,
+	0x8b5b, 0x007e, 0xa00e, 0x2400, 0x1078, 0x4a60, 0x1078, 0x4982,
+	0x007f, 0x007a, 0x2418, 0x1078, 0x5fa7, 0x62a0, 0x087e, 0x2041,
+	0x0001, 0x2039, 0x0001, 0x2608, 0x1078, 0x5d6d, 0x087f, 0x1078,
+	0x5c78, 0x2f08, 0x2648, 0x1078, 0x9c38, 0x613c, 0x81ff, 0x1040,
+	0x5e21, 0x127f, 0x077f, 0x097f, 0x007c, 0x0c7e, 0x127e, 0x2091,
+	0x8000, 0x0c7e, 0x1078, 0x74d7, 0x017f, 0x0040, 0x8b9e, 0x660a,
+	0x611a, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x001f, 0x1078,
+	0x756c, 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078,
+	0x8b9b, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078, 0x74d7,
+	0x017f, 0x0040, 0x8bba, 0x660a, 0x611a, 0x601f, 0x0008, 0x2d00,
+	0x6012, 0x2009, 0x0021, 0x1078, 0x756c, 0xa085, 0x0001, 0x127f,
+	0x0c7f, 0x007c, 0xa006, 0x0078, 0x8bb7, 0x0c7e, 0x127e, 0x2091,
+	0x8000, 0x0c7e, 0x1078, 0x74d7, 0x017f, 0x0040, 0x8bd6, 0x660a,
+	0x611a, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x003d, 0x1078,
+	0x756c, 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078,
+	0x8bd3, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078, 0x74d7,
+	0x017f, 0x0040, 0x8bf1, 0x611a, 0x601f, 0x0001, 0x2d00, 0x6012,
+	0x2009, 0x0000, 0x1078, 0x756c, 0xa085, 0x0001, 0x127f, 0x0c7f,
+	0x007c, 0xa006, 0x0078, 0x8bee, 0x027e, 0x0d7e, 0x6218, 0x2268,
+	0x6a3c, 0x82ff, 0x0040, 0x8bfe, 0x8211, 0x6a3e, 0x0d7f, 0x027f,
+	0x007c, 0x007e, 0x6000, 0xa086, 0x0000, 0x0040, 0x8c13, 0x6013,
+	0x0000, 0x601f, 0x0007, 0x2001, 0xa5a1, 0x2004, 0x6016, 0x1078,
+	0xa134, 0x603f, 0x0000, 0x007f, 0x007c, 0x067e, 0x0c7e, 0x0d7e,
+	0x2031, 0xa352, 0x2634, 0xd6e4, 0x0040, 0x8c23, 0x6618, 0x2660,
+	0x6e48, 0x1078, 0x461b, 0x0d7f, 0x0c7f, 0x067f, 0x007c, 0x007e,
+	0x017e, 0x6004, 0xa08e, 0x0002, 0x0040, 0x8c38, 0xa08e, 0x0003,
+	0x0040, 0x8c38, 0xa08e, 0x0004, 0x0040, 0x8c38, 0xa085, 0x0001,
+	0x017f, 0x007f, 0x007c, 0x007e, 0x0d7e, 0x6010, 0xa06d, 0x0040,
+	0x8c48, 0x6838, 0xd0fc, 0x0040, 0x8c48, 0xa006, 0x0078, 0x8c4a,
+	0xa085, 0x0001, 0x0d7f, 0x007f, 0x007c, 0x0c7e, 0x127e, 0x2091,
+	0x8000, 0x0c7e, 0x1078, 0x74d7, 0x017f, 0x0040, 0x8c67, 0x611a,
+	0x601f, 0x0001, 0x2d00, 0x6012, 0x1078, 0x2813, 0x2009, 0x0028,
+	0x1078, 0x756c, 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006,
+	0x0078, 0x8c64, 0xa186, 0x0015, 0x00c0, 0x8c7f, 0x2011, 0xa31f,
+	0x2204, 0xa086, 0x0074, 0x00c0, 0x8c7f, 0x1078, 0x7d0d, 0x6003,
+	0x0001, 0x6007, 0x0029, 0x1078, 0x5c45, 0x0078, 0x8c83, 0x1078,
+	0x7a05, 0x1078, 0x753d, 0x007c, 0xa186, 0x0016, 0x00c0, 0x8c8e,
+	0x2001, 0x0004, 0x1078, 0x443f, 0x0078, 0x8caf, 0xa186, 0x0015,
+	0x00c0, 0x8cb3, 0x2011, 0xa31f, 0x2204, 0xa086, 0x0014, 0x00c0,
+	0x8cb3, 0x0d7e, 0x6018, 0x2068, 0x1078, 0x457d, 0x0d7f, 0x1078,
+	0x7dba, 0x00c0, 0x8cb3, 0x0d7e, 0x6018, 0x2068, 0x6890, 0x0d7f,
+	0xa005, 0x0040, 0x8cb3, 0x2001, 0x0006, 0x1078, 0x443f, 0x1078,
+	0x7608, 0x0078, 0x8cb7, 0x1078, 0x7a05, 0x1078, 0x753d, 0x007c,
+	0x6848, 0xa086, 0x0005, 0x00c0, 0x8cbf, 0x1078, 0x8cc0, 0x007c,
+	0x6850, 0xc0ad, 0x6852, 0x007c, 0x0e7e, 0x2071, 0xa88c, 0x7014,
+	0xd0e4, 0x0040, 0x8cd5, 0x6013, 0x0000, 0x6003, 0x0001, 0x6007,
+	0x0050, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x0e7f, 0x007c, 0x0c7e,
+	0x0f7e, 0x2c78, 0x1078, 0x4893, 0x0f7f, 0x0040, 0x8ce4, 0x601c,
+	0xa084, 0x000f, 0x1079, 0x8ce6, 0x0c7f, 0x007c, 0x8827, 0x8cf1,
+	0x8cf4, 0x8cf7, 0x9f00, 0x9f1c, 0x9f1f, 0x8827, 0x8827, 0x1078,
+	0x1328, 0x0005, 0x0005, 0x007c, 0x0005, 0x0005, 0x007c, 0x1078,
+	0x8cfa, 0x007c, 0x0f7e, 0x2c78, 0x1078, 0x4893, 0x0040, 0x8d29,
+	0x1078, 0x74d7, 0x00c0, 0x8d0a, 0x2001, 0xa5a2, 0x2004, 0x783e,
+	0x0078, 0x8d29, 0x7818, 0x601a, 0x781c, 0xa086, 0x0003, 0x0040,
+	0x8d17, 0x7808, 0x6036, 0x2f00, 0x603a, 0x0078, 0x8d1b, 0x7808,
+	0x603a, 0x2f00, 0x6036, 0x602a, 0x601f, 0x0001, 0x6007, 0x0035,
+	0x6003, 0x0001, 0x7920, 0x6122, 0x1078, 0x5bf8, 0x1078, 0x6109,
+	0x2f60, 0x0f7f, 0x007c, 0x017e, 0x0f7e, 0x682c, 0x6032, 0xa08e,
+	0x0001, 0x0040, 0x8d3c, 0xa086, 0x0005, 0x0040, 0x8d40, 0xa006,
+	0x602a, 0x602e, 0x0078, 0x8d51, 0x6824, 0xc0f4, 0xc0d5, 0x6826,
+	0x6810, 0x2078, 0x787c, 0x6938, 0xa102, 0x7880, 0x6934, 0xa103,
+	0x00c8, 0x8d37, 0x6834, 0x602a, 0x6838, 0xa084, 0xfffc, 0x683a,
+	0x602e, 0x2d00, 0x6036, 0x6808, 0x603a, 0x6918, 0x611a, 0x6920,
+	0x6122, 0x601f, 0x0001, 0x6007, 0x0039, 0x6003, 0x0001, 0x1078,
+	0x5bf8, 0x6803, 0x0002, 0x0f7f, 0x017f, 0x007c, 0x007e, 0x017e,
+	0x6004, 0xa08e, 0x0034, 0x0040, 0x8d8b, 0xa08e, 0x0035, 0x0040,
+	0x8d8b, 0xa08e, 0x0036, 0x0040, 0x8d8b, 0xa08e, 0x0037, 0x0040,
+	0x8d8b, 0xa08e, 0x0038, 0x0040, 0x8d8b, 0xa08e, 0x0039, 0x0040,
+	0x8d8b, 0xa08e, 0x003a, 0x0040, 0x8d8b, 0xa08e, 0x003b, 0x0040,
+	0x8d8b, 0xa085, 0x0001, 0x017f, 0x007f, 0x007c, 0x0f7e, 0x2c78,
+	0x1078, 0x4893, 0x00c0, 0x8d98, 0xa085, 0x0001, 0x0078, 0x8da7,
+	0x6024, 0xd0f4, 0x00c0, 0x8da6, 0xc0f5, 0x6026, 0x6010, 0x2078,
+	0x7828, 0x603a, 0x782c, 0x6036, 0x1078, 0x1749, 0xa006, 0x0f7f,
+	0x007c, 0x007e, 0x017e, 0x027e, 0x037e, 0x0e7e, 0x2001, 0xa59c,
+	0x200c, 0x8000, 0x2014, 0x2001, 0x0032, 0x1078, 0x5a98, 0x2001,
+	0xa5a0, 0x82ff, 0x00c0, 0x8dbe, 0x2011, 0x0002, 0x2202, 0x2001,
+	0xa59e, 0x200c, 0x8000, 0x2014, 0x2071, 0xa58c, 0x711a, 0x721e,
+	0x2001, 0x0064, 0x1078, 0x5a98, 0x2001, 0xa5a1, 0x82ff, 0x00c0,
+	0x8dd3, 0x2011, 0x0002, 0x2202, 0x2009, 0xa5a2, 0xa280, 0x000a,
+	0x200a, 0x0e7f, 0x037f, 0x027f, 0x017f, 0x007f, 0x007c, 0x007e,
+	0x0e7e, 0x2001, 0xa5a0, 0x2003, 0x0028, 0x2001, 0xa5a1, 0x2003,
+	0x0014, 0x2071, 0xa58c, 0x701b, 0x0000, 0x701f, 0x07d0, 0x2001,
+	0xa5a2, 0x2003, 0x001e, 0x0e7f, 0x007f, 0x007c, 0x0c7e, 0x127e,
+	0x2091, 0x8000, 0x0c7e, 0x1078, 0x74d7, 0x017f, 0x0040, 0x8e0e,
+	0x611a, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x0033, 0x1078,
+	0x756c, 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078,
+	0x8e0b, 0x0d7e, 0x0e7e, 0x0f7e, 0x2071, 0xa300, 0xa186, 0x0015,
+	0x00c0, 0x8e40, 0x707c, 0xa086, 0x0018, 0x00c0, 0x8e40, 0x6010,
+	0x2068, 0x6a3c, 0xd2e4, 0x00c0, 0x8e34, 0x2c78, 0x1078, 0x62c6,
+	0x0040, 0x8e48, 0x7068, 0x6a50, 0xa206, 0x00c0, 0x8e3c, 0x706c,
+	0x6a54, 0xa206, 0x00c0, 0x8e3c, 0x6218, 0xa290, 0x0028, 0x2214,
+	0x2009, 0x0000, 0x1078, 0x285b, 0x1078, 0x7608, 0x0078, 0x8e44,
+	0x1078, 0x7a05, 0x1078, 0x753d, 0x0f7f, 0x0e7f, 0x0d7f, 0x007c,
+	0x704c, 0xa080, 0x293f, 0x2004, 0x6a54, 0xa206, 0x0040, 0x8e34,
+	0x0078, 0x8e3c, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078,
+	0x74d7, 0x017f, 0x0040, 0x8e6a, 0x611a, 0x601f, 0x0001, 0x2d00,
+	0x6012, 0x2009, 0x0043, 0x1078, 0x756c, 0xa085, 0x0001, 0x127f,
+	0x0c7f, 0x007c, 0xa006, 0x0078, 0x8e67, 0x0d7e, 0x0e7e, 0x0f7e,
+	0x2071, 0xa300, 0xa186, 0x0015, 0x00c0, 0x8e93, 0x707c, 0xa086,
+	0x0004, 0x00c0, 0x8e93, 0x6010, 0xa0e8, 0x000f, 0x2c78, 0x1078,
+	0x62c6, 0x0040, 0x8e9b, 0x7068, 0x6a08, 0xa206, 0x00c0, 0x8e8f,
+	0x706c, 0x6a0c, 0xa206, 0x00c0, 0x8e8f, 0x1078, 0x2813, 0x1078,
+	0x7608, 0x0078, 0x8e97, 0x1078, 0x7a05, 0x1078, 0x753d, 0x0f7f,
+	0x0e7f, 0x0d7f, 0x007c, 0x704c, 0xa080, 0x293f, 0x2004, 0x6a0c,
+	0xa206, 0x0040, 0x8e8d, 0x0078, 0x8e8f, 0x017e, 0x027e, 0x684c,
+	0xd0ac, 0x0040, 0x8ebd, 0x6914, 0x6a10, 0x2100, 0xa205, 0x0040,
+	0x8ebd, 0x6860, 0xa106, 0x00c0, 0x8eb9, 0x685c, 0xa206, 0x0040,
+	0x8ebd, 0x6962, 0x6a5e, 0xa085, 0x0001, 0x027f, 0x017f, 0x007c,
+	0x0e7e, 0x127e, 0x2071, 0xa300, 0x2091, 0x8000, 0x7544, 0xa582,
+	0x0001, 0x0048, 0x8ef2, 0x7048, 0x2060, 0x6000, 0xa086, 0x0000,
+	0x0040, 0x8ede, 0xace0, 0x0010, 0x7054, 0xac02, 0x00c8, 0x8eda,
+	0x0078, 0x8ecd, 0x2061, 0xaa00, 0x0078, 0x8ecd, 0x6003, 0x0008,
+	0x8529, 0x7546, 0xaca8, 0x0010, 0x7054, 0xa502, 0x00c8, 0x8eee,
+	0x754a, 0xa085, 0x0001, 0x127f, 0x0e7f, 0x007c, 0x704b, 0xaa00,
+	0x0078, 0x8ee9, 0xa006, 0x0078, 0x8eeb, 0x0c7e, 0x027e, 0x017e,
+	0xa186, 0x0035, 0x0040, 0x8eff, 0x6a34, 0x0078, 0x8f00, 0x6a28,
+	0x1078, 0x8a30, 0x0040, 0x8f29, 0x2260, 0x611c, 0xa186, 0x0003,
+	0x0040, 0x8f0e, 0xa186, 0x0006, 0x00c0, 0x8f25, 0x6834, 0xa206,
+	0x0040, 0x8f1d, 0x6838, 0xa206, 0x00c0, 0x8f25, 0x6108, 0x6834,
+	0xa106, 0x00c0, 0x8f25, 0x0078, 0x8f22, 0x6008, 0x6938, 0xa106,
+	0x00c0, 0x8f25, 0x6018, 0x6918, 0xa106, 0x017f, 0x027f, 0x0c7f,
+	0x007c, 0xa085, 0x0001, 0x0078, 0x8f25, 0x067e, 0x6000, 0xa0b2,
+	0x0010, 0x10c8, 0x1328, 0x1079, 0x8f37, 0x067f, 0x007c, 0x8f47,
+	0x93bb, 0x94d3, 0x8f47, 0x8f47, 0x8f47, 0x8f47, 0x8f47, 0x8f81,
+	0x955e, 0x8f47, 0x8f47, 0x8f47, 0x8f47, 0x8f47, 0x8f47, 0x1078,
+	0x1328, 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8, 0x1328, 0x1079,
+	0x8f53, 0x067f, 0x007c, 0x8f63, 0x99f6, 0x8f63, 0x8f63, 0x8f63,
+	0x8f63, 0x8f63, 0x8f63, 0x99b4, 0x9a44, 0x8f63, 0xa053, 0xa087,
+	0xa053, 0xa087, 0x8f63, 0x1078, 0x1328, 0x067e, 0x6000, 0xa0b2,
+	0x0010, 0x10c8, 0x1328, 0x1079, 0x8f6f, 0x067f, 0x007c, 0x8f7f,
+	0x969f, 0x976a, 0x9798, 0x9813, 0x8f7f, 0x9919, 0x98c1, 0x956a,
+	0x9988, 0x999e, 0x8f7f, 0x8f7f, 0x8f7f, 0x8f7f, 0x8f7f, 0x1078,
+	0x1328, 0xa1b2, 0x0044, 0x10c8, 0x1328, 0x2100, 0x0079, 0x8f88,
+	0x8fc8, 0x919a, 0x8fc8, 0x8fc8, 0x8fc8, 0x91a2, 0x8fc8, 0x8fc8,
+	0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8,
+	0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fca,
+	0x902d, 0x9038, 0x9081, 0x909c, 0x911b, 0x918b, 0x8fc8, 0x8fc8,
+	0x91a6, 0x8fc8, 0x8fc8, 0x91b5, 0x91bc, 0x8fc8, 0x8fc8, 0x8fc8,
+	0x8fc8, 0x8fc8, 0x91ea, 0x8fc8, 0x8fc8, 0x91f5, 0x8fc8, 0x8fc8,
+	0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x920a, 0x8fc8, 0x8fc8, 0x8fc8,
+	0x9291, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x9305,
+	0x1078, 0x1328, 0x1078, 0x4897, 0x00c0, 0x8fd7, 0x2001, 0xa332,
+	0x2004, 0xa084, 0x0009, 0xa086, 0x0008, 0x00c0, 0x8fdf, 0x6007,
+	0x0009, 0x602b, 0x0009, 0x6013, 0x0000, 0x0078, 0x9195, 0x1078,
+	0x4887, 0x0e7e, 0x0c7e, 0x037e, 0x027e, 0x017e, 0x6218, 0x2270,
+	0x72a0, 0x027e, 0x2019, 0x0029, 0x1078, 0x5d53, 0x077e, 0x2039,
+	0x0000, 0x1078, 0x5c78, 0x2c08, 0x1078, 0x9c38, 0x077f, 0x017f,
+	0x2e60, 0x1078, 0x471b, 0x017f, 0x027f, 0x037f, 0x0c7f, 0x0e7f,
+	0x6618, 0x0c7e, 0x2660, 0x1078, 0x4513, 0x0c7f, 0xa6b0, 0x0001,
+	0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x0048, 0x901f, 0x1078,
+	0x9b6c, 0x00c0, 0x907b, 0x1078, 0x9afd, 0x00c0, 0x901b, 0x6007,
+	0x0008, 0x0078, 0x9195, 0x6007, 0x0009, 0x0078, 0x9195, 0x1078,
+	0x9d45, 0x0040, 0x9029, 0x1078, 0x9b6c, 0x0040, 0x9013, 0x0078,
+	0x907b, 0x6013, 0x1900, 0x0078, 0x901b, 0x6106, 0x1078, 0x9aa8,
+	0x6007, 0x0006, 0x0078, 0x9195, 0x6007, 0x0007, 0x0078, 0x9195,
+	0x1078, 0xa0bf, 0x00c0, 0x9340, 0x0d7e, 0x6618, 0x2668, 0x6e04,
+	0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0040, 0x905d, 0xa686,
+	0x0004, 0x0040, 0x905d, 0x6e04, 0xa6b4, 0x00ff, 0xa686, 0x0006,
+	0x0040, 0x905d, 0xa686, 0x0004, 0x0040, 0x905d, 0xa686, 0x0005,
+	0x0040, 0x905d, 0x0d7f, 0x0078, 0x907b, 0x1078, 0x9bd2, 0x00c0,
+	0x9076, 0xa686, 0x0006, 0x00c0, 0x906f, 0x027e, 0x6218, 0xa290,
+	0x0028, 0x2214, 0x2009, 0x0000, 0x1078, 0x285b, 0x027f, 0x1078,
+	0x457d, 0x6007, 0x000a, 0x0d7f, 0x0078, 0x9195, 0x6007, 0x000b,
+	0x0d7f, 0x0078, 0x9195, 0x1078, 0x2813, 0x6007, 0x0001, 0x0078,
+	0x9195, 0x1078, 0xa0bf, 0x00c0, 0x9340, 0x6618, 0x0d7e, 0x2668,
+	0x6e04, 0x0d7f, 0xa686, 0x0707, 0x0040, 0x907b, 0x027e, 0x6218,
+	0xa290, 0x0028, 0x2214, 0x2009, 0x0000, 0x1078, 0x285b, 0x027f,
+	0x6007, 0x000c, 0x0078, 0x9195, 0x1078, 0x4897, 0x00c0, 0x90a9,
+	0x2001, 0xa332, 0x2004, 0xa084, 0x0009, 0xa086, 0x0008, 0x00c0,
+	0x90b1, 0x6007, 0x0009, 0x602b, 0x0009, 0x6013, 0x0000, 0x0078,
+	0x9195, 0x1078, 0x4887, 0x6618, 0xa6b0, 0x0001, 0x2634, 0xa684,
+	0x00ff, 0xa082, 0x0006, 0x0048, 0x90f5, 0xa6b4, 0xff00, 0x8637,
+	0xa686, 0x0004, 0x0040, 0x90c8, 0xa686, 0x0006, 0x00c0, 0x907b,
+	0x1078, 0x9be1, 0x00c0, 0x90d0, 0x6007, 0x000e, 0x0078, 0x9195,
+	0x047e, 0x6418, 0xa4a0, 0x0028, 0x2424, 0xa4a4, 0x00ff, 0x8427,
+	0x047e, 0x1078, 0x2813, 0x047f, 0x017e, 0xa006, 0x2009, 0xa352,
+	0x210c, 0xd1a4, 0x0040, 0x90ef, 0x2009, 0x0029, 0x1078, 0x9ec0,
+	0x6018, 0x0d7e, 0x2068, 0x6800, 0xc0e5, 0x6802, 0x0d7f, 0x017f,
+	0x047f, 0x6007, 0x0001, 0x0078, 0x9195, 0x2001, 0x0001, 0x1078,
+	0x442b, 0x157e, 0x017e, 0x027e, 0x037e, 0x20a9, 0x0004, 0x2019,
+	0xa305, 0x2011, 0xa890, 0x1078, 0x7e55, 0x037f, 0x027f, 0x017f,
+	0x157f, 0xa005, 0x0040, 0x9115, 0xa6b4, 0xff00, 0x8637, 0xa686,
+	0x0006, 0x0040, 0x90c8, 0x0078, 0x907b, 0x6013, 0x1900, 0x6007,
+	0x0009, 0x0078, 0x9195, 0x1078, 0x4897, 0x00c0, 0x9128, 0x2001,
+	0xa332, 0x2004, 0xa084, 0x0009, 0xa086, 0x0008, 0x00c0, 0x9130,
+	0x6007, 0x0009, 0x602b, 0x0009, 0x6013, 0x0000, 0x0078, 0x9195,
+	0x1078, 0x4887, 0x6618, 0xa6b0, 0x0001, 0x2634, 0xa684, 0x00ff,
+	0xa082, 0x0006, 0x0048, 0x9178, 0xa6b4, 0xff00, 0x8637, 0xa686,
+	0x0004, 0x0040, 0x9147, 0xa686, 0x0006, 0x00c0, 0x907b, 0x1078,
+	0x9c0c, 0x00c0, 0x9153, 0x1078, 0x9afd, 0x00c0, 0x9153, 0x6007,
+	0x0010, 0x0078, 0x9195, 0x047e, 0x6418, 0xa4a0, 0x0028, 0x2424,
+	0xa4a4, 0x00ff, 0x8427, 0x047e, 0x1078, 0x2813, 0x047f, 0x017e,
+	0xa006, 0x2009, 0xa352, 0x210c, 0xd1a4, 0x0040, 0x9172, 0x2009,
+	0x0029, 0x1078, 0x9ec0, 0x6018, 0x0d7e, 0x2068, 0x6800, 0xc0e5,
+	0x6802, 0x0d7f, 0x017f, 0x047f, 0x6007, 0x0001, 0x0078, 0x9195,
+	0x1078, 0x9d45, 0x0040, 0x9185, 0xa6b4, 0xff00, 0x8637, 0xa686,
+	0x0006, 0x0040, 0x9147, 0x0078, 0x907b, 0x6013, 0x1900, 0x6007,
+	0x0009, 0x0078, 0x9195, 0x1078, 0xa0bf, 0x00c0, 0x9340, 0x1078,
+	0x9343, 0x00c0, 0x907b, 0x6007, 0x0012, 0x6003, 0x0001, 0x1078,
+	0x5c45, 0x007c, 0x6007, 0x0001, 0x6003, 0x0001, 0x1078, 0x5c45,
+	0x0078, 0x9199, 0x6007, 0x0005, 0x0078, 0x919c, 0x1078, 0xa0bf,
+	0x00c0, 0x9340, 0x1078, 0x9343, 0x00c0, 0x907b, 0x6007, 0x0020,
+	0x6003, 0x0001, 0x1078, 0x5c45, 0x007c, 0x6007, 0x0023, 0x6003,
+	0x0001, 0x1078, 0x5c45, 0x007c, 0x1078, 0xa0bf, 0x00c0, 0x9340,
+	0x1078, 0x9343, 0x00c0, 0x907b, 0x017e, 0x027e, 0x2011, 0xa890,
+	0x2214, 0x2c08, 0x1078, 0x9e8c, 0x00c0, 0x91de, 0x2160, 0x6007,
+	0x0026, 0x6013, 0x1700, 0x2011, 0xa889, 0x2214, 0xa296, 0xffff,
+	0x00c0, 0x91e3, 0x6007, 0x0025, 0x0078, 0x91e3, 0x1078, 0x753d,
+	0x2160, 0x6007, 0x0025, 0x6003, 0x0001, 0x1078, 0x5c45, 0x027f,
+	0x017f, 0x007c, 0x6106, 0x1078, 0x9363, 0x6007, 0x002b, 0x0078,
+	0x9195, 0x6007, 0x002c, 0x0078, 0x9195, 0x1078, 0xa0bf, 0x00c0,
+	0x9340, 0x1078, 0x9343, 0x00c0, 0x907b, 0x6106, 0x1078, 0x9368,
+	0x00c0, 0x9206, 0x6007, 0x002e, 0x0078, 0x9195, 0x6007, 0x002f,
+	0x0078, 0x9195, 0x0e7e, 0x0d7e, 0x0c7e, 0x6018, 0xa080, 0x0001,
+	0x200c, 0xa184, 0x00ff, 0xa086, 0x0006, 0x0040, 0x9223, 0xa184,
+	0xff00, 0x8007, 0xa086, 0x0006, 0x0040, 0x9223, 0x0c7f, 0x0d7f,
+	0x0e7f, 0x0078, 0x919a, 0x2001, 0xa371, 0x2004, 0xd0e4, 0x0040,
+	0x928d, 0x2071, 0xa88c, 0x7010, 0x6036, 0x7014, 0x603a, 0x7108,
+	0x720c, 0x2001, 0xa352, 0x2004, 0xd0a4, 0x0040, 0x9241, 0x6018,
+	0x2068, 0x6810, 0xa106, 0x00c0, 0x9241, 0x6814, 0xa206, 0x0040,
+	0x9265, 0x2001, 0xa352, 0x2004, 0xd0ac, 0x00c0, 0x9281, 0x2069,
+	0xa300, 0x686c, 0xa206, 0x00c0, 0x9281, 0x6868, 0xa106, 0x00c0,
+	0x9281, 0x7210, 0x1078, 0x8a30, 0x0040, 0x9287, 0x1078, 0x9f31,
+	0x0040, 0x9287, 0x622a, 0x6007, 0x0036, 0x6003, 0x0001, 0x1078,
+	0x5bf8, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0x7214, 0xa286, 0xffff,
+	0x0040, 0x9277, 0x1078, 0x8a30, 0x0040, 0x9287, 0xa280, 0x0002,
+	0x2004, 0x7110, 0xa106, 0x00c0, 0x9287, 0x0078, 0x9252, 0x7210,
+	0x2c08, 0x1078, 0x9e8c, 0x2c10, 0x2160, 0x0040, 0x9287, 0x0078,
+	0x9252, 0x6007, 0x0037, 0x6013, 0x1500, 0x0078, 0x925d, 0x6007,
+	0x0037, 0x6013, 0x1700, 0x0078, 0x925d, 0x6007, 0x0012, 0x0078,
+	0x925d, 0x6018, 0xa080, 0x0001, 0x2004, 0xa084, 0xff00, 0x8007,
+	0xa086, 0x0006, 0x00c0, 0x919a, 0x0e7e, 0x0d7e, 0x0c7e, 0x2001,
+	0xa371, 0x2004, 0xd0e4, 0x0040, 0x92fd, 0x2069, 0xa300, 0x2071,
+	0xa88c, 0x7008, 0x6036, 0x720c, 0x623a, 0xa286, 0xffff, 0x00c0,
+	0x92ba, 0x7208, 0x0c7e, 0x2c08, 0x1078, 0x9e8c, 0x2c10, 0x0c7f,
+	0x0040, 0x92f1, 0x1078, 0x8a30, 0x0040, 0x92f1, 0x0c7e, 0x027e,
+	0x2260, 0x1078, 0x874a, 0x027f, 0x0c7f, 0x7118, 0xa18c, 0xff00,
+	0x810f, 0xa186, 0x0001, 0x0040, 0x92db, 0xa186, 0x0005, 0x0040,
+	0x92d5, 0xa186, 0x0007, 0x00c0, 0x92e5, 0xa280, 0x0004, 0x2004,
+	0xa005, 0x0040, 0x92e5, 0x057e, 0x7510, 0x7614, 0x1078, 0x9f46,
+	0x057f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0x6007, 0x003b, 0x602b,
+	0x0009, 0x6013, 0x2a00, 0x6003, 0x0001, 0x1078, 0x5bf8, 0x0078,
+	0x92e1, 0x6007, 0x003b, 0x602b, 0x0009, 0x6013, 0x1700, 0x6003,
+	0x0001, 0x1078, 0x5bf8, 0x0078, 0x92e1, 0x6007, 0x003b, 0x602b,
+	0x000b, 0x6013, 0x0000, 0x0078, 0x925d, 0x0e7e, 0x027e, 0x1078,
+	0x4897, 0x0040, 0x933a, 0x1078, 0x4887, 0x1078, 0xa148, 0x00c0,
+	0x9338, 0x2071, 0xa300, 0x70c8, 0xc085, 0x70ca, 0x0f7e, 0x2079,
+	0x0100, 0x7294, 0xa284, 0x00ff, 0x706a, 0x78e6, 0xa284, 0xff00,
+	0x726c, 0xa205, 0x706e, 0x78ea, 0x0f7f, 0x70d3, 0x0000, 0x2001,
+	0xa352, 0x2004, 0xd0a4, 0x0040, 0x9331, 0x2011, 0xa5c4, 0x2013,
+	0x07d0, 0xd0ac, 0x00c0, 0x933a, 0x1078, 0x260d, 0x0078, 0x933a,
+	0x1078, 0xa178, 0x027f, 0x0e7f, 0x1078, 0x753d, 0x0078, 0x9199,
+	0x1078, 0x753d, 0x007c, 0x0d7e, 0x067e, 0x6618, 0x2668, 0x6e04,
+	0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0040, 0x9360, 0xa686,
+	0x0004, 0x0040, 0x9360, 0x6e04, 0xa6b4, 0x00ff, 0xa686, 0x0006,
+	0x0040, 0x9360, 0xa686, 0x0004, 0x0040, 0x9360, 0xa085, 0x0001,
+	0x067f, 0x0d7f, 0x007c, 0x0d7e, 0x1078, 0x9397, 0x0d7f, 0x007c,
+	0x0d7e, 0x1078, 0x93a6, 0x00c0, 0x9390, 0x680c, 0xa08c, 0xff00,
+	0x6820, 0xa084, 0x00ff, 0xa115, 0x6212, 0x6824, 0x602a, 0xd1e4,
+	0x0040, 0x937e, 0x2009, 0x0001, 0x0078, 0x938c, 0xd1ec, 0x0040,
+	0x9390, 0x6920, 0xa18c, 0x00ff, 0x6824, 0x1078, 0x24e3, 0x00c0,
+	0x9390, 0x2110, 0x2009, 0x0000, 0x1078, 0x285b, 0x0078, 0x9394,
+	0xa085, 0x0001, 0x0078, 0x9395, 0xa006, 0x0d7f, 0x007c, 0x2069,
+	0xa88d, 0x6800, 0xa082, 0x0010, 0x00c8, 0x93a4, 0x6013, 0x0000,
+	0xa085, 0x0001, 0x0078, 0x93a5, 0xa006, 0x007c, 0x6013, 0x0000,
+	0x2069, 0xa88c, 0x6808, 0xa084, 0xff00, 0xa086, 0x0800, 0x00c0,
+	0x93ba, 0x6800, 0xa084, 0x00ff, 0xa08e, 0x0014, 0x0040, 0x93ba,
+	0xa08e, 0x0010, 0x007c, 0x6004, 0xa0b2, 0x0044, 0x10c8, 0x1328,
+	0xa1b6, 0x0013, 0x00c0, 0x93c7, 0x2008, 0x0079, 0x93da, 0xa1b6,
+	0x0027, 0x0040, 0x93cf, 0xa1b6, 0x0014, 0x10c0, 0x1328, 0x2001,
+	0x0007, 0x1078, 0x4472, 0x1078, 0x6010, 0x1078, 0x8c01, 0x1078,
+	0x6109, 0x007c, 0x941a, 0x941c, 0x941a, 0x941a, 0x941a, 0x941c,
+	0x9424, 0x94ae, 0x9471, 0x94ae, 0x9485, 0x94ae, 0x9424, 0x94ae,
+	0x94a6, 0x94ae, 0x94a6, 0x94ae, 0x94ae, 0x941a, 0x941a, 0x941a,
+	0x941a, 0x941a, 0x941a, 0x941a, 0x941a, 0x941a, 0x941a, 0x941a,
+	0x941c, 0x941a, 0x94ae, 0x941a, 0x941a, 0x94ae, 0x941a, 0x94ae,
+	0x94ae, 0x941a, 0x941a, 0x941a, 0x941a, 0x94ae, 0x94ae, 0x941a,
+	0x94ae, 0x94ae, 0x941a, 0x941a, 0x941a, 0x941a, 0x941a, 0x941c,
+	0x94ae, 0x94ae, 0x941a, 0x941a, 0x94ae, 0x94ae, 0x941a, 0x941a,
+	0x941a, 0x941a, 0x1078, 0x1328, 0x1078, 0x6010, 0x6003, 0x0002,
+	0x1078, 0x6109, 0x0078, 0x94b4, 0x0f7e, 0x2079, 0xa351, 0x7804,
+	0x0f7f, 0xd0ac, 0x00c0, 0x94ae, 0x2001, 0x0000, 0x1078, 0x442b,
+	0x6018, 0xa080, 0x0004, 0x2004, 0xa086, 0x00ff, 0x0040, 0x94ae,
+	0x0c7e, 0x6018, 0x2060, 0x6000, 0xd0f4, 0x00c0, 0x9448, 0x6010,
+	0xa005, 0x0040, 0x9448, 0x0c7f, 0x1078, 0x35f7, 0x0078, 0x94ae,
+	0x0c7f, 0x2001, 0xa300, 0x2004, 0xa086, 0x0002, 0x00c0, 0x9457,
+	0x0f7e, 0x2079, 0xa300, 0x788c, 0x8000, 0x788e, 0x0f7f, 0x2001,
+	0x0002, 0x1078, 0x443f, 0x1078, 0x6010, 0x601f, 0x0001, 0x6003,
+	0x0001, 0x6007, 0x0002, 0x1078, 0x5c45, 0x1078, 0x6109, 0x0c7e,
+	0x6118, 0x2160, 0x2009, 0x0001, 0x1078, 0x58e1, 0x0c7f, 0x0078,
+	0x94b4, 0x6618, 0x0d7e, 0x2668, 0x6e04, 0x0d7f, 0xa6b4, 0xff00,
+	0x8637, 0xa686, 0x0006, 0x0040, 0x94ae, 0xa686, 0x0004, 0x0040,
+	0x94ae, 0x2001, 0x0004, 0x0078, 0x94ac, 0x2001, 0xa300, 0x2004,
+	0xa086, 0x0003, 0x00c0, 0x948e, 0x1078, 0x35f7, 0x2001, 0x0006,
+	0x1078, 0x94b5, 0x6618, 0x0d7e, 0x2668, 0x6e04, 0x0d7f, 0xa6b4,
+	0xff00, 0x8637, 0xa686, 0x0006, 0x0040, 0x94ae, 0x2001, 0x0006,
+	0x0078, 0x94ac, 0x2001, 0x0004, 0x0078, 0x94ac, 0x2001, 0x0006,
+	0x1078, 0x94b5, 0x0078, 0x94ae, 0x1078, 0x4472, 0x1078, 0x6010,
+	0x1078, 0x753d, 0x1078, 0x6109, 0x007c, 0x017e, 0x0d7e, 0x6118,
+	0x2168, 0x6900, 0xd184, 0x0040, 0x94d0, 0x6104, 0xa18e, 0x000a,
+	0x00c0, 0x94c8, 0x699c, 0xd1a4, 0x00c0, 0x94c8, 0x2001, 0x0007,
+	0x1078, 0x443f, 0x2001, 0x0000, 0x1078, 0x442b, 0x1078, 0x2839,
+	0x0d7f, 0x017f, 0x007c, 0x0d7e, 0x6618, 0x2668, 0x6804, 0xa084,
+	0xff00, 0x8007, 0x0d7f, 0xa0b2, 0x000c, 0x10c8, 0x1328, 0xa1b6,
+	0x0015, 0x00c0, 0x94e7, 0x1079, 0x94ee, 0x0078, 0x94ed, 0xa1b6,
+	0x0016, 0x10c0, 0x1328, 0x1079, 0x94fa, 0x007c, 0x7ad0, 0x7ad0,
+	0x7ad0, 0x7ad0, 0x7ad0, 0x7ad0, 0x9547, 0x9506, 0x7ad0, 0x7ad0,
+	0x7ad0, 0x7ad0, 0x7ad0, 0x7ad0, 0x7ad0, 0x7ad0, 0x7ad0, 0x7ad0,
+	0x9547, 0x954f, 0x7ad0, 0x7ad0, 0x7ad0, 0x7ad0, 0x0f7e, 0x2079,
+	0xa351, 0x7804, 0xd0ac, 0x00c0, 0x952d, 0x6018, 0xa07d, 0x0040,
+	0x952d, 0x7800, 0xd0f4, 0x00c0, 0x9519, 0x7810, 0xa005, 0x00c0,
+	0x952d, 0x2001, 0x0000, 0x1078, 0x442b, 0x2001, 0x0002, 0x1078,
+	0x443f, 0x601f, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x1078,
+	0x5c45, 0x1078, 0x6109, 0x0078, 0x9545, 0x2011, 0xa883, 0x2204,
+	0x8211, 0x220c, 0x1078, 0x24e3, 0x00c0, 0x9545, 0x0c7e, 0x1078,
+	0x4501, 0x0040, 0x9540, 0x0c7f, 0x1078, 0x753d, 0x0078, 0x9545,
+	0x1078, 0x4235, 0x0c7f, 0x1078, 0x753d, 0x0f7f, 0x007c, 0x6604,
+	0xa6b6, 0x001e, 0x00c0, 0x954e, 0x1078, 0x753d, 0x007c, 0x1078,
+	0x7d0a, 0x00c0, 0x955b, 0x6003, 0x0001, 0x6007, 0x0001, 0x1078,
+	0x5c45, 0x0078, 0x955d, 0x1078, 0x753d, 0x007c, 0x6004, 0xa08a,
+	0x0044, 0x10c8, 0x1328, 0x1078, 0x6010, 0x1078, 0x8c01, 0x1078,
+	0x6109, 0x007c, 0xa182, 0x0040, 0x0079, 0x956e, 0x9581, 0x9581,
+	0x9581, 0x9581, 0x9583, 0x9581, 0x9581, 0x9581, 0x9581, 0x9581,
+	0x9581, 0x9581, 0x9581, 0x9581, 0x9581, 0x9581, 0x9581, 0x9581,
+	0x9581, 0x1078, 0x1328, 0x0d7e, 0x0e7e, 0x0f7e, 0x157e, 0x047e,
+	0x027e, 0x6218, 0xa280, 0x002b, 0x2004, 0xa005, 0x0040, 0x9594,
+	0x2021, 0x0000, 0x1078, 0xa111, 0x6106, 0x2071, 0xa880, 0x7444,
+	0xa4a4, 0xff00, 0x0040, 0x95eb, 0xa486, 0x2000, 0x00c0, 0x95a6,
+	0x2009, 0x0001, 0x2011, 0x0200, 0x1078, 0x5a6d, 0x1078, 0x1381,
+	0x1040, 0x1328, 0x6003, 0x0007, 0x2d00, 0x6837, 0x010d, 0x6803,
+	0x0000, 0x683b, 0x0000, 0x6c5a, 0x2c00, 0x685e, 0x6008, 0x68b2,
+	0x6018, 0x2078, 0x78a0, 0x8007, 0x7130, 0x694a, 0x017e, 0xa084,
+	0xff00, 0x6846, 0x684f, 0x0000, 0x6857, 0x0036, 0x1078, 0x4982,
+	0x017f, 0xa486, 0x2000, 0x00c0, 0x95d3, 0x2019, 0x0017, 0x1078,
+	0x9e3b, 0x0078, 0x9645, 0xa486, 0x0400, 0x00c0, 0x95dd, 0x2019,
+	0x0002, 0x1078, 0x9dec, 0x0078, 0x9645, 0xa486, 0x0200, 0x00c0,
+	0x95e3, 0x1078, 0x9dd1, 0xa486, 0x1000, 0x00c0, 0x95e9, 0x1078,
+	0x9e20, 0x0078, 0x9645, 0x2069, 0xa62d, 0x6a00, 0xd284, 0x0040,
+	0x969b, 0xa284, 0x0300, 0x00c0, 0x9693, 0x6804, 0xa005, 0x0040,
+	0x9683, 0x2d78, 0x6003, 0x0007, 0x1078, 0x1366, 0x0040, 0x964c,
+	0x7800, 0xd08c, 0x00c0, 0x9607, 0x7804, 0x8001, 0x7806, 0x6013,
+	0x0000, 0x6803, 0x0000, 0x6837, 0x0116, 0x683b, 0x0000, 0x6008,
+	0x68b2, 0x2c00, 0x684a, 0x6018, 0x2078, 0x78a0, 0x8007, 0x7130,
+	0x6986, 0x6846, 0x6853, 0x003d, 0x7244, 0xa294, 0x0003, 0xa286,
+	0x0002, 0x00c0, 0x9627, 0x684f, 0x0040, 0x0078, 0x9631, 0xa286,
+	0x0001, 0x00c0, 0x962f, 0x684f, 0x0080, 0x0078, 0x9631, 0x684f,
+	0x0000, 0x20a9, 0x000a, 0x2001, 0xa890, 0xad90, 0x0015, 0x200c,
+	0x810f, 0x2112, 0x8000, 0x8210, 0x00f0, 0x9637, 0x200c, 0x6982,
+	0x8000, 0x200c, 0x697e, 0x1078, 0x4982, 0x027f, 0x047f, 0x157f,
+	0x0f7f, 0x0e7f, 0x0d7f, 0x007c, 0x6013, 0x0100, 0x6003, 0x0001,
+	0x6007, 0x0041, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x0078, 0x9645,
+	0x2069, 0xa892, 0x2d04, 0xa084, 0xff00, 0xa086, 0x1200, 0x00c0,
+	0x9677, 0x2069, 0xa880, 0x686c, 0xa084, 0x00ff, 0x017e, 0x6110,
+	0xa18c, 0x0700, 0xa10d, 0x6112, 0x017f, 0x6003, 0x0001, 0x6007,
+	0x0043, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x0078, 0x9645, 0x6013,
+	0x0200, 0x6003, 0x0001, 0x6007, 0x0041, 0x1078, 0x5bf8, 0x1078,
+	0x6109, 0x0078, 0x9645, 0x6013, 0x0300, 0x0078, 0x9689, 0x6013,
+	0x0100, 0x6003, 0x0001, 0x6007, 0x0041, 0x1078, 0x5bf8, 0x1078,
+	0x6109, 0x0078, 0x9645, 0x6013, 0x0500, 0x0078, 0x9689, 0x6013,
+	0x0600, 0x0078, 0x9658, 0x6013, 0x0200, 0x0078, 0x9658, 0xa186,
+	0x0013, 0x00c0, 0x96b1, 0x6004, 0xa08a, 0x0040, 0x1048, 0x1328,
+	0xa08a, 0x0053, 0x10c8, 0x1328, 0xa082, 0x0040, 0x2008, 0x0079,
+	0x9725, 0xa186, 0x0051, 0x0040, 0x96be, 0xa186, 0x0047, 0x00c0,
+	0x96d7, 0x6004, 0xa086, 0x0041, 0x0040, 0x96e5, 0x2001, 0x0109,
+	0x2004, 0xd084, 0x0040, 0x96e5, 0x127e, 0x2091, 0x2200, 0x007e,
+	0x017e, 0x027e, 0x1078, 0x5ad2, 0x027f, 0x017f, 0x007f, 0x127f,
+	0x6000, 0xa086, 0x0002, 0x00c0, 0x96e5, 0x0078, 0x976a, 0xa186,
+	0x0027, 0x0040, 0x96df, 0xa186, 0x0014, 0x10c0, 0x1328, 0x6004,
+	0xa082, 0x0040, 0x2008, 0x0079, 0x96e8, 0x1078, 0x7583, 0x007c,
+	0x96fb, 0x96fd, 0x96fd, 0x96fb, 0x96fb, 0x96fb, 0x96fb, 0x96fb,
+	0x96fb, 0x96fb, 0x96fb, 0x96fb, 0x96fb, 0x96fb, 0x96fb, 0x96fb,
+	0x96fb, 0x96fb, 0x96fb, 0x1078, 0x1328, 0x1078, 0x6010, 0x1078,
+	0x6109, 0x037e, 0x0d7e, 0x6010, 0xa06d, 0x0040, 0x9722, 0xad84,
+	0xf000, 0x0040, 0x9722, 0x6003, 0x0002, 0x6018, 0x2004, 0xd0bc,
+	0x00c0, 0x9722, 0x2019, 0x0004, 0x1078, 0x9e70, 0x6013, 0x0000,
+	0x6014, 0xa005, 0x00c0, 0x9720, 0x2001, 0xa5a1, 0x2004, 0x6016,
+	0x6003, 0x0007, 0x0d7f, 0x037f, 0x007c, 0x9738, 0x9757, 0x9741,
+	0x9764, 0x9738, 0x9738, 0x9738, 0x9738, 0x9738, 0x9738, 0x9738,
+	0x9738, 0x9738, 0x9738, 0x9738, 0x9738, 0x9738, 0x9738, 0x9738,
+	0x1078, 0x1328, 0x6010, 0xa088, 0x0013, 0x2104, 0xa085, 0x0400,
+	0x200a, 0x1078, 0x6010, 0x6010, 0xa080, 0x0013, 0x2004, 0xd0b4,
+	0x0040, 0x9752, 0x6003, 0x0007, 0x2009, 0x0043, 0x1078, 0x756c,
+	0x0078, 0x9754, 0x6003, 0x0002, 0x1078, 0x6109, 0x007c, 0x1078,
+	0x6010, 0x1078, 0xa0c6, 0x00c0, 0x9761, 0x1078, 0x5a41, 0x1078,
+	0x753d, 0x1078, 0x6109, 0x007c, 0x1078, 0x6010, 0x2009, 0x0041,
+	0x0078, 0x98c1, 0xa182, 0x0040, 0x0079, 0x976e, 0x9781, 0x9783,
+	0x9781, 0x9781, 0x9781, 0x9781, 0x9781, 0x9784, 0x9781, 0x9781,
+	0x9781, 0x9781, 0x9781, 0x9781, 0x9781, 0x9781, 0x9781, 0x978f,
+	0x9781, 0x1078, 0x1328, 0x007c, 0x6003, 0x0004, 0x6110, 0x20e1,
+	0x0005, 0x3d18, 0x3e20, 0x2c10, 0x1078, 0x15ec, 0x007c, 0x0d7e,
+	0x1078, 0x5a41, 0x0d7f, 0x1078, 0xa134, 0x1078, 0x753d, 0x007c,
+	0xa182, 0x0040, 0x0079, 0x979c, 0x97af, 0x97af, 0x97af, 0x97af,
+	0x97af, 0x97af, 0x97af, 0x97b1, 0x97af, 0x97b4, 0x97df, 0x97af,
+	0x97af, 0x97af, 0x97af, 0x97df, 0x97af, 0x97af, 0x97af, 0x1078,
+	0x1328, 0x1078, 0x7583, 0x007c, 0x1078, 0x60b8, 0x1078, 0x61d3,
+	0x6010, 0x0d7e, 0x2068, 0x684c, 0xd0fc, 0x0040, 0x97ca, 0xa08c,
+	0x0003, 0xa18e, 0x0002, 0x0040, 0x97d2, 0x2009, 0x0041, 0x0d7f,
+	0x0078, 0x98c1, 0x6003, 0x0007, 0x6017, 0x0000, 0x1078, 0x5a41,
+	0x0d7f, 0x007c, 0x1078, 0xa0c6, 0x0040, 0x97d8, 0x0d7f, 0x007c,
+	0x1078, 0x5a41, 0x1078, 0x753d, 0x0d7f, 0x0078, 0x97d1, 0x037e,
+	0x1078, 0x60b8, 0x1078, 0x61d3, 0x6010, 0x0d7e, 0x2068, 0x6018,
+	0x2004, 0xd0bc, 0x0040, 0x97ff, 0x684c, 0xa084, 0x0003, 0xa086,
+	0x0002, 0x0040, 0x97fb, 0x687c, 0x632c, 0xa31a, 0x632e, 0x6880,
+	0x6328, 0xa31b, 0x632a, 0x6003, 0x0002, 0x0078, 0x9810, 0x2019,
+	0x0004, 0x1078, 0x9e70, 0x6014, 0xa005, 0x00c0, 0x980c, 0x2001,
+	0xa5a1, 0x2004, 0x8003, 0x6016, 0x6013, 0x0000, 0x6003, 0x0007,
+	0x0d7f, 0x037f, 0x007c, 0xa186, 0x0013, 0x00c0, 0x9821, 0x6004,
+	0xa086, 0x0042, 0x10c0, 0x1328, 0x1078, 0x6010, 0x1078, 0x6109,
+	0x007c, 0xa186, 0x0027, 0x0040, 0x9829, 0xa186, 0x0014, 0x00c0,
+	0x9839, 0x6004, 0xa086, 0x0042, 0x10c0, 0x1328, 0x2001, 0x0007,
+	0x1078, 0x4472, 0x1078, 0x6010, 0x1078, 0x8c01, 0x1078, 0x6109,
+	0x007c, 0xa182, 0x0040, 0x0079, 0x983d, 0x9850, 0x9850, 0x9850,
+	0x9850, 0x9850, 0x9850, 0x9850, 0x9852, 0x985e, 0x9850, 0x9850,
+	0x9850, 0x9850, 0x9850, 0x9850, 0x9850, 0x9850, 0x9850, 0x9850,
+	0x1078, 0x1328, 0x037e, 0x047e, 0x20e1, 0x0005, 0x3d18, 0x3e20,
+	0x2c10, 0x1078, 0x15ec, 0x047f, 0x037f, 0x007c, 0x6010, 0x0d7e,
+	0x2068, 0x6810, 0x6a14, 0x6118, 0x210c, 0xd1bc, 0x0040, 0x987d,
+	0x6124, 0xd1f4, 0x00c0, 0x987d, 0x007e, 0x047e, 0x057e, 0x6c7c,
+	0xa422, 0x6d80, 0x2200, 0xa52b, 0x602c, 0xa420, 0x642e, 0x6028,
+	0xa529, 0x652a, 0x057f, 0x047f, 0x007f, 0xa20d, 0x00c0, 0x9891,
+	0x684c, 0xd0fc, 0x0040, 0x9889, 0x2009, 0x0041, 0x0d7f, 0x0078,
+	0x98c1, 0x6003, 0x0007, 0x6017, 0x0000, 0x1078, 0x5a41, 0x0d7f,
+	0x007c, 0x007e, 0x0f7e, 0x2c78, 0x1078, 0x4893, 0x0f7f, 0x007f,
+	0x0040, 0x989e, 0x6003, 0x0002, 0x0d7f, 0x007c, 0x2009, 0xa30d,
+	0x210c, 0xd19c, 0x0040, 0x98a8, 0x6003, 0x0007, 0x0078, 0x98aa,
+	0x6003, 0x0006, 0x1078, 0x98b0, 0x1078, 0x5a43, 0x0d7f, 0x007c,
+	0xd2fc, 0x0040, 0x98bc, 0x8002, 0x8000, 0x8212, 0xa291, 0x0000,
+	0x2009, 0x0009, 0x0078, 0x98be, 0x2009, 0x0015, 0x6a6a, 0x6866,
+	0x007c, 0xa182, 0x0040, 0x0048, 0x98c7, 0x0079, 0x98d4, 0xa186,
+	0x0013, 0x0040, 0x98cf, 0xa186, 0x0014, 0x10c0, 0x1328, 0x6024,
+	0xd0dc, 0x1040, 0x1328, 0x007c, 0x98e7, 0x98ee, 0x98fa, 0x9906,
+	0x98e7, 0x98e7, 0x98e7, 0x9915, 0x98e7, 0x98e9, 0x98e9, 0x98e7,
+	0x98e7, 0x98e7, 0x98e7, 0x98e7, 0x98e7, 0x98e7, 0x98e7, 0x1078,
+	0x1328, 0x6024, 0xd0dc, 0x1040, 0x1328, 0x007c, 0x6003, 0x0001,
+	0x6106, 0x1078, 0x5bf8, 0x127e, 0x2091, 0x8000, 0x1078, 0x6109,
+	0x127f, 0x007c, 0x6003, 0x0001, 0x6106, 0x1078, 0x5bf8, 0x127e,
+	0x2091, 0x8000, 0x1078, 0x6109, 0x127f, 0x007c, 0x6003, 0x0003,
+	0x6106, 0x2c10, 0x1078, 0x1cab, 0x127e, 0x2091, 0x8000, 0x1078,
+	0x5c64, 0x1078, 0x61d3, 0x127f, 0x007c, 0xa016, 0x1078, 0x15ec,
+	0x007c, 0x127e, 0x2091, 0x8000, 0x037e, 0x0d7e, 0xa182, 0x0040,
+	0x1079, 0x9926, 0x0d7f, 0x037f, 0x127f, 0x007c, 0x9936, 0x9938,
+	0x994d, 0x996c, 0x9936, 0x9936, 0x9936, 0x9984, 0x9936, 0x9936,
+	0x9936, 0x9936, 0x9936, 0x9936, 0x9936, 0x9936, 0x1078, 0x1328,
+	0x6010, 0x2068, 0x684c, 0xd0fc, 0x0040, 0x9962, 0xa09c, 0x0003,
+	0xa39e, 0x0003, 0x0040, 0x9962, 0x6003, 0x0001, 0x6106, 0x1078,
+	0x5bf8, 0x1078, 0x6109, 0x0078, 0x9987, 0x6010, 0x2068, 0x684c,
+	0xd0fc, 0x0040, 0x9962, 0xa09c, 0x0003, 0xa39e, 0x0003, 0x0040,
+	0x9962, 0x6003, 0x0001, 0x6106, 0x1078, 0x5bf8, 0x1078, 0x6109,
+	0x0078, 0x9987, 0x6013, 0x0000, 0x6017, 0x0000, 0x2019, 0x0004,
+	0x1078, 0x9e70, 0x0078, 0x9987, 0x6010, 0x2068, 0x684c, 0xd0fc,
+	0x0040, 0x9962, 0xa09c, 0x0003, 0xa39e, 0x0003, 0x0040, 0x9962,
+	0x6003, 0x0003, 0x6106, 0x2c10, 0x1078, 0x1cab, 0x1078, 0x5c64,
+	0x1078, 0x61d3, 0x0078, 0x9987, 0xa016, 0x1078, 0x15ec, 0x007c,
+	0x1078, 0x6010, 0x6110, 0x81ff, 0x0040, 0x9999, 0x0d7e, 0x2168,
+	0x1078, 0xa181, 0x037e, 0x2019, 0x0029, 0x1078, 0x9e70, 0x037f,
+	0x0d7f, 0x1078, 0x8c01, 0x1078, 0x6109, 0x007c, 0x1078, 0x60b8,
+	0x6110, 0x81ff, 0x0040, 0x99af, 0x0d7e, 0x2168, 0x1078, 0xa181,
+	0x037e, 0x2019, 0x0029, 0x1078, 0x9e70, 0x037f, 0x0d7f, 0x1078,
+	0x8c01, 0x1078, 0x61d3, 0x007c, 0xa182, 0x0085, 0x0079, 0x99b8,
+	0x99c1, 0x99bf, 0x99bf, 0x99cd, 0x99bf, 0x99bf, 0x99bf, 0x1078,
+	0x1328, 0x6003, 0x000b, 0x6106, 0x1078, 0x5bf8, 0x127e, 0x2091,
+	0x8000, 0x1078, 0x6109, 0x127f, 0x007c, 0x027e, 0x0e7e, 0x1078,
+	0xa0bf, 0x0040, 0x99d7, 0x1078, 0x753d, 0x0078, 0x99f3, 0x2071,
+	0xa880, 0x7224, 0x6212, 0x7220, 0x1078, 0x9d10, 0x0040, 0x99e4,
+	0x6007, 0x0086, 0x0078, 0x99ed, 0x6007, 0x0087, 0x7224, 0xa296,
+	0xffff, 0x00c0, 0x99ed, 0x6007, 0x0086, 0x6003, 0x0001, 0x1078,
+	0x5bf8, 0x1078, 0x6109, 0x0e7f, 0x027f, 0x007c, 0xa186, 0x0013,
+	0x00c0, 0x9a07, 0x6004, 0xa08a, 0x0085, 0x1048, 0x1328, 0xa08a,
+	0x008c, 0x10c8, 0x1328, 0xa082, 0x0085, 0x0079, 0x9a1e, 0xa186,
+	0x0027, 0x0040, 0x9a13, 0xa186, 0x0014, 0x0040, 0x9a13, 0x1078,
+	0x7583, 0x0078, 0x9a1d, 0x2001, 0x0007, 0x1078, 0x4472, 0x1078,
+	0x6010, 0x1078, 0x8c01, 0x1078, 0x6109, 0x007c, 0x9a25, 0x9a27,
+	0x9a27, 0x9a25, 0x9a25, 0x9a25, 0x9a25, 0x1078, 0x1328, 0x1078,
+	0x6010, 0x1078, 0x8c01, 0x1078, 0x6109, 0x007c, 0xa182, 0x0085,
+	0x1048, 0x1328, 0xa182, 0x008c, 0x10c8, 0x1328, 0xa182, 0x0085,
+	0x0079, 0x9a3a, 0x9a41, 0x9a41, 0x9a41, 0x9a43, 0x9a41, 0x9a41,
+	0x9a41, 0x1078, 0x1328, 0x007c, 0xa186, 0x0013, 0x0040, 0x9a54,
+	0xa186, 0x0014, 0x0040, 0x9a54, 0xa186, 0x0027, 0x0040, 0x9a54,
+	0x1078, 0x7583, 0x0078, 0x9a5a, 0x1078, 0x6010, 0x1078, 0x8c01,
+	0x1078, 0x6109, 0x007c, 0x037e, 0x1078, 0xa134, 0x603f, 0x0000,
+	0x2019, 0x000b, 0x1078, 0x9a6a, 0x601f, 0x0006, 0x6003, 0x0007,
+	0x037f, 0x007c, 0x127e, 0x037e, 0x2091, 0x8000, 0x087e, 0x2c40,
+	0x097e, 0x2049, 0x0000, 0x1078, 0x7058, 0x097f, 0x087f, 0x00c0,
+	0x9aa5, 0x077e, 0x2c38, 0x1078, 0x7105, 0x077f, 0x00c0, 0x9aa5,
+	0x6000, 0xa086, 0x0000, 0x0040, 0x9aa5, 0x601c, 0xa086, 0x0007,
+	0x0040, 0x9aa5, 0x0d7e, 0x6000, 0xa086, 0x0004, 0x00c0, 0x9a96,
+	0x1078, 0xa134, 0x601f, 0x0007, 0x1078, 0x1749, 0x6010, 0x2068,
+	0x1078, 0x8a44, 0x0040, 0x9a9e, 0x1078, 0x9e70, 0x0d7f, 0x6013,
+	0x0000, 0x1078, 0xa134, 0x601f, 0x0007, 0x037f, 0x127f, 0x007c,
+	0x0f7e, 0x0c7e, 0x037e, 0x157e, 0x2079, 0xa880, 0x7938, 0x783c,
+	0x1078, 0x24e3, 0x00c0, 0x9af6, 0x017e, 0x0c7e, 0x1078, 0x4501,
+	0x00c0, 0x9af6, 0x2011, 0xa890, 0xac98, 0x000a, 0x20a9, 0x0004,
+	0x1078, 0x7e55, 0x00c0, 0x9af6, 0x017f, 0x027f, 0x027e, 0x017e,
+	0x2019, 0x0029, 0x1078, 0x71e0, 0x1078, 0x5d53, 0x077e, 0x2039,
+	0x0000, 0x1078, 0x5c78, 0x077f, 0x017f, 0x077e, 0x2039, 0x0000,
+	0x1078, 0x9c38, 0x077f, 0x1078, 0x471b, 0x027e, 0x6204, 0xa294,
+	0xff00, 0x8217, 0xa286, 0x0006, 0x0040, 0x9aea, 0xa286, 0x0004,
+	0x00c0, 0x9aed, 0x62a0, 0x1078, 0x28d5, 0x027f, 0x017f, 0x1078,
+	0x4235, 0x6612, 0x6516, 0xa006, 0x0078, 0x9af8, 0x0c7f, 0x017f,
+	0x157f, 0x037f, 0x0c7f, 0x0f7f, 0x007c, 0x0c7e, 0x0d7e, 0x0e7e,
+	0x017e, 0x2009, 0xa31f, 0x2104, 0xa086, 0x0074, 0x00c0, 0x9b60,
+	0x2069, 0xa88e, 0x690c, 0xa182, 0x0100, 0x0048, 0x9b50, 0x6908,
+	0xa184, 0x8000, 0x0040, 0x9b5c, 0x6018, 0x2070, 0x7010, 0xa084,
+	0x00ff, 0x0040, 0x9b1f, 0x7000, 0xd0f4, 0x0040, 0x9b23, 0xa184,
+	0x0800, 0x0040, 0x9b5c, 0x6910, 0xa18a, 0x0001, 0x0048, 0x9b54,
+	0x6914, 0x2069, 0xa8ae, 0x6904, 0x81ff, 0x00c0, 0x9b48, 0x690c,
+	0xa182, 0x0100, 0x0048, 0x9b50, 0x6908, 0x81ff, 0x00c0, 0x9b4c,
+	0x6910, 0xa18a, 0x0001, 0x0048, 0x9b54, 0x6918, 0xa18a, 0x0001,
+	0x0048, 0x9b5c, 0x0078, 0x9b66, 0x6013, 0x0100, 0x0078, 0x9b62,
+	0x6013, 0x0300, 0x0078, 0x9b62, 0x6013, 0x0500, 0x0078, 0x9b62,
+	0x6013, 0x0700, 0x0078, 0x9b62, 0x6013, 0x0900, 0x0078, 0x9b62,
+	0x6013, 0x0b00, 0x0078, 0x9b62, 0x6013, 0x0f00, 0x0078, 0x9b62,
+	0x6013, 0x2d00, 0xa085, 0x0001, 0x0078, 0x9b67, 0xa006, 0x017f,
+	0x0e7f, 0x0d7f, 0x0c7f, 0x007c, 0x0c7e, 0x0d7e, 0x027e, 0x037e,
+	0x157e, 0x6218, 0x2268, 0x6b04, 0xa394, 0x00ff, 0xa286, 0x0006,
+	0x0040, 0x9b90, 0xa286, 0x0004, 0x0040, 0x9b90, 0xa394, 0xff00,
+	0x8217, 0xa286, 0x0006, 0x0040, 0x9b90, 0xa286, 0x0004, 0x0040,
+	0x9b90, 0x0c7e, 0x2d60, 0x1078, 0x4513, 0x0c7f, 0x0078, 0x9bcb,
+	0x2011, 0xa896, 0xad98, 0x000a, 0x20a9, 0x0004, 0x1078, 0x7e55,
+	0x00c0, 0x9bcc, 0x2011, 0xa89a, 0xad98, 0x0006, 0x20a9, 0x0004,
+	0x1078, 0x7e55, 0x00c0, 0x9bcc, 0x047e, 0x017e, 0x6aa0, 0xa294,
+	0x00ff, 0x8227, 0xa006, 0x2009, 0xa352, 0x210c, 0xd1a4, 0x0040,
+	0x9bb8, 0x2009, 0x0029, 0x1078, 0x9ec0, 0x6800, 0xc0e5, 0x6802,
+	0x2019, 0x0029, 0x1078, 0x5d53, 0x077e, 0x2039, 0x0000, 0x1078,
+	0x5c78, 0x2c08, 0x1078, 0x9c38, 0x077f, 0x2001, 0x0007, 0x1078,
+	0x4472, 0x017f, 0x047f, 0xa006, 0x157f, 0x037f, 0x027f, 0x0d7f,
+	0x0c7f, 0x007c, 0x0d7e, 0x2069, 0xa88e, 0x6800, 0xa086, 0x0800,
+	0x0040, 0x9bde, 0x6013, 0x0000, 0x0078, 0x9bdf, 0xa006, 0x0d7f,
+	0x007c, 0x0c7e, 0x0f7e, 0x017e, 0x027e, 0x037e, 0x157e, 0x2079,
+	0xa88c, 0x7930, 0x7834, 0x1078, 0x24e3, 0x00c0, 0x9c05, 0x1078,
+	0x4501, 0x00c0, 0x9c05, 0x2011, 0xa890, 0xac98, 0x000a, 0x20a9,
+	0x0004, 0x1078, 0x7e55, 0x00c0, 0x9c05, 0x2011, 0xa894, 0xac98,
+	0x0006, 0x20a9, 0x0004, 0x1078, 0x7e55, 0x157f, 0x037f, 0x027f,
+	0x017f, 0x0f7f, 0x0c7f, 0x007c, 0x0c7e, 0x007e, 0x017e, 0x027e,
+	0x037e, 0x157e, 0x2011, 0xa883, 0x2204, 0x8211, 0x220c, 0x1078,
+	0x24e3, 0x00c0, 0x9c31, 0x1078, 0x4501, 0x00c0, 0x9c31, 0x2011,
+	0xa896, 0xac98, 0x000a, 0x20a9, 0x0004, 0x1078, 0x7e55, 0x00c0,
+	0x9c31, 0x2011, 0xa89a, 0xac98, 0x0006, 0x20a9, 0x0004, 0x1078,
+	0x7e55, 0x157f, 0x037f, 0x027f, 0x017f, 0x007f, 0x0c7f, 0x007c,
+	0x0e7e, 0x0c7e, 0x087e, 0x077e, 0x067e, 0x057e, 0x047e, 0x027e,
+	0x127e, 0x2091, 0x8000, 0x2740, 0x2029, 0xa5b4, 0x252c, 0x2021,
+	0xa5ba, 0x2424, 0x2061, 0xaa00, 0x2071, 0xa300, 0x7644, 0x7060,
+	0x81ff, 0x0040, 0x9c59, 0x8001, 0xa602, 0x00c8, 0x9cc3, 0x0078,
+	0x9c5c, 0xa606, 0x0040, 0x9cc3, 0x2100, 0xac06, 0x0040, 0x9cb9,
+	0x1078, 0x9ee5, 0x0040, 0x9cb9, 0x671c, 0xa786, 0x0001, 0x0040,
+	0x9cde, 0xa786, 0x0004, 0x0040, 0x9cde, 0xa786, 0x0007, 0x0040,
+	0x9cb9, 0x2500, 0xac06, 0x0040, 0x9cb9, 0x2400, 0xac06, 0x0040,
+	0x9cb9, 0x1078, 0x9ef9, 0x00c0, 0x9cb9, 0x88ff, 0x0040, 0x9c84,
+	0x6020, 0xa906, 0x00c0, 0x9cb9, 0x0d7e, 0x6000, 0xa086, 0x0004,
+	0x00c0, 0x9c8e, 0x017e, 0x1078, 0x1749, 0x017f, 0xa786, 0x0008,
+	0x00c0, 0x9c9d, 0x1078, 0x8c3b, 0x00c0, 0x9c9d, 0x1078, 0x7a05,
+	0x0d7f, 0x1078, 0x8c01, 0x0078, 0x9cb9, 0x6010, 0x2068, 0x1078,
+	0x8a44, 0x0040, 0x9cb6, 0xa786, 0x0003, 0x00c0, 0x9ccd, 0x6837,
+	0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0xa181, 0x017e, 0x1078,
+	0x8cb8, 0x1078, 0x4982, 0x017f, 0x1078, 0x8bf4, 0x0d7f, 0x1078,
+	0x8c01, 0xace0, 0x0010, 0x2001, 0xa315, 0x2004, 0xac02, 0x00c8,
+	0x9cc3, 0x0078, 0x9c4c, 0x127f, 0x027f, 0x047f, 0x057f, 0x067f,
+	0x077f, 0x087f, 0x0c7f, 0x0e7f, 0x007c, 0xa786, 0x0006, 0x00c0,
+	0x9ca7, 0xa386, 0x0005, 0x0040, 0x9cdb, 0x1078, 0xa181, 0x1078,
+	0x9e70, 0x0078, 0x9cb6, 0x0d7f, 0x0078, 0x9cb9, 0x1078, 0x9ef9,
+	0x00c0, 0x9cb9, 0x81ff, 0x0040, 0x9cb9, 0xa180, 0x0001, 0x2004,
+	0xa086, 0x0018, 0x0040, 0x9cf3, 0xa180, 0x0001, 0x2004, 0xa086,
+	0x002d, 0x00c0, 0x9cb9, 0x6000, 0xa086, 0x0002, 0x00c0, 0x9cb9,
+	0x1078, 0x8c27, 0x0040, 0x9d04, 0x1078, 0x8c3b, 0x00c0, 0x9cb9,
+	0x1078, 0x7a05, 0x0078, 0x9d0c, 0x1078, 0x2839, 0x1078, 0x8c3b,
+	0x00c0, 0x9d0c, 0x1078, 0x7a05, 0x1078, 0x8c01, 0x0078, 0x9cb9,
+	0x0c7e, 0x0e7e, 0x017e, 0x2c08, 0x2170, 0x1078, 0x9e8c, 0x017f,
+	0x0040, 0x9d1f, 0x601c, 0xa084, 0x000f, 0x1079, 0x9d22, 0x0e7f,
+	0x0c7f, 0x007c, 0x9d2a, 0x9d2a, 0x9d2a, 0x9d2a, 0x9d2a, 0x9d2a,
+	0x9d2c, 0x9d2a, 0xa006, 0x007c, 0x047e, 0x017e, 0x7018, 0xa080,
+	0x0028, 0x2024, 0xa4a4, 0x00ff, 0x8427, 0x2c00, 0x2009, 0x0020,
+	0x1078, 0x9ec0, 0x017f, 0x047f, 0x037e, 0x2019, 0x0002, 0x1078,
+	0x9a6a, 0x037f, 0xa085, 0x0001, 0x007c, 0x2001, 0x0001, 0x1078,
+	0x442b, 0x157e, 0x017e, 0x027e, 0x037e, 0x20a9, 0x0004, 0x2019,
+	0xa305, 0x2011, 0xa896, 0x1078, 0x7e55, 0x037f, 0x027f, 0x017f,
+	0x157f, 0xa005, 0x007c, 0x0f7e, 0x0e7e, 0x0c7e, 0x087e, 0x077e,
+	0x067e, 0x027e, 0x127e, 0x2091, 0x8000, 0x2740, 0x2061, 0xaa00,
+	0x2079, 0x0001, 0x8fff, 0x0040, 0x9dc3, 0x2071, 0xa300, 0x7644,
+	0x7060, 0x8001, 0xa602, 0x00c8, 0x9dc3, 0x88ff, 0x0040, 0x9d7e,
+	0x2800, 0xac06, 0x00c0, 0x9db9, 0x2079, 0x0000, 0x1078, 0x9ee5,
+	0x0040, 0x9db9, 0x2400, 0xac06, 0x0040, 0x9db9, 0x671c, 0xa786,
+	0x0006, 0x00c0, 0x9db9, 0xa786, 0x0007, 0x0040, 0x9db9, 0x88ff,
+	0x00c0, 0x9d9d, 0x6018, 0xa206, 0x00c0, 0x9db9, 0x85ff, 0x0040,
+	0x9d9d, 0x6020, 0xa106, 0x00c0, 0x9db9, 0x0d7e, 0x6000, 0xa086,
+	0x0004, 0x00c0, 0x9da9, 0x1078, 0xa134, 0x601f, 0x0007, 0x1078,
+	0x1749, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040, 0x9db3, 0x047e,
+	0x1078, 0x9e70, 0x047f, 0x0d7f, 0x1078, 0x8c01, 0x88ff, 0x00c0,
+	0x9dcd, 0xace0, 0x0010, 0x2001, 0xa315, 0x2004, 0xac02, 0x00c8,
+	0x9dc3, 0x0078, 0x9d6a, 0xa006, 0x127f, 0x027f, 0x067f, 0x077f,
+	0x087f, 0x0c7f, 0x0e7f, 0x0f7f, 0x007c, 0xa8c5, 0x0001, 0x0078,
+	0x9dc4, 0x077e, 0x057e, 0x087e, 0x2041, 0x0000, 0x2029, 0x0001,
+	0x2c20, 0x2019, 0x0002, 0x6218, 0x097e, 0x2049, 0x0000, 0x1078,
+	0x7058, 0x097f, 0x087f, 0x2039, 0x0000, 0x1078, 0x7105, 0x1078,
+	0x9d5b, 0x057f, 0x077f, 0x007c, 0x027e, 0x047e, 0x057e, 0x077e,
+	0x0c7e, 0x157e, 0x2c20, 0x2128, 0x20a9, 0x007f, 0x2009, 0x0000,
+	0x017e, 0x037e, 0x1078, 0x4501, 0x00c0, 0x9e14, 0x2c10, 0x057e,
+	0x087e, 0x2041, 0x0000, 0x2508, 0x2029, 0x0001, 0x097e, 0x2049,
+	0x0000, 0x1078, 0x7058, 0x097f, 0x087f, 0x2039, 0x0000, 0x1078,
+	0x7105, 0x1078, 0x9d5b, 0x057f, 0x037f, 0x017f, 0x8108, 0x00f0,
+	0x9df8, 0x157f, 0x0c7f, 0x077f, 0x057f, 0x047f, 0x027f, 0x007c,
+	0x077e, 0x057e, 0x6218, 0x087e, 0x2041, 0x0000, 0x2029, 0x0001,
+	0x2019, 0x0048, 0x097e, 0x2049, 0x0000, 0x1078, 0x7058, 0x097f,
+	0x087f, 0x2039, 0x0000, 0x1078, 0x7105, 0x2c20, 0x1078, 0x9d5b,
+	0x057f, 0x077f, 0x007c, 0x027e, 0x047e, 0x057e, 0x077e, 0x0c7e,
+	0x157e, 0x2c20, 0x20a9, 0x007f, 0x2009, 0x0000, 0x017e, 0x037e,
+	0x1078, 0x4501, 0x00c0, 0x9e64, 0x2c10, 0x087e, 0x2041, 0x0000,
+	0x2828, 0x047e, 0x2021, 0x0001, 0x1078, 0xa111, 0x047f, 0x097e,
+	0x2049, 0x0000, 0x1078, 0x7058, 0x097f, 0x087f, 0x2039, 0x0000,
+	0x1078, 0x7105, 0x1078, 0x9d5b, 0x037f, 0x017f, 0x8108, 0x00f0,
+	0x9e46, 0x157f, 0x0c7f, 0x077f, 0x057f, 0x047f, 0x027f, 0x007c,
+	0x017e, 0x0f7e, 0xad82, 0xca00, 0x0048, 0x9e89, 0xad82, 0xffff,
+	0x00c8, 0x9e89, 0x6800, 0xa07d, 0x0040, 0x9e86, 0x6803, 0x0000,
+	0x6b52, 0x1078, 0x4982, 0x2f68, 0x0078, 0x9e7a, 0x6b52, 0x1078,
+	0x4982, 0x0f7f, 0x017f, 0x007c, 0x0e7e, 0x047e, 0x037e, 0x2061,
+	0xaa00, 0x2071, 0xa300, 0x7444, 0x7060, 0x8001, 0xa402, 0x00c8,
+	0x9ebb, 0x2100, 0xac06, 0x0040, 0x9ead, 0x6000, 0xa086, 0x0000,
+	0x0040, 0x9ead, 0x6008, 0xa206, 0x00c0, 0x9ead, 0x6018, 0xa1a0,
+	0x0006, 0x2424, 0xa406, 0x0040, 0x9eb7, 0xace0, 0x0010, 0x2001,
+	0xa315, 0x2004, 0xac02, 0x00c8, 0x9ebb, 0x0078, 0x9e91, 0xa085,
+	0x0001, 0x0078, 0x9ebc, 0xa006, 0x037f, 0x047f, 0x0e7f, 0x007c,
+	0x0d7e, 0x007e, 0x1078, 0x1381, 0x007f, 0x1040, 0x1328, 0x6837,
+	0x010d, 0x685e, 0x027e, 0x2010, 0x1078, 0x8a30, 0x2001, 0x0000,
+	0x0040, 0x9ed6, 0x2200, 0xa080, 0x0008, 0x2004, 0x027f, 0x684a,
+	0x6956, 0x6c46, 0x684f, 0x0000, 0xa006, 0x68b2, 0x6802, 0x683a,
+	0x685a, 0x1078, 0x4982, 0x0d7f, 0x007c, 0x6700, 0xa786, 0x0000,
+	0x0040, 0x9ef8, 0xa786, 0x0001, 0x0040, 0x9ef8, 0xa786, 0x000a,
+	0x0040, 0x9ef8, 0xa786, 0x0009, 0x0040, 0x9ef8, 0xa085, 0x0001,
+	0x007c, 0x0e7e, 0x6018, 0x2070, 0x70a0, 0xa206, 0x0e7f, 0x007c,
+	0x017e, 0x6004, 0xa08e, 0x001e, 0x00c0, 0x9f1a, 0x8007, 0x6130,
+	0xa18c, 0x00ff, 0xa105, 0x6032, 0x6007, 0x0085, 0x6003, 0x000b,
+	0x601f, 0x0005, 0x2001, 0xa5a1, 0x2004, 0x6016, 0x1078, 0x5bf8,
+	0x1078, 0x6109, 0x017f, 0x007c, 0x0005, 0x0005, 0x007c, 0x6024,
+	0xd0e4, 0x0040, 0x9f30, 0xd0cc, 0x0040, 0x9f2a, 0x1078, 0x8cfa,
+	0x0078, 0x9f30, 0x1078, 0xa134, 0x1078, 0x5a41, 0x1078, 0x753d,
+	0x007c, 0xa280, 0x0007, 0x2004, 0xa084, 0x000f, 0x0079, 0x9f38,
+	0x9f41, 0x9f41, 0x9f41, 0x9f43, 0x9f41, 0x9f43, 0x9f43, 0x9f41,
+	0x9f43, 0xa006, 0x007c, 0xa085, 0x0001, 0x007c, 0xa280, 0x0007,
+	0x2004, 0xa084, 0x000f, 0x0079, 0x9f4d, 0x9f56, 0x9f56, 0x9f56,
+	0x9f56, 0x9f56, 0x9f56, 0x9f61, 0x9f56, 0x9f56, 0x6007, 0x003b,
+	0x602b, 0x0009, 0x6013, 0x2a00, 0x6003, 0x0001, 0x1078, 0x5bf8,
+	0x007c, 0x0c7e, 0x2260, 0x1078, 0xa134, 0x603f, 0x0000, 0x6024,
+	0xc0f4, 0xc0cc, 0x6026, 0x0c7f, 0x0d7e, 0x2268, 0xa186, 0x0007,
+	0x00c0, 0x9fc2, 0x6810, 0xa005, 0x0040, 0x9f7f, 0xa080, 0x0013,
+	0x2004, 0xd0fc, 0x00c0, 0x9f7f, 0x0d7f, 0x0078, 0x9f56, 0x6007,
+	0x003a, 0x6003, 0x0001, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x0c7e,
+	0x2d60, 0x6100, 0xa186, 0x0002, 0x00c0, 0xa050, 0x6010, 0xa005,
+	0x00c0, 0x9f99, 0x6000, 0xa086, 0x0007, 0x10c0, 0x1328, 0x0078,
+	0xa050, 0xa08c, 0xf000, 0x00c0, 0x9fa5, 0x0078, 0x9fa5, 0x2068,
+	0x6800, 0xa005, 0x00c0, 0x9f9f, 0x2d00, 0xa080, 0x0013, 0x2004,
+	0xa084, 0x0003, 0xa086, 0x0002, 0x00c0, 0x9fbe, 0x6010, 0x2068,
+	0x684c, 0xc0dc, 0xc0f4, 0x684e, 0x6850, 0xc0f4, 0xc0fc, 0x6852,
+	0x2009, 0x0043, 0x1078, 0x98c1, 0x0078, 0xa050, 0x2009, 0x0041,
+	0x0078, 0xa04a, 0xa186, 0x0005, 0x00c0, 0xa009, 0x6810, 0xa080,
+	0x0013, 0x2004, 0xd0bc, 0x00c0, 0x9fd0, 0x0d7f, 0x0078, 0x9f56,
+	0xd0b4, 0x0040, 0x9fd8, 0xd0fc, 0x1040, 0x1328, 0x0078, 0x9f72,
+	0x6007, 0x003a, 0x6003, 0x0001, 0x1078, 0x5bf8, 0x1078, 0x6109,
+	0x0c7e, 0x2d60, 0x6100, 0xa186, 0x0002, 0x0040, 0x9feb, 0xa186,
+	0x0004, 0x00c0, 0xa050, 0x2071, 0xa5e1, 0x7000, 0xa086, 0x0003,
+	0x00c0, 0x9ff8, 0x7004, 0xac06, 0x00c0, 0x9ff8, 0x7003, 0x0000,
+	0x6810, 0xa080, 0x0013, 0x200c, 0xc1f4, 0xc1dc, 0x2102, 0x8000,
+	0x200c, 0xc1f4, 0xc1fc, 0xc1bc, 0x2102, 0x2009, 0x0042, 0x0078,
+	0xa04a, 0x037e, 0x0d7e, 0x0d7e, 0x1078, 0x1381, 0x037f, 0x1040,
+	0x1328, 0x6837, 0x010d, 0x6803, 0x0000, 0x683b, 0x0000, 0x685b,
+	0x0000, 0x6b5e, 0x6857, 0x0045, 0x2c00, 0x6862, 0x6034, 0x6872,
+	0x2360, 0x6024, 0xc0dd, 0x6026, 0x6018, 0xa080, 0x0028, 0x2004,
+	0xa084, 0x00ff, 0x8007, 0x6320, 0x6b4a, 0x6846, 0x684f, 0x0000,
+	0x6d6a, 0x6e66, 0x686f, 0x0001, 0x1078, 0x4982, 0x2019, 0x0045,
+	0x6008, 0x2068, 0x1078, 0x9a6a, 0x2d00, 0x600a, 0x601f, 0x0006,
+	0x6003, 0x0007, 0x6017, 0x0000, 0x603f, 0x0000, 0x0d7f, 0x037f,
+	0x0078, 0xa051, 0x603f, 0x0000, 0x6003, 0x0007, 0x1078, 0x98c1,
+	0x0c7f, 0x0d7f, 0x007c, 0xa186, 0x0013, 0x00c0, 0xa05d, 0x6004,
+	0xa082, 0x0085, 0x2008, 0x0079, 0xa077, 0xa186, 0x0027, 0x00c0,
+	0xa070, 0x1078, 0x6010, 0x037e, 0x0d7e, 0x6010, 0x2068, 0x2019,
+	0x0004, 0x1078, 0x9e70, 0x0d7f, 0x037f, 0x1078, 0x6109, 0x007c,
+	0xa186, 0x0014, 0x0040, 0xa061, 0x1078, 0x7583, 0x007c, 0xa080,
+	0xa07e, 0xa07e, 0xa07e, 0xa07e, 0xa07e, 0xa080, 0x1078, 0x1328,
+	0x1078, 0x6010, 0x6003, 0x000c, 0x1078, 0x6109, 0x007c, 0xa182,
+	0x008c, 0x00c8, 0xa091, 0xa182, 0x0085, 0x0048, 0xa091, 0x0079,
+	0xa094, 0x1078, 0x7583, 0x007c, 0xa09b, 0xa09b, 0xa09b, 0xa09b,
+	0xa09d, 0xa0bc, 0xa09b, 0x1078, 0x1328, 0x0d7e, 0x2c68, 0x1078,
+	0x74d7, 0x0040, 0xa0b7, 0x6003, 0x0001, 0x6007, 0x001e, 0x2009,
+	0xa88e, 0x210c, 0x6136, 0x2009, 0xa88f, 0x210c, 0x613a, 0x600b,
+	0xffff, 0x6918, 0x611a, 0x601f, 0x0004, 0x1078, 0x5bf8, 0x2d60,
+	0x1078, 0x753d, 0x0d7f, 0x007c, 0x1078, 0x753d, 0x007c, 0x0e7e,
+	0x6018, 0x2070, 0x7000, 0xd0ec, 0x0e7f, 0x007c, 0x6010, 0xa080,
+	0x0013, 0x200c, 0xd1ec, 0x0040, 0xa110, 0x2001, 0xa371, 0x2004,
+	0xd0ec, 0x0040, 0xa110, 0x6003, 0x0002, 0x6024, 0xc0e5, 0x6026,
+	0xd1ac, 0x0040, 0xa0ee, 0x0f7e, 0x2c78, 0x1078, 0x488f, 0x0f7f,
+	0x0040, 0xa0ee, 0x2001, 0xa5a2, 0x2004, 0x603e, 0x2009, 0xa371,
+	0x210c, 0xd1f4, 0x00c0, 0xa10e, 0x0078, 0xa100, 0x2009, 0xa371,
+	0x210c, 0xd1f4, 0x0040, 0xa0fa, 0x6024, 0xc0e4, 0x6026, 0xa006,
+	0x0078, 0xa110, 0x2001, 0xa5a2, 0x200c, 0x8103, 0xa100, 0x603e,
+	0x6018, 0xa088, 0x002b, 0x2104, 0xa005, 0x0040, 0xa10b, 0xa088,
+	0x0003, 0x0078, 0xa103, 0x2c0a, 0x600f, 0x0000, 0xa085, 0x0001,
+	0x007c, 0x017e, 0x0c7e, 0x0e7e, 0x6120, 0xa2f0, 0x002b, 0x2e04,
+	0x2060, 0x8cff, 0x0040, 0xa130, 0x84ff, 0x00c0, 0xa123, 0x6020,
+	0xa106, 0x00c0, 0xa12b, 0x600c, 0x2072, 0x1078, 0x5a41, 0x1078,
+	0x753d, 0x0078, 0xa12d, 0xacf0, 0x0003, 0x2e64, 0x0078, 0xa119,
+	0x0e7f, 0x0c7f, 0x017f, 0x007c, 0x0d7e, 0x6018, 0xa0e8, 0x002b,
+	0x2d04, 0xa005, 0x0040, 0xa146, 0xac06, 0x0040, 0xa144, 0x2d04,
+	0xa0e8, 0x0003, 0x0078, 0xa138, 0x600c, 0x206a, 0x0d7f, 0x007c,
+	0x027e, 0x037e, 0x157e, 0x2011, 0xa325, 0x2204, 0xa084, 0x00ff,
+	0x2019, 0xa88e, 0x2334, 0xa636, 0x00c0, 0xa174, 0x8318, 0x2334,
+	0x2204, 0xa084, 0xff00, 0xa636, 0x00c0, 0xa174, 0x2011, 0xa890,
+	0x6018, 0xa098, 0x000a, 0x20a9, 0x0004, 0x1078, 0x7e55, 0x00c0,
+	0xa174, 0x2011, 0xa894, 0x6018, 0xa098, 0x0006, 0x20a9, 0x0004,
+	0x1078, 0x7e55, 0x00c0, 0xa174, 0x157f, 0x037f, 0x027f, 0x007c,
+	0x0e7e, 0x2071, 0xa300, 0x1078, 0x41f5, 0x1078, 0x260d, 0x0e7f,
+	0x007c, 0x0e7e, 0x6018, 0x2070, 0x7000, 0xd0fc, 0x0040, 0xa18a,
+	0x1078, 0xa18c, 0x0e7f, 0x007c, 0x6850, 0xc0e5, 0x6852, 0x007c,
+	0x0e7e, 0x0c7e, 0x077e, 0x067e, 0x057e, 0x047e, 0x027e, 0x017e,
+	0x127e, 0x2091, 0x8000, 0x2029, 0xa5b4, 0x252c, 0x2021, 0xa5ba,
+	0x2424, 0x2061, 0xaa00, 0x2071, 0xa300, 0x7644, 0x7060, 0xa606,
+	0x0040, 0xa1e4, 0x671c, 0xa786, 0x0001, 0x0040, 0xa1b3, 0xa786,
+	0x0008, 0x00c0, 0xa1da, 0x2500, 0xac06, 0x0040, 0xa1da, 0x2400,
+	0xac06, 0x0040, 0xa1da, 0x1078, 0x9ee5, 0x0040, 0xa1da, 0x1078,
+	0x9ef9, 0x00c0, 0xa1da, 0x6000, 0xa086, 0x0004, 0x00c0, 0xa1cc,
+	0x017e, 0x1078, 0x1749, 0x017f, 0x1078, 0x8c27, 0x00c0, 0xa1d2,
+	0x1078, 0x2839, 0x1078, 0x8c3b, 0x00c0, 0xa1d8, 0x1078, 0x7a05,
+	0x1078, 0x8c01, 0xace0, 0x0010, 0x2001, 0xa315, 0x2004, 0xac02,
+	0x00c8, 0xa1e4, 0x0078, 0xa1a3, 0x127f, 0x017f, 0x027f, 0x047f,
+	0x057f, 0x067f, 0x077f, 0x0c7f, 0x0e7f, 0x007c, 0x127e, 0x007e,
+	0x0e7e, 0x2091, 0x8000, 0x2071, 0xa340, 0xd5a4, 0x0040, 0xa1fb,
+	0x7034, 0x8000, 0x7036, 0xd5b4, 0x0040, 0xa201, 0x7030, 0x8000,
+	0x7032, 0xd5ac, 0x0040, 0xa208, 0x2071, 0xa34a, 0x1078, 0xa237,
+	0x0e7f, 0x007f, 0x127f, 0x007c, 0x127e, 0x007e, 0x0e7e, 0x2091,
+	0x8000, 0x2071, 0xa340, 0xd5a4, 0x0040, 0xa219, 0x7034, 0x8000,
+	0x7036, 0xd5b4, 0x0040, 0xa21f, 0x7030, 0x8000, 0x7032, 0xd5ac,
+	0x0040, 0xa226, 0x2071, 0xa34a, 0x1078, 0xa237, 0x0e7f, 0x007f,
+	0x127f, 0x007c, 0x127e, 0x007e, 0x0e7e, 0x2091, 0x8000, 0x2071,
+	0xa342, 0x1078, 0xa237, 0x0e7f, 0x007f, 0x127f, 0x007c, 0x2e04,
+	0x8000, 0x2072, 0x00c8, 0xa240, 0x8e70, 0x2e04, 0x8000, 0x2072,
+	0x007c, 0x0e7e, 0x2071, 0xa340, 0x1078, 0xa237, 0x0e7f, 0x007c,
+	0x0e7e, 0x2071, 0xa344, 0x1078, 0xa237, 0x0e7f, 0x007c, 0x0001,
+	0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100,
+	0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0x6286
+};
+
+/************************************************************************
+ *									*
+ *               --- ISP2200 Initiator/Target Firmware ---              *
+ *             with Fabric (Public Loop), Point-point, and              *
+ *             expanded LUN addressing for FCTAPE                       *
+ *									*
+ ************************************************************************
+  Copyright (C) 2000 and 2100 Qlogic Corporation 
+  (www.qlogic.com)
+
+  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.
+************************************************************************/
+
+/*
+ *	Firmware Version 2.01.27 (11:07 Dec 18, 2000)
+ */
+
+unsigned short risc_code_length2200 = 0x9cbf;
+unsigned short risc_code2200[] = { 
+	0x0470, 0x0000, 0x0000, 0x9cbf, 0x0000, 0x0002, 0x0001, 0x001b,
+	0x0017, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2031, 0x3939,
+	0x3920, 0x514c, 0x4f47, 0x4943, 0x2043, 0x4f52, 0x504f, 0x5241,
+	0x5449, 0x4f4e, 0x2049, 0x5350, 0x3232, 0x3030, 0x2046, 0x6972,
+	0x6d77, 0x6172, 0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030,
+	0x322e, 0x3031, 0x2e32, 0x3720, 0x2020, 0x2020, 0x2400, 0x20c1,
+	0x0005, 0x2001, 0x017f, 0x2003, 0x0000, 0x20c9, 0xb1ff, 0x2091,
+	0x2000, 0x2059, 0x0000, 0x2b78, 0x7823, 0x0004, 0x2089, 0x27b5,
+	0x2051, 0xad00, 0x2a70, 0x2029, 0xe400, 0x2031, 0xffff, 0x2039,
+	0xe3e9, 0x2021, 0x0200, 0x0804, 0x1449, 0x20a1, 0xacbf, 0xa00e,
+	0x20a9, 0x0741, 0x41a4, 0x3400, 0x755e, 0x7662, 0x775a, 0x7466,
+	0x746a, 0x20a1, 0xb400, 0x7160, 0x810d, 0x810d, 0x810d, 0x810d,
+	0xa18c, 0x000f, 0x2001, 0x000b, 0xa112, 0xa00e, 0x21a8, 0x41a4,
+	0x3400, 0x8211, 0x1dd8, 0x7160, 0x3400, 0xa102, 0x0120, 0x0218,
+	0x20a8, 0xa00e, 0x41a4, 0x3800, 0xd08c, 0x01d8, 0x2009, 0xad00,
+	0x810d, 0x810d, 0x810d, 0x810d, 0xa18c, 0x000f, 0x2001, 0x0001,
+	0xa112, 0x20a1, 0x1000, 0xa00e, 0x21a8, 0x41a4, 0x8211, 0x1de0,
+	0x2009, 0xad00, 0x3400, 0xa102, 0x0120, 0x0218, 0x20a8, 0xa00e,
+	0x41a4, 0x080c, 0x13fc, 0x080c, 0x1613, 0x080c, 0x17ac, 0x080c,
+	0x1e67, 0x080c, 0x492e, 0x080c, 0x801a, 0x080c, 0x159c, 0x080c,
+	0x2ce6, 0x080c, 0x5a01, 0x080c, 0x5045, 0x080c, 0x6487, 0x080c,
+	0x236a, 0x080c, 0x6686, 0x080c, 0x5fae, 0x080c, 0x226b, 0x080c,
+	0x2338, 0x2091, 0x3009, 0x7823, 0x0000, 0x1004, 0x10c5, 0x7820,
+	0xa086, 0x0002, 0x1150, 0x7823, 0x4000, 0x0e04, 0x10bd, 0x781b,
+	0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x2a70, 0x7003, 0x0000,
+	0x2a70, 0x7000, 0xa08e, 0x0003, 0x1158, 0x080c, 0x3c98, 0x080c,
+	0x2d0d, 0x080c, 0x5a4f, 0x080c, 0x51f4, 0x080c, 0x64a2, 0x0c80,
+	0x000b, 0x0c98, 0x10e4, 0x10e5, 0x1203, 0x10e2, 0x12cc, 0x13f9,
+	0x13fa, 0x13fb, 0x080c, 0x14f6, 0x0005, 0x0126, 0x00f6, 0x2091,
+	0x8000, 0x7000, 0xa086, 0x0001, 0x1904, 0x11d1, 0x080c, 0x1569,
+	0x080c, 0x574f, 0x0150, 0x080c, 0x5775, 0x1580, 0x2079, 0x0100,
+	0x7828, 0xa085, 0x1800, 0x782a, 0x0448, 0x080c, 0x569a, 0x7000,
+	0xa086, 0x0001, 0x1904, 0x11d1, 0x7088, 0xa086, 0x0028, 0x1904,
+	0x11d1, 0x2079, 0x0100, 0x7827, 0xffff, 0x7a28, 0xa295, 0x1e2f,
+	0x7a2a, 0x2011, 0x566e, 0x080c, 0x650d, 0x2011, 0x567b, 0x080c,
+	0x650d, 0x2011, 0x481b, 0x080c, 0x650d, 0x2011, 0x8030, 0x2019,
+	0x0000, 0x7087, 0x0000, 0x080c, 0x1d0f, 0x00e8, 0x080c, 0x41d1,
+	0x2079, 0x0100, 0x7844, 0xa005, 0x1904, 0x11d1, 0x2011, 0x481b,
+	0x080c, 0x650d, 0x2011, 0x567b, 0x080c, 0x650d, 0x080c, 0x1d0f,
+	0x2001, 0xaf8c, 0x2004, 0x780e, 0x7840, 0xa084, 0xfffb, 0x7842,
+	0x2011, 0x8010, 0x73c8, 0x080c, 0x3c5c, 0x7238, 0xc284, 0x723a,
+	0x2001, 0xad0c, 0x200c, 0xc1ac, 0x2102, 0x080c, 0x79bd, 0x2011,
+	0x0004, 0x080c, 0x959c, 0x080c, 0x4f71, 0x080c, 0x574f, 0x0158,
+	0x080c, 0x4917, 0x0140, 0x7087, 0x0001, 0x70c3, 0x0000, 0x080c,
+	0x436e, 0x0804, 0x11d1, 0x080c, 0x502d, 0x0120, 0x7a0c, 0xc2b4,
+	0x7a0e, 0x0050, 0x080c, 0x9937, 0x70d0, 0xd09c, 0x1128, 0x709c,
+	0xa005, 0x0110, 0x080c, 0x48f5, 0x70db, 0x0000, 0x70d7, 0x0000,
+	0x72d0, 0x080c, 0x574f, 0x1178, 0x2011, 0x0000, 0x0016, 0x080c,
+	0x2744, 0x2019, 0xaf8e, 0x211a, 0x001e, 0x704f, 0xffff, 0x7053,
+	0x00ef, 0x7073, 0x0000, 0x2079, 0xad51, 0x7804, 0xd0ac, 0x0108,
+	0xc295, 0x72d2, 0x080c, 0x574f, 0x0118, 0xa296, 0x0004, 0x0508,
+	0x2011, 0x0001, 0x080c, 0x959c, 0x7097, 0x0000, 0x709b, 0xffff,
+	0x7003, 0x0002, 0x00fe, 0x080c, 0x28fa, 0x2011, 0x0005, 0x080c,
+	0x7adf, 0x080c, 0x6c50, 0x080c, 0x574f, 0x0148, 0x00c6, 0x2061,
+	0x0100, 0x0016, 0x080c, 0x2744, 0x61e2, 0x001e, 0x00ce, 0x012e,
+	0x00d0, 0x7097, 0x0000, 0x709b, 0xffff, 0x7003, 0x0002, 0x2011,
+	0x0005, 0x080c, 0x7adf, 0x080c, 0x6c50, 0x080c, 0x574f, 0x0148,
+	0x00c6, 0x2061, 0x0100, 0x0016, 0x080c, 0x2744, 0x61e2, 0x001e,
+	0x00ce, 0x00fe, 0x012e, 0x0005, 0x00c6, 0x080c, 0x574f, 0x1118,
+	0x20a9, 0x0100, 0x0010, 0x20a9, 0x0082, 0x080c, 0x574f, 0x1118,
+	0x2009, 0x0000, 0x0010, 0x2009, 0x007e, 0x0016, 0x0026, 0x0036,
+	0x2110, 0x0026, 0x2019, 0x0029, 0x080c, 0x7cf4, 0x002e, 0x080c,
+	0xac07, 0x003e, 0x002e, 0x001e, 0x080c, 0x2bc9, 0x8108, 0x1f04,
+	0x11e5, 0x00ce, 0x706f, 0x0000, 0x7070, 0xa084, 0x00ff, 0x7072,
+	0x709f, 0x0000, 0x0005, 0x0126, 0x2091, 0x8000, 0x7000, 0xa086,
+	0x0002, 0x1904, 0x12ca, 0x7098, 0xa086, 0xffff, 0x0130, 0x080c,
+	0x28fa, 0x080c, 0x6c50, 0x0804, 0x12ca, 0x70d0, 0xd0ac, 0x1110,
+	0xd09c, 0x0540, 0xd084, 0x0530, 0x0006, 0x0016, 0x2001, 0x0103,
+	0x2009, 0xaf8c, 0x210c, 0x2102, 0x001e, 0x000e, 0xd08c, 0x01d0,
+	0x70d4, 0xa086, 0xffff, 0x0190, 0x080c, 0x2a56, 0x080c, 0x6c50,
+	0x70d0, 0xd094, 0x1904, 0x12ca, 0x2011, 0x0001, 0x2019, 0x0000,
+	0x080c, 0x2a8c, 0x080c, 0x6c50, 0x0804, 0x12ca, 0x70d8, 0xa005,
+	0x1904, 0x12ca, 0x7094, 0xa005, 0x1904, 0x12ca, 0x70d0, 0xd0a4,
+	0x0118, 0xd0b4, 0x0904, 0x12ca, 0x080c, 0x502d, 0x1904, 0x12ca,
+	0x2001, 0xad52, 0x2004, 0xd0ac, 0x01c8, 0x0156, 0x00c6, 0x20a9,
+	0x007f, 0x2009, 0x0000, 0x0016, 0x080c, 0x4cdc, 0x1118, 0x6000,
+	0xd0ec, 0x1138, 0x001e, 0x8108, 0x1f04, 0x125b, 0x00ce, 0x015e,
+	0x0028, 0x001e, 0x00ce, 0x015e, 0x0804, 0x12ca, 0x0006, 0x0016,
+	0x2001, 0x0103, 0x2009, 0xaf8c, 0x210c, 0x2102, 0x001e, 0x000e,
+	0xa006, 0x2009, 0x0700, 0x20a9, 0x0002, 0x20a1, 0xafb5, 0x40a1,
+	0x706c, 0x8007, 0x7170, 0x810f, 0x20a9, 0x0002, 0x40a1, 0x2009,
+	0x0000, 0x080c, 0x14dc, 0x2001, 0x0000, 0x810f, 0x20a9, 0x0002,
+	0x40a1, 0xa006, 0x2009, 0x0200, 0x20a9, 0x0002, 0x20a1, 0xafc5,
+	0x40a1, 0x7030, 0xc08c, 0x7032, 0x7003, 0x0003, 0x709b, 0xffff,
+	0x080c, 0x1562, 0xa006, 0x080c, 0x261e, 0x080c, 0x3cce, 0x00f6,
+	0x2079, 0x0100, 0x080c, 0x5775, 0x0150, 0x080c, 0x574f, 0x7828,
+	0x0118, 0xa084, 0xe1ff, 0x0010, 0xa084, 0xffdf, 0x782a, 0x00fe,
+	0x2001, 0xafc8, 0x2004, 0xa086, 0x0005, 0x1120, 0x2011, 0x0000,
+	0x080c, 0x7adf, 0x2011, 0x0000, 0x080c, 0x7ae9, 0x080c, 0x6c50,
+	0x080c, 0x6d0d, 0x012e, 0x0005, 0x0016, 0x0046, 0x00f6, 0x0126,
+	0x2091, 0x8000, 0x2079, 0x0100, 0x2009, 0xad33, 0x2104, 0xa005,
+	0x1110, 0x080c, 0x2770, 0x2009, 0x00f7, 0x080c, 0x48de, 0x7940,
+	0xa18c, 0x0010, 0x7942, 0x7924, 0xd1b4, 0x0110, 0x7827, 0x0040,
+	0xd19c, 0x0110, 0x7827, 0x0008, 0x0006, 0x0036, 0x0156, 0x7954,
+	0xd1ac, 0x1904, 0x133a, 0x080c, 0x5761, 0x0158, 0x080c, 0x5775,
+	0x1128, 0x2001, 0xaf9d, 0x2003, 0x0000, 0x0070, 0x080c, 0x5757,
+	0x0dc0, 0x2001, 0xaf9d, 0x2003, 0xaaaa, 0x2001, 0xaf9e, 0x2003,
+	0x0001, 0x080c, 0x569a, 0x0058, 0x080c, 0x574f, 0x0140, 0x2009,
+	0x00f8, 0x080c, 0x48de, 0x7843, 0x0090, 0x7843, 0x0010, 0x20a9,
+	0x09c4, 0x7820, 0xd09c, 0x1138, 0x080c, 0x574f, 0x0138, 0x7824,
+	0xd0ac, 0x1904, 0x13e0, 0x1f04, 0x1319, 0x0070, 0x7824, 0x080c,
+	0x576b, 0x0118, 0xd0ac, 0x1904, 0x13e0, 0xa084, 0x1800, 0x0d98,
+	0x7003, 0x0001, 0x0804, 0x13e0, 0x2001, 0x0001, 0x080c, 0x261e,
+	0x0804, 0x13ef, 0x7850, 0xa084, 0x0180, 0x7852, 0x782f, 0x0020,
+	0x20a9, 0x0046, 0x1d04, 0x1342, 0x2091, 0x6000, 0x1f04, 0x1342,
+	0x7850, 0xa084, 0x0180, 0xa085, 0x0400, 0x7852, 0x782f, 0x0000,
+	0x080c, 0x5761, 0x0158, 0x080c, 0x5775, 0x1128, 0x2001, 0xaf9d,
+	0x2003, 0x0000, 0x0070, 0x080c, 0x5757, 0x0dc0, 0x2001, 0xaf9d,
+	0x2003, 0xaaaa, 0x2001, 0xaf9e, 0x2003, 0x0001, 0x080c, 0x569a,
+	0x0020, 0x2009, 0x00f8, 0x080c, 0x48de, 0x20a9, 0x000e, 0xe000,
+	0x1f04, 0x136f, 0x7850, 0xa084, 0x0180, 0xa085, 0x1400, 0x7852,
+	0x080c, 0x574f, 0x0120, 0x7843, 0x0090, 0x7843, 0x0010, 0x2021,
+	0xe678, 0x2019, 0xea60, 0x7820, 0xd09c, 0x1558, 0x080c, 0x574f,
+	0x05b8, 0x7824, 0xd0ac, 0x1904, 0x13e0, 0x080c, 0x5775, 0x1508,
+	0x0046, 0x2021, 0x0190, 0x8421, 0x1df0, 0x004e, 0x8421, 0x11c8,
+	0x7827, 0x0048, 0x20a9, 0x01f4, 0x1d04, 0x139c, 0x2091, 0x6000,
+	0x1f04, 0x139c, 0x7824, 0xa084, 0x0068, 0x15a8, 0x2001, 0xaf9d,
+	0x2003, 0xaaaa, 0x2001, 0xaf9e, 0x2003, 0x0001, 0x7003, 0x0001,
+	0x0478, 0x8319, 0x1980, 0x2009, 0xad33, 0x2104, 0x8000, 0x200a,
+	0xa084, 0xfff0, 0x0120, 0x200b, 0x0000, 0x080c, 0x2770, 0x00d8,
+	0x080c, 0x5761, 0x1140, 0xa4a2, 0x0064, 0x1128, 0x080c, 0x5726,
+	0x7003, 0x0001, 0x00a8, 0x7827, 0x1800, 0xe000, 0xe000, 0x7824,
+	0x080c, 0x576b, 0x0110, 0xd0ac, 0x1158, 0xa084, 0x1800, 0x09c8,
+	0x7003, 0x0001, 0x0028, 0x2001, 0x0001, 0x080c, 0x261e, 0x0048,
+	0x2001, 0xad33, 0x2003, 0x0000, 0x7827, 0x0048, 0x7828, 0xc09d,
+	0x782a, 0x7850, 0xa084, 0x0180, 0xa085, 0x0400, 0x7852, 0x015e,
+	0x003e, 0x000e, 0x080c, 0x1539, 0x012e, 0x00fe, 0x004e, 0x001e,
+	0x0005, 0x0005, 0x0005, 0x0005, 0x2a70, 0x2001, 0xaf9d, 0x2003,
+	0x0000, 0x7087, 0x0000, 0x2009, 0x0100, 0x2104, 0xa082, 0x0002,
+	0x0218, 0x704f, 0xffff, 0x0010, 0x704f, 0x0000, 0x7057, 0xffff,
+	0x706f, 0x0000, 0x7073, 0x0000, 0x080c, 0x9937, 0x2061, 0xaf8d,
+	0x6003, 0x0909, 0x6007, 0x0000, 0x600b, 0x8800, 0x600f, 0x0200,
+	0x6013, 0x00ff, 0x6017, 0x0003, 0x601b, 0x0000, 0x601f, 0x07d0,
+	0x2061, 0xaf95, 0x6003, 0x8000, 0x6007, 0x0000, 0x600b, 0x0000,
+	0x600f, 0x0200, 0x6013, 0x00ff, 0x6017, 0x0000, 0x601b, 0x0001,
+	0x601f, 0x0000, 0x2061, 0xafa6, 0x6003, 0x514c, 0x6007, 0x4f47,
+	0x600b, 0x4943, 0x600f, 0x2020, 0x2001, 0xad27, 0x2003, 0x0000,
+	0x0005, 0x04a0, 0x2011, 0x0000, 0x81ff, 0x0570, 0xa186, 0x0001,
+	0x1148, 0x2031, 0x8fff, 0x2039, 0xcc01, 0x2021, 0x0100, 0x2029,
+	0xcc00, 0x00e8, 0xa186, 0x0002, 0x1118, 0x2011, 0x0000, 0x00b8,
+	0xa186, 0x0005, 0x1118, 0x2011, 0x0001, 0x0088, 0xa186, 0x0009,
+	0x1118, 0x2011, 0x0002, 0x0058, 0xa186, 0x000a, 0x1118, 0x2011,
+	0x0002, 0x0028, 0xa186, 0x0055, 0x1110, 0x2011, 0x0003, 0x3800,
+	0xa084, 0xfffc, 0xa205, 0x20c0, 0x0804, 0x104d, 0xa00e, 0x2011,
+	0x0003, 0x2019, 0x1485, 0x0804, 0x14d6, 0x2019, 0xaaaa, 0x2061,
+	0xffff, 0x2c14, 0x2362, 0xe000, 0xe000, 0x2c04, 0xa306, 0x2262,
+	0x1110, 0xc1b5, 0xc1a5, 0x2011, 0x0000, 0x2019, 0x1498, 0x04f0,
+	0x2019, 0xaaaa, 0x2061, 0xffff, 0x2c14, 0x2362, 0xe000, 0xe000,
+	0x2c1c, 0x2061, 0x7fff, 0xe000, 0xe000, 0x2c04, 0x2061, 0xffff,
+	0x2262, 0xa306, 0x0110, 0xc18d, 0x0008, 0xc185, 0x2011, 0x0002,
+	0x2019, 0x14b3, 0x0418, 0x2061, 0xffff, 0x2019, 0xaaaa, 0x2c14,
+	0x2362, 0xe000, 0xe000, 0x2c04, 0x2262, 0xa306, 0x1180, 0x2c14,
+	0x2362, 0xe000, 0xe000, 0x2c1c, 0x2061, 0x7fff, 0x2c04, 0x2061,
+	0xffff, 0x2262, 0xa306, 0x1110, 0xc195, 0x0008, 0xc19d, 0x2011,
+	0x0001, 0x2019, 0x14d4, 0x0010, 0x0804, 0x144a, 0x3800, 0xa084,
+	0xfffc, 0xa205, 0x20c0, 0x0837, 0x2011, 0x0000, 0x080c, 0x4cdc,
+	0x1178, 0x6004, 0xa0c4, 0x00ff, 0xa8c6, 0x0006, 0x0128, 0xa0c4,
+	0xff00, 0xa8c6, 0x0600, 0x1120, 0xa186, 0x0080, 0x0108, 0x8210,
+	0x8108, 0xa186, 0x0100, 0x1d50, 0x2208, 0x0005, 0x2091, 0x8000,
+	0x0e04, 0x14f8, 0x0006, 0x0016, 0x2079, 0x0000, 0x7818, 0xd084,
+	0x1de8, 0x001e, 0x792e, 0x000e, 0x782a, 0x000e, 0x7826, 0x3900,
+	0x783a, 0x7823, 0x8002, 0x781b, 0x0001, 0x2091, 0x5000, 0x0126,
+	0x0156, 0x0146, 0x20a9, 0x0010, 0x20a1, 0xb0c8, 0x2091, 0x2000,
+	0x40a1, 0x20a9, 0x0010, 0x2091, 0x2200, 0x40a1, 0x20a9, 0x0010,
+	0x2091, 0x2400, 0x40a1, 0x20a9, 0x0010, 0x2091, 0x2600, 0x40a1,
+	0x20a9, 0x0010, 0x2091, 0x2800, 0x40a1, 0x014e, 0x015e, 0x012e,
+	0x2079, 0xad00, 0x7803, 0x0005, 0x2091, 0x4080, 0x04c9, 0x0cf8,
+	0x0005, 0x0006, 0x080c, 0x1584, 0x1518, 0x00f6, 0x2079, 0xad23,
+	0x2f04, 0x8000, 0x207a, 0xa082, 0x000f, 0x0258, 0xa006, 0x207a,
+	0x2079, 0xad25, 0x2f04, 0xa084, 0x0001, 0xa086, 0x0001, 0x207a,
+	0x0070, 0x2079, 0xad25, 0x2f7c, 0x8fff, 0x1128, 0x2001, 0x0c03,
+	0x2003, 0x0040, 0x0020, 0x2001, 0x0c03, 0x2003, 0x00c0, 0x00fe,
+	0x000e, 0x0005, 0x0409, 0x1120, 0x2001, 0x0c03, 0x2003, 0x0080,
+	0x0005, 0x00d1, 0x1120, 0x2001, 0x0c03, 0x2003, 0x0040, 0x0005,
+	0x0006, 0x0091, 0x1178, 0x2001, 0x0c03, 0x2003, 0x0040, 0x2009,
+	0x0fff, 0x00a1, 0x2001, 0x0c03, 0x2003, 0x0080, 0x2009, 0x0fff,
+	0x0069, 0x0c88, 0x000e, 0x0005, 0x00c6, 0x2061, 0x0c00, 0x2c04,
+	0xa084, 0x00ff, 0xa086, 0x00aa, 0x00ce, 0x0005, 0x0156, 0x0126,
+	0xa18c, 0x0fff, 0x21a8, 0x1d04, 0x1593, 0x2091, 0x6000, 0x1f04,
+	0x1593, 0x012e, 0x015e, 0x0005, 0x2071, 0xad00, 0x715c, 0x712e,
+	0x2021, 0x0001, 0xa190, 0x0030, 0xa298, 0x0030, 0x0240, 0x7060,
+	0xa302, 0x1228, 0x220a, 0x2208, 0x2310, 0x8420, 0x0ca8, 0x3800,
+	0xd08c, 0x0148, 0x7060, 0xa086, 0xad00, 0x0128, 0x7063, 0xad00,
+	0x2011, 0x1000, 0x0c48, 0x200b, 0x0000, 0x74ae, 0x74b2, 0x0005,
+	0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0xad00, 0x70b0, 0xa0ea,
+	0x0010, 0x0268, 0x8001, 0x70b2, 0x702c, 0x2068, 0x2d04, 0x702e,
+	0x206b, 0x0000, 0x6807, 0x0000, 0x012e, 0x00ee, 0x0005, 0xa06e,
+	0x0cd8, 0x00e6, 0x2071, 0xad00, 0x0126, 0x2091, 0x8000, 0x70b0,
+	0x8001, 0x0260, 0x70b2, 0x702c, 0x2068, 0x2d04, 0x702e, 0x206b,
+	0x0000, 0x6807, 0x0000, 0x012e, 0x00ee, 0x0005, 0xa06e, 0x0cd8,
+	0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0xad00, 0x702c, 0x206a,
+	0x2d00, 0x702e, 0x70b0, 0x8000, 0x70b2, 0x012e, 0x00ee, 0x0005,
+	0x8dff, 0x0138, 0x6804, 0x6807, 0x0000, 0x0006, 0x0c49, 0x00de,
+	0x0cb8, 0x0005, 0x00e6, 0x2071, 0xad00, 0x70b0, 0xa08a, 0x0010,
+	0xa00d, 0x00ee, 0x0005, 0x00e6, 0x2071, 0xafec, 0x7007, 0x0000,
+	0x701b, 0x0000, 0x701f, 0x0000, 0x2071, 0x0000, 0x7010, 0xa085,
+	0x8004, 0x7012, 0x00ee, 0x0005, 0x00e6, 0x2270, 0x700b, 0x0000,
+	0x2071, 0xafec, 0x7018, 0xa088, 0xaff5, 0x220a, 0x8000, 0xa084,
+	0x0007, 0x701a, 0x7004, 0xa005, 0x1128, 0x00f6, 0x2079, 0x0010,
+	0x0081, 0x00fe, 0x00ee, 0x0005, 0x00e6, 0x2071, 0xafec, 0x7004,
+	0xa005, 0x1128, 0x00f6, 0x2079, 0x0010, 0x0019, 0x00fe, 0x00ee,
+	0x0005, 0x7000, 0x0002, 0x164f, 0x16b3, 0x16d0, 0x16d0, 0x7018,
+	0x711c, 0xa106, 0x1118, 0x7007, 0x0000, 0x0005, 0x00d6, 0xa180,
+	0xaff5, 0x2004, 0x700a, 0x2068, 0x8108, 0xa18c, 0x0007, 0x711e,
+	0x7803, 0x0026, 0x6824, 0x7832, 0x6828, 0x7836, 0x682c, 0x783a,
+	0x6830, 0x783e, 0x6810, 0x700e, 0x680c, 0x7016, 0x6804, 0x00de,
+	0xd084, 0x0120, 0x7007, 0x0001, 0x0029, 0x0005, 0x7007, 0x0002,
+	0x00b1, 0x0005, 0x0016, 0x0026, 0x710c, 0x2011, 0x0040, 0xa182,
+	0x0040, 0x1210, 0x2110, 0xa006, 0x700e, 0x7212, 0x8203, 0x7822,
+	0x7803, 0x0020, 0x7803, 0x0041, 0x002e, 0x001e, 0x0005, 0x0016,
+	0x0026, 0x0136, 0x0146, 0x0156, 0x7014, 0x2098, 0x20a1, 0x0014,
+	0x7803, 0x0026, 0x710c, 0x2011, 0x0040, 0xa182, 0x0040, 0x1210,
+	0x2110, 0xa006, 0x700e, 0x22a8, 0x53a6, 0x8203, 0x7822, 0x7803,
+	0x0020, 0x3300, 0x7016, 0x7803, 0x0001, 0x015e, 0x014e, 0x013e,
+	0x002e, 0x001e, 0x0005, 0x0136, 0x0146, 0x0156, 0x2099, 0xadf9,
+	0x20a1, 0x0018, 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x0126,
+	0x2091, 0x8000, 0x7803, 0x0041, 0x7007, 0x0003, 0x7000, 0xc084,
+	0x7002, 0x700b, 0xadf4, 0x012e, 0x015e, 0x014e, 0x013e, 0x0005,
+	0x0136, 0x0146, 0x0156, 0x2001, 0xae28, 0x209c, 0x20a1, 0x0014,
+	0x7803, 0x0026, 0x2001, 0xae29, 0x20ac, 0x53a6, 0x2099, 0xae2a,
+	0x20a1, 0x0018, 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x0126,
+	0x2091, 0x8000, 0x7803, 0x0001, 0x7007, 0x0004, 0x7000, 0xc08c,
+	0x7002, 0x700b, 0xae25, 0x012e, 0x015e, 0x014e, 0x013e, 0x0005,
+	0x0016, 0x00e6, 0x2071, 0xafec, 0x00f6, 0x2079, 0x0010, 0x7904,
+	0x7803, 0x0002, 0xd1fc, 0x0120, 0xa18c, 0x0700, 0x7004, 0x0023,
+	0x00fe, 0x00ee, 0x001e, 0x0005, 0x1649, 0x1713, 0x1741, 0x176b,
+	0x179b, 0x1712, 0x0cf8, 0xa18c, 0x0700, 0x1528, 0x0136, 0x0146,
+	0x0156, 0x7014, 0x20a0, 0x2099, 0x0014, 0x7803, 0x0040, 0x7010,
+	0x20a8, 0x53a5, 0x3400, 0x7016, 0x015e, 0x014e, 0x013e, 0x700c,
+	0xa005, 0x0570, 0x7830, 0x7832, 0x7834, 0x7836, 0x080c, 0x167a,
+	0x0005, 0x7008, 0xa080, 0x0002, 0x2003, 0x0100, 0x7007, 0x0000,
+	0x080c, 0x1649, 0x0005, 0x7008, 0xa080, 0x0002, 0x2003, 0x0200,
+	0x0ca8, 0xa18c, 0x0700, 0x1150, 0x700c, 0xa005, 0x0188, 0x7830,
+	0x7832, 0x7834, 0x7836, 0x080c, 0x168f, 0x0005, 0x7008, 0xa080,
+	0x0002, 0x2003, 0x0200, 0x7007, 0x0000, 0x080c, 0x1649, 0x0005,
+	0x00d6, 0x7008, 0x2068, 0x7830, 0x6826, 0x7834, 0x682a, 0x7838,
+	0x682e, 0x783c, 0x6832, 0x680b, 0x0100, 0x00de, 0x7007, 0x0000,
+	0x080c, 0x1649, 0x0005, 0xa18c, 0x0700, 0x1540, 0x0136, 0x0146,
+	0x0156, 0x2001, 0xadf7, 0x2004, 0xa080, 0x000d, 0x20a0, 0x2099,
+	0x0014, 0x7803, 0x0040, 0x20a9, 0x0020, 0x53a5, 0x2001, 0xadf9,
+	0x2004, 0xd0bc, 0x0148, 0x2001, 0xae02, 0x2004, 0xa080, 0x000d,
+	0x20a0, 0x20a9, 0x0020, 0x53a5, 0x015e, 0x014e, 0x013e, 0x7007,
+	0x0000, 0x080c, 0x5ae6, 0x080c, 0x1649, 0x0005, 0x2011, 0x8003,
+	0x080c, 0x3c5c, 0x0cf8, 0xa18c, 0x0700, 0x1148, 0x2001, 0xae27,
+	0x2003, 0x0100, 0x7007, 0x0000, 0x080c, 0x1649, 0x0005, 0x2011,
+	0x8004, 0x080c, 0x3c5c, 0x0cf8, 0x0126, 0x2091, 0x2200, 0x2079,
+	0x0030, 0x2071, 0xaffd, 0x7003, 0x0000, 0x700f, 0xb003, 0x7013,
+	0xb003, 0x780f, 0x00f6, 0x7803, 0x0004, 0x012e, 0x0005, 0x6934,
+	0xa184, 0x0007, 0x0002, 0x17cb, 0x1809, 0x17cb, 0x17cb, 0x17cb,
+	0x17f1, 0x17d8, 0x17cf, 0xa085, 0x0001, 0x0804, 0x1823, 0x684c,
+	0xd0bc, 0x0dc8, 0x6860, 0x682e, 0x685c, 0x682a, 0x6858, 0x04c8,
+	0xa18c, 0x00ff, 0xa186, 0x001e, 0x1d70, 0x684c, 0xd0bc, 0x0d58,
+	0x6860, 0x682e, 0x685c, 0x682a, 0x6804, 0x681a, 0xa080, 0x000d,
+	0x2004, 0xa084, 0x000f, 0xa080, 0x2186, 0x2005, 0x6832, 0x6858,
+	0x0440, 0xa18c, 0x00ff, 0xa186, 0x0015, 0x19a8, 0x684c, 0xd0ac,
+	0x0990, 0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f,
+	0xa080, 0x2186, 0x2005, 0x6832, 0xa006, 0x682e, 0x682a, 0x6858,
+	0x0080, 0x684c, 0xd0ac, 0x0904, 0x17cb, 0xa006, 0x682e, 0x682a,
+	0x6858, 0xa18c, 0x000f, 0xa188, 0x2186, 0x210d, 0x6932, 0x2d08,
+	0x691a, 0x6826, 0x684c, 0xc0dd, 0x684e, 0xa006, 0x680a, 0x697c,
+	0x6912, 0x6980, 0x6916, 0x0005, 0x20e1, 0x0007, 0x20e1, 0x2000,
+	0x2001, 0x020a, 0x2004, 0x82ff, 0x01a8, 0xa280, 0x0004, 0x00d6,
+	0x206c, 0x684c, 0xd0dc, 0x1150, 0x080c, 0x17bf, 0x0138, 0x00de,
+	0xa280, 0x0000, 0x2003, 0x0002, 0xa016, 0x0020, 0x6808, 0x8000,
+	0x680a, 0x00de, 0x0126, 0x0046, 0x0036, 0x0026, 0x2091, 0x2200,
+	0x002e, 0x003e, 0x004e, 0x7000, 0xa005, 0x01d0, 0x710c, 0x220a,
+	0x8108, 0x230a, 0x8108, 0x240a, 0x8108, 0xa182, 0xb01e, 0x0210,
+	0x2009, 0xb003, 0x710e, 0x7010, 0xa102, 0xa082, 0x0009, 0x0118,
+	0xa080, 0x001b, 0x1118, 0x2009, 0x0138, 0x200a, 0x012e, 0x0005,
+	0x7206, 0x2001, 0x1866, 0x0006, 0x2260, 0x0804, 0x197a, 0x0126,
+	0x0026, 0x0036, 0x00c6, 0x0006, 0x2091, 0x2200, 0x000e, 0x004e,
+	0x003e, 0x002e, 0x00d6, 0x00c6, 0x2460, 0x6110, 0x2168, 0x6a62,
+	0x6b5e, 0xa005, 0x0904, 0x18c8, 0x6808, 0xa005, 0x0904, 0x18ff,
+	0x7000, 0xa005, 0x1108, 0x0488, 0x700c, 0x7110, 0xa106, 0x1904,
+	0x1907, 0x7004, 0xa406, 0x1548, 0x2001, 0x0005, 0x2004, 0xd08c,
+	0x0168, 0x0046, 0x080c, 0x1a6c, 0x004e, 0x2460, 0x6010, 0xa080,
+	0x0002, 0x2004, 0xa005, 0x0904, 0x18ff, 0x0c10, 0x2001, 0x0207,
+	0x2004, 0xd09c, 0x1d48, 0x7804, 0xa084, 0x6000, 0x0120, 0xa086,
+	0x6000, 0x0108, 0x0c08, 0x7818, 0x6812, 0x781c, 0x6816, 0x7803,
+	0x0004, 0x7003, 0x0000, 0x7004, 0x2060, 0x6100, 0xa18e, 0x0004,
+	0x1904, 0x1907, 0x2009, 0x0048, 0x080c, 0x80a7, 0x0804, 0x1907,
+	0x6808, 0xa005, 0x05a0, 0x7000, 0xa005, 0x0588, 0x700c, 0x7110,
+	0xa106, 0x1118, 0x7004, 0xa406, 0x1550, 0x2001, 0x0005, 0x2004,
+	0xd08c, 0x0160, 0x0046, 0x080c, 0x1a6c, 0x004e, 0x2460, 0x6010,
+	0xa080, 0x0002, 0x2004, 0xa005, 0x01d0, 0x0c28, 0x2001, 0x0207,
+	0x2004, 0xd09c, 0x1d50, 0x2001, 0x0005, 0x2004, 0xd08c, 0x1d50,
+	0x7804, 0xa084, 0x6000, 0x0118, 0xa086, 0x6000, 0x19f0, 0x7818,
+	0x6812, 0x781c, 0x6816, 0x7803, 0x0004, 0x7003, 0x0000, 0x6100,
+	0xa18e, 0x0004, 0x1120, 0x2009, 0x0048, 0x080c, 0x80a7, 0x00ce,
+	0x00de, 0x012e, 0x0005, 0x00f6, 0x00e6, 0x0026, 0x0036, 0x0046,
+	0x0056, 0x080c, 0x1d86, 0x0026, 0x0056, 0x2071, 0xaffd, 0x7000,
+	0xa086, 0x0000, 0x0580, 0x7004, 0xac06, 0x11f8, 0x2079, 0x0030,
+	0x7000, 0xa086, 0x0003, 0x01c8, 0x7804, 0xd0fc, 0x1198, 0x2001,
+	0x0207, 0x2004, 0xd09c, 0x1dc0, 0x7803, 0x0004, 0x7804, 0xd0ac,
+	0x1de8, 0x7803, 0x0002, 0x7803, 0x0009, 0x7003, 0x0003, 0x7007,
+	0x0000, 0x0018, 0x080c, 0x1a6c, 0x08d0, 0x0156, 0x20a9, 0x0009,
+	0x2009, 0xb003, 0x2104, 0xac06, 0x1108, 0x200a, 0xa188, 0x0003,
+	0x1f04, 0x1942, 0x015e, 0x005e, 0x002e, 0x2001, 0x015d, 0x201c,
+	0x831a, 0x2302, 0x2001, 0x0160, 0x2502, 0x2001, 0x0138, 0x2202,
+	0x005e, 0x004e, 0x003e, 0x002e, 0x00ee, 0x00fe, 0x0005, 0x700c,
+	0x7110, 0xa106, 0x0904, 0x19dd, 0x2104, 0x7006, 0x2060, 0x8108,
+	0x211c, 0x8108, 0x2124, 0x8108, 0xa182, 0xb01e, 0x0210, 0x2009,
+	0xb003, 0x7112, 0x700c, 0xa106, 0x1128, 0x080c, 0x2744, 0x2001,
+	0x0138, 0x2102, 0x8cff, 0x0588, 0x6010, 0x2068, 0x2d58, 0x6828,
+	0xa406, 0x1580, 0x682c, 0xa306, 0x1568, 0x7004, 0x2060, 0x6020,
+	0xc0d4, 0x6022, 0x684c, 0xd0f4, 0x0128, 0x6817, 0xffff, 0x6813,
+	0xffff, 0x00d8, 0x6850, 0xd0f4, 0x1130, 0x7803, 0x0004, 0x6810,
+	0x781a, 0x6814, 0x781e, 0x6824, 0x2050, 0x6818, 0x2060, 0x6830,
+	0x2040, 0x6034, 0xa0cc, 0x000f, 0x2009, 0x0011, 0x04c9, 0x0118,
+	0x2009, 0x0001, 0x04a9, 0x2d58, 0x0005, 0x080c, 0x1ced, 0x0904,
+	0x195f, 0x0cd0, 0x6020, 0xd0d4, 0x01b8, 0x6038, 0xa402, 0x6034,
+	0xa303, 0x0108, 0x1288, 0x643a, 0x6336, 0x6c2a, 0x6b2e, 0x0046,
+	0x0036, 0x2400, 0x6c7c, 0xa402, 0x6812, 0x2300, 0x6b80, 0xa303,
+	0x6816, 0x003e, 0x004e, 0x0018, 0x080c, 0x98cb, 0x09f0, 0x601c,
+	0xa08e, 0x0008, 0x0904, 0x1985, 0xa08e, 0x000a, 0x0904, 0x1985,
+	0x080c, 0x21a6, 0x1990, 0x0804, 0x1985, 0x7003, 0x0000, 0x0005,
+	0x8aff, 0x0904, 0x1a46, 0xa03e, 0x2730, 0x6850, 0xd0fc, 0x11b8,
+	0xd0f4, 0x1528, 0x00d6, 0x2805, 0xac68, 0x2900, 0x0002, 0x1a30,
+	0x1a15, 0x1a15, 0x1a30, 0x1a30, 0x1a29, 0x1a30, 0x1a15, 0x1a30,
+	0x1a1a, 0x1a1a, 0x1a30, 0x1a30, 0x1a30, 0x1a21, 0x1a1a, 0x7803,
+	0x0004, 0xc0fc, 0x6852, 0x6b6c, 0x6a70, 0x6d1c, 0x6c20, 0x00d6,
+	0xd99c, 0x0548, 0x2805, 0xac68, 0x6f08, 0x6e0c, 0x0420, 0xc0f4,
+	0x6852, 0x6b6c, 0x6a70, 0x00d6, 0x0428, 0x6b08, 0x6a0c, 0x6d00,
+	0x6c04, 0x00c8, 0x6b10, 0x6a14, 0x6d00, 0x6c04, 0x6f08, 0x6e0c,
+	0x0090, 0x00de, 0x00d6, 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e,
+	0x1138, 0x00de, 0x080c, 0x2148, 0x1904, 0x19e0, 0xa00e, 0x00b0,
+	0x00de, 0x080c, 0x14f6, 0x7b22, 0x7a26, 0x7d32, 0x7c36, 0x7f3a,
+	0x7e3e, 0x7902, 0x7000, 0x8000, 0x7002, 0x00de, 0x6828, 0xa300,
+	0x682a, 0x682c, 0xa201, 0x682e, 0x080c, 0x2148, 0x0005, 0x080c,
+	0x14f6, 0x080c, 0x1e1a, 0x7004, 0x2060, 0x00d6, 0x6010, 0x2068,
+	0x7003, 0x0000, 0x080c, 0x1d22, 0x080c, 0x9596, 0x0170, 0x6808,
+	0x8001, 0x680a, 0x697c, 0x6912, 0x6980, 0x6916, 0x682b, 0xffff,
+	0x682f, 0xffff, 0x6850, 0xc0bd, 0x6852, 0x00de, 0x080c, 0x929c,
+	0x0804, 0x1c5e, 0x080c, 0x14f6, 0x0126, 0x2091, 0x2200, 0x0006,
+	0x0016, 0x2b68, 0x6818, 0x2060, 0x7904, 0x7803, 0x0002, 0xa184,
+	0x0700, 0x1978, 0xa184, 0x0003, 0xa086, 0x0003, 0x0d58, 0x7000,
+	0x0002, 0x1a89, 0x1a8f, 0x1b92, 0x1c39, 0x1c4d, 0x1a89, 0x1a89,
+	0x1a89, 0x7804, 0xd09c, 0x1904, 0x1c5e, 0x080c, 0x14f6, 0x8001,
+	0x7002, 0xa184, 0x0880, 0x1190, 0xd19c, 0x1904, 0x1b20, 0x8aff,
+	0x0904, 0x1b20, 0x2009, 0x0001, 0x080c, 0x19e0, 0x0904, 0x1c5e,
+	0x2009, 0x0001, 0x080c, 0x19e0, 0x0804, 0x1c5e, 0x7803, 0x0004,
+	0x7003, 0x0000, 0xd1bc, 0x1904, 0x1b00, 0x0026, 0x0036, 0x7c20,
+	0x7d24, 0x7e30, 0x7f34, 0x7818, 0x6812, 0x781c, 0x6816, 0x2001,
+	0x0201, 0x2004, 0xa005, 0x0140, 0x7808, 0xd0ec, 0x1128, 0x7803,
+	0x0009, 0x7003, 0x0004, 0x0010, 0x080c, 0x1c62, 0x6b28, 0x6a2c,
+	0x2400, 0x686e, 0xa31a, 0x2500, 0x6872, 0xa213, 0x6b2a, 0x6a2e,
+	0x00c6, 0x7004, 0x2060, 0x6020, 0xd0f4, 0x1110, 0x633a, 0x6236,
+	0x00ce, 0x003e, 0x002e, 0x6e1e, 0x6f22, 0x080c, 0x215e, 0x2a00,
+	0x6826, 0x2c00, 0x681a, 0x2800, 0x6832, 0x6850, 0xc0fd, 0x6852,
+	0x6808, 0x8001, 0x680a, 0x1148, 0x684c, 0xd0e4, 0x0130, 0x7004,
+	0x2060, 0x2009, 0x0048, 0x080c, 0x80a7, 0x7000, 0xa086, 0x0004,
+	0x0904, 0x1c5e, 0x7003, 0x0000, 0x080c, 0x195f, 0x0804, 0x1c5e,
+	0x0056, 0x7d0c, 0xd5bc, 0x1110, 0x080c, 0xac73, 0x005e, 0x080c,
+	0x1d22, 0x00f6, 0x7004, 0x2078, 0x080c, 0x5029, 0x0118, 0x7820,
+	0xc0f5, 0x7822, 0x00fe, 0x682b, 0xffff, 0x682f, 0xffff, 0x6808,
+	0x8001, 0x680a, 0x697c, 0x791a, 0x6980, 0x791e, 0x0804, 0x1c5e,
+	0x7004, 0x00c6, 0x2060, 0x6020, 0x00ce, 0xd0f4, 0x0128, 0x6808,
+	0x8001, 0x680a, 0x0804, 0x1c5e, 0x7818, 0x6812, 0x7a1c, 0x6a16,
+	0xd19c, 0x0160, 0xa205, 0x0150, 0x7004, 0xa080, 0x0007, 0x2004,
+	0xa084, 0xfffd, 0xa086, 0x0008, 0x1904, 0x1aa6, 0x684c, 0xc0f5,
+	0x684e, 0x7814, 0xa005, 0x1180, 0x7003, 0x0000, 0x6808, 0x8001,
+	0x680a, 0x1130, 0x7004, 0x2060, 0x2009, 0x0048, 0x080c, 0x80a7,
+	0x080c, 0x195f, 0x0804, 0x1c5e, 0x7818, 0x6812, 0x781c, 0x6816,
+	0x7814, 0x7908, 0xa18c, 0x0fff, 0xa188, 0x0007, 0x8114, 0x8214,
+	0x8214, 0xa10a, 0x8104, 0x8004, 0x8004, 0xa20a, 0x810b, 0x810b,
+	0x810b, 0x080c, 0x1da5, 0x7803, 0x0004, 0x780f, 0xffff, 0x7803,
+	0x0001, 0x7804, 0xd0fc, 0x0de8, 0x7803, 0x0002, 0x7803, 0x0004,
+	0x780f, 0x00f6, 0x7004, 0x7007, 0x0000, 0x2060, 0x2009, 0x0048,
+	0x080c, 0x80a7, 0x080c, 0x1dd7, 0x0958, 0x7908, 0xd1ec, 0x1118,
+	0x2009, 0x0009, 0x0010, 0x2009, 0x0019, 0x7902, 0x7003, 0x0003,
+	0x0804, 0x1c5e, 0x8001, 0x7002, 0xd194, 0x01a8, 0x7804, 0xd0fc,
+	0x1904, 0x1c2c, 0xd09c, 0x0130, 0x7804, 0xd0fc, 0x1904, 0x1a74,
+	0xd09c, 0x11a8, 0x8aff, 0x0904, 0x1c5e, 0x2009, 0x0001, 0x080c,
+	0x19e0, 0x0804, 0x1c5e, 0xa184, 0x0888, 0x1148, 0x8aff, 0x0904,
+	0x1c5e, 0x2009, 0x0001, 0x080c, 0x19e0, 0x0804, 0x1c5e, 0x7818,
+	0x6812, 0x7a1c, 0x6a16, 0xa205, 0x0904, 0x1b3e, 0x7803, 0x0004,
+	0x7003, 0x0000, 0xd1bc, 0x1904, 0x1c0f, 0x6834, 0xa084, 0x00ff,
+	0xa086, 0x0029, 0x1118, 0xd19c, 0x1904, 0x1b3e, 0x0026, 0x0036,
+	0x7c20, 0x7d24, 0x7e30, 0x7f34, 0x7818, 0x6812, 0x781c, 0x6816,
+	0x2001, 0x0201, 0x2004, 0xa005, 0x0140, 0x7808, 0xd0ec, 0x1128,
+	0x7803, 0x0009, 0x7003, 0x0004, 0x0020, 0x0016, 0x080c, 0x1c62,
+	0x001e, 0x6b28, 0x6a2c, 0x080c, 0x215e, 0x00d6, 0x2805, 0xac68,
+	0x6034, 0xd09c, 0x1128, 0x6808, 0xa31a, 0x680c, 0xa213, 0x0020,
+	0x6810, 0xa31a, 0x6814, 0xa213, 0x00de, 0xd194, 0x0904, 0x1ac8,
+	0x2a00, 0x6826, 0x2c00, 0x681a, 0x2800, 0x6832, 0x6808, 0x8001,
+	0x680a, 0x6b2a, 0x6a2e, 0x003e, 0x002e, 0x0804, 0x1b50, 0x0056,
+	0x7d0c, 0x080c, 0xac73, 0x005e, 0x080c, 0x1d22, 0x00f6, 0x7004,
+	0x2078, 0x080c, 0x5029, 0x0118, 0x7820, 0xc0f5, 0x7822, 0x00fe,
+	0x682b, 0xffff, 0x682f, 0xffff, 0x6808, 0x8001, 0x680a, 0x697c,
+	0x791a, 0x6980, 0x791e, 0x0490, 0x7804, 0xd09c, 0x0904, 0x1a74,
+	0x7c20, 0x7824, 0xa405, 0x1904, 0x1a74, 0x7803, 0x0002, 0x0804,
+	0x1bb7, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, 0xa00d, 0x0150,
+	0x6808, 0x8001, 0x680a, 0x1130, 0x7004, 0x2060, 0x2009, 0x0048,
+	0x080c, 0x80a7, 0x080c, 0x195f, 0x0088, 0x7803, 0x0004, 0x7003,
+	0x0000, 0x7004, 0x2060, 0x6010, 0xa005, 0x0da0, 0x2068, 0x6808,
+	0x8000, 0x680a, 0x6c28, 0x6b2c, 0x080c, 0x197a, 0x001e, 0x000e,
+	0x012e, 0x0005, 0x700c, 0x7110, 0xa106, 0x0904, 0x1ce1, 0x7004,
+	0x0016, 0x210c, 0xa106, 0x001e, 0x0904, 0x1ce1, 0x00d6, 0x00c6,
+	0x216c, 0x2d00, 0xa005, 0x0904, 0x1cdf, 0x6820, 0xd0d4, 0x1904,
+	0x1cdf, 0x6810, 0x2068, 0x6850, 0xd0fc, 0x0558, 0x8108, 0x2104,
+	0x6b2c, 0xa306, 0x1904, 0x1cdf, 0x8108, 0x2104, 0x6a28, 0xa206,
+	0x1904, 0x1cdf, 0x6850, 0xc0fc, 0xc0f5, 0x6852, 0x686c, 0x7822,
+	0x6870, 0x7826, 0x681c, 0x7832, 0x6820, 0x7836, 0x6818, 0x2060,
+	0x6034, 0xd09c, 0x0150, 0x6830, 0x2005, 0x00d6, 0xac68, 0x6808,
+	0x783a, 0x680c, 0x783e, 0x00de, 0x04a0, 0xa006, 0x783a, 0x783e,
+	0x0480, 0x8108, 0x2104, 0xa005, 0x1590, 0x8108, 0x2104, 0xa005,
+	0x1570, 0x6850, 0xc0f5, 0x6852, 0x6830, 0x2005, 0x6918, 0xa160,
+	0xa180, 0x000d, 0x2004, 0xd09c, 0x1170, 0x6008, 0x7822, 0x686e,
+	0x600c, 0x7826, 0x6872, 0x6000, 0x7832, 0x6004, 0x7836, 0xa006,
+	0x783a, 0x783e, 0x0070, 0x6010, 0x7822, 0x686e, 0x6014, 0x7826,
+	0x6872, 0x6000, 0x7832, 0x6004, 0x7836, 0x6008, 0x783a, 0x600c,
+	0x783e, 0x6810, 0x781a, 0x6814, 0x781e, 0x7803, 0x0011, 0x00ce,
+	0x00de, 0x0005, 0x2011, 0x0201, 0x2009, 0x003c, 0x2204, 0xa005,
+	0x1118, 0x8109, 0x1dd8, 0x0005, 0x0005, 0x0ca1, 0x01e0, 0x7908,
+	0xd1ec, 0x1160, 0x080c, 0x1dd7, 0x0148, 0x7803, 0x0009, 0x7904,
+	0xd1fc, 0x0de8, 0x7803, 0x0006, 0x0c29, 0x0168, 0x780c, 0xd0a4,
+	0x1150, 0x7007, 0x0000, 0x080c, 0x1dd7, 0x0140, 0x7803, 0x0019,
+	0x7003, 0x0003, 0x0018, 0x00b1, 0xa085, 0x0001, 0x0005, 0x0126,
+	0x2091, 0x2200, 0x7000, 0xa086, 0x0003, 0x1150, 0x700c, 0x7110,
+	0xa106, 0x0130, 0x20e1, 0x9028, 0x700f, 0xb003, 0x7013, 0xb003,
+	0x012e, 0x0005, 0x00c6, 0x080c, 0x574f, 0x1550, 0x2001, 0x0160,
+	0x2003, 0x0000, 0x2001, 0x0138, 0x2003, 0x0000, 0x2011, 0x00c8,
+	0xe000, 0xe000, 0x8211, 0x1de0, 0x080c, 0x1d7e, 0x700c, 0x7110,
+	0xa106, 0x0190, 0x2104, 0xa005, 0x0130, 0x2060, 0x6010, 0x2060,
+	0x6008, 0x8001, 0x600a, 0xa188, 0x0003, 0xa182, 0xb01e, 0x0210,
+	0x2009, 0xb003, 0x7112, 0x0c50, 0x080c, 0x57d1, 0x00ce, 0x0005,
+	0x04a9, 0x20e1, 0x9028, 0x700c, 0x7110, 0xa106, 0x01d0, 0x2104,
+	0xa005, 0x0130, 0x2060, 0x6010, 0x2060, 0x6008, 0x8001, 0x600a,
+	0xa188, 0x0003, 0xa182, 0xb01e, 0x0210, 0x2009, 0xb003, 0x7112,
+	0x700c, 0xa106, 0x1d40, 0x080c, 0x2744, 0x2001, 0x0138, 0x2102,
+	0x0c10, 0x2001, 0x015d, 0x200c, 0x810a, 0x2102, 0x2001, 0x0160,
+	0x2502, 0x2001, 0x0138, 0x2202, 0x00ce, 0x0005, 0x20e1, 0x9028,
+	0x2001, 0x015d, 0x200c, 0x810a, 0x2102, 0x0005, 0x2001, 0x0138,
+	0x2014, 0x2003, 0x0000, 0x2001, 0x0160, 0x202c, 0x2003, 0x0000,
+	0x2021, 0xb015, 0x2001, 0x0141, 0x201c, 0xd3dc, 0x1168, 0x2001,
+	0x0109, 0x201c, 0xa39c, 0x0048, 0x1138, 0x2001, 0x0111, 0x201c,
+	0x83ff, 0x1110, 0x8421, 0x1d70, 0x0005, 0x00e6, 0x2071, 0x0200,
+	0x7808, 0xa084, 0xf000, 0xa10d, 0x08c9, 0x2019, 0x5000, 0x8319,
+	0x0168, 0x2001, 0xb01e, 0x2004, 0xa086, 0x0000, 0x0138, 0x2001,
+	0x0021, 0xd0fc, 0x0da0, 0x080c, 0x1ff4, 0x0c78, 0x20e1, 0x7000,
+	0x7324, 0x7420, 0x7028, 0x7028, 0x7426, 0x7037, 0x0001, 0x810f,
+	0x712e, 0x702f, 0x0100, 0x7037, 0x0008, 0x7326, 0x7422, 0x2001,
+	0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x00ee, 0x0005, 0x7908,
+	0xa18c, 0x0fff, 0xa182, 0x0009, 0x0218, 0xa085, 0x0001, 0x0088,
+	0x2001, 0x020a, 0x81ff, 0x0130, 0x20e1, 0x6000, 0x200c, 0x200c,
+	0x200c, 0x200c, 0x20e1, 0x7000, 0x200c, 0x200c, 0x7003, 0x0000,
+	0xa006, 0x0005, 0x00f6, 0x00e6, 0x0016, 0x0026, 0x2071, 0xaffd,
+	0x2079, 0x0030, 0x2011, 0x0050, 0x7000, 0xa086, 0x0000, 0x01a8,
+	0x8211, 0x0188, 0x2001, 0x0005, 0x2004, 0xd08c, 0x0dc8, 0x7904,
+	0xa18c, 0x0780, 0x0016, 0x080c, 0x1a6c, 0x001e, 0x81ff, 0x1118,
+	0x2011, 0x0050, 0x0c48, 0xa085, 0x0001, 0x002e, 0x001e, 0x00ee,
+	0x00fe, 0x0005, 0x7803, 0x0004, 0x2009, 0x0064, 0x7804, 0xd0ac,
+	0x0904, 0x1e66, 0x8109, 0x1dd0, 0x2009, 0x0100, 0x210c, 0xa18a,
+	0x0003, 0x0a0c, 0x14f6, 0x080c, 0x20f2, 0x00e6, 0x00f6, 0x2071,
+	0xafec, 0x2079, 0x0010, 0x7004, 0xa086, 0x0000, 0x0538, 0x7800,
+	0x0006, 0x7820, 0x0006, 0x7830, 0x0006, 0x7834, 0x0006, 0x7838,
+	0x0006, 0x783c, 0x0006, 0x7803, 0x0004, 0xe000, 0xe000, 0x2079,
+	0x0030, 0x7804, 0xd0ac, 0x190c, 0x14f6, 0x2079, 0x0010, 0x000e,
+	0x783e, 0x000e, 0x783a, 0x000e, 0x7836, 0x000e, 0x7832, 0x000e,
+	0x7822, 0x000e, 0x7802, 0x00fe, 0x00ee, 0x0030, 0x00fe, 0x00ee,
+	0x7804, 0xd0ac, 0x190c, 0x14f6, 0x080c, 0x6d0d, 0x0005, 0x00e6,
+	0x2071, 0xb01e, 0x7003, 0x0000, 0x00ee, 0x0005, 0x00d6, 0xa280,
+	0x0004, 0x206c, 0x694c, 0xd1dc, 0x1904, 0x1ee4, 0x6934, 0xa184,
+	0x0007, 0x0002, 0x1e82, 0x1ecf, 0x1e82, 0x1e82, 0x1e82, 0x1eb6,
+	0x1e95, 0x1e84, 0x080c, 0x14f6, 0x684c, 0xd0b4, 0x0904, 0x1fcc,
+	0x6860, 0x682e, 0x6816, 0x685c, 0x682a, 0x6812, 0x687c, 0x680a,
+	0x6880, 0x680e, 0x6958, 0x0804, 0x1ed7, 0x6834, 0xa084, 0x00ff,
+	0xa086, 0x001e, 0x1d38, 0x684c, 0xd0b4, 0x0904, 0x1fcc, 0x6860,
+	0x682e, 0x6816, 0x685c, 0x682a, 0x6812, 0x687c, 0x680a, 0x6880,
+	0x680e, 0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f,
+	0xa080, 0x2186, 0x2005, 0x6832, 0x6958, 0x0450, 0xa18c, 0x00ff,
+	0xa186, 0x0015, 0x1548, 0x684c, 0xd0b4, 0x0904, 0x1fcc, 0x6804,
+	0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080, 0x2186,
+	0x2005, 0x6832, 0x6958, 0xa006, 0x682e, 0x682a, 0x0088, 0x684c,
+	0xd0b4, 0x0904, 0x1a47, 0x6958, 0xa006, 0x682e, 0x682a, 0x2d00,
+	0x681a, 0x6834, 0xa084, 0x000f, 0xa080, 0x2186, 0x2005, 0x6832,
+	0x6926, 0x684c, 0xc0dd, 0x684e, 0x00de, 0x0005, 0x00f6, 0x2079,
+	0x0020, 0x7804, 0xd0fc, 0x190c, 0x1ff4, 0x00e6, 0x00d6, 0x2071,
+	0xb01e, 0x7000, 0xa005, 0x1904, 0x1f4c, 0x00c6, 0x7206, 0xa280,
+	0x0004, 0x205c, 0x7004, 0x2068, 0x7803, 0x0004, 0x6818, 0x00d6,
+	0x2068, 0x686c, 0x7812, 0x6890, 0x00f6, 0x20e1, 0x9040, 0x2079,
+	0x0200, 0x781a, 0x2079, 0x0100, 0x8004, 0x78d6, 0x00fe, 0x00de,
+	0x2b68, 0x6824, 0x2050, 0x6818, 0x2060, 0x6830, 0x2040, 0x6034,
+	0xa0cc, 0x000f, 0x6908, 0x791a, 0x7116, 0x680c, 0x781e, 0x701a,
+	0xa006, 0x700e, 0x7012, 0x7004, 0x692c, 0x6814, 0xa106, 0x1120,
+	0x6928, 0x6810, 0xa106, 0x0158, 0x0036, 0x0046, 0x6b14, 0x6c10,
+	0x080c, 0x21a6, 0x004e, 0x003e, 0x0110, 0x00ce, 0x00a8, 0x8aff,
+	0x1120, 0x00ce, 0xa085, 0x0001, 0x0078, 0x0126, 0x2091, 0x8000,
+	0x2079, 0x0020, 0x2009, 0x0001, 0x0059, 0x0118, 0x2009, 0x0001,
+	0x0039, 0x012e, 0x00ce, 0xa006, 0x00de, 0x00ee, 0x00fe, 0x0005,
+	0x0076, 0x0066, 0x0056, 0x0046, 0x0036, 0x0026, 0x8aff, 0x0904,
+	0x1fc5, 0x700c, 0x7214, 0xa23a, 0x7010, 0x7218, 0xa203, 0x0a04,
+	0x1fc4, 0xa705, 0x0904, 0x1fc4, 0xa03e, 0x2730, 0x6850, 0xd0fc,
+	0x11a8, 0x00d6, 0x2805, 0xac68, 0x2900, 0x0002, 0x1fa7, 0x1f8c,
+	0x1f8c, 0x1fa7, 0x1fa7, 0x1fa0, 0x1fa7, 0x1f8c, 0x1fa7, 0x1f91,
+	0x1f91, 0x1fa7, 0x1fa7, 0x1fa7, 0x1f98, 0x1f91, 0xc0fc, 0x6852,
+	0x6b6c, 0x6a70, 0x6d1c, 0x6c20, 0xd99c, 0x0528, 0x00d6, 0x2805,
+	0xac68, 0x6f08, 0x6e0c, 0x00f0, 0x6b08, 0x6a0c, 0x6d00, 0x6c04,
+	0x00c8, 0x6b10, 0x6a14, 0x6d00, 0x6c04, 0x6f08, 0x6e0c, 0x0090,
+	0x00de, 0x00d6, 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e, 0x1138,
+	0x00de, 0x080c, 0x2148, 0x1904, 0x1f56, 0xa00e, 0x00f0, 0x00de,
+	0x080c, 0x14f6, 0x00de, 0x7b22, 0x7a26, 0x7d32, 0x7c36, 0x7f3a,
+	0x7e3e, 0x7902, 0x7000, 0x8000, 0x7002, 0x6828, 0xa300, 0x682a,
+	0x682c, 0xa201, 0x682e, 0x700c, 0xa300, 0x700e, 0x7010, 0xa201,
+	0x7012, 0x080c, 0x2148, 0x0008, 0xa006, 0x002e, 0x003e, 0x004e,
+	0x005e, 0x006e, 0x007e, 0x0005, 0x080c, 0x14f6, 0x0026, 0x2001,
+	0x0105, 0x2003, 0x0010, 0x20e1, 0x9040, 0x7803, 0x0004, 0x7003,
+	0x0000, 0x7004, 0x2060, 0x00d6, 0x6010, 0x2068, 0x080c, 0x9596,
+	0x0118, 0x6850, 0xc0bd, 0x6852, 0x00de, 0x080c, 0x929c, 0x20e1,
+	0x9040, 0x080c, 0x7cb8, 0x2011, 0x0000, 0x080c, 0x7ae9, 0x080c,
+	0x6d0d, 0x002e, 0x0804, 0x20ad, 0x0126, 0x2091, 0x2400, 0x0006,
+	0x0016, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x2079, 0x0020, 0x2071,
+	0xb01e, 0x2b68, 0x6818, 0x2060, 0x7904, 0x7803, 0x0002, 0xa184,
+	0x0700, 0x1920, 0x7000, 0x0002, 0x20ad, 0x2010, 0x2080, 0x20ab,
+	0x8001, 0x7002, 0xd19c, 0x1170, 0x8aff, 0x05d0, 0x2009, 0x0001,
+	0x080c, 0x1f50, 0x0904, 0x20ad, 0x2009, 0x0001, 0x080c, 0x1f50,
+	0x0804, 0x20ad, 0x7803, 0x0004, 0xd194, 0x0148, 0x6850, 0xc0fc,
+	0x6852, 0x8aff, 0x11d8, 0x684c, 0xc0f5, 0x684e, 0x00b8, 0x0026,
+	0x0036, 0x6b28, 0x6a2c, 0x7820, 0x686e, 0xa31a, 0x7824, 0x6872,
+	0xa213, 0x7830, 0x681e, 0x7834, 0x6822, 0x6b2a, 0x6a2e, 0x003e,
+	0x002e, 0x080c, 0x215e, 0x6850, 0xc0fd, 0x6852, 0x2a00, 0x6826,
+	0x2c00, 0x681a, 0x2800, 0x6832, 0x7003, 0x0000, 0x0804, 0x20ad,
+	0x00f6, 0x0026, 0x781c, 0x0006, 0x7818, 0x0006, 0x2079, 0x0100,
+	0x7a14, 0xa284, 0x0184, 0xa085, 0x0012, 0x7816, 0x0036, 0x2019,
+	0x1000, 0x8319, 0x090c, 0x14f6, 0x7820, 0xd0bc, 0x1dd0, 0x003e,
+	0x79c8, 0x000e, 0xa102, 0x001e, 0x0006, 0x0016, 0x79c4, 0x000e,
+	0xa103, 0x78c6, 0x000e, 0x78ca, 0xa284, 0x0184, 0xa085, 0x0012,
+	0x7816, 0x002e, 0x00fe, 0x7803, 0x0008, 0x7003, 0x0000, 0x0468,
+	0x8001, 0x7002, 0xd194, 0x0168, 0x7804, 0xd0fc, 0x1904, 0x2004,
+	0xd19c, 0x11f8, 0x8aff, 0x0508, 0x2009, 0x0001, 0x080c, 0x1f50,
+	0x00e0, 0x0026, 0x0036, 0x6b28, 0x6a2c, 0x080c, 0x215e, 0x00d6,
+	0x2805, 0xac68, 0x6034, 0xd09c, 0x1128, 0x6808, 0xa31a, 0x680c,
+	0xa213, 0x0020, 0x6810, 0xa31a, 0x6814, 0xa213, 0x00de, 0x0804,
+	0x2033, 0x0804, 0x202f, 0x080c, 0x14f6, 0x00ce, 0x00de, 0x00ee,
+	0x00fe, 0x001e, 0x000e, 0x012e, 0x0005, 0x00f6, 0x00e6, 0x2071,
+	0xb01e, 0x7000, 0xa086, 0x0000, 0x0590, 0x2079, 0x0020, 0x0016,
+	0x2009, 0x0207, 0x210c, 0xd194, 0x0158, 0x2009, 0x020c, 0x210c,
+	0xa184, 0x0003, 0x0128, 0x20e1, 0x9040, 0x2001, 0x020c, 0x2102,
+	0x2009, 0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0xa106, 0x1110,
+	0x20e1, 0x9040, 0x7804, 0xd0fc, 0x0d18, 0x080c, 0x1ff4, 0x7000,
+	0xa086, 0x0000, 0x19e8, 0x001e, 0x7803, 0x0004, 0x7804, 0xd0ac,
+	0x1de8, 0x20e1, 0x9040, 0x7803, 0x0002, 0x7003, 0x0000, 0x00ee,
+	0x00fe, 0x0005, 0x0026, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2071,
+	0xb01e, 0x2079, 0x0020, 0x7000, 0xa086, 0x0000, 0x0540, 0x7004,
+	0x2060, 0x6010, 0x2068, 0x080c, 0x9596, 0x0158, 0x6850, 0xc0b5,
+	0x6852, 0x680c, 0x7a1c, 0xa206, 0x1120, 0x6808, 0x7a18, 0xa206,
+	0x01e0, 0x2001, 0x0105, 0x2003, 0x0010, 0x20e1, 0x9040, 0x7803,
+	0x0004, 0x7003, 0x0000, 0x7004, 0x2060, 0x080c, 0x929c, 0x20e1,
+	0x9040, 0x080c, 0x7cb8, 0x2011, 0x0000, 0x080c, 0x7ae9, 0x00fe,
+	0x00ee, 0x00de, 0x00ce, 0x002e, 0x0005, 0x6810, 0x6a14, 0xa205,
+	0x1d00, 0x684c, 0xc0dc, 0x684e, 0x2c10, 0x080c, 0x1e6e, 0x2001,
+	0x0105, 0x2003, 0x0010, 0x20e1, 0x9040, 0x7803, 0x0004, 0x7003,
+	0x0000, 0x2069, 0xafc7, 0x6833, 0x0000, 0x683f, 0x0000, 0x08f8,
+	0x8840, 0x2805, 0xa005, 0x1170, 0x6004, 0xa005, 0x0168, 0x681a,
+	0x2060, 0x6034, 0xa084, 0x000f, 0xa080, 0x2186, 0x2045, 0x88ff,
+	0x090c, 0x14f6, 0x8a51, 0x0005, 0x2050, 0x0005, 0x8a50, 0x8841,
+	0x2805, 0xa005, 0x1190, 0x2c00, 0xad06, 0x0120, 0x6000, 0xa005,
+	0x1108, 0x2d00, 0x2060, 0x681a, 0x6034, 0xa084, 0x000f, 0xa080,
+	0x2196, 0x2045, 0x88ff, 0x090c, 0x14f6, 0x0005, 0x0000, 0x0011,
+	0x0015, 0x0019, 0x001d, 0x0021, 0x0025, 0x0029, 0x0000, 0x000f,
+	0x0015, 0x001b, 0x0021, 0x0027, 0x0000, 0x0000, 0x0000, 0x217b,
+	0x2177, 0x0000, 0x0000, 0x2185, 0x0000, 0x217b, 0x0000, 0x2182,
+	0x217f, 0x0000, 0x0000, 0x0000, 0x2185, 0x2182, 0x0000, 0x217d,
+	0x217d, 0x0000, 0x0000, 0x2185, 0x0000, 0x217d, 0x0000, 0x2183,
+	0x2183, 0x0000, 0x0000, 0x0000, 0x2185, 0x2183, 0x00a6, 0x0096,
+	0x0086, 0x6b2e, 0x6c2a, 0x6858, 0xa055, 0x0904, 0x2237, 0x2d60,
+	0x6034, 0xa0cc, 0x000f, 0xa9c0, 0x2186, 0xa986, 0x0007, 0x0130,
+	0xa986, 0x000e, 0x0118, 0xa986, 0x000f, 0x1120, 0x605c, 0xa422,
+	0x6060, 0xa31a, 0x2805, 0xa045, 0x1140, 0x0310, 0x0804, 0x2237,
+	0x6004, 0xa065, 0x0904, 0x2237, 0x0c18, 0x2805, 0xa005, 0x01a8,
+	0xac68, 0xd99c, 0x1128, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0020,
+	0x6810, 0xa422, 0x6814, 0xa31b, 0x0620, 0x2300, 0xa405, 0x0150,
+	0x8a51, 0x0904, 0x2237, 0x8840, 0x0c40, 0x6004, 0xa065, 0x0904,
+	0x2237, 0x0830, 0x8a51, 0x0904, 0x2237, 0x8840, 0x2805, 0xa005,
+	0x1158, 0x6004, 0xa065, 0x0904, 0x2237, 0x6034, 0xa0cc, 0x000f,
+	0xa9c0, 0x2186, 0x2805, 0x2040, 0x2b68, 0x6850, 0xc0fc, 0x6852,
+	0x0458, 0x8422, 0x8420, 0x831a, 0xa399, 0x0000, 0x00d6, 0x2b68,
+	0x6c6e, 0x6b72, 0x00de, 0xd99c, 0x1168, 0x6908, 0x2400, 0xa122,
+	0x690c, 0x2300, 0xa11b, 0x0a0c, 0x14f6, 0x6800, 0xa420, 0x6804,
+	0xa319, 0x0060, 0x6910, 0x2400, 0xa122, 0x6914, 0x2300, 0xa11b,
+	0x0a0c, 0x14f6, 0x6800, 0xa420, 0x6804, 0xa319, 0x2b68, 0x6c1e,
+	0x6b22, 0x6850, 0xc0fd, 0x6852, 0x2c00, 0x681a, 0x2800, 0x6832,
+	0x2a00, 0x6826, 0x000e, 0x000e, 0x000e, 0xa006, 0x0028, 0x008e,
+	0x009e, 0x00ae, 0xa085, 0x0001, 0x0005, 0x2001, 0x0005, 0x2004,
+	0xa084, 0x0007, 0x0002, 0x224b, 0x224c, 0x224f, 0x2252, 0x2257,
+	0x225a, 0x225f, 0x2264, 0x0005, 0x080c, 0x1ff4, 0x0005, 0x080c,
+	0x1a6c, 0x0005, 0x080c, 0x1a6c, 0x080c, 0x1ff4, 0x0005, 0x080c,
+	0x16f8, 0x0005, 0x080c, 0x1ff4, 0x080c, 0x16f8, 0x0005, 0x080c,
+	0x1a6c, 0x080c, 0x16f8, 0x0005, 0x080c, 0x1a6c, 0x080c, 0x1ff4,
+	0x080c, 0x16f8, 0x0005, 0x0126, 0x2091, 0x2600, 0x2079, 0x0200,
+	0x2071, 0xb280, 0x2069, 0xad00, 0x2009, 0x0004, 0x7912, 0x7817,
+	0x0004, 0x080c, 0x2651, 0x781b, 0x0002, 0x20e1, 0x9080, 0x20e1,
+	0x4000, 0x20a9, 0x0080, 0x782f, 0x0000, 0x1f04, 0x2283, 0x20e1,
+	0x9080, 0x783b, 0x001f, 0x20e1, 0x8700, 0x012e, 0x0005, 0x0126,
+	0x2091, 0x2600, 0x781c, 0xd0a4, 0x190c, 0x2335, 0xa084, 0x0007,
+	0x0002, 0x22b3, 0x22a1, 0x22a4, 0x22a7, 0x22ac, 0x22ae, 0x22b0,
+	0x22b2, 0x080c, 0x5fb7, 0x0078, 0x080c, 0x5ff0, 0x0060, 0x080c,
+	0x5fb7, 0x080c, 0x5ff0, 0x0038, 0x0041, 0x0028, 0x0031, 0x0018,
+	0x0021, 0x0008, 0x0011, 0x012e, 0x0005, 0x0006, 0x0016, 0x0026,
+	0x7930, 0xa184, 0x0003, 0x0118, 0x20e1, 0x9040, 0x04a0, 0xa184,
+	0x0030, 0x01e0, 0x6a00, 0xa286, 0x0003, 0x1108, 0x00a0, 0x080c,
+	0x574f, 0x1178, 0x2001, 0xaf9e, 0x2003, 0x0001, 0x2001, 0xad00,
+	0x2003, 0x0001, 0xa085, 0x0001, 0x080c, 0x5793, 0x080c, 0x569a,
+	0x0010, 0x080c, 0x485e, 0x20e1, 0x9010, 0x00a8, 0xa184, 0x00c0,
+	0x0168, 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071, 0xaffd, 0x080c,
+	0x1d22, 0x005e, 0x004e, 0x003e, 0x00ee, 0x0028, 0xa184, 0x0300,
+	0x0110, 0x20e1, 0x9020, 0x7932, 0x002e, 0x001e, 0x000e, 0x0005,
+	0x0016, 0x00e6, 0x00f6, 0x2071, 0xad00, 0x7128, 0x2001, 0xaf90,
+	0x2102, 0x2001, 0xaf98, 0x2102, 0xa182, 0x0211, 0x1218, 0x2009,
+	0x0008, 0x0400, 0xa182, 0x0259, 0x1218, 0x2009, 0x0007, 0x00d0,
+	0xa182, 0x02c1, 0x1218, 0x2009, 0x0006, 0x00a0, 0xa182, 0x0349,
+	0x1218, 0x2009, 0x0005, 0x0070, 0xa182, 0x0421, 0x1218, 0x2009,
+	0x0004, 0x0040, 0xa182, 0x0581, 0x1218, 0x2009, 0x0003, 0x0010,
+	0x2009, 0x0002, 0x2079, 0x0200, 0x7912, 0x7817, 0x0004, 0x080c,
+	0x2651, 0x00fe, 0x00ee, 0x001e, 0x0005, 0x7938, 0x080c, 0x14f6,
+	0x0126, 0x2091, 0x2800, 0x2061, 0x0100, 0x2071, 0xad00, 0x6024,
+	0x6026, 0x6053, 0x0030, 0x080c, 0x2690, 0x6050, 0xa084, 0xfe7f,
+	0x6052, 0x2009, 0x00ef, 0x6132, 0x6136, 0x080c, 0x26a0, 0x60e7,
+	0x0000, 0x61ea, 0x60e3, 0x0008, 0x604b, 0xf7f7, 0x6043, 0x0000,
+	0x602f, 0x0080, 0x602f, 0x0000, 0x6007, 0x0e9f, 0x601b, 0x001e,
+	0x600f, 0x00ff, 0x2001, 0xaf8c, 0x2003, 0x00ff, 0x602b, 0x002f,
+	0x012e, 0x0005, 0x2001, 0xad31, 0x2003, 0x0000, 0x2001, 0xad30,
+	0x2003, 0x0001, 0x0005, 0x0126, 0x2091, 0x2800, 0x0006, 0x0016,
+	0x0026, 0x6124, 0xa184, 0x1e2c, 0x1118, 0xa184, 0x0007, 0x002a,
+	0xa195, 0x0004, 0xa284, 0x0007, 0x0002, 0x23a7, 0x238d, 0x2390,
+	0x2393, 0x2398, 0x239a, 0x239e, 0x23a2, 0x080c, 0x6699, 0x00b8,
+	0x080c, 0x6774, 0x00a0, 0x080c, 0x6774, 0x080c, 0x6699, 0x0078,
+	0x0099, 0x0068, 0x080c, 0x6699, 0x0079, 0x0048, 0x080c, 0x6774,
+	0x0059, 0x0028, 0x080c, 0x6774, 0x080c, 0x6699, 0x0029, 0x002e,
+	0x001e, 0x000e, 0x012e, 0x0005, 0x6124, 0xd19c, 0x1904, 0x25bf,
+	0x080c, 0x574f, 0x0578, 0x7000, 0xa086, 0x0003, 0x0198, 0x6024,
+	0xa084, 0x1800, 0x0178, 0x080c, 0x5775, 0x0118, 0x080c, 0x5761,
+	0x1148, 0x6027, 0x0020, 0x6043, 0x0000, 0x2001, 0xaf9d, 0x2003,
+	0xaaaa, 0x0458, 0x080c, 0x5775, 0x15d0, 0x6024, 0xa084, 0x1800,
+	0x1108, 0x04a8, 0x2001, 0xaf9d, 0x2003, 0xaaaa, 0x2001, 0xaf9e,
+	0x2003, 0x0001, 0x2001, 0xad00, 0x2003, 0x0001, 0x080c, 0x569a,
+	0x0804, 0x25bf, 0xd1ac, 0x1518, 0x6024, 0xd0dc, 0x1170, 0xd0e4,
+	0x1188, 0xd0d4, 0x11a0, 0xd0cc, 0x0130, 0x7088, 0xa086, 0x0028,
+	0x1110, 0x080c, 0x58da, 0x0804, 0x25bf, 0x2001, 0xaf9e, 0x2003,
+	0x0000, 0x0048, 0x2001, 0xaf9e, 0x2003, 0x0002, 0x0020, 0x080c,
+	0x584d, 0x0804, 0x25bf, 0x080c, 0x597a, 0x0804, 0x25bf, 0xd1ac,
+	0x0904, 0x2507, 0x080c, 0x574f, 0x11d8, 0x6027, 0x0020, 0x0006,
+	0x0026, 0x0036, 0x080c, 0x576b, 0x1170, 0x2001, 0xaf9e, 0x2003,
+	0x0001, 0x2001, 0xad00, 0x2003, 0x0001, 0x080c, 0x569a, 0x003e,
+	0x002e, 0x000e, 0x0005, 0x003e, 0x002e, 0x000e, 0x080c, 0x5726,
+	0x0016, 0x0046, 0x00c6, 0x644c, 0xa486, 0xf0f0, 0x1138, 0x2061,
+	0x0100, 0x644a, 0x6043, 0x0090, 0x6043, 0x0010, 0x74ca, 0xa48c,
+	0xff00, 0x7034, 0xd084, 0x0178, 0xa186, 0xf800, 0x1160, 0x7038,
+	0xd084, 0x1148, 0xc085, 0x703a, 0x0036, 0x2418, 0x2011, 0x8016,
+	0x080c, 0x3c5c, 0x003e, 0xa196, 0xff00, 0x05b8, 0x7050, 0xa084,
+	0x00ff, 0x810f, 0xa116, 0x0588, 0x7130, 0xd184, 0x1570, 0x2011,
+	0xad52, 0x2214, 0xd2ec, 0x0138, 0xc18d, 0x7132, 0x2011, 0xad52,
+	0x2214, 0xd2ac, 0x1510, 0x6240, 0xa294, 0x0010, 0x0130, 0x6248,
+	0xa294, 0xff00, 0xa296, 0xff00, 0x01c0, 0x7030, 0xd08c, 0x0904,
+	0x24d2, 0x7034, 0xd08c, 0x1140, 0x2001, 0xad0c, 0x200c, 0xd1ac,
+	0x1904, 0x24d2, 0xc1ad, 0x2102, 0x0036, 0x73c8, 0x2011, 0x8013,
+	0x080c, 0x3c5c, 0x003e, 0x0804, 0x24d2, 0x7034, 0xd08c, 0x1140,
+	0x2001, 0xad0c, 0x200c, 0xd1ac, 0x1904, 0x24d2, 0xc1ad, 0x2102,
+	0x0036, 0x73c8, 0x2011, 0x8013, 0x080c, 0x3c5c, 0x003e, 0x7130,
+	0xc185, 0x7132, 0x2011, 0xad52, 0x220c, 0xd1a4, 0x01d0, 0x0016,
+	0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x663f, 0x2019, 0x000e,
+	0x080c, 0xa8eb, 0xa484, 0x00ff, 0xa080, 0x2be6, 0x200d, 0xa18c,
+	0xff00, 0x810f, 0x8127, 0xa006, 0x2009, 0x000e, 0x080c, 0xa96c,
+	0x001e, 0xd1ac, 0x1148, 0x0016, 0x2009, 0x0000, 0x2019, 0x0004,
+	0x080c, 0x2aac, 0x001e, 0x0070, 0x0156, 0x20a9, 0x007f, 0x2009,
+	0x0000, 0x080c, 0x4cdc, 0x1110, 0x080c, 0x493a, 0x8108, 0x1f04,
+	0x24c9, 0x015e, 0x00ce, 0x004e, 0x2011, 0x0003, 0x080c, 0x7adf,
+	0x2011, 0x0002, 0x080c, 0x7ae9, 0x080c, 0x79e1, 0x080c, 0x6581,
+	0x0036, 0x2019, 0x0000, 0x080c, 0x7a64, 0x003e, 0x60e3, 0x0000,
+	0x001e, 0x2001, 0xad00, 0x2014, 0xa296, 0x0004, 0x1128, 0xd19c,
+	0x1118, 0x6228, 0xc29d, 0x622a, 0x2003, 0x0001, 0x2001, 0xad22,
+	0x2003, 0x0000, 0x6027, 0x0020, 0x080c, 0x5775, 0x1140, 0x0016,
+	0x2009, 0x07d0, 0x2011, 0x567b, 0x080c, 0x6593, 0x001e, 0xd194,
+	0x0904, 0x25bf, 0x0016, 0x6220, 0xd2b4, 0x0904, 0x2570, 0x080c,
+	0x6581, 0x080c, 0x7834, 0x6027, 0x0004, 0x00f6, 0x2019, 0xafd0,
+	0x2304, 0xa07d, 0x0570, 0x7804, 0xa086, 0x0032, 0x1550, 0x00d6,
+	0x00c6, 0x00e6, 0x2069, 0x0140, 0x618c, 0x6288, 0x7818, 0x608e,
+	0x7808, 0x608a, 0x6043, 0x0002, 0x2001, 0x0003, 0x8001, 0x1df0,
+	0x6043, 0x0000, 0x6803, 0x1000, 0x6803, 0x0000, 0x618e, 0x628a,
+	0x080c, 0x6b73, 0x080c, 0x6c50, 0x7810, 0x2070, 0x7037, 0x0103,
+	0x2f60, 0x080c, 0x8078, 0x00ee, 0x00ce, 0x00de, 0x00fe, 0x001e,
+	0x0005, 0x00fe, 0x00d6, 0x2069, 0x0140, 0x6804, 0xa084, 0x4000,
+	0x0120, 0x6803, 0x1000, 0x6803, 0x0000, 0x00de, 0x00c6, 0x2061,
+	0xafc7, 0x6028, 0xa09a, 0x00c8, 0x1238, 0x8000, 0x602a, 0x00ce,
+	0x080c, 0x7827, 0x0804, 0x25be, 0x2019, 0xafd0, 0x2304, 0xa065,
+	0x0120, 0x2009, 0x0027, 0x080c, 0x80a7, 0x00ce, 0x0804, 0x25be,
+	0xd2bc, 0x0904, 0x25be, 0x080c, 0x658e, 0x6014, 0xa084, 0x0184,
+	0xa085, 0x0010, 0x6016, 0x6027, 0x0004, 0x00d6, 0x2069, 0x0140,
+	0x6804, 0xa084, 0x4000, 0x0120, 0x6803, 0x1000, 0x6803, 0x0000,
+	0x00de, 0x00c6, 0x2061, 0xafc7, 0x6044, 0xa09a, 0x00c8, 0x12f0,
+	0x8000, 0x6046, 0x603c, 0x00ce, 0xa005, 0x0540, 0x2009, 0x07d0,
+	0x080c, 0x6586, 0xa080, 0x0007, 0x2004, 0xa086, 0x0006, 0x1138,
+	0x6114, 0xa18c, 0x0184, 0xa18d, 0x0012, 0x6116, 0x00b8, 0x6114,
+	0xa18c, 0x0184, 0xa18d, 0x0016, 0x6116, 0x0080, 0x0036, 0x2019,
+	0x0001, 0x080c, 0x7a64, 0x003e, 0x2019, 0xafd6, 0x2304, 0xa065,
+	0x0120, 0x2009, 0x004f, 0x080c, 0x80a7, 0x00ce, 0x001e, 0xd19c,
+	0x0904, 0x261a, 0x7034, 0xd0ac, 0x1560, 0x0016, 0x0156, 0x6027,
+	0x0008, 0x602f, 0x0020, 0x20a9, 0x0006, 0x1d04, 0x25cd, 0x2091,
+	0x6000, 0x1f04, 0x25cd, 0x602f, 0x0000, 0x6150, 0xa185, 0x1400,
+	0x6052, 0x20a9, 0x0366, 0x1d04, 0x25db, 0x2091, 0x6000, 0x6020,
+	0xd09c, 0x1130, 0x015e, 0x6152, 0x001e, 0x6027, 0x0008, 0x0490,
+	0x080c, 0x2760, 0x1f04, 0x25db, 0x015e, 0x6152, 0x001e, 0x6027,
+	0x0008, 0x0016, 0x6028, 0xc09c, 0x602a, 0x2011, 0x0003, 0x080c,
+	0x7adf, 0x2011, 0x0002, 0x080c, 0x7ae9, 0x080c, 0x79e1, 0x080c,
+	0x6581, 0x0036, 0x2019, 0x0000, 0x080c, 0x7a64, 0x003e, 0x60e3,
+	0x0000, 0x080c, 0xac8d, 0x080c, 0xaca8, 0xa085, 0x0001, 0x080c,
+	0x5793, 0x2001, 0xad00, 0x2003, 0x0004, 0x6027, 0x0008, 0x080c,
+	0x12cc, 0x001e, 0xa18c, 0xffd0, 0x6126, 0x0005, 0x0006, 0x0016,
+	0x0026, 0x00e6, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2071, 0xad00,
+	0x71c0, 0x70c2, 0xa116, 0x01f0, 0x81ff, 0x0128, 0x2011, 0x8011,
+	0x080c, 0x3c5c, 0x00b8, 0x2011, 0x8012, 0x080c, 0x3c5c, 0x2001,
+	0xad71, 0x2004, 0xd0fc, 0x1170, 0x0036, 0x00c6, 0x080c, 0x26eb,
+	0x2061, 0x0100, 0x2019, 0x0028, 0x2009, 0x0000, 0x080c, 0x2aac,
+	0x00ce, 0x003e, 0x012e, 0x00fe, 0x00ee, 0x002e, 0x001e, 0x000e,
+	0x0005, 0x00c6, 0x00f6, 0x0006, 0x0026, 0x2061, 0x0100, 0xa190,
+	0x2664, 0x2205, 0x60f2, 0x2011, 0x2671, 0x2205, 0x60ee, 0x002e,
+	0x000e, 0x00fe, 0x00ce, 0x0005, 0x0840, 0x0840, 0x0840, 0x0580,
+	0x0420, 0x0348, 0x02c0, 0x0258, 0x0210, 0x01a8, 0x01a8, 0x01a8,
+	0x01a8, 0x0140, 0x00f8, 0x00d0, 0x00b0, 0x00a0, 0x2028, 0xa18c,
+	0x00ff, 0x2130, 0xa094, 0xff00, 0x1110, 0x81ff, 0x0118, 0x080c,
+	0x6278, 0x0038, 0xa080, 0x2be6, 0x200d, 0xa18c, 0xff00, 0x810f,
+	0xa006, 0x0005, 0xa080, 0x2be6, 0x200d, 0xa18c, 0x00ff, 0x0005,
+	0x00d6, 0x2069, 0x0140, 0x2001, 0xad14, 0x2003, 0x00ef, 0x20a9,
+	0x0010, 0xa006, 0x6852, 0x6856, 0x1f04, 0x269b, 0x00de, 0x0005,
+	0x0006, 0x00d6, 0x0026, 0x2069, 0x0140, 0x2001, 0xad14, 0x2102,
+	0x8114, 0x8214, 0x8214, 0x8214, 0x20a9, 0x0010, 0x6853, 0x0000,
+	0xa006, 0x82ff, 0x1128, 0xa184, 0x000f, 0xa080, 0xacae, 0x2005,
+	0x6856, 0x8211, 0x1f04, 0x26b0, 0x002e, 0x00de, 0x000e, 0x0005,
+	0x00c6, 0x2061, 0xad00, 0x6030, 0x0110, 0xc09d, 0x0008, 0xc09c,
+	0x6032, 0x00ce, 0x0005, 0x0156, 0x00d6, 0x0026, 0x0016, 0x0006,
+	0x2069, 0x0140, 0x6980, 0xa116, 0x0180, 0xa112, 0x1230, 0x8212,
+	0x8210, 0x22a8, 0x2001, 0x0402, 0x0018, 0x22a8, 0x2001, 0x0404,
+	0x680e, 0x1f04, 0x26e0, 0x680f, 0x0000, 0x000e, 0x001e, 0x002e,
+	0x00de, 0x015e, 0x0005, 0x2001, 0xad52, 0x2004, 0xd0c4, 0x0150,
+	0xd0a4, 0x0140, 0xa006, 0x0046, 0x2020, 0x2009, 0x002e, 0x080c,
+	0xa96c, 0x004e, 0x0005, 0x00f6, 0x0016, 0x0026, 0x2079, 0x0140,
+	0x78c4, 0xd0dc, 0x0548, 0xa084, 0x0700, 0xa08e, 0x0300, 0x1520,
+	0x2011, 0x0000, 0x2009, 0x0002, 0x2300, 0xa080, 0x0020, 0x2018,
+	0x2300, 0x080c, 0x6665, 0x2011, 0x0030, 0x2200, 0x8007, 0xa085,
+	0x004c, 0x78c2, 0x2009, 0x0204, 0x210c, 0x2200, 0xa100, 0x2009,
+	0x0138, 0x200a, 0x080c, 0x574f, 0x1118, 0x2009, 0xaf8e, 0x200a,
+	0x002e, 0x001e, 0x00fe, 0x0005, 0x78c3, 0x0000, 0x0cc8, 0x0126,
+	0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x2001, 0x0170, 0x200c,
+	0x8000, 0x2014, 0xa184, 0x0003, 0x0110, 0x0804, 0x1a6a, 0x002e,
+	0x001e, 0x000e, 0x012e, 0x0005, 0x0006, 0x2001, 0x0100, 0x2004,
+	0xa082, 0x0005, 0x000e, 0x0268, 0x2001, 0x0170, 0x200c, 0xa18c,
+	0x00ff, 0xa18e, 0x004c, 0x1128, 0x200c, 0xa18c, 0xff00, 0x810f,
+	0x0010, 0x2009, 0x0000, 0x2001, 0x0204, 0x2004, 0xa108, 0x0005,
+	0x0006, 0x0156, 0x00f6, 0x2079, 0x0100, 0x20a9, 0x000a, 0x7854,
+	0xd08c, 0x1110, 0x1f04, 0x2767, 0x00fe, 0x015e, 0x000e, 0x0005,
+	0x0016, 0x00c6, 0x0006, 0x2061, 0x0100, 0x6030, 0x0006, 0x6048,
+	0x0006, 0x60e4, 0x0006, 0x60e8, 0x0006, 0x6050, 0x0006, 0x60f0,
+	0x0006, 0x60ec, 0x0006, 0x600c, 0x0006, 0x6004, 0x0006, 0x6028,
+	0x0006, 0x60e0, 0x0006, 0x602f, 0x0100, 0x602f, 0x0000, 0xe000,
+	0xe000, 0xe000, 0xe000, 0x602f, 0x0040, 0x602f, 0x0000, 0x000e,
+	0x60e2, 0x000e, 0x602a, 0x000e, 0x6006, 0x000e, 0x600e, 0x000e,
+	0x60ee, 0x000e, 0x60f2, 0x000e, 0x6052, 0x000e, 0x60ea, 0x000e,
+	0x60e6, 0x000e, 0x604a, 0x000e, 0x6032, 0x6036, 0x2008, 0x080c,
+	0x26a0, 0x000e, 0x00ce, 0x001e, 0x0005, 0x2845, 0x2849, 0x284d,
+	0x2853, 0x2859, 0x285f, 0x2865, 0x286d, 0x2875, 0x287b, 0x2881,
+	0x2889, 0x2891, 0x2899, 0x28a1, 0x28ab, 0x28b5, 0x28b5, 0x28b5,
+	0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+	0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+	0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+	0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+	0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+	0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b7, 0x28b7, 0x28bc,
+	0x28bc, 0x28c3, 0x28c3, 0x28ca, 0x28ca, 0x28d3, 0x28d3, 0x28da,
+	0x28da, 0x28e3, 0x28e3, 0x28ec, 0x28ec, 0x28b5, 0x28b5, 0x28b5,
+	0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+	0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+	0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+	0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+	0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+	0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+	0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+	0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x0106, 0x0006, 0x0804,
+	0x28f7, 0x0106, 0x0006, 0x0804, 0x28f7, 0x0106, 0x0006, 0x080c,
+	0x2373, 0x0804, 0x28f7, 0x0106, 0x0006, 0x080c, 0x2373, 0x0804,
+	0x28f7, 0x0106, 0x0006, 0x080c, 0x223d, 0x0804, 0x28f7, 0x0106,
+	0x0006, 0x080c, 0x223d, 0x0804, 0x28f7, 0x0106, 0x0006, 0x080c,
+	0x2373, 0x080c, 0x223d, 0x0804, 0x28f7, 0x0106, 0x0006, 0x080c,
+	0x2373, 0x080c, 0x223d, 0x0804, 0x28f7, 0x0106, 0x0006, 0x080c,
+	0x228f, 0x0804, 0x28f7, 0x0106, 0x0006, 0x080c, 0x228f, 0x0804,
+	0x28f7, 0x0106, 0x0006, 0x080c, 0x2373, 0x080c, 0x228f, 0x0804,
+	0x28f7, 0x0106, 0x0006, 0x080c, 0x2373, 0x080c, 0x228f, 0x0804,
+	0x28f7, 0x0106, 0x0006, 0x080c, 0x223d, 0x080c, 0x228f, 0x0804,
+	0x28f7, 0x0106, 0x0006, 0x080c, 0x223d, 0x080c, 0x228f, 0x0804,
+	0x28f7, 0x0106, 0x0006, 0x080c, 0x2373, 0x080c, 0x223d, 0x080c,
+	0x228f, 0x0804, 0x28f7, 0x0106, 0x0006, 0x080c, 0x2373, 0x080c,
+	0x223d, 0x080c, 0x228f, 0x0804, 0x28f7, 0xe000, 0x0cf0, 0x0106,
+	0x0006, 0x080c, 0x272f, 0x04d8, 0x0106, 0x0006, 0x080c, 0x272f,
+	0x080c, 0x2373, 0x04a0, 0x0106, 0x0006, 0x080c, 0x272f, 0x080c,
+	0x223d, 0x0468, 0x0106, 0x0006, 0x080c, 0x272f, 0x080c, 0x2373,
+	0x080c, 0x223d, 0x0420, 0x0106, 0x0006, 0x080c, 0x272f, 0x080c,
+	0x228f, 0x00e8, 0x0106, 0x0006, 0x080c, 0x272f, 0x080c, 0x2373,
+	0x080c, 0x228f, 0x00a0, 0x0106, 0x0006, 0x080c, 0x272f, 0x080c,
+	0x223d, 0x080c, 0x228f, 0x0058, 0x0106, 0x0006, 0x080c, 0x272f,
+	0x080c, 0x2373, 0x080c, 0x223d, 0x080c, 0x228f, 0x0000, 0x000e,
+	0x010e, 0x000d, 0x00c6, 0x0026, 0x0046, 0x2021, 0x0000, 0x080c,
+	0x502d, 0x1904, 0x29d4, 0x72d0, 0x2001, 0xaf9d, 0x2004, 0xa005,
+	0x1110, 0xd29c, 0x0148, 0xd284, 0x1138, 0xd2bc, 0x1904, 0x29d4,
+	0x080c, 0x29d8, 0x0804, 0x29d4, 0x080c, 0x574f, 0x1120, 0x709b,
+	0xffff, 0x0804, 0x29d4, 0xd294, 0x0120, 0x709b, 0xffff, 0x0804,
+	0x29d4, 0x2001, 0xad14, 0x203c, 0x7284, 0xd284, 0x0904, 0x2976,
+	0xd28c, 0x1904, 0x2976, 0x0036, 0x7398, 0xa38e, 0xffff, 0x1110,
+	0x2019, 0x0001, 0x8314, 0xa2e0, 0xb3c0, 0x2c04, 0xa38c, 0x0001,
+	0x0120, 0xa084, 0xff00, 0x8007, 0x0010, 0xa084, 0x00ff, 0xa70e,
+	0x0560, 0xa08e, 0x0000, 0x0548, 0xa08e, 0x00ff, 0x1150, 0x7230,
+	0xd284, 0x1538, 0x7284, 0xc28d, 0x7286, 0x709b, 0xffff, 0x003e,
+	0x0428, 0x2009, 0x0000, 0x080c, 0x2676, 0x080c, 0x4c80, 0x11b8,
+	0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1150, 0x7030, 0xd08c,
+	0x0118, 0x6000, 0xd0bc, 0x0120, 0x080c, 0x29eb, 0x0140, 0x0028,
+	0x080c, 0x2b1a, 0x080c, 0x2a19, 0x0110, 0x8318, 0x0818, 0x739a,
+	0x0010, 0x709b, 0xffff, 0x003e, 0x0804, 0x29d4, 0xa780, 0x2be6,
+	0x203d, 0xa7bc, 0xff00, 0x873f, 0x2041, 0x007e, 0x7098, 0xa096,
+	0xffff, 0x1120, 0x2009, 0x0000, 0x28a8, 0x0050, 0xa812, 0x0220,
+	0x2008, 0xa802, 0x20a8, 0x0020, 0x709b, 0xffff, 0x0804, 0x29d4,
+	0x2700, 0x0156, 0x0016, 0xa106, 0x05a0, 0xc484, 0x080c, 0x4cdc,
+	0x0120, 0x080c, 0x4c80, 0x15a8, 0x0008, 0xc485, 0x6004, 0xa084,
+	0x00ff, 0xa086, 0x0006, 0x1130, 0x7030, 0xd08c, 0x01e8, 0x6000,
+	0xd0bc, 0x11d0, 0x7284, 0xd28c, 0x0188, 0x6004, 0xa084, 0x00ff,
+	0xa082, 0x0006, 0x02b0, 0xd484, 0x1118, 0x080c, 0x4c9f, 0x0028,
+	0x080c, 0x2b9c, 0x0170, 0x080c, 0x2bc9, 0x0058, 0x080c, 0x2b1a,
+	0x080c, 0x2a19, 0x0170, 0x0028, 0x080c, 0x2b9c, 0x0110, 0x0419,
+	0x0140, 0x001e, 0x8108, 0x015e, 0x1f04, 0x2990, 0x709b, 0xffff,
+	0x0018, 0x001e, 0x015e, 0x719a, 0x004e, 0x002e, 0x00ce, 0x0005,
+	0x00c6, 0x0016, 0x709b, 0x0000, 0x2009, 0x007e, 0x080c, 0x4c80,
+	0x1138, 0x080c, 0x2b1a, 0x04a9, 0x0118, 0x70d0, 0xc0bd, 0x70d2,
+	0x001e, 0x00ce, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2c68,
+	0x2001, 0xad56, 0x2004, 0xa084, 0x00ff, 0x6842, 0x080c, 0x9807,
+	0x01d8, 0x2d00, 0x601a, 0x080c, 0x9956, 0x601f, 0x0001, 0x2001,
+	0x0000, 0x080c, 0x4c1e, 0x2001, 0x0000, 0x080c, 0x4c30, 0x0126,
+	0x2091, 0x8000, 0x7094, 0x8000, 0x7096, 0x012e, 0x2009, 0x0004,
+	0x080c, 0x80a7, 0xa085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e,
+	0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2c68, 0x2001, 0xad56,
+	0x2004, 0xa084, 0x00ff, 0x6842, 0x080c, 0x9807, 0x0550, 0x2d00,
+	0x601a, 0x6800, 0xc0c4, 0x6802, 0x68a0, 0xa086, 0x007e, 0x0140,
+	0x6804, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1110, 0x080c, 0x2ad9,
+	0x080c, 0x9956, 0x601f, 0x0001, 0x2001, 0x0000, 0x080c, 0x4c1e,
+	0x2001, 0x0002, 0x080c, 0x4c30, 0x0126, 0x2091, 0x8000, 0x7094,
+	0x8000, 0x7096, 0x012e, 0x2009, 0x0002, 0x080c, 0x80a7, 0xa085,
+	0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x00c6, 0x0026,
+	0x2009, 0x0080, 0x080c, 0x4c80, 0x1120, 0x0031, 0x0110, 0x70d7,
+	0xffff, 0x002e, 0x00ce, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6,
+	0x2c68, 0x080c, 0x8022, 0x01d8, 0x2d00, 0x601a, 0x080c, 0x9956,
+	0x601f, 0x0001, 0x2001, 0x0000, 0x080c, 0x4c1e, 0x2001, 0x0002,
+	0x080c, 0x4c30, 0x0126, 0x2091, 0x8000, 0x70d8, 0x8000, 0x70da,
+	0x012e, 0x2009, 0x0002, 0x080c, 0x80a7, 0xa085, 0x0001, 0x00ce,
+	0x00de, 0x007e, 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0126, 0x2091,
+	0x8000, 0x2009, 0x007f, 0x080c, 0x4c80, 0x1190, 0x2c68, 0x080c,
+	0x8022, 0x0170, 0x2d00, 0x601a, 0x6312, 0x601f, 0x0001, 0x620a,
+	0x080c, 0x9956, 0x2009, 0x0022, 0x080c, 0x80a7, 0xa085, 0x0001,
+	0x012e, 0x00de, 0x00ce, 0x0005, 0x00e6, 0x00c6, 0x0066, 0x0036,
+	0x0026, 0x080c, 0x68f3, 0x080c, 0x689d, 0x080c, 0x8a15, 0x2130,
+	0x81ff, 0x0128, 0x20a9, 0x007e, 0x2009, 0x0000, 0x0020, 0x20a9,
+	0x007f, 0x2009, 0x0000, 0x0016, 0x080c, 0x4cdc, 0x1120, 0x080c,
+	0x4ecf, 0x080c, 0x493a, 0x001e, 0x8108, 0x1f04, 0x2ac3, 0x86ff,
+	0x1110, 0x080c, 0x11d4, 0x002e, 0x003e, 0x006e, 0x00ce, 0x00ee,
+	0x0005, 0x00e6, 0x00c6, 0x0036, 0x0026, 0x0016, 0x6218, 0x2270,
+	0x72a0, 0x0026, 0x2019, 0x0029, 0x080c, 0x68e7, 0x0076, 0x2039,
+	0x0000, 0x080c, 0x681d, 0x2c08, 0x080c, 0xa712, 0x007e, 0x001e,
+	0x2e60, 0x080c, 0x4ecf, 0x6210, 0x6314, 0x080c, 0x493a, 0x6212,
+	0x6316, 0x001e, 0x002e, 0x003e, 0x00ce, 0x00ee, 0x0005, 0x00e6,
+	0x0006, 0x6018, 0xa080, 0x0028, 0x2004, 0xa086, 0x0080, 0x0150,
+	0x2071, 0xad00, 0x7094, 0xa005, 0x0110, 0x8001, 0x7096, 0x000e,
+	0x00ee, 0x0005, 0x2071, 0xad00, 0x70d8, 0xa005, 0x0dc0, 0x8001,
+	0x70da, 0x0ca8, 0x6000, 0xc08c, 0x6002, 0x0005, 0x00f6, 0x00e6,
+	0x00c6, 0x0036, 0x0026, 0x0016, 0x0156, 0x2178, 0x81ff, 0x1118,
+	0x20a9, 0x0001, 0x0098, 0x2001, 0xad52, 0x2004, 0xd0c4, 0x0150,
+	0xd0a4, 0x0140, 0xa006, 0x0046, 0x2020, 0x2009, 0x002d, 0x080c,
+	0xa96c, 0x004e, 0x20a9, 0x00ff, 0x2011, 0x0000, 0x0026, 0xa28e,
+	0x007e, 0x05c8, 0xa28e, 0x007f, 0x05b0, 0xa28e, 0x0080, 0x0598,
+	0xa288, 0xae34, 0x210c, 0x81ff, 0x0570, 0x8fff, 0x05c1, 0x00c6,
+	0x2160, 0x2001, 0x0001, 0x080c, 0x5037, 0x00ce, 0x2019, 0x0029,
+	0x080c, 0x68e7, 0x0076, 0x2039, 0x0000, 0x080c, 0x681d, 0x00c6,
+	0x0026, 0x2160, 0x6204, 0xa294, 0x00ff, 0xa286, 0x0006, 0x1118,
+	0x6007, 0x0404, 0x0028, 0x2001, 0x0004, 0x8007, 0xa215, 0x6206,
+	0x002e, 0x00ce, 0x0016, 0x2c08, 0x080c, 0xa712, 0x001e, 0x007e,
+	0x2160, 0x080c, 0x4ecf, 0x002e, 0x8210, 0x1f04, 0x2b3e, 0x015e,
+	0x001e, 0x002e, 0x003e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x0046,
+	0x0026, 0x0016, 0x2001, 0xad52, 0x2004, 0xd0c4, 0x0148, 0xd0a4,
+	0x0138, 0xa006, 0x2220, 0x8427, 0x2009, 0x0029, 0x080c, 0xa96c,
+	0x001e, 0x002e, 0x004e, 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6,
+	0x7284, 0x82ff, 0x01f8, 0x2011, 0xad52, 0x2214, 0xd2ac, 0x11d0,
+	0x2100, 0x080c, 0x268a, 0x81ff, 0x01b8, 0x2019, 0x0001, 0x8314,
+	0xa2e0, 0xb3c0, 0x2c04, 0xd384, 0x0120, 0xa084, 0xff00, 0x8007,
+	0x0010, 0xa084, 0x00ff, 0xa116, 0x0138, 0xa096, 0x00ff, 0x0110,
+	0x8318, 0x0c68, 0xa085, 0x0001, 0x00ce, 0x003e, 0x002e, 0x001e,
+	0x0005, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0xa180, 0xae34,
+	0x2004, 0xa065, 0x0178, 0x0016, 0x00c6, 0x080c, 0x9807, 0x001e,
+	0x090c, 0x14f6, 0x611a, 0x080c, 0x2ad9, 0x080c, 0x8078, 0x001e,
+	0x080c, 0x4c9f, 0x012e, 0x00ce, 0x001e, 0x0005, 0x7eef, 0x7de8,
+	0x7ce4, 0x80e2, 0x7be1, 0x80e0, 0x80dc, 0x80da, 0x7ad9, 0x80d6,
+	0x80d5, 0x80d4, 0x80d3, 0x80d2, 0x80d1, 0x79ce, 0x78cd, 0x80cc,
+	0x80cb, 0x80ca, 0x80c9, 0x80c7, 0x80c6, 0x77c5, 0x76c3, 0x80bc,
+	0x80ba, 0x75b9, 0x80b6, 0x74b5, 0x73b4, 0x72b3, 0x80b2, 0x80b1,
+	0x80ae, 0x71ad, 0x80ac, 0x70ab, 0x6faa, 0x6ea9, 0x80a7, 0x6da6,
+	0x6ca5, 0x6ba3, 0x6a9f, 0x699e, 0x689d, 0x809b, 0x8098, 0x6797,
+	0x6690, 0x658f, 0x6488, 0x6384, 0x6282, 0x8081, 0x8080, 0x617c,
+	0x607a, 0x8079, 0x5f76, 0x8075, 0x8074, 0x8073, 0x8072, 0x8071,
+	0x806e, 0x5e6d, 0x806c, 0x5d6b, 0x5c6a, 0x5b69, 0x8067, 0x5a66,
+	0x5965, 0x5863, 0x575c, 0x565a, 0x5559, 0x8056, 0x8055, 0x5454,
+	0x5353, 0x5252, 0x5151, 0x504e, 0x4f4d, 0x804c, 0x804b, 0x4e4a,
+	0x4d49, 0x8047, 0x4c46, 0x8045, 0x8043, 0x803c, 0x803a, 0x8039,
+	0x8036, 0x4b35, 0x8034, 0x4a33, 0x4932, 0x4831, 0x802e, 0x472d,
+	0x462c, 0x452b, 0x442a, 0x4329, 0x4227, 0x8026, 0x8025, 0x4123,
+	0x401f, 0x3f1e, 0x3e1d, 0x3d1b, 0x3c18, 0x8017, 0x8010, 0x3b0f,
+	0x3a08, 0x8004, 0x3902, 0x8001, 0x8000, 0x8000, 0x3800, 0x3700,
+	0x3600, 0x8000, 0x3500, 0x8000, 0x8000, 0x8000, 0x3400, 0x8000,
+	0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x3300, 0x3200, 0x8000,
+	0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x3100, 0x3000, 0x8000,
+	0x8000, 0x2f00, 0x8000, 0x2e00, 0x2d00, 0x2c00, 0x8000, 0x8000,
+	0x8000, 0x2b00, 0x8000, 0x2a00, 0x2900, 0x2800, 0x8000, 0x2700,
+	0x2600, 0x2500, 0x2400, 0x2300, 0x2200, 0x8000, 0x8000, 0x2100,
+	0x2000, 0x1f00, 0x1e00, 0x1d00, 0x1c00, 0x8000, 0x8000, 0x1b00,
+	0x1a00, 0x8000, 0x1900, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
+	0x8000, 0x1800, 0x8000, 0x1700, 0x1600, 0x1500, 0x8000, 0x1400,
+	0x1300, 0x1200, 0x1100, 0x1000, 0x0f00, 0x8000, 0x8000, 0x0e00,
+	0x0d00, 0x0c00, 0x0b00, 0x0a00, 0x0900, 0x8000, 0x8000, 0x0800,
+	0x0700, 0x8000, 0x0600, 0x8000, 0x8000, 0x8000, 0x0500, 0x0400,
+	0x0300, 0x8000, 0x0200, 0x8000, 0x8000, 0x8000, 0x0100, 0x8000,
+	0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x0000, 0x8000, 0x8000,
+	0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
+	0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x2071, 0xad81,
+	0x7003, 0x0002, 0xa006, 0x7012, 0x7016, 0x703a, 0x703e, 0x7033,
+	0xad91, 0x7037, 0xad91, 0x7007, 0x0001, 0x2061, 0xadd1, 0x6003,
+	0x0002, 0x0005, 0x1004, 0x2d0c, 0x0e04, 0x2d0c, 0x2071, 0xad81,
+	0x2b78, 0x7818, 0xd084, 0x1140, 0x2a60, 0x7820, 0xa08e, 0x0069,
+	0x1904, 0x2df1, 0x0804, 0x2d8a, 0x0005, 0x2071, 0xad81, 0x7004,
+	0x0002, 0x2d15, 0x2d16, 0x2d1f, 0x2d30, 0x0005, 0x1004, 0x2d1e,
+	0x0e04, 0x2d1e, 0x2b78, 0x7818, 0xd084, 0x01e8, 0x0005, 0x2b78,
+	0x2061, 0xadd1, 0x6008, 0xa08e, 0x0100, 0x0128, 0xa086, 0x0200,
+	0x0904, 0x2deb, 0x0005, 0x7014, 0x2068, 0x2a60, 0x7018, 0x0807,
+	0x7010, 0x2068, 0x6834, 0xa086, 0x0103, 0x0108, 0x0005, 0x2a60,
+	0x2b78, 0x7018, 0x0807, 0x2a60, 0x7820, 0xa08a, 0x0040, 0x1210,
+	0x61c0, 0x0042, 0x2100, 0xa08a, 0x003f, 0x1a04, 0x2de8, 0x61c0,
+	0x0804, 0x2d8a, 0x2dcc, 0x2df7, 0x2dff, 0x2e03, 0x2e0b, 0x2e11,
+	0x2e15, 0x2e21, 0x2e24, 0x2e2e, 0x2e31, 0x2de8, 0x2de8, 0x2de8,
+	0x2e34, 0x2de8, 0x2e43, 0x2e5a, 0x2e71, 0x2ee8, 0x2eed, 0x2f16,
+	0x2f67, 0x2f78, 0x2f96, 0x2fcd, 0x2fd7, 0x2fe4, 0x2ff7, 0x3018,
+	0x3021, 0x3057, 0x305d, 0x2de8, 0x3086, 0x2de8, 0x2de8, 0x2de8,
+	0x2de8, 0x2de8, 0x308d, 0x3097, 0x2de8, 0x2de8, 0x2de8, 0x2de8,
+	0x2de8, 0x2de8, 0x2de8, 0x2de8, 0x309f, 0x2de8, 0x2de8, 0x2de8,
+	0x2de8, 0x2de8, 0x30b1, 0x30b9, 0x2de8, 0x2de8, 0x2de8, 0x2de8,
+	0x2de8, 0x2de8, 0x0002, 0x30cb, 0x311f, 0x317a, 0x318a, 0x2de8,
+	0x31a4, 0x35cb, 0x3fbb, 0x2de8, 0x2de8, 0x2de8, 0x2de8, 0x2de8,
+	0x2de8, 0x2de8, 0x2de8, 0x2e2e, 0x2e31, 0x35cd, 0x2de8, 0x35da,
+	0x403c, 0x4097, 0x40fb, 0x2de8, 0x415a, 0x4180, 0x419f, 0x2de8,
+	0x2de8, 0x2de8, 0x2de8, 0x35de, 0x376b, 0x3785, 0x37a3, 0x3804,
+	0x3858, 0x3863, 0x389a, 0x38a9, 0x38b8, 0x38bb, 0x38de, 0x3928,
+	0x398e, 0x399b, 0x3a9c, 0x3bb3, 0x3bdc, 0x3cda, 0x3cfc, 0x3d08,
+	0x3d41, 0x3e05, 0x2de8, 0x2de8, 0x2de8, 0x2de8, 0x3e6d, 0x3e88,
+	0x3efa, 0x3fac, 0x713c, 0x0000, 0x2021, 0x4000, 0x080c, 0x3c39,
+	0x0126, 0x2091, 0x8000, 0x0e04, 0x2dd8, 0x7818, 0xd084, 0x0110,
+	0x012e, 0x0cb0, 0x7c22, 0x7926, 0x7a2a, 0x7b2e, 0x781b, 0x0001,
+	0x2091, 0x4080, 0x7007, 0x0001, 0x2091, 0x5000, 0x012e, 0x0005,
+	0x2021, 0x4001, 0x0c18, 0x2021, 0x4002, 0x0c00, 0x2021, 0x4003,
+	0x08e8, 0x2021, 0x4005, 0x08d0, 0x2021, 0x4006, 0x08b8, 0xa02e,
+	0x2520, 0x7b28, 0x7a2c, 0x7824, 0x7930, 0x0804, 0x3c46, 0x7823,
+	0x0004, 0x7824, 0x0807, 0xa02e, 0x2520, 0x7b28, 0x7a2c, 0x7824,
+	0x7930, 0x0804, 0x3c49, 0x7924, 0x7828, 0x2114, 0x200a, 0x0804,
+	0x2dcc, 0x7924, 0x2114, 0x0804, 0x2dcc, 0x2099, 0x0009, 0x20a1,
+	0x0009, 0x20a9, 0x0007, 0x53a3, 0x7924, 0x7a28, 0x7b2c, 0x0804,
+	0x2dcc, 0x7824, 0x2060, 0x0090, 0x2009, 0x0002, 0x2011, 0x0001,
+	0x2019, 0x001b, 0x783b, 0x0017, 0x0804, 0x2dcc, 0x7d38, 0x7c3c,
+	0x0840, 0x7d38, 0x7c3c, 0x0888, 0x2061, 0x1000, 0xe10c, 0xa006,
+	0x2c15, 0xa200, 0x8c60, 0x8109, 0x1dd8, 0x2010, 0xa005, 0x0904,
+	0x2dcc, 0x0804, 0x2dee, 0x2069, 0xad51, 0x7824, 0x7930, 0xa11a,
+	0x1a04, 0x2df4, 0x8019, 0x0904, 0x2df4, 0x684a, 0x6942, 0x782c,
+	0x6852, 0x7828, 0x6856, 0xa006, 0x685a, 0x685e, 0x080c, 0x5a1c,
+	0x0804, 0x2dcc, 0x2069, 0xad51, 0x7824, 0x7934, 0xa11a, 0x1a04,
+	0x2df4, 0x8019, 0x0904, 0x2df4, 0x684e, 0x6946, 0x782c, 0x6862,
+	0x7828, 0x6866, 0xa006, 0x686a, 0x686e, 0x080c, 0x50d9, 0x0804,
+	0x2dcc, 0xa02e, 0x2520, 0x81ff, 0x1904, 0x2df1, 0x7924, 0x7b28,
+	0x7a2c, 0x20a9, 0x0005, 0x20a1, 0xad88, 0x41a1, 0x080c, 0x3c05,
+	0x0904, 0x2df1, 0x2009, 0x0020, 0x080c, 0x3c46, 0x701b, 0x2e89,
+	0x0005, 0x6834, 0x2008, 0xa084, 0x00ff, 0xa096, 0x0011, 0x0120,
+	0xa096, 0x0019, 0x1904, 0x2df1, 0x810f, 0xa18c, 0x00ff, 0x0904,
+	0x2df1, 0x710e, 0x700c, 0x8001, 0x0528, 0x700e, 0x080c, 0x3c05,
+	0x0904, 0x2df1, 0x2009, 0x0020, 0x2061, 0xadd1, 0x6224, 0x6328,
+	0x642c, 0x6530, 0xa290, 0x0040, 0xa399, 0x0000, 0xa4a1, 0x0000,
+	0xa5a9, 0x0000, 0x080c, 0x3c46, 0x701b, 0x2eb7, 0x0005, 0x6834,
+	0xa084, 0x00ff, 0xa096, 0x0002, 0x0120, 0xa096, 0x000a, 0x1904,
+	0x2df1, 0x08c0, 0x7010, 0x2068, 0x6838, 0xc0fd, 0x683a, 0x080c,
+	0x4b7c, 0x1128, 0x7007, 0x0003, 0x701b, 0x2ed1, 0x0005, 0x080c,
+	0x51df, 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x2099, 0xad88,
+	0x530a, 0x2100, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9,
+	0x0000, 0xad80, 0x000d, 0x2009, 0x0020, 0x012e, 0x0804, 0x3c49,
+	0x61a8, 0x7824, 0x60aa, 0x0804, 0x2dcc, 0x2091, 0x8000, 0x7823,
+	0x4000, 0x7827, 0x4953, 0x782b, 0x5020, 0x782f, 0x2020, 0x2009,
+	0x017f, 0x2104, 0x7832, 0x3f00, 0x7836, 0x2061, 0x0100, 0x6200,
+	0x2061, 0x0200, 0x603c, 0x8007, 0xa205, 0x783a, 0x2009, 0x04fd,
+	0x2104, 0x783e, 0x781b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080,
+	0x2071, 0x0010, 0x20c1, 0x00f0, 0x0804, 0x0427, 0x81ff, 0x1904,
+	0x2df1, 0x7924, 0x810f, 0xa18c, 0x00ff, 0x080c, 0x4cdc, 0x1904,
+	0x2df4, 0x7e38, 0xa684, 0x3fff, 0xa082, 0x4000, 0x0210, 0x0804,
+	0x2df4, 0x7c28, 0x7d2c, 0x080c, 0x4e96, 0xd28c, 0x1118, 0x080c,
+	0x4e41, 0x0010, 0x080c, 0x4e6f, 0x1518, 0x2061, 0xb400, 0x0126,
+	0x2091, 0x8000, 0x6000, 0xa086, 0x0000, 0x0148, 0x6010, 0xa06d,
+	0x0130, 0x683c, 0xa406, 0x1118, 0x6840, 0xa506, 0x0150, 0x012e,
+	0xace0, 0x0018, 0x2001, 0xad16, 0x2004, 0xac02, 0x1a04, 0x2df1,
+	0x0c30, 0x080c, 0x929c, 0x012e, 0x0904, 0x2df1, 0x0804, 0x2dcc,
+	0xa00e, 0x2001, 0x0005, 0x080c, 0x51df, 0x0126, 0x2091, 0x8000,
+	0x080c, 0x9803, 0x080c, 0x510c, 0x012e, 0x0804, 0x2dcc, 0x81ff,
+	0x1904, 0x2df1, 0x080c, 0x3c1a, 0x0904, 0x2df4, 0x080c, 0x4d96,
+	0x0904, 0x2df1, 0x080c, 0x4ea2, 0x0904, 0x2df1, 0x0804, 0x2dcc,
+	0x81ff, 0x1904, 0x2df1, 0x080c, 0x3c2a, 0x0904, 0x2df4, 0x080c,
+	0x4f0d, 0x0904, 0x2df1, 0x2019, 0x0005, 0x080c, 0x4ebd, 0x0904,
+	0x2df1, 0x7828, 0xa08a, 0x1000, 0x1a04, 0x2df4, 0x8003, 0x800b,
+	0x810b, 0xa108, 0x080c, 0x6519, 0x0804, 0x2dcc, 0x0126, 0x2091,
+	0x8000, 0x81ff, 0x0118, 0x2009, 0x0001, 0x0448, 0x2029, 0x00ff,
+	0x644c, 0x2400, 0xa506, 0x01f0, 0x2508, 0x080c, 0x4cdc, 0x11d0,
+	0x080c, 0x4f0d, 0x1128, 0x2009, 0x0002, 0x62b0, 0x2518, 0x00b8,
+	0x2019, 0x0004, 0x080c, 0x4ebd, 0x1118, 0x2009, 0x0006, 0x0078,
+	0x7824, 0xa08a, 0x1000, 0x1270, 0x8003, 0x800b, 0x810b, 0xa108,
+	0x080c, 0x6519, 0x8529, 0x1ae8, 0x012e, 0x0804, 0x2dcc, 0x012e,
+	0x0804, 0x2df1, 0x012e, 0x0804, 0x2df4, 0x080c, 0x3c1a, 0x0904,
+	0x2df4, 0x080c, 0x4dfc, 0x080c, 0x4e96, 0x0804, 0x2dcc, 0x81ff,
+	0x1904, 0x2df1, 0x080c, 0x3c1a, 0x0904, 0x2df4, 0x080c, 0x4ded,
+	0x080c, 0x4e96, 0x0804, 0x2dcc, 0x81ff, 0x1904, 0x2df1, 0x080c,
+	0x3c1a, 0x0904, 0x2df4, 0x080c, 0x4e71, 0x0904, 0x2df1, 0x080c,
+	0x4bc0, 0x080c, 0x4e3a, 0x080c, 0x4e96, 0x0804, 0x2dcc, 0x080c,
+	0x3c1a, 0x0904, 0x2df4, 0x080c, 0x4d96, 0x0904, 0x2df1, 0x62a0,
+	0x2019, 0x0005, 0x00c6, 0x080c, 0x4ecf, 0x2061, 0x0000, 0x080c,
+	0x68e7, 0x0076, 0x2039, 0x0000, 0x080c, 0x681d, 0x2009, 0x0000,
+	0x080c, 0xa712, 0x007e, 0x00ce, 0x080c, 0x4e96, 0x0804, 0x2dcc,
+	0x080c, 0x3c1a, 0x0904, 0x2df4, 0x080c, 0x4e96, 0x2208, 0x0804,
+	0x2dcc, 0x0156, 0x00d6, 0x00e6, 0x2069, 0xae13, 0x6810, 0x6914,
+	0xa10a, 0x1210, 0x2009, 0x0000, 0x6816, 0x2011, 0x0000, 0x2019,
+	0x0000, 0x20a9, 0x007e, 0x2069, 0xae34, 0x2d04, 0xa075, 0x0130,
+	0x704c, 0x0071, 0xa210, 0x7080, 0x0059, 0xa318, 0x8d68, 0x1f04,
+	0x3035, 0x2300, 0xa218, 0x00ee, 0x00de, 0x015e, 0x0804, 0x2dcc,
+	0x00f6, 0x0016, 0xa07d, 0x0140, 0x2001, 0x0000, 0x8000, 0x2f0c,
+	0x81ff, 0x0110, 0x2178, 0x0cd0, 0x001e, 0x00fe, 0x0005, 0x2069,
+	0xae13, 0x6910, 0x62ac, 0x0804, 0x2dcc, 0x81ff, 0x1904, 0x2df1,
+	0x614c, 0xa190, 0x2be6, 0x2215, 0xa294, 0x00ff, 0x636c, 0x83ff,
+	0x0108, 0x6270, 0x67d0, 0xd79c, 0x0118, 0x2031, 0x0001, 0x0090,
+	0xd7ac, 0x0118, 0x2031, 0x0003, 0x0068, 0xd7a4, 0x0118, 0x2031,
+	0x0002, 0x0040, 0x080c, 0x574f, 0x1118, 0x2031, 0x0004, 0x0010,
+	0x2031, 0x0000, 0x7e3a, 0x7f3e, 0x0804, 0x2dcc, 0x613c, 0x6240,
+	0x2019, 0xafa3, 0x231c, 0x0804, 0x2dcc, 0x0126, 0x2091, 0x8000,
+	0x6134, 0xa006, 0x2010, 0x2018, 0x012e, 0x0804, 0x2dcc, 0x080c,
+	0x3c2a, 0x0904, 0x2df4, 0x6244, 0x6338, 0x0804, 0x2dcc, 0x613c,
+	0x6240, 0x7824, 0x603e, 0x7b28, 0x6342, 0x2069, 0xad51, 0x831f,
+	0xa305, 0x6816, 0x782c, 0x2069, 0xafa3, 0x2d1c, 0x206a, 0x0804,
+	0x2dcc, 0x0126, 0x2091, 0x8000, 0x7824, 0x6036, 0x012e, 0x0804,
+	0x2dcc, 0x080c, 0x3c2a, 0x0904, 0x2df4, 0x7828, 0xa00d, 0x0904,
+	0x2df4, 0x782c, 0xa005, 0x0904, 0x2df4, 0x6244, 0x6146, 0x6338,
+	0x603a, 0x0804, 0x2dcc, 0x2001, 0xad00, 0x2004, 0xa086, 0x0003,
+	0x1904, 0x2df1, 0x00c6, 0x2061, 0x0100, 0x7924, 0x810f, 0xa18c,
+	0x00ff, 0xa196, 0x00ff, 0x1130, 0x2001, 0xad14, 0x2004, 0xa085,
+	0xff00, 0x0078, 0xa182, 0x007f, 0x16a0, 0xa188, 0x2be6, 0x210d,
+	0xa18c, 0x00ff, 0x2001, 0xad14, 0x2004, 0xa116, 0x0550, 0x810f,
+	0xa105, 0x0126, 0x2091, 0x8000, 0x0006, 0x080c, 0x8022, 0x000e,
+	0x01e0, 0x601a, 0x600b, 0xbc09, 0x601f, 0x0001, 0x080c, 0x3c05,
+	0x01d8, 0x6837, 0x0000, 0x7007, 0x0003, 0x6833, 0x0000, 0x6838,
+	0xc0fd, 0x683a, 0x701b, 0x3173, 0x2d00, 0x6012, 0x2009, 0x0032,
+	0x080c, 0x80a7, 0x012e, 0x00ce, 0x0005, 0x012e, 0x00ce, 0x0804,
+	0x2df1, 0x00ce, 0x0804, 0x2df4, 0x080c, 0x8078, 0x0cb0, 0x2001,
+	0xad00, 0x2004, 0xa086, 0x0003, 0x1904, 0x2df1, 0x00c6, 0x2061,
+	0x0100, 0x7924, 0x810f, 0xa18c, 0x00ff, 0xa196, 0x00ff, 0x1130,
+	0x2001, 0xad14, 0x2004, 0xa085, 0xff00, 0x0078, 0xa182, 0x007f,
+	0x16a0, 0xa188, 0x2be6, 0x210d, 0xa18c, 0x00ff, 0x2001, 0xad14,
+	0x2004, 0xa116, 0x0550, 0x810f, 0xa105, 0x0126, 0x2091, 0x8000,
+	0x0006, 0x080c, 0x8022, 0x000e, 0x01e0, 0x601a, 0x600b, 0xbc05,
+	0x601f, 0x0001, 0x080c, 0x3c05, 0x01d8, 0x6837, 0x0000, 0x7007,
+	0x0003, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x701b, 0x3173,
+	0x2d00, 0x6012, 0x2009, 0x0032, 0x080c, 0x80a7, 0x012e, 0x00ce,
+	0x0005, 0x012e, 0x00ce, 0x0804, 0x2df1, 0x00ce, 0x0804, 0x2df4,
+	0x080c, 0x8078, 0x0cb0, 0x6830, 0xa086, 0x0100, 0x0904, 0x2df1,
+	0x0804, 0x2dcc, 0x2061, 0xb048, 0x0126, 0x2091, 0x8000, 0x6000,
+	0xd084, 0x0128, 0x6104, 0x6208, 0x012e, 0x0804, 0x2dcc, 0x012e,
+	0x0804, 0x2df4, 0x81ff, 0x1904, 0x2df1, 0x080c, 0x574f, 0x0904,
+	0x2df1, 0x0126, 0x2091, 0x8000, 0x6244, 0x6064, 0xa202, 0x0248,
+	0xa085, 0x0001, 0x080c, 0x26c0, 0x080c, 0x436e, 0x012e, 0x0804,
+	0x2dcc, 0x012e, 0x0804, 0x2df4, 0x0126, 0x2091, 0x8000, 0x7824,
+	0xa084, 0x0007, 0x0002, 0x31b6, 0x31bf, 0x31c6, 0x31b3, 0x31b3,
+	0x31b3, 0x31b3, 0x31b3, 0x012e, 0x0804, 0x2df4, 0x2009, 0x0114,
+	0x2104, 0xa085, 0x0800, 0x200a, 0x080c, 0x332f, 0x0070, 0x2009,
+	0x010b, 0x200b, 0x0010, 0x080c, 0x332f, 0x0038, 0x81ff, 0x0128,
+	0x012e, 0x2021, 0x400b, 0x0804, 0x2dce, 0x0086, 0x0096, 0x00a6,
+	0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2009, 0x0101, 0x210c,
+	0x0016, 0x2001, 0x0138, 0x200c, 0x2003, 0x0001, 0x0016, 0x2001,
+	0x007a, 0x2034, 0x2001, 0x007b, 0x202c, 0xa006, 0x2048, 0x2050,
+	0x2058, 0x080c, 0x3570, 0x080c, 0x34da, 0xa03e, 0x2720, 0x00f6,
+	0x00e6, 0x00c6, 0x2d60, 0x2071, 0xb01e, 0x2079, 0x0020, 0x00d6,
+	0x2069, 0x0000, 0x6824, 0xd0b4, 0x0140, 0x2001, 0x007d, 0x2004,
+	0x783e, 0x2001, 0x007c, 0x2004, 0x783a, 0x00de, 0x2011, 0x0001,
+	0x080c, 0x3486, 0x080c, 0x3486, 0x00ce, 0x00ee, 0x00fe, 0x080c,
+	0x33d5, 0x080c, 0x34ae, 0x080c, 0x342b, 0x080c, 0x3394, 0x080c,
+	0x33c5, 0x00f6, 0x2079, 0x0100, 0x7824, 0xd094, 0x0530, 0x7814,
+	0xa084, 0x0184, 0xa085, 0x0010, 0x7816, 0x2079, 0x0140, 0x080c,
+	0x330d, 0x1110, 0x00fe, 0x0430, 0x7804, 0xd0dc, 0x0dc0, 0x2079,
+	0x0100, 0x7827, 0x0086, 0x7814, 0xa084, 0x0184, 0xa085, 0x0032,
+	0x7816, 0x080c, 0x330d, 0x1110, 0x00fe, 0x00a0, 0x7824, 0xd0bc,
+	0x0dc0, 0x7827, 0x0080, 0xa026, 0x7c16, 0x7824, 0xd0ac, 0x0130,
+	0x8b58, 0x080c, 0x3317, 0x00fe, 0x0804, 0x32d7, 0x00fe, 0x080c,
+	0x330d, 0x1150, 0x8948, 0x2001, 0x007a, 0x2602, 0x2001, 0x007b,
+	0x2502, 0x080c, 0x3317, 0x0088, 0x87ff, 0x0140, 0x2001, 0x0201,
+	0x2004, 0xa005, 0x1904, 0x3211, 0x8739, 0x0038, 0x2001, 0xaffd,
+	0x2004, 0xa086, 0x0000, 0x1904, 0x3211, 0x2001, 0x0033, 0x2003,
+	0x00f6, 0x8631, 0x1208, 0x8529, 0x2500, 0xa605, 0x0904, 0x32d7,
+	0x7824, 0xd0bc, 0x0128, 0x2900, 0xaa05, 0xab05, 0x1904, 0x32d7,
+	0x6033, 0x000d, 0x2001, 0x0030, 0x2003, 0x0004, 0x7824, 0xd0ac,
+	0x1148, 0x2001, 0xaffd, 0x2003, 0x0003, 0x2001, 0x0030, 0x2003,
+	0x0009, 0x0040, 0x6027, 0x0001, 0x2001, 0x0075, 0x2004, 0xa005,
+	0x0108, 0x6026, 0x2c00, 0x601a, 0x20e1, 0x9040, 0x2d00, 0x681a,
+	0x6833, 0x000d, 0x7824, 0xd0a4, 0x1180, 0x6827, 0x0000, 0x00c6,
+	0x20a9, 0x0004, 0x2061, 0x0020, 0x6003, 0x0008, 0x2001, 0x0203,
+	0x2004, 0x1f04, 0x32ac, 0x00ce, 0x0040, 0x6827, 0x0001, 0x2001,
+	0x0074, 0x2004, 0xa005, 0x0108, 0x6826, 0x00f6, 0x00c6, 0x2079,
+	0x0100, 0x2061, 0x0020, 0x7827, 0x0002, 0x2001, 0x0072, 0x2004,
+	0xa084, 0xfff8, 0x601a, 0x0006, 0x2001, 0x0073, 0x2004, 0x601e,
+	0x78c6, 0x000e, 0x78ca, 0x00ce, 0x00fe, 0x0804, 0x31ef, 0x2061,
+	0x0100, 0x6027, 0x0002, 0x001e, 0x61e2, 0x001e, 0x6106, 0x7824,
+	0xa084, 0x0003, 0xa086, 0x0002, 0x0188, 0x20e1, 0x9028, 0x6050,
+	0xa084, 0xf7ef, 0x6052, 0x602f, 0x0000, 0x602c, 0xc0ac, 0x602e,
+	0x604b, 0xf7f7, 0x6043, 0x0090, 0x6043, 0x0010, 0x2908, 0x2a10,
+	0x2b18, 0x2b00, 0xaa05, 0xa905, 0x00fe, 0x00ee, 0x00de, 0x00ce,
+	0x00be, 0x00ae, 0x009e, 0x008e, 0x1118, 0x012e, 0x0804, 0x2dcc,
+	0x012e, 0x2021, 0x400c, 0x0804, 0x2dce, 0xa085, 0x0001, 0x1d04,
+	0x3316, 0x2091, 0x6000, 0x8420, 0xa486, 0x0064, 0x0005, 0x2001,
+	0x0105, 0x2003, 0x0010, 0x2001, 0x0030, 0x2003, 0x0004, 0x2001,
+	0x0020, 0x2003, 0x0004, 0x2001, 0xaffd, 0x2003, 0x0000, 0x2001,
+	0xb01e, 0x2003, 0x0000, 0x20e1, 0xf000, 0xa026, 0x0005, 0x00f6,
+	0x2079, 0x0100, 0x2001, 0xad14, 0x200c, 0x7932, 0x7936, 0x080c,
+	0x26a0, 0x7850, 0xa084, 0x0980, 0xa085, 0x0030, 0x7852, 0x2019,
+	0x01f4, 0x8319, 0x1df0, 0xa084, 0x0980, 0x7852, 0x782c, 0xc0ad,
+	0x782e, 0x20a9, 0x0046, 0x1d04, 0x334b, 0x2091, 0x6000, 0x1f04,
+	0x334b, 0x7850, 0xa085, 0x0400, 0x7852, 0x2001, 0x0009, 0x2004,
+	0xa084, 0x0003, 0xa086, 0x0001, 0x1118, 0x782c, 0xc0ac, 0x782e,
+	0x784b, 0xf7f7, 0x7843, 0x0090, 0x7843, 0x0010, 0x20a9, 0x000e,
+	0xe000, 0x1f04, 0x3368, 0x7850, 0xa085, 0x1400, 0x7852, 0x2019,
+	0x61a8, 0x7854, 0xe000, 0xe000, 0xd08c, 0x1110, 0x8319, 0x1dc8,
+	0x7827, 0x0048, 0x7850, 0xa085, 0x0400, 0x7852, 0x7843, 0x0040,
+	0x2019, 0x01f4, 0xe000, 0xe000, 0x8319, 0x1de0, 0x2001, 0x0140,
+	0x2003, 0x0100, 0x7827, 0x0020, 0x7843, 0x0000, 0x2003, 0x0000,
+	0x7827, 0x0048, 0x00fe, 0x0005, 0x7824, 0xd0ac, 0x11c8, 0x00f6,
+	0x00e6, 0x2071, 0xaffd, 0x2079, 0x0030, 0x2001, 0x0201, 0x2004,
+	0xa005, 0x0160, 0x7000, 0xa086, 0x0000, 0x1140, 0x0051, 0xd0bc,
+	0x0108, 0x8738, 0x7003, 0x0003, 0x7803, 0x0019, 0x00ee, 0x00fe,
+	0x0005, 0x780c, 0xa08c, 0x0070, 0x0178, 0x2009, 0x007a, 0x260a,
+	0x2009, 0x007b, 0x250a, 0xd0b4, 0x0108, 0x8a50, 0xd0ac, 0x0108,
+	0x8948, 0xd0a4, 0x0108, 0x8b58, 0x0005, 0x00f6, 0x2079, 0x0200,
+	0x781c, 0xd084, 0x0140, 0x20e1, 0x0007, 0x20e1, 0x2000, 0x2001,
+	0x020a, 0x2004, 0x0ca8, 0x00fe, 0x0005, 0x00e6, 0x2071, 0x0100,
+	0x2009, 0xad14, 0x210c, 0x716e, 0x7063, 0x0100, 0x7166, 0x719e,
+	0x706b, 0x0000, 0x7073, 0x0809, 0x7077, 0x0008, 0x7078, 0xa080,
+	0x0100, 0x707a, 0x7080, 0x8000, 0x7082, 0x7087, 0xaaaa, 0xa006,
+	0x708a, 0x708e, 0x707e, 0x70d6, 0x70ab, 0x0036, 0x70af, 0x95d5,
+	0x7027, 0x0080, 0x7014, 0xa084, 0x0184, 0xa085, 0x0032, 0x7016,
+	0x080c, 0x34ae, 0x080c, 0x330d, 0x1110, 0x8421, 0x0028, 0x7024,
+	0xd0bc, 0x0db0, 0x7027, 0x0080, 0x00f6, 0x00e6, 0x2071, 0xaffd,
+	0x2079, 0x0030, 0x00d6, 0x2069, 0x0000, 0x6824, 0xd0b4, 0x0120,
+	0x683c, 0x783e, 0x6838, 0x783a, 0x00de, 0x2011, 0x0011, 0x080c,
+	0x3486, 0x2011, 0x0001, 0x080c, 0x3486, 0x00ee, 0x00fe, 0x7017,
+	0x0000, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x2071, 0xaffd, 0x2079,
+	0x0030, 0x7904, 0xd1fc, 0x0904, 0x3483, 0x7803, 0x0002, 0xa026,
+	0xd19c, 0x1904, 0x347f, 0x7000, 0x0002, 0x3483, 0x3441, 0x3465,
+	0x347f, 0xd1bc, 0x1150, 0xd1dc, 0x1150, 0x8001, 0x7002, 0x2011,
+	0x0001, 0x04e1, 0x05c0, 0x04d1, 0x04b0, 0x780f, 0x0000, 0x7820,
+	0x7924, 0x7803, 0x0004, 0x7822, 0x7926, 0x2001, 0x0201, 0x200c,
+	0x81ff, 0x0de8, 0x080c, 0x33b1, 0x2009, 0x0001, 0x7808, 0xd0ec,
+	0x0110, 0x2009, 0x0011, 0x7902, 0x00f0, 0x8001, 0x7002, 0xa184,
+	0x0880, 0x1138, 0x7804, 0xd0fc, 0x1940, 0x2011, 0x0001, 0x00b1,
+	0x0090, 0x6030, 0xa092, 0x0004, 0xa086, 0x0009, 0x1120, 0x6000,
+	0x601a, 0x2011, 0x0025, 0x6232, 0xd1dc, 0x1988, 0x0870, 0x7803,
+	0x0004, 0x7003, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x6024, 0xa005,
+	0x0520, 0x8001, 0x6026, 0x6018, 0x6130, 0xa140, 0x2804, 0x7832,
+	0x8840, 0x2804, 0x7836, 0x8840, 0x2804, 0x7822, 0x8840, 0x2804,
+	0x7826, 0x8840, 0x7a02, 0x7000, 0x8000, 0x7002, 0x6018, 0xa802,
+	0xa08a, 0x0029, 0x1138, 0x6018, 0xa080, 0x0001, 0x2004, 0x601a,
+	0x2001, 0x000d, 0x6032, 0xa085, 0x0001, 0x0005, 0x00f6, 0x00e6,
+	0x00c6, 0x2071, 0xb01e, 0x2079, 0x0020, 0x7904, 0xd1fc, 0x01f0,
+	0x7803, 0x0002, 0x2d60, 0xa026, 0x7000, 0x0002, 0x34d6, 0x34c1,
+	0x34cd, 0x8001, 0x7002, 0xd19c, 0x1188, 0x2011, 0x0001, 0x080c,
+	0x3486, 0x0160, 0x080c, 0x3486, 0x0048, 0x8001, 0x7002, 0x7804,
+	0xd0fc, 0x1d30, 0x2011, 0x0001, 0x080c, 0x3486, 0x00ce, 0x00ee,
+	0x00fe, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x2061, 0x0200, 0x601b,
+	0x0004, 0x2061, 0x0100, 0x60cf, 0x0400, 0x6004, 0xc0ac, 0xa085,
+	0x0200, 0x6006, 0x2001, 0x0074, 0x2004, 0xa005, 0x01f8, 0x2038,
+	0x2001, 0x0076, 0x2024, 0x2001, 0x0077, 0x201c, 0x080c, 0x3c05,
+	0x6833, 0x000d, 0x6f26, 0x2d00, 0x681a, 0xa78a, 0x0007, 0x0220,
+	0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0xa03e, 0x6818, 0xa080,
+	0x000d, 0x04a1, 0x1d90, 0x2d00, 0x681a, 0x0088, 0x080c, 0x3c05,
+	0x6833, 0x000d, 0x2070, 0x6827, 0x0001, 0x2d00, 0x681a, 0x2001,
+	0x0076, 0x2004, 0x2072, 0x2001, 0x0077, 0x2004, 0x7006, 0x2061,
+	0x0020, 0x2079, 0x0100, 0x6013, 0x0400, 0x20e1, 0x9040, 0x2001,
+	0x0072, 0x2004, 0xa084, 0xfff8, 0x700a, 0x601a, 0x0006, 0x2001,
+	0x0073, 0x2004, 0x700e, 0x601e, 0x78c6, 0x000e, 0x78ca, 0xa006,
+	0x603a, 0x603e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x00e6, 0x2071,
+	0x0010, 0x20a0, 0x2099, 0x0014, 0x7003, 0x0026, 0x7432, 0x7336,
+	0xa006, 0x703a, 0x703e, 0x810b, 0x810b, 0x21a8, 0x810b, 0x7122,
+	0x7003, 0x0041, 0x7004, 0xd0fc, 0x0de8, 0x7003, 0x0002, 0x7003,
+	0x0040, 0x53a5, 0x7430, 0x7334, 0x87ff, 0x0180, 0x00c6, 0x00d6,
+	0x2d60, 0x00c6, 0x080c, 0x3c05, 0x00ce, 0x6018, 0x2070, 0x2d00,
+	0x7006, 0x601a, 0x00de, 0x00ce, 0xa085, 0x0001, 0x00ee, 0x0005,
+	0x00e6, 0x2001, 0x0075, 0x2004, 0xa005, 0x0508, 0x2038, 0x2001,
+	0x0078, 0x2024, 0x2001, 0x0079, 0x201c, 0x080c, 0x3c05, 0x2d60,
+	0x6833, 0x000d, 0x6f26, 0x2d00, 0x681a, 0xa78a, 0x0007, 0x0220,
+	0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0xa03e, 0x6818, 0xa080,
+	0x000d, 0x080c, 0x353e, 0x1d88, 0x2d00, 0x681a, 0x00e0, 0x080c,
+	0x3c05, 0x2d60, 0x6033, 0x000d, 0x2070, 0x6027, 0x0001, 0x2c00,
+	0x601a, 0x2001, 0x0078, 0x2004, 0x2072, 0x2001, 0x0079, 0x2004,
+	0x7006, 0x2001, 0x0072, 0x2004, 0xa084, 0xfff8, 0x700a, 0x2001,
+	0x0073, 0x2004, 0x700e, 0x2001, 0x0030, 0x2003, 0x0004, 0x7824,
+	0xd0ac, 0x1178, 0x2001, 0x0101, 0x200c, 0xc1ed, 0x2102, 0x6027,
+	0x0000, 0x2001, 0xaffd, 0x2003, 0x0003, 0x2001, 0x0030, 0x2003,
+	0x0009, 0x00ee, 0x0005, 0x0804, 0x2dcc, 0x0126, 0x2091, 0x8000,
+	0x20a9, 0x0011, 0x2001, 0xad40, 0x20a0, 0xa006, 0x40a4, 0x012e,
+	0x0804, 0x2dcc, 0x7d38, 0x7c3c, 0x0804, 0x2e73, 0x080c, 0x3c05,
+	0x0904, 0x2df1, 0x080c, 0x574f, 0x0110, 0x080c, 0x491f, 0x2009,
+	0x001c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3c46, 0x701b,
+	0x35f2, 0x0005, 0xade8, 0x000d, 0x6800, 0xa005, 0x0904, 0x2df4,
+	0x6804, 0xd0ac, 0x0118, 0xd0a4, 0x0904, 0x2df4, 0xd094, 0x00c6,
+	0x2061, 0x0100, 0x6104, 0x0138, 0x6200, 0xa292, 0x0005, 0x0218,
+	0xa18c, 0xffdf, 0x0010, 0xa18d, 0x0020, 0x6106, 0x00ce, 0xd08c,
+	0x00c6, 0x2061, 0x0100, 0x6104, 0x0118, 0xa18d, 0x0010, 0x0010,
+	0xa18c, 0xffef, 0x6106, 0x00ce, 0x2009, 0x0100, 0x210c, 0xa18a,
+	0x0002, 0x0268, 0xd084, 0x0158, 0x6a28, 0xa28a, 0x007f, 0x1a04,
+	0x2df4, 0xa288, 0x2be6, 0x210d, 0xa18c, 0x00ff, 0x6156, 0xd0dc,
+	0x0130, 0x6828, 0xa08a, 0x007f, 0x1a04, 0x2df4, 0x604e, 0x6808,
+	0xa08a, 0x0100, 0x0a04, 0x2df4, 0xa08a, 0x0841, 0x1a04, 0x2df4,
+	0xa084, 0x0007, 0x1904, 0x2df4, 0x680c, 0xa005, 0x0904, 0x2df4,
+	0x6810, 0xa005, 0x0904, 0x2df4, 0x6848, 0x6940, 0xa10a, 0x1a04,
+	0x2df4, 0x8001, 0x0904, 0x2df4, 0x684c, 0x6944, 0xa10a, 0x1a04,
+	0x2df4, 0x8001, 0x0904, 0x2df4, 0x6804, 0xd0fc, 0x0560, 0x080c,
+	0x3c05, 0x0904, 0x2df1, 0x2009, 0x0014, 0x7a2c, 0x7b28, 0x7c3c,
+	0x7d38, 0xa290, 0x0038, 0xa399, 0x0000, 0x080c, 0x3c46, 0x701b,
+	0x3672, 0x0005, 0xade8, 0x000d, 0x20a9, 0x0014, 0x2d98, 0x2069,
+	0xad6d, 0x2da0, 0x53a3, 0x7010, 0xa0e8, 0x000d, 0x2001, 0xad71,
+	0x200c, 0xd1e4, 0x0140, 0x00c6, 0x2061, 0x0100, 0x6004, 0xa085,
+	0x0b00, 0x6006, 0x00ce, 0x20a9, 0x001c, 0x2d98, 0x2069, 0xad51,
+	0x2da0, 0x53a3, 0x6814, 0xa08c, 0x00ff, 0x613e, 0x8007, 0xa084,
+	0x00ff, 0x6042, 0x080c, 0x5a1c, 0x080c, 0x5070, 0x080c, 0x50d9,
+	0x6000, 0xa086, 0x0000, 0x1904, 0x3755, 0x6808, 0x602a, 0x080c,
+	0x22f8, 0x0006, 0x2001, 0x0100, 0x2004, 0xa082, 0x0005, 0x000e,
+	0x0268, 0x2009, 0x0170, 0x200b, 0x0080, 0xe000, 0xe000, 0x200b,
+	0x0000, 0x0036, 0x6b08, 0x080c, 0x26fb, 0x003e, 0x6818, 0x691c,
+	0x6a20, 0x6b24, 0x8007, 0x810f, 0x8217, 0x831f, 0x6016, 0x611a,
+	0x621e, 0x6322, 0x6c04, 0xd4f4, 0x0148, 0x6830, 0x6934, 0x6a38,
+	0x6b3c, 0x8007, 0x810f, 0x8217, 0x831f, 0x0010, 0xa084, 0xf0ff,
+	0x6006, 0x610a, 0x620e, 0x6312, 0x8007, 0x810f, 0x8217, 0x831f,
+	0x20a9, 0x0004, 0x20a1, 0xafad, 0x40a1, 0x080c, 0x659c, 0x6904,
+	0xd1fc, 0x0520, 0x00c6, 0x2009, 0x0000, 0x20a9, 0x0001, 0x6b70,
+	0xd384, 0x01c8, 0x0020, 0x839d, 0x12b0, 0x3508, 0x8109, 0x080c,
+	0x5fa9, 0x6878, 0x6016, 0x6874, 0x2008, 0xa084, 0xff00, 0x8007,
+	0x600a, 0xa184, 0x00ff, 0x6006, 0x8108, 0x1118, 0x6003, 0x0003,
+	0x0010, 0x6003, 0x0001, 0x1f04, 0x36f3, 0x00ce, 0x2069, 0xad51,
+	0x2001, 0xaf9d, 0x6a80, 0xa294, 0x0030, 0xa28e, 0x0000, 0x0170,
+	0xa28e, 0x0010, 0x0118, 0xa28e, 0x0020, 0x0140, 0x2003, 0xaaaa,
+	0x080c, 0x2744, 0x2001, 0xaf8e, 0x2102, 0x0008, 0x2102, 0x00c6,
+	0x2061, 0x0100, 0x602f, 0x0040, 0x602f, 0x0000, 0x00ce, 0x080c,
+	0x574f, 0x0128, 0x080c, 0x3e5f, 0x0110, 0x080c, 0x26c0, 0x60c4,
+	0xa005, 0x01b0, 0x6003, 0x0001, 0x2009, 0x373f, 0x00c0, 0x080c,
+	0x574f, 0x1158, 0x2011, 0x566e, 0x080c, 0x650d, 0x2001, 0xaf9e,
+	0x2003, 0x0000, 0x080c, 0x569a, 0x0040, 0x080c, 0x485e, 0x0028,
+	0x6003, 0x0004, 0x2009, 0x3755, 0x0010, 0x0804, 0x2dcc, 0x2001,
+	0x0100, 0x2004, 0xa082, 0x0005, 0x0258, 0x2001, 0x0170, 0x2004,
+	0xa084, 0x00ff, 0xa086, 0x004c, 0x1118, 0x2091, 0x309d, 0x0817,
+	0x2091, 0x301d, 0x0817, 0x6000, 0xa086, 0x0000, 0x0904, 0x2df1,
+	0x2069, 0xad51, 0x7830, 0x6842, 0x7834, 0x6846, 0x6804, 0xd0fc,
+	0x0118, 0x2009, 0x0030, 0x0010, 0x2009, 0x001c, 0x2d00, 0x7a2c,
+	0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3c49, 0xa006, 0x080c, 0x26c0,
+	0x81ff, 0x1904, 0x2df1, 0x080c, 0x574f, 0x1178, 0x2001, 0xaf9e,
+	0x2003, 0x0001, 0x2001, 0xad00, 0x2003, 0x0001, 0xa085, 0x0001,
+	0x080c, 0x5793, 0x080c, 0x569a, 0x0020, 0x080c, 0x491f, 0x080c,
+	0x485e, 0x0804, 0x2dcc, 0x81ff, 0x1904, 0x2df1, 0x080c, 0x574f,
+	0x1110, 0x0804, 0x2df1, 0x6184, 0x81ff, 0x0198, 0x703f, 0x0000,
+	0x2001, 0xb3c0, 0x2009, 0x0040, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38,
+	0x0126, 0x2091, 0x8000, 0x080c, 0x3c49, 0x701b, 0x2dca, 0x012e,
+	0x0005, 0x703f, 0x0001, 0x00d6, 0x2069, 0xb3c0, 0x20a9, 0x0040,
+	0x20a1, 0xb3c0, 0x2019, 0xffff, 0x43a4, 0x654c, 0xa588, 0x2be6,
+	0x210d, 0xa18c, 0x00ff, 0x216a, 0xa00e, 0x2011, 0x0002, 0x2100,
+	0xa506, 0x01a8, 0x080c, 0x4cdc, 0x1190, 0x6014, 0x821c, 0x0238,
+	0xa398, 0xb3c0, 0xa085, 0xff00, 0x8007, 0x201a, 0x0038, 0xa398,
+	0xb3c0, 0x2324, 0xa4a4, 0xff00, 0xa405, 0x201a, 0x8210, 0x8108,
+	0xa182, 0x0080, 0x1208, 0x0c18, 0x8201, 0x8007, 0x2d0c, 0xa105,
+	0x206a, 0x00de, 0x20a9, 0x0040, 0x20a1, 0xb3c0, 0x2099, 0xb3c0,
+	0x080c, 0x48be, 0x0804, 0x37b0, 0x080c, 0x3c2a, 0x0904, 0x2df4,
+	0x00c6, 0x080c, 0x3c05, 0x00ce, 0x1120, 0x2009, 0x0002, 0x0804,
+	0x2df1, 0x2001, 0xad52, 0x2004, 0xd0b4, 0x01f0, 0x6000, 0xd08c,
+	0x11d8, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x11a8, 0x6837,
+	0x0000, 0x6838, 0xc0fd, 0x683a, 0x080c, 0x970b, 0x1120, 0x2009,
+	0x0003, 0x0804, 0x2df1, 0x7007, 0x0003, 0x701b, 0x3830, 0x0005,
+	0x080c, 0x3c2a, 0x0904, 0x2df4, 0x20a9, 0x002b, 0x2c98, 0xade8,
+	0x0002, 0x2da0, 0x53a3, 0x20a9, 0x0004, 0xac80, 0x0006, 0x2098,
+	0xad80, 0x0006, 0x20a0, 0x080c, 0x48be, 0x20a9, 0x0004, 0xac80,
+	0x000a, 0x2098, 0xad80, 0x000a, 0x20a0, 0x080c, 0x48be, 0x2d00,
+	0x2009, 0x002b, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3c49,
+	0x81ff, 0x1904, 0x2df1, 0x080c, 0x3c1a, 0x0904, 0x2df4, 0x080c,
+	0x4eab, 0x0804, 0x2dcc, 0x81ff, 0x1904, 0x2df1, 0x7828, 0xa08a,
+	0x1000, 0x1a04, 0x2df4, 0x080c, 0x3c2a, 0x0904, 0x2df4, 0x080c,
+	0x4f0d, 0x0904, 0x2df1, 0x2019, 0x0004, 0x080c, 0x4ebd, 0x7924,
+	0x810f, 0x7a28, 0x0011, 0x0804, 0x2dcc, 0xa186, 0x00ff, 0x0110,
+	0x0071, 0x0060, 0x2029, 0x007e, 0x2061, 0xad00, 0x644c, 0x2400,
+	0xa506, 0x0110, 0x2508, 0x0019, 0x8529, 0x1ec8, 0x0005, 0x080c,
+	0x4cdc, 0x1138, 0x2200, 0x8003, 0x800b, 0x810b, 0xa108, 0x080c,
+	0x6519, 0x0005, 0x81ff, 0x1904, 0x2df1, 0x080c, 0x3c1a, 0x0904,
+	0x2df4, 0x080c, 0x4d96, 0x0904, 0x2df1, 0x080c, 0x4eb4, 0x0804,
+	0x2dcc, 0x81ff, 0x1904, 0x2df1, 0x080c, 0x3c1a, 0x0904, 0x2df4,
+	0x080c, 0x4d96, 0x0904, 0x2df1, 0x080c, 0x4ea2, 0x0804, 0x2dcc,
+	0x6100, 0x0804, 0x2dcc, 0x080c, 0x3c2a, 0x0904, 0x2df4, 0x2001,
+	0xad00, 0x2004, 0xa086, 0x0003, 0x1904, 0x2df1, 0x00d6, 0xace8,
+	0x000a, 0x7924, 0xd184, 0x0110, 0xace8, 0x0006, 0x680c, 0x8007,
+	0x783e, 0x6808, 0x8007, 0x783a, 0x6b04, 0x831f, 0x6a00, 0x8217,
+	0x00de, 0x6100, 0xa18c, 0x0200, 0x0804, 0x2dcc, 0x7824, 0xa09c,
+	0x00ff, 0xa39a, 0x0003, 0x1a04, 0x2df1, 0x624c, 0xa294, 0x00ff,
+	0xa084, 0xff00, 0x8007, 0xa206, 0x1150, 0x2001, 0xad40, 0x2009,
+	0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3c49, 0x81ff,
+	0x1904, 0x2df1, 0x080c, 0x3c2a, 0x0904, 0x2df4, 0x6004, 0xa084,
+	0x00ff, 0xa086, 0x0006, 0x1904, 0x2df1, 0x00c6, 0x080c, 0x3c05,
+	0x00ce, 0x0904, 0x2df1, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a,
+	0x080c, 0x96b7, 0x0904, 0x2df1, 0x7007, 0x0003, 0x701b, 0x3919,
+	0x0005, 0x6830, 0xa086, 0x0100, 0x0904, 0x2df1, 0xad80, 0x000e,
+	0x2009, 0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3c49,
+	0xa006, 0x080c, 0x26c0, 0x7824, 0xa084, 0x00ff, 0xa086, 0x00ff,
+	0x0118, 0x81ff, 0x1904, 0x2df1, 0x080c, 0x574f, 0x0110, 0x080c,
+	0x491f, 0x7828, 0xa08a, 0x1000, 0x1a04, 0x2df4, 0x7924, 0xa18c,
+	0xff00, 0x810f, 0xa186, 0x00ff, 0x0138, 0xa182, 0x007f, 0x1a04,
+	0x2df4, 0x2100, 0x080c, 0x268a, 0x0026, 0x00c6, 0x0126, 0x2091,
+	0x8000, 0x2061, 0xafda, 0x601b, 0x0000, 0x601f, 0x0000, 0x080c,
+	0x574f, 0x1178, 0x2001, 0xaf9e, 0x2003, 0x0001, 0x2001, 0xad00,
+	0x2003, 0x0001, 0xa085, 0x0001, 0x080c, 0x5793, 0x080c, 0x569a,
+	0x00a0, 0x2061, 0x0100, 0x2001, 0xad14, 0x2004, 0xa084, 0x00ff,
+	0x810f, 0xa105, 0x604a, 0x6043, 0x0090, 0x6043, 0x0010, 0x2009,
+	0x002d, 0x2011, 0x4883, 0x080c, 0x6593, 0x7924, 0xa18c, 0xff00,
+	0x810f, 0x080c, 0x574f, 0x1110, 0x2009, 0x00ff, 0x7a28, 0x080c,
+	0x387d, 0x012e, 0x00ce, 0x002e, 0x0804, 0x2dcc, 0x7924, 0xa18c,
+	0xff00, 0x810f, 0x00c6, 0x080c, 0x4c80, 0x2c08, 0x00ce, 0x1904,
+	0x2df4, 0x0804, 0x2dcc, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804,
+	0x2df1, 0x60d0, 0xd0ac, 0x1130, 0xd09c, 0x1120, 0x2009, 0x0005,
+	0x0804, 0x2df1, 0x080c, 0x3c05, 0x1120, 0x2009, 0x0002, 0x0804,
+	0x2df1, 0x7924, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3c46,
+	0x701b, 0x39bb, 0x0005, 0x2009, 0x0080, 0x080c, 0x4cdc, 0x1130,
+	0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x0120, 0x2021, 0x400a,
+	0x0804, 0x2dce, 0x00d6, 0xade8, 0x000d, 0x6900, 0x6a08, 0x6b0c,
+	0x6c10, 0x6d14, 0x6e18, 0x6820, 0xa0be, 0x0100, 0x0904, 0x3a32,
+	0xa0be, 0x0112, 0x0904, 0x3a32, 0xa0be, 0x0113, 0x0904, 0x3a32,
+	0xa0be, 0x0114, 0x0904, 0x3a32, 0xa0be, 0x0117, 0x0904, 0x3a32,
+	0xa0be, 0x011a, 0x0904, 0x3a32, 0xa0be, 0x011c, 0x0904, 0x3a32,
+	0xa0be, 0x0121, 0x05b0, 0xa0be, 0x0131, 0x0598, 0xa0be, 0x0171,
+	0x05c8, 0xa0be, 0x0173, 0x05b0, 0xa0be, 0x01a1, 0x1120, 0x6830,
+	0x8007, 0x6832, 0x04a8, 0xa0be, 0x0212, 0x0540, 0xa0be, 0x0213,
+	0x0528, 0xa0be, 0x0214, 0x01b0, 0xa0be, 0x0217, 0x0168, 0xa0be,
+	0x021a, 0x1120, 0x6838, 0x8007, 0x683a, 0x00e0, 0xa0be, 0x0300,
+	0x01c8, 0x00de, 0x0804, 0x2df4, 0xad80, 0x0010, 0x20a9, 0x0007,
+	0x080c, 0x3a78, 0xad80, 0x000e, 0x20a9, 0x0001, 0x080c, 0x3a78,
+	0x0048, 0xad80, 0x000c, 0x080c, 0x3a86, 0x0050, 0xad80, 0x000e,
+	0x080c, 0x3a86, 0xad80, 0x000c, 0x20a9, 0x0001, 0x080c, 0x3a78,
+	0x00c6, 0x080c, 0x3c05, 0x0568, 0x6838, 0xc0fd, 0x683a, 0x6837,
+	0x0119, 0x6853, 0x0000, 0x684f, 0x0020, 0x685b, 0x0001, 0x810b,
+	0x697e, 0x6883, 0x0000, 0x6a86, 0x6b8a, 0x6c8e, 0x6d92, 0x6996,
+	0x689b, 0x0000, 0x00ce, 0x00de, 0x6837, 0x0000, 0x6838, 0xc0fd,
+	0x683a, 0x6823, 0x0000, 0x6804, 0x2068, 0x080c, 0x96d3, 0x1120,
+	0x2009, 0x0003, 0x0804, 0x2df1, 0x7007, 0x0003, 0x701b, 0x3a6f,
+	0x0005, 0x00ce, 0x00de, 0x2009, 0x0002, 0x0804, 0x2df1, 0x6820,
+	0xa086, 0x8001, 0x1904, 0x2dcc, 0x2009, 0x0004, 0x0804, 0x2df1,
+	0x0016, 0x2008, 0x2044, 0x8000, 0x204c, 0x8000, 0x290a, 0x8108,
+	0x280a, 0x8108, 0x1f04, 0x3a7a, 0x001e, 0x0005, 0x0016, 0x00a6,
+	0x00b6, 0x2008, 0x2044, 0x8000, 0x204c, 0x8000, 0x2054, 0x8000,
+	0x205c, 0x2b0a, 0x8108, 0x2a0a, 0x8108, 0x290a, 0x8108, 0x280a,
+	0x00be, 0x00ae, 0x001e, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001,
+	0x0804, 0x2df1, 0x7924, 0x2140, 0xa18c, 0xff00, 0x810f, 0x60d0,
+	0xd0ac, 0x1120, 0xa182, 0x0080, 0x0a04, 0x2df4, 0xa182, 0x00ff,
+	0x1a04, 0x2df4, 0x7a2c, 0x7b28, 0x606c, 0xa306, 0x1140, 0x6070,
+	0xa24e, 0x0904, 0x2df4, 0xa9cc, 0xff00, 0x0904, 0x2df4, 0x00c6,
+	0x080c, 0x3b58, 0x2c68, 0x00ce, 0x0538, 0xa0c6, 0x4000, 0x1180,
+	0x00c6, 0x0006, 0x2d60, 0x2009, 0x0000, 0x080c, 0x4f6e, 0x1108,
+	0xc185, 0x6000, 0xd0bc, 0x0108, 0xc18d, 0x000e, 0x00ce, 0x0088,
+	0xa0c6, 0x4007, 0x1110, 0x2408, 0x0060, 0xa0c6, 0x4008, 0x1118,
+	0x2708, 0x2610, 0x0030, 0xa0c6, 0x4009, 0x1108, 0x0010, 0x2001,
+	0x4006, 0x2020, 0x0804, 0x2dce, 0x2d00, 0x7022, 0x0016, 0x00b6,
+	0x00c6, 0x00e6, 0x2c70, 0x080c, 0x8022, 0x05d8, 0x2d00, 0x601a,
+	0x080c, 0x9956, 0x2e58, 0x00ee, 0x00e6, 0x00c6, 0x080c, 0x3c05,
+	0x00ce, 0x2b70, 0x1150, 0x080c, 0x8078, 0x00ee, 0x00ce, 0x00be,
+	0x001e, 0x2009, 0x0002, 0x0804, 0x2df1, 0x6837, 0x0000, 0x683b,
+	0x0000, 0x2d00, 0x6012, 0x6833, 0x0000, 0x6838, 0xc0fd, 0xd88c,
+	0x0108, 0xc0f5, 0x683a, 0x0126, 0x2091, 0x8000, 0x080c, 0x2ad9,
+	0x012e, 0x601f, 0x0001, 0x2001, 0x0000, 0x080c, 0x4c1e, 0x2001,
+	0x0002, 0x080c, 0x4c30, 0x2009, 0x0002, 0x080c, 0x80a7, 0xa085,
+	0x0001, 0x00ee, 0x00ce, 0x00be, 0x001e, 0x1120, 0x2009, 0x0003,
+	0x0804, 0x2df1, 0x7007, 0x0003, 0x701b, 0x3b3f, 0x0005, 0x6830,
+	0xa086, 0x0100, 0x7020, 0x2060, 0x1138, 0x2009, 0x0004, 0x6204,
+	0xa294, 0x00ff, 0x0804, 0x2df1, 0x2009, 0x0000, 0x080c, 0x4f6e,
+	0x1108, 0xc185, 0x6000, 0xd0bc, 0x0108, 0xc18d, 0x0804, 0x2dcc,
+	0x00e6, 0x00d6, 0x2029, 0x0000, 0x2001, 0xad34, 0x2004, 0xd0ac,
+	0x0138, 0x2021, 0x0000, 0x20a9, 0x00ff, 0x2071, 0xae34, 0x0030,
+	0x2021, 0x0080, 0x20a9, 0x007f, 0x2071, 0xaeb4, 0x2e04, 0xa005,
+	0x1130, 0x2100, 0xa406, 0x1548, 0x2428, 0xc5fd, 0x0430, 0x2068,
+	0x6f10, 0x2700, 0xa306, 0x11b0, 0x6e14, 0x2600, 0xa206, 0x1190,
+	0x2400, 0xa106, 0x1160, 0x2d60, 0xd884, 0x0540, 0x6004, 0xa084,
+	0x00ff, 0xa086, 0x0006, 0x1510, 0x2001, 0x4000, 0x0400, 0x2001,
+	0x4007, 0x00e8, 0x2400, 0xa106, 0x1140, 0x6e14, 0x87ff, 0x1110,
+	0x86ff, 0x09d0, 0x2001, 0x4008, 0x0090, 0x8420, 0x8e70, 0x1f04,
+	0x3b6e, 0x85ff, 0x1130, 0x2001, 0x4009, 0x0048, 0x2001, 0x0001,
+	0x0030, 0x080c, 0x4c80, 0x1dd0, 0x6312, 0x6216, 0xa006, 0xa005,
+	0x00de, 0x00ee, 0x0005, 0x81ff, 0x1904, 0x2df1, 0x080c, 0x3c05,
+	0x0904, 0x2df1, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x7824,
+	0xa005, 0x0904, 0x2df4, 0xa096, 0x00ff, 0x0120, 0xa092, 0x0004,
+	0x1a04, 0x2df4, 0x2010, 0x2d18, 0x080c, 0x2a8c, 0x0904, 0x2df1,
+	0x7007, 0x0003, 0x701b, 0x3bd5, 0x0005, 0x6830, 0xa086, 0x0100,
+	0x0904, 0x2df1, 0x0804, 0x2dcc, 0x7924, 0xa18c, 0xff00, 0x810f,
+	0x60d0, 0xd0ac, 0x1120, 0xa182, 0x0080, 0x0a04, 0x2df4, 0xa182,
+	0x00ff, 0x1a04, 0x2df4, 0x0126, 0x2091, 0x8000, 0x080c, 0x95c6,
+	0x1188, 0xa190, 0xae34, 0x2204, 0xa065, 0x0160, 0x080c, 0x493a,
+	0x2001, 0xad34, 0x2004, 0xd0ac, 0x0110, 0x6017, 0x0000, 0x012e,
+	0x0804, 0x2dcc, 0x012e, 0x0804, 0x2df1, 0x080c, 0x15d9, 0x0188,
+	0xa006, 0x6802, 0x7010, 0xa005, 0x1120, 0x2d00, 0x7012, 0x7016,
+	0x0030, 0x7014, 0x6802, 0x2060, 0x2d00, 0x6006, 0x7016, 0xad80,
+	0x000d, 0x0005, 0x7924, 0x810f, 0xa18c, 0x00ff, 0x080c, 0x4cdc,
+	0x1130, 0x7e28, 0xa684, 0x3fff, 0xa082, 0x4000, 0x0208, 0xa066,
+	0x8cff, 0x0005, 0x7e24, 0x860f, 0xa18c, 0x00ff, 0x080c, 0x4cdc,
+	0x1128, 0xa6b4, 0x00ff, 0xa682, 0x4000, 0x0208, 0xa066, 0x8cff,
+	0x0005, 0x0016, 0x7110, 0x81ff, 0x0128, 0x2168, 0x6904, 0x080c,
+	0x15f0, 0x0cc8, 0x7112, 0x7116, 0x001e, 0x0005, 0x2031, 0x0001,
+	0x0010, 0x2031, 0x0000, 0x2061, 0xadd1, 0x6606, 0x6112, 0x600e,
+	0x6226, 0x632a, 0x642e, 0x6532, 0x2c10, 0x080c, 0x1624, 0x7007,
+	0x0002, 0x701b, 0x2dcc, 0x0005, 0x00f6, 0x0126, 0x2091, 0x8000,
+	0x2079, 0x0000, 0x2001, 0xad8f, 0x2004, 0xa005, 0x1168, 0x0e04,
+	0x3c74, 0x7818, 0xd084, 0x1140, 0x7a22, 0x7b26, 0x7c2a, 0x781b,
+	0x0001, 0x2091, 0x4080, 0x0408, 0x0016, 0x00c6, 0x00e6, 0x2071,
+	0xad81, 0x7138, 0xa182, 0x0010, 0x0218, 0x7030, 0x2060, 0x0078,
+	0x7030, 0xa0e0, 0x0004, 0xac82, 0xadd1, 0x0210, 0x2061, 0xad91,
+	0x2c00, 0x7032, 0x81ff, 0x1108, 0x7036, 0x8108, 0x713a, 0x2262,
+	0x6306, 0x640a, 0x00ee, 0x00ce, 0x001e, 0x012e, 0x00fe, 0x0005,
+	0x00e6, 0x2071, 0xad81, 0x7038, 0xa005, 0x0570, 0x0126, 0x2091,
+	0x8000, 0x0e04, 0x3ccb, 0x00f6, 0x2079, 0x0000, 0x7818, 0xd084,
+	0x1508, 0x00c6, 0x7034, 0x2060, 0x2c04, 0x7822, 0x6004, 0x7826,
+	0x6008, 0x782a, 0x781b, 0x0001, 0x2091, 0x4080, 0x7038, 0x8001,
+	0x703a, 0xa005, 0x1130, 0x7033, 0xad91, 0x7037, 0xad91, 0x00ce,
+	0x0048, 0xac80, 0x0004, 0xa0fa, 0xadd1, 0x0210, 0x2001, 0xad91,
+	0x7036, 0x00ce, 0x00fe, 0x012e, 0x00ee, 0x0005, 0x0026, 0x2001,
+	0xad52, 0x2004, 0xd0c4, 0x0120, 0x2011, 0x8014, 0x080c, 0x3c5c,
+	0x002e, 0x0005, 0x81ff, 0x1904, 0x2df1, 0x0126, 0x2091, 0x8000,
+	0x6030, 0xc08d, 0xc085, 0xc0ac, 0x6032, 0x080c, 0x574f, 0x1178,
+	0x2001, 0xaf9e, 0x2003, 0x0001, 0x2001, 0xad00, 0x2003, 0x0001,
+	0xa085, 0x0001, 0x080c, 0x5793, 0x080c, 0x569a, 0x0010, 0x080c,
+	0x485e, 0x012e, 0x0804, 0x2dcc, 0x7824, 0x2008, 0xa18c, 0xfffd,
+	0x1128, 0x61dc, 0xa10d, 0x61de, 0x0804, 0x2dcc, 0x0804, 0x2df4,
+	0x81ff, 0x1904, 0x2df1, 0x6000, 0xa086, 0x0003, 0x1904, 0x2df1,
+	0x2001, 0xad52, 0x2004, 0xd0ac, 0x1904, 0x2df1, 0x080c, 0x3c2a,
+	0x0904, 0x2df4, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1120,
+	0x7828, 0xa005, 0x0904, 0x2dcc, 0x00c6, 0x080c, 0x3c05, 0x00ce,
+	0x0904, 0x2df1, 0x6837, 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd,
+	0x683a, 0x080c, 0x979c, 0x0904, 0x2df1, 0x7007, 0x0003, 0x701b,
+	0x3d3a, 0x0005, 0x6830, 0xa086, 0x0100, 0x0904, 0x2df1, 0x0804,
+	0x2dcc, 0x2001, 0xad00, 0x2004, 0xa086, 0x0003, 0x1904, 0x2df1,
+	0x7f24, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3c05, 0x0904,
+	0x2df1, 0x2009, 0x0000, 0x2031, 0x0000, 0x7023, 0x0000, 0x702f,
+	0x0000, 0xad80, 0x0005, 0x7026, 0x20a0, 0x080c, 0x4cdc, 0x1904,
+	0x3db4, 0x6004, 0xa0c4, 0x00ff, 0xa8c6, 0x0006, 0x0130, 0xa0c4,
+	0xff00, 0xa8c6, 0x0600, 0x1904, 0x3db4, 0x2001, 0xad52, 0x2004,
+	0xd0ac, 0x1128, 0x080c, 0x4f6e, 0x1110, 0xd79c, 0x05e8, 0xd794,
+	0x1110, 0xd784, 0x0158, 0xac80, 0x0006, 0x2098, 0x3400, 0x20a9,
+	0x0004, 0x53a3, 0x080c, 0x3a86, 0xd794, 0x0148, 0xac80, 0x000a,
+	0x2098, 0x3400, 0x20a9, 0x0004, 0x53a3, 0x080c, 0x3a86, 0x21a2,
+	0xd794, 0x01d8, 0xac80, 0x0000, 0x2098, 0x94a0, 0x20a9, 0x0002,
+	0x53a3, 0xac80, 0x0003, 0x20a6, 0x94a0, 0xac80, 0x0004, 0x2098,
+	0x3400, 0x20a9, 0x0002, 0x53a3, 0x080c, 0x3a78, 0xac80, 0x0026,
+	0x2098, 0x20a9, 0x0002, 0x53a3, 0x0008, 0x94a0, 0xd794, 0x0110,
+	0xa6b0, 0x000b, 0xa6b0, 0x0005, 0x8108, 0x2001, 0xad34, 0x2004,
+	0xd0ac, 0x0118, 0xa186, 0x0100, 0x0040, 0xd78c, 0x0120, 0xa186,
+	0x0100, 0x0170, 0x0018, 0xa186, 0x007e, 0x0150, 0xd794, 0x0118,
+	0xa686, 0x0020, 0x0010, 0xa686, 0x0028, 0x0150, 0x0804, 0x3d5d,
+	0x86ff, 0x1120, 0x7120, 0x810b, 0x0804, 0x2dcc, 0x702f, 0x0001,
+	0x711e, 0x7020, 0xa600, 0x7022, 0x772a, 0x2061, 0xadd1, 0x6007,
+	0x0000, 0x6612, 0x7024, 0x600e, 0x6226, 0x632a, 0x642e, 0x6532,
+	0x2c10, 0x080c, 0x1624, 0x7007, 0x0002, 0x701b, 0x3df0, 0x0005,
+	0x702c, 0xa005, 0x1170, 0x711c, 0x7024, 0x20a0, 0x7728, 0x2031,
+	0x0000, 0x2061, 0xadd1, 0x6224, 0x6328, 0x642c, 0x6530, 0x0804,
+	0x3d5d, 0x7120, 0x810b, 0x0804, 0x2dcc, 0x2029, 0x007e, 0x7924,
+	0x7a28, 0x7b2c, 0x7c38, 0xa184, 0xff00, 0x8007, 0xa0e2, 0x0020,
+	0x0a04, 0x2df4, 0xa502, 0x0a04, 0x2df4, 0xa184, 0x00ff, 0xa0e2,
+	0x0020, 0x0a04, 0x2df4, 0xa502, 0x0a04, 0x2df4, 0xa284, 0xff00,
+	0x8007, 0xa0e2, 0x0020, 0x0a04, 0x2df4, 0xa502, 0x0a04, 0x2df4,
+	0xa284, 0x00ff, 0xa0e2, 0x0020, 0x0a04, 0x2df4, 0xa502, 0x0a04,
+	0x2df4, 0xa384, 0xff00, 0x8007, 0xa0e2, 0x0020, 0x0a04, 0x2df4,
+	0xa502, 0x0a04, 0x2df4, 0xa384, 0x00ff, 0xa0e2, 0x0020, 0x0a04,
+	0x2df4, 0xa502, 0x0a04, 0x2df4, 0xa484, 0xff00, 0x8007, 0xa0e2,
+	0x0020, 0x0a04, 0x2df4, 0xa502, 0x0a04, 0x2df4, 0xa484, 0x00ff,
+	0xa0e2, 0x0020, 0x0a04, 0x2df4, 0xa502, 0x0a04, 0x2df4, 0x2061,
+	0xafa6, 0x6102, 0x6206, 0x630a, 0x640e, 0x0804, 0x2dcc, 0x0006,
+	0x2001, 0xad52, 0x2004, 0xd0cc, 0x000e, 0x0005, 0x0006, 0x2001,
+	0xad71, 0x2004, 0xd0bc, 0x000e, 0x0005, 0x6164, 0x7a24, 0x6300,
+	0x82ff, 0x1118, 0x7926, 0x0804, 0x2dcc, 0x83ff, 0x1904, 0x2df4,
+	0x2001, 0xfff0, 0xa200, 0x1a04, 0x2df4, 0x2019, 0xffff, 0x6068,
+	0xa302, 0xa200, 0x0a04, 0x2df4, 0x7926, 0x6266, 0x0804, 0x2dcc,
+	0x2001, 0xad00, 0x2004, 0xa086, 0x0003, 0x1904, 0x2df1, 0x7c28,
+	0x7d24, 0x7e38, 0x7f2c, 0x080c, 0x3c05, 0x0904, 0x2df1, 0x2009,
+	0x0000, 0x2019, 0x0000, 0x7023, 0x0000, 0x702f, 0x0000, 0xad80,
+	0x0003, 0x7026, 0x20a0, 0xa1e0, 0xae34, 0x2c64, 0x8cff, 0x01b8,
+	0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x0130, 0x6004, 0xa084,
+	0xff00, 0xa086, 0x0600, 0x1158, 0x6014, 0x20a2, 0x94a0, 0x6010,
+	0x8007, 0xa105, 0x8007, 0x20a2, 0x94a0, 0xa398, 0x0002, 0x8108,
+	0xa182, 0x00ff, 0x0120, 0xa386, 0x002a, 0x0148, 0x08e0, 0x83ff,
+	0x1120, 0x7120, 0x810c, 0x0804, 0x2dcc, 0x702f, 0x0001, 0x711e,
+	0x7020, 0xa300, 0x7022, 0x2061, 0xadd1, 0x6007, 0x0000, 0x6312,
+	0x7024, 0x600e, 0x6426, 0x652a, 0x662e, 0x6732, 0x2c10, 0x080c,
+	0x1624, 0x7007, 0x0002, 0x701b, 0x3ee6, 0x0005, 0x702c, 0xa005,
+	0x1168, 0x711c, 0x7024, 0x20a0, 0x2019, 0x0000, 0x2061, 0xadd1,
+	0x6424, 0x6528, 0x662c, 0x6730, 0x0804, 0x3ea3, 0x7120, 0x810c,
+	0x0804, 0x2dcc, 0x81ff, 0x1904, 0x2df1, 0x60d0, 0xd0ac, 0x1118,
+	0xd09c, 0x0904, 0x2df1, 0x080c, 0x3c05, 0x0904, 0x2df1, 0x7924,
+	0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3c46, 0x701b, 0x3f11,
+	0x0005, 0x00d6, 0xade8, 0x000d, 0x6828, 0xa0be, 0x7000, 0x0148,
+	0xa0be, 0x7100, 0x0130, 0xa0be, 0x7200, 0x0118, 0x00de, 0x0804,
+	0x2df4, 0x6820, 0x6924, 0x080c, 0x2676, 0x1510, 0x080c, 0x4c80,
+	0x11f8, 0x7122, 0x6612, 0x6516, 0x6e18, 0x00c6, 0x080c, 0x3c05,
+	0x01b8, 0x080c, 0x3c05, 0x01a0, 0x00ce, 0x00de, 0x6837, 0x0000,
+	0x6838, 0xc0fd, 0x683a, 0x6823, 0x0000, 0x6804, 0x2068, 0x080c,
+	0x96ef, 0x0904, 0x2df1, 0x7007, 0x0003, 0x701b, 0x3f4b, 0x0005,
+	0x00de, 0x0804, 0x2df1, 0x7120, 0x080c, 0x2bc9, 0x6820, 0xa086,
+	0x8001, 0x0904, 0x2df1, 0x2d00, 0x701e, 0x6804, 0xa080, 0x0002,
+	0x0006, 0x20a9, 0x002a, 0x2098, 0x20a0, 0x080c, 0x48be, 0x000e,
+	0xade8, 0x000d, 0x6a08, 0x6b0c, 0x6c10, 0x6d14, 0x2061, 0xadd1,
+	0x6007, 0x0000, 0x6e00, 0x6f28, 0xa7c6, 0x7000, 0x1108, 0x0018,
+	0xa7c6, 0x7100, 0x1140, 0xa6c2, 0x0004, 0x0a04, 0x2df4, 0x2009,
+	0x0004, 0x0804, 0x3c49, 0xa7c6, 0x7200, 0x1904, 0x2df4, 0xa6c2,
+	0x0054, 0x0a04, 0x2df4, 0x600e, 0x6013, 0x002a, 0x6226, 0x632a,
+	0x642e, 0x6532, 0x2c10, 0x080c, 0x1624, 0x7007, 0x0002, 0x701b,
+	0x3f92, 0x0005, 0x701c, 0x2068, 0x6804, 0xa080, 0x0001, 0x2004,
+	0xa080, 0x0002, 0x0006, 0x20a9, 0x002a, 0x2098, 0x20a0, 0x080c,
+	0x48be, 0x000e, 0x2009, 0x002a, 0x2061, 0xadd1, 0x6224, 0x6328,
+	0x642c, 0x6530, 0x0804, 0x3c49, 0x81ff, 0x1904, 0x2df1, 0x080c,
+	0x3c1a, 0x0904, 0x2df4, 0x080c, 0x4d96, 0x0904, 0x2df1, 0x080c,
+	0x4ec6, 0x0804, 0x2dcc, 0x7824, 0xd084, 0x0904, 0x3804, 0x080c,
+	0x3c2a, 0x0904, 0x2df4, 0x00c6, 0x080c, 0x3c05, 0x00ce, 0x1120,
+	0x2009, 0x0002, 0x0804, 0x2df1, 0x6004, 0xa084, 0x00ff, 0xa086,
+	0x0006, 0x0128, 0xa08e, 0x0004, 0x0110, 0xa08e, 0x0005, 0x1508,
+	0x2001, 0xad52, 0x2004, 0xd0b4, 0x0904, 0x3834, 0x6000, 0xd08c,
+	0x1904, 0x3834, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x080c,
+	0x970b, 0x1120, 0x2009, 0x0003, 0x0804, 0x2df1, 0x7007, 0x0003,
+	0x701b, 0x3ff3, 0x0005, 0x080c, 0x3c2a, 0x0904, 0x2df4, 0x0804,
+	0x3834, 0x2009, 0xad30, 0x210c, 0x81ff, 0x0120, 0x2009, 0x0001,
+	0x0804, 0x2df1, 0x2001, 0xad00, 0x2004, 0xa086, 0x0003, 0x0120,
+	0x2009, 0x0007, 0x0804, 0x2df1, 0x2001, 0xad52, 0x2004, 0xd0ac,
+	0x0120, 0x2009, 0x0008, 0x0804, 0x2df1, 0x609c, 0xd0a4, 0x1118,
+	0xd0ac, 0x1904, 0x3834, 0x6837, 0x0000, 0x6833, 0x0000, 0x6838,
+	0xc0fd, 0x683a, 0x080c, 0x979c, 0x1120, 0x2009, 0x0003, 0x0804,
+	0x2df1, 0x7007, 0x0003, 0x701b, 0x402e, 0x0005, 0x6830, 0xa086,
+	0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x2df1, 0x080c, 0x3c2a,
+	0x0904, 0x2df4, 0x0804, 0x3fd8, 0x81ff, 0x2009, 0x0001, 0x1904,
+	0x2df1, 0x6000, 0xa086, 0x0003, 0x2009, 0x0007, 0x1904, 0x2df1,
+	0x2001, 0xad52, 0x2004, 0xd0ac, 0x2009, 0x0008, 0x1904, 0x2df1,
+	0x080c, 0x3c2a, 0x0904, 0x2df4, 0x6004, 0xa084, 0x00ff, 0xa086,
+	0x0006, 0x2009, 0x0009, 0x1904, 0x2df1, 0x00c6, 0x080c, 0x3c05,
+	0x00ce, 0x2009, 0x0002, 0x0904, 0x2df1, 0x6837, 0x0000, 0x6833,
+	0x0000, 0x6838, 0xc0fd, 0x683a, 0x7928, 0xa194, 0xff00, 0xa18c,
+	0x00ff, 0xa006, 0x82ff, 0x1128, 0xc0ed, 0x6952, 0x792c, 0x6956,
+	0x0048, 0xa28e, 0x0100, 0x1904, 0x2df4, 0xc0e5, 0x6853, 0x0000,
+	0x6857, 0x0000, 0x683e, 0x080c, 0x9957, 0x2009, 0x0003, 0x0904,
+	0x2df1, 0x7007, 0x0003, 0x701b, 0x408e, 0x0005, 0x6830, 0xa086,
+	0x0100, 0x2009, 0x0004, 0x0904, 0x2df1, 0x0804, 0x2dcc, 0x81ff,
+	0x2009, 0x0001, 0x1904, 0x2df1, 0x6000, 0xa086, 0x0003, 0x2009,
+	0x0007, 0x1904, 0x2df1, 0x080c, 0x3c2a, 0x0904, 0x2df4, 0x6004,
+	0xa084, 0x00ff, 0xa086, 0x0006, 0x2009, 0x0009, 0x1904, 0x2df1,
+	0x00c6, 0x080c, 0x3c05, 0x00ce, 0x2009, 0x0002, 0x0904, 0x2df1,
+	0xad80, 0x000f, 0x2009, 0x0008, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38,
+	0x080c, 0x3c46, 0x701b, 0x40c5, 0x0005, 0x00d6, 0xade8, 0x000f,
+	0x6800, 0xa086, 0x0500, 0x1140, 0x6804, 0xa005, 0x1128, 0x6808,
+	0xa084, 0xff00, 0x1108, 0x0018, 0x00de, 0x1904, 0x2df4, 0x00de,
+	0x6837, 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x00c6,
+	0x080c, 0x3c2a, 0x1118, 0x00ce, 0x0804, 0x2df4, 0x080c, 0x99a6,
+	0x2009, 0x0003, 0x00ce, 0x0904, 0x2df1, 0x7007, 0x0003, 0x701b,
+	0x40f2, 0x0005, 0x6830, 0xa086, 0x0100, 0x2009, 0x0004, 0x0904,
+	0x2df1, 0x0804, 0x2dcc, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804,
+	0x2df1, 0x6000, 0xa086, 0x0003, 0x0120, 0x2009, 0x0007, 0x0804,
+	0x2df1, 0x7e24, 0x860f, 0xa18c, 0x00ff, 0xa6b4, 0x00ff, 0x080c,
+	0x4cdc, 0x1904, 0x2df4, 0xa186, 0x007f, 0x0150, 0x6004, 0xa084,
+	0x00ff, 0xa086, 0x0006, 0x0120, 0x2009, 0x0009, 0x0804, 0x2df1,
+	0x00c6, 0x080c, 0x3c05, 0x00ce, 0x1120, 0x2009, 0x0002, 0x0804,
+	0x2df1, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x080c, 0x9726,
+	0x1120, 0x2009, 0x0003, 0x0804, 0x2df1, 0x7007, 0x0003, 0x701b,
+	0x413a, 0x0005, 0x6808, 0x8007, 0xa086, 0x0100, 0x1120, 0x2009,
+	0x0004, 0x0804, 0x2df1, 0x68b0, 0x6836, 0x6810, 0x8007, 0xa084,
+	0x00ff, 0x808e, 0x6814, 0x8007, 0xa084, 0x00ff, 0x8086, 0xa080,
+	0x0002, 0xa108, 0xad80, 0x0004, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38,
+	0x0804, 0x3c49, 0x080c, 0x3c05, 0x1120, 0x2009, 0x0002, 0x0804,
+	0x2df1, 0x7924, 0xa194, 0xff00, 0xa18c, 0x00ff, 0x8217, 0x82ff,
+	0x0110, 0x0804, 0x2df4, 0x2009, 0x001a, 0x7a2c, 0x7b28, 0x7c3c,
+	0x7d38, 0x080c, 0x3c46, 0x701b, 0x4176, 0x0005, 0xad80, 0x000d,
+	0x2098, 0x20a9, 0x001a, 0x20a1, 0xafad, 0x53a3, 0x0804, 0x2dcc,
+	0x080c, 0x3c05, 0x1120, 0x2009, 0x0002, 0x0804, 0x2df1, 0x7924,
+	0xa194, 0xff00, 0xa18c, 0x00ff, 0x8217, 0x82ff, 0x0110, 0x0804,
+	0x2df4, 0x2099, 0xafad, 0x20a0, 0x20a9, 0x001a, 0x53a3, 0x2009,
+	0x001a, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3c49, 0x7824,
+	0xa08a, 0x1000, 0x1a04, 0x2df4, 0x0126, 0x2091, 0x8000, 0x8003,
+	0x800b, 0x810b, 0xa108, 0x00c6, 0x2061, 0xafda, 0x6142, 0x00ce,
+	0x012e, 0x0804, 0x2dcc, 0x00c6, 0x080c, 0x574f, 0x1188, 0x2001,
+	0xaf9e, 0x2003, 0x0001, 0x2001, 0xad00, 0x2003, 0x0001, 0xa085,
+	0x0001, 0x080c, 0x5793, 0x080c, 0x569a, 0x080c, 0x14f6, 0x0038,
+	0x2061, 0xad00, 0x6030, 0xc09d, 0x6032, 0x080c, 0x485e, 0x00ce,
+	0x0005, 0x0126, 0x00c6, 0x00e6, 0x2061, 0x0100, 0x2071, 0xad00,
+	0x6044, 0xd0a4, 0x11b0, 0xd084, 0x0118, 0x080c, 0x4348, 0x0068,
+	0xd08c, 0x0118, 0x080c, 0x4269, 0x0040, 0xd094, 0x0118, 0x080c,
+	0x423a, 0x0018, 0xd09c, 0x0108, 0x0061, 0x00ee, 0x00ce, 0x012e,
+	0x0005, 0x0016, 0x6128, 0xd19c, 0x1110, 0xc19d, 0x612a, 0x001e,
+	0x0ca0, 0x624c, 0xa286, 0xf0f0, 0x1150, 0x6048, 0xa086, 0xf0f0,
+	0x0130, 0x624a, 0x6043, 0x0090, 0x6043, 0x0010, 0x0490, 0xa294,
+	0xff00, 0xa296, 0xf700, 0x0178, 0x7134, 0xd1a4, 0x1160, 0x6240,
+	0xa295, 0x0100, 0x6242, 0xa294, 0x0010, 0x0128, 0x2009, 0x00f7,
+	0x080c, 0x48de, 0x00f0, 0x6040, 0xa084, 0x0010, 0xa085, 0x0040,
+	0x6042, 0x6043, 0x0000, 0x7077, 0x0000, 0x7093, 0x0001, 0x70b7,
+	0x0000, 0x70d3, 0x0000, 0x2009, 0xb3c0, 0x200b, 0x0000, 0x7087,
+	0x0000, 0x707b, 0x000a, 0x2009, 0x000a, 0x2011, 0x4814, 0x080c,
+	0x6593, 0x0005, 0x0156, 0x2001, 0xad73, 0x2004, 0xd08c, 0x0110,
+	0x704f, 0xffff, 0x7078, 0xa005, 0x1510, 0x2011, 0x4814, 0x080c,
+	0x650d, 0x6040, 0xa094, 0x0010, 0xa285, 0x0020, 0x6042, 0x20a9,
+	0x00c8, 0x6044, 0xd08c, 0x1168, 0x1f04, 0x4251, 0x6242, 0x708b,
+	0x0000, 0x6040, 0xa094, 0x0010, 0xa285, 0x0080, 0x6042, 0x6242,
+	0x0030, 0x6242, 0x708b, 0x0000, 0x707f, 0x0000, 0x0000, 0x015e,
+	0x0005, 0x707c, 0xa08a, 0x0003, 0x1210, 0x0023, 0x0010, 0x080c,
+	0x14f6, 0x0005, 0x4275, 0x42c5, 0x4347, 0x00f6, 0x707f, 0x0001,
+	0x20e1, 0xa000, 0xe000, 0x20e1, 0x8700, 0x080c, 0x22f8, 0x20e1,
+	0x9080, 0x20e1, 0x4000, 0x2079, 0xb200, 0x207b, 0x2200, 0x7807,
+	0x00ef, 0x780b, 0x0000, 0x780f, 0x00ef, 0x7813, 0x0138, 0x7817,
+	0x0000, 0x781b, 0x0000, 0x781f, 0x0000, 0x7823, 0xffff, 0x7827,
+	0xffff, 0x782b, 0x0000, 0x782f, 0x0000, 0x2079, 0xb20c, 0x207b,
+	0x1101, 0x7807, 0x0000, 0x2099, 0xad05, 0x20a1, 0xb20e, 0x20a9,
+	0x0004, 0x53a3, 0x2079, 0xb212, 0x207b, 0x0000, 0x7807, 0x0000,
+	0x2099, 0xb200, 0x20a1, 0x020b, 0x20a9, 0x0014, 0x53a6, 0x60c3,
+	0x000c, 0x600f, 0x0000, 0x080c, 0x4845, 0x00fe, 0x7083, 0x0000,
+	0x6043, 0x0008, 0x6043, 0x0000, 0x0005, 0x00d6, 0x7080, 0x7083,
+	0x0000, 0xa025, 0x0904, 0x432f, 0x6020, 0xd0b4, 0x1904, 0x432d,
+	0x7190, 0x81ff, 0x0904, 0x431d, 0xa486, 0x000c, 0x1904, 0x4328,
+	0xa480, 0x0018, 0x8004, 0x20a8, 0x2011, 0xb280, 0x2019, 0xb200,
+	0x220c, 0x2304, 0xa106, 0x11b8, 0x8210, 0x8318, 0x1f04, 0x42e0,
+	0x6043, 0x0004, 0x608b, 0xbc94, 0x608f, 0xf0f0, 0x6043, 0x0006,
+	0x707f, 0x0002, 0x708b, 0x0002, 0x2009, 0x07d0, 0x2011, 0x481b,
+	0x080c, 0x6593, 0x0490, 0x2069, 0xb280, 0x6930, 0xa18e, 0x1101,
+	0x1538, 0x6834, 0xa005, 0x1520, 0x6900, 0xa18c, 0x00ff, 0x1118,
+	0x6804, 0xa005, 0x0190, 0x2011, 0xb28e, 0x2019, 0xad05, 0x20a9,
+	0x0004, 0x220c, 0x2304, 0xa102, 0x0230, 0x1190, 0x8210, 0x8318,
+	0x1f04, 0x4311, 0x0068, 0x7093, 0x0000, 0x20e1, 0x9080, 0x20e1,
+	0x4000, 0x2099, 0xb280, 0x20a1, 0x020b, 0x20a9, 0x0014, 0x53a6,
+	0x6043, 0x0008, 0x6043, 0x0000, 0x0010, 0x00de, 0x0005, 0x6040,
+	0xa085, 0x0100, 0x6042, 0x6020, 0xd0b4, 0x1db8, 0x60c3, 0x000c,
+	0x2011, 0xafd1, 0x2013, 0x0000, 0x7083, 0x0000, 0x20e1, 0x9080,
+	0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0x782b, 0x0c30, 0x0005,
+	0x7088, 0xa08a, 0x001d, 0x1210, 0x0023, 0x0010, 0x080c, 0x14f6,
+	0x0005, 0x437b, 0x438a, 0x43b2, 0x43cb, 0x43ef, 0x4417, 0x443b,
+	0x446c, 0x4490, 0x44b8, 0x44ef, 0x4517, 0x4533, 0x4549, 0x4569,
+	0x457c, 0x4584, 0x45b1, 0x45d5, 0x45fd, 0x4621, 0x4652, 0x468f,
+	0x46be, 0x46da, 0x4719, 0x4739, 0x4752, 0x4753, 0x00c6, 0x2061,
+	0xad00, 0x6003, 0x0007, 0x2061, 0x0100, 0x6004, 0xa084, 0xfff9,
+	0x6006, 0x00ce, 0x0005, 0x608b, 0xbc94, 0x608f, 0xf0f0, 0x6043,
+	0x0002, 0x708b, 0x0001, 0x2009, 0x07d0, 0x2011, 0x481b, 0x080c,
+	0x6593, 0x0005, 0x00f6, 0x7080, 0xa086, 0x0014, 0x1508, 0x6043,
+	0x0000, 0x6020, 0xd0b4, 0x11e0, 0x2079, 0xb280, 0x7a30, 0xa296,
+	0x1102, 0x11a0, 0x7834, 0xa005, 0x1188, 0x7a38, 0xd2fc, 0x0128,
+	0x70b4, 0xa005, 0x1110, 0x70b7, 0x0001, 0x2011, 0x481b, 0x080c,
+	0x650d, 0x708b, 0x0010, 0x080c, 0x4584, 0x0010, 0x080c, 0x485e,
+	0x00fe, 0x0005, 0x708b, 0x0003, 0x6043, 0x0004, 0x2011, 0x481b,
+	0x080c, 0x650d, 0x080c, 0x48c6, 0x20a3, 0x1102, 0x20a3, 0x0000,
+	0x20a9, 0x000a, 0x20a3, 0x0000, 0x1f04, 0x43c2, 0x60c3, 0x0014,
+	0x080c, 0x4845, 0x0005, 0x00f6, 0x7080, 0xa005, 0x01f0, 0x2011,
+	0x481b, 0x080c, 0x650d, 0xa086, 0x0014, 0x11a8, 0x2079, 0xb280,
+	0x7a30, 0xa296, 0x1102, 0x1178, 0x7834, 0xa005, 0x1160, 0x7a38,
+	0xd2fc, 0x0128, 0x70b4, 0xa005, 0x1110, 0x70b7, 0x0001, 0x708b,
+	0x0004, 0x0029, 0x0010, 0x080c, 0x485e, 0x00fe, 0x0005, 0x708b,
+	0x0005, 0x080c, 0x48c6, 0x20a3, 0x1103, 0x20a3, 0x0000, 0x3430,
+	0x2011, 0xb28e, 0x080c, 0x4917, 0x1160, 0x7074, 0xa005, 0x1148,
+	0x714c, 0xa186, 0xffff, 0x0128, 0x080c, 0x47df, 0x0110, 0x080c,
+	0x48f5, 0x20a9, 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000,
+	0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, 0x4845, 0x0005, 0x00f6,
+	0x7080, 0xa005, 0x01f0, 0x2011, 0x481b, 0x080c, 0x650d, 0xa086,
+	0x0014, 0x11a8, 0x2079, 0xb280, 0x7a30, 0xa296, 0x1103, 0x1178,
+	0x7834, 0xa005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70b4, 0xa005,
+	0x1110, 0x70b7, 0x0001, 0x708b, 0x0006, 0x0029, 0x0010, 0x080c,
+	0x485e, 0x00fe, 0x0005, 0x708b, 0x0007, 0x080c, 0x48c6, 0x20a3,
+	0x1104, 0x20a3, 0x0000, 0x3430, 0x2011, 0xb28e, 0x080c, 0x4917,
+	0x11a8, 0x7074, 0xa005, 0x1190, 0x7154, 0xa186, 0xffff, 0x0170,
+	0xa180, 0x2be6, 0x200d, 0xa18c, 0xff00, 0x810f, 0x080c, 0x47df,
+	0x0128, 0x080c, 0x3e66, 0x0110, 0x080c, 0x26c0, 0x20a9, 0x0008,
+	0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3,
+	0x0014, 0x080c, 0x4845, 0x0005, 0x00f6, 0x7080, 0xa005, 0x01f0,
+	0x2011, 0x481b, 0x080c, 0x650d, 0xa086, 0x0014, 0x11a8, 0x2079,
+	0xb280, 0x7a30, 0xa296, 0x1104, 0x1178, 0x7834, 0xa005, 0x1160,
+	0x7a38, 0xd2fc, 0x0128, 0x70b4, 0xa005, 0x1110, 0x70b7, 0x0001,
+	0x708b, 0x0008, 0x0029, 0x0010, 0x080c, 0x485e, 0x00fe, 0x0005,
+	0x708b, 0x0009, 0x080c, 0x48c6, 0x20a3, 0x1105, 0x20a3, 0x0100,
+	0x3430, 0x080c, 0x4917, 0x1150, 0x7074, 0xa005, 0x1138, 0x080c,
+	0x4754, 0x1170, 0xa085, 0x0001, 0x080c, 0x26c0, 0x20a9, 0x0008,
+	0x2099, 0xb28e, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000,
+	0x60c3, 0x0014, 0x080c, 0x4845, 0x0010, 0x080c, 0x436e, 0x0005,
+	0x00f6, 0x7080, 0xa005, 0x0588, 0x2011, 0x481b, 0x080c, 0x650d,
+	0xa086, 0x0014, 0x1540, 0x2079, 0xb280, 0x7a30, 0xa296, 0x1105,
+	0x1510, 0x7834, 0x2011, 0x0100, 0xa21e, 0x1160, 0x7a38, 0xd2fc,
+	0x0128, 0x70b4, 0xa005, 0x1110, 0x70b7, 0x0001, 0x708b, 0x000a,
+	0x00b1, 0x0098, 0xa005, 0x1178, 0x7a38, 0xd2fc, 0x0128, 0x70b4,
+	0xa005, 0x1110, 0x70b7, 0x0001, 0x7087, 0x0000, 0x708b, 0x000e,
+	0x080c, 0x4569, 0x0010, 0x080c, 0x485e, 0x00fe, 0x0005, 0x708b,
+	0x000b, 0x2011, 0xb20e, 0x22a0, 0x20a9, 0x0040, 0x2019, 0xffff,
+	0x43a4, 0x20a9, 0x0002, 0x2009, 0x0000, 0x41a4, 0x080c, 0x48c6,
+	0x20a3, 0x1106, 0x20a3, 0x0000, 0x080c, 0x4917, 0x0118, 0x2013,
+	0x0000, 0x0020, 0x7050, 0xa085, 0x0100, 0x2012, 0x2298, 0x20a9,
+	0x0042, 0x53a6, 0x60c3, 0x0084, 0x080c, 0x4845, 0x0005, 0x00f6,
+	0x7080, 0xa005, 0x01b0, 0x2011, 0x481b, 0x080c, 0x650d, 0xa086,
+	0x0084, 0x1168, 0x2079, 0xb280, 0x7a30, 0xa296, 0x1106, 0x1138,
+	0x7834, 0xa005, 0x1120, 0x708b, 0x000c, 0x0029, 0x0010, 0x080c,
+	0x485e, 0x00fe, 0x0005, 0x708b, 0x000d, 0x080c, 0x48c6, 0x20a3,
+	0x1107, 0x20a3, 0x0000, 0x2099, 0xb28e, 0x20a9, 0x0040, 0x53a6,
+	0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0084, 0x080c, 0x4845,
+	0x0005, 0x00f6, 0x7080, 0xa005, 0x01d0, 0x2011, 0x481b, 0x080c,
+	0x650d, 0xa086, 0x0084, 0x1188, 0x2079, 0xb280, 0x7a30, 0xa296,
+	0x1107, 0x1158, 0x7834, 0xa005, 0x1140, 0x7087, 0x0001, 0x080c,
+	0x48b8, 0x708b, 0x000e, 0x0029, 0x0010, 0x080c, 0x485e, 0x00fe,
+	0x0005, 0x708b, 0x000f, 0x7083, 0x0000, 0x608b, 0xbc85, 0x608f,
+	0xb5b5, 0x6043, 0x0005, 0x6043, 0x0004, 0x2009, 0x07d0, 0x2011,
+	0x481b, 0x080c, 0x6501, 0x0005, 0x7080, 0xa005, 0x0120, 0x2011,
+	0x481b, 0x080c, 0x650d, 0x0005, 0x708b, 0x0011, 0x080c, 0x4917,
+	0x1188, 0x716c, 0x81ff, 0x0170, 0x2009, 0x0000, 0x7070, 0xa084,
+	0x00ff, 0x080c, 0x2676, 0xa186, 0x0080, 0x0120, 0x2011, 0xb28e,
+	0x080c, 0x47df, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xb280,
+	0x20a1, 0x020b, 0x7480, 0xa480, 0x0018, 0xa080, 0x0007, 0xa084,
+	0x03f8, 0x8004, 0x20a8, 0x53a6, 0x60c3, 0x0014, 0x080c, 0x4845,
+	0x0005, 0x00f6, 0x7080, 0xa005, 0x01f0, 0x2011, 0x481b, 0x080c,
+	0x650d, 0xa086, 0x0014, 0x11a8, 0x2079, 0xb280, 0x7a30, 0xa296,
+	0x1103, 0x1178, 0x7834, 0xa005, 0x1160, 0x7a38, 0xd2fc, 0x0128,
+	0x70b4, 0xa005, 0x1110, 0x70b7, 0x0001, 0x708b, 0x0012, 0x0029,
+	0x0010, 0x080c, 0x485e, 0x00fe, 0x0005, 0x708b, 0x0013, 0x080c,
+	0x48d2, 0x20a3, 0x1103, 0x20a3, 0x0000, 0x3430, 0x2011, 0xb28e,
+	0x080c, 0x4917, 0x1160, 0x7074, 0xa005, 0x1148, 0x714c, 0xa186,
+	0xffff, 0x0128, 0x080c, 0x47df, 0x0110, 0x080c, 0x48f5, 0x20a9,
+	0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000,
+	0x60c3, 0x0014, 0x080c, 0x4845, 0x0005, 0x00f6, 0x7080, 0xa005,
+	0x01f0, 0x2011, 0x481b, 0x080c, 0x650d, 0xa086, 0x0014, 0x11a8,
+	0x2079, 0xb280, 0x7a30, 0xa296, 0x1104, 0x1178, 0x7834, 0xa005,
+	0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70b4, 0xa005, 0x1110, 0x70b7,
+	0x0001, 0x708b, 0x0014, 0x0029, 0x0010, 0x080c, 0x485e, 0x00fe,
+	0x0005, 0x708b, 0x0015, 0x080c, 0x48d2, 0x20a3, 0x1104, 0x20a3,
+	0x0000, 0x3430, 0x2011, 0xb28e, 0x080c, 0x4917, 0x11a8, 0x7074,
+	0xa005, 0x1190, 0x7154, 0xa186, 0xffff, 0x0170, 0xa180, 0x2be6,
+	0x200d, 0xa18c, 0xff00, 0x810f, 0x080c, 0x47df, 0x0128, 0x080c,
+	0x3e66, 0x0110, 0x080c, 0x26c0, 0x20a9, 0x0008, 0x2298, 0x26a0,
+	0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c,
+	0x4845, 0x0005, 0x00f6, 0x7080, 0xa005, 0x05b8, 0x2011, 0x481b,
+	0x080c, 0x650d, 0xa086, 0x0014, 0x1570, 0x2079, 0xb280, 0x7a30,
+	0xa296, 0x1105, 0x1540, 0x7834, 0x2011, 0x0100, 0xa21e, 0x1148,
+	0x7a38, 0xd2fc, 0x0128, 0x70b4, 0xa005, 0x1110, 0x70b7, 0x0001,
+	0x0060, 0xa005, 0x11c0, 0x7a38, 0xd2fc, 0x0128, 0x70b4, 0xa005,
+	0x1110, 0x70b7, 0x0001, 0x7087, 0x0000, 0x7a38, 0xd2f4, 0x0138,
+	0x2001, 0xad73, 0x2004, 0xd0a4, 0x1110, 0x70d3, 0x0008, 0x708b,
+	0x0016, 0x0029, 0x0010, 0x080c, 0x485e, 0x00fe, 0x0005, 0x20e1,
+	0x9080, 0x20e1, 0x4000, 0x2099, 0xb280, 0x20a1, 0x020b, 0x20a9,
+	0x000e, 0x53a6, 0x3430, 0x2011, 0xb28e, 0x708b, 0x0017, 0x080c,
+	0x4917, 0x1150, 0x7074, 0xa005, 0x1138, 0x080c, 0x4754, 0x1170,
+	0xa085, 0x0001, 0x080c, 0x26c0, 0x20a9, 0x0008, 0x2099, 0xb28e,
+	0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014,
+	0x080c, 0x4845, 0x0010, 0x080c, 0x436e, 0x0005, 0x00f6, 0x7080,
+	0xa005, 0x01b0, 0x2011, 0x481b, 0x080c, 0x650d, 0xa086, 0x0084,
+	0x1168, 0x2079, 0xb280, 0x7a30, 0xa296, 0x1106, 0x1138, 0x7834,
+	0xa005, 0x1120, 0x708b, 0x0018, 0x0029, 0x0010, 0x080c, 0x485e,
+	0x00fe, 0x0005, 0x708b, 0x0019, 0x080c, 0x48d2, 0x20a3, 0x1106,
+	0x20a3, 0x0000, 0x3430, 0x2099, 0xb28e, 0x2039, 0xb20e, 0x27a0,
+	0x20a9, 0x0040, 0x53a3, 0x080c, 0x4917, 0x11e8, 0x2728, 0x2514,
+	0x8207, 0xa084, 0x00ff, 0x8000, 0x2018, 0xa294, 0x00ff, 0x8007,
+	0xa205, 0x202a, 0x7050, 0x2310, 0x8214, 0xa2a0, 0xb20e, 0x2414,
+	0xa38c, 0x0001, 0x0118, 0xa294, 0xff00, 0x0018, 0xa294, 0x00ff,
+	0x8007, 0xa215, 0x2222, 0x2798, 0x26a0, 0x20a9, 0x0040, 0x53a6,
+	0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0084, 0x080c, 0x4845,
+	0x0005, 0x00f6, 0x7080, 0xa005, 0x01d0, 0x2011, 0x481b, 0x080c,
+	0x650d, 0xa086, 0x0084, 0x1188, 0x2079, 0xb280, 0x7a30, 0xa296,
+	0x1107, 0x1158, 0x7834, 0xa005, 0x1140, 0x7087, 0x0001, 0x080c,
+	0x48b8, 0x708b, 0x001a, 0x0029, 0x0010, 0x080c, 0x485e, 0x00fe,
+	0x0005, 0x708b, 0x001b, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099,
+	0xb280, 0x20a1, 0x020b, 0x7480, 0xa480, 0x0018, 0xa080, 0x0007,
+	0xa084, 0x03f8, 0x8004, 0x20a8, 0x53a6, 0x60c3, 0x0084, 0x080c,
+	0x4845, 0x0005, 0x0005, 0x0005, 0x0086, 0x0096, 0x2029, 0xad52,
+	0x252c, 0x20a9, 0x0008, 0x2041, 0xb20e, 0x28a0, 0x2099, 0xb28e,
+	0x53a3, 0x20a9, 0x0008, 0x2011, 0x0007, 0xd5d4, 0x0110, 0x2011,
+	0x0000, 0x2800, 0xa200, 0x200c, 0xa1a6, 0xffff, 0x1148, 0xd5d4,
+	0x0110, 0x8210, 0x0008, 0x8211, 0x1f04, 0x4769, 0x0804, 0x47d7,
+	0x82ff, 0x1160, 0xd5d4, 0x0120, 0xa1a6, 0x3fff, 0x0d90, 0x0020,
+	0xa1a6, 0x3fff, 0x0904, 0x47d7, 0xa18d, 0xc000, 0x20a9, 0x0010,
+	0x2019, 0x0001, 0xd5d4, 0x0110, 0x2019, 0x0010, 0x2120, 0xd5d4,
+	0x0110, 0x8423, 0x0008, 0x8424, 0x1240, 0xd5d4, 0x0110, 0x8319,
+	0x0008, 0x8318, 0x1f04, 0x478f, 0x04d0, 0x23a8, 0x2021, 0x0001,
+	0x8426, 0x8425, 0x1f04, 0x47a1, 0x2328, 0x8529, 0xa2be, 0x0007,
+	0x0158, 0x0006, 0x2039, 0x0007, 0x2200, 0xa73a, 0x000e, 0x27a8,
+	0xa5a8, 0x0010, 0x1f04, 0x47b0, 0x754e, 0xa5c8, 0x2be6, 0x292d,
+	0xa5ac, 0x00ff, 0x7572, 0x6532, 0x6536, 0x0016, 0x2508, 0x080c,
+	0x26a0, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x2018, 0x2304, 0xa405,
+	0x201a, 0x7077, 0x0001, 0x26a0, 0x2898, 0x20a9, 0x0008, 0x53a6,
+	0x20a3, 0x0000, 0x20a3, 0x0000, 0xa085, 0x0001, 0x0028, 0xa006,
+	0x0018, 0xa006, 0x080c, 0x14f6, 0x009e, 0x008e, 0x0005, 0x2118,
+	0x2021, 0x0000, 0x2001, 0x0007, 0xa39a, 0x0010, 0x0218, 0x8420,
+	0x8001, 0x0cd0, 0x2118, 0x84ff, 0x0120, 0xa39a, 0x0010, 0x8421,
+	0x1de0, 0x2021, 0x0001, 0x83ff, 0x0118, 0x8423, 0x8319, 0x1de8,
+	0xa238, 0x2704, 0xa42c, 0x11b8, 0xa405, 0x203a, 0x714e, 0xa1a0,
+	0x2be6, 0x242d, 0xa5ac, 0x00ff, 0x7572, 0x6532, 0x6536, 0x0016,
+	0x2508, 0x080c, 0x26a0, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x7077,
+	0x0001, 0xa084, 0x0000, 0x0005, 0x00e6, 0x2071, 0xad00, 0x707b,
+	0x0000, 0x00ee, 0x0005, 0x00e6, 0x00f6, 0x2079, 0x0100, 0x2071,
+	0x0140, 0x080c, 0x7834, 0x7004, 0xa084, 0x4000, 0x0120, 0x7003,
+	0x1000, 0x7003, 0x0000, 0x0126, 0x2091, 0x8000, 0x2071, 0xad22,
+	0x2073, 0x0000, 0x7840, 0x0026, 0x0016, 0x2009, 0x00f7, 0x080c,
+	0x48de, 0x001e, 0xa094, 0x0010, 0xa285, 0x0080, 0x7842, 0x7a42,
+	0x002e, 0x012e, 0x00fe, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000,
+	0x2011, 0xafd1, 0x2013, 0x0000, 0x7083, 0x0000, 0x012e, 0x20e1,
+	0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0x782b, 0x2009,
+	0x07d0, 0x2011, 0x481b, 0x080c, 0x6593, 0x0005, 0x0016, 0x0026,
+	0x00c6, 0x0126, 0x2091, 0x8000, 0x2009, 0x00f7, 0x080c, 0x48de,
+	0x2061, 0xafda, 0x601b, 0x0000, 0x601f, 0x0000, 0x2061, 0xad00,
+	0x6003, 0x0001, 0x2061, 0x0100, 0x6043, 0x0090, 0x6043, 0x0010,
+	0x2009, 0x002d, 0x2011, 0x4883, 0x080c, 0x6501, 0x012e, 0x00ce,
+	0x002e, 0x001e, 0x0005, 0x00e6, 0x0006, 0x0126, 0x2091, 0x8000,
+	0x2071, 0x0100, 0x080c, 0x7834, 0x2071, 0x0140, 0x7004, 0xa084,
+	0x4000, 0x0120, 0x7003, 0x1000, 0x7003, 0x0000, 0x080c, 0x5757,
+	0x01a8, 0x080c, 0x5775, 0x1190, 0x2001, 0xaf9d, 0x2003, 0xaaaa,
+	0x0016, 0x080c, 0x2744, 0x2001, 0xaf8e, 0x2102, 0x001e, 0x2001,
+	0xaf9e, 0x2003, 0x0000, 0x080c, 0x569a, 0x0030, 0x2001, 0x0001,
+	0x080c, 0x261e, 0x080c, 0x485e, 0x012e, 0x000e, 0x00ee, 0x0005,
+	0x20a9, 0x0040, 0x20a1, 0xb3c0, 0x2099, 0xb28e, 0x3304, 0x8007,
+	0x20a2, 0x9398, 0x94a0, 0x1f04, 0x48be, 0x0005, 0x20e1, 0x9080,
+	0x20e1, 0x4000, 0x2099, 0xb200, 0x20a1, 0x020b, 0x20a9, 0x000c,
+	0x53a6, 0x0005, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xb280,
+	0x20a1, 0x020b, 0x20a9, 0x000c, 0x53a6, 0x0005, 0x00c6, 0x0006,
+	0x2061, 0x0100, 0x810f, 0x2001, 0xad30, 0x2004, 0xa005, 0x1138,
+	0x2001, 0xad14, 0x2004, 0xa084, 0x00ff, 0xa105, 0x0010, 0xa185,
+	0x00f7, 0x604a, 0x000e, 0x00ce, 0x0005, 0x0016, 0x0046, 0x2001,
+	0xad52, 0x2004, 0xd0a4, 0x0158, 0xa006, 0x2020, 0x2009, 0x002a,
+	0x080c, 0xa96c, 0x2001, 0xad0c, 0x200c, 0xc195, 0x2102, 0x2019,
+	0x002a, 0x2009, 0x0000, 0x080c, 0x2aac, 0x004e, 0x001e, 0x0005,
+	0x080c, 0x485e, 0x708b, 0x0000, 0x7083, 0x0000, 0x0005, 0x0006,
+	0x2001, 0xad0c, 0x2004, 0xd09c, 0x0100, 0x000e, 0x0005, 0x0006,
+	0x0016, 0x0126, 0x2091, 0x8000, 0x2001, 0x0101, 0x200c, 0xa18d,
+	0x0006, 0x2102, 0x012e, 0x001e, 0x000e, 0x0005, 0x0156, 0x20a9,
+	0x00ff, 0x2009, 0xae34, 0xa006, 0x200a, 0x8108, 0x1f04, 0x4934,
+	0x015e, 0x0005, 0x00d6, 0x0036, 0x0156, 0x0136, 0x0146, 0x2069,
+	0xad51, 0xa006, 0x6002, 0x6007, 0x0707, 0x600a, 0x600e, 0x6012,
+	0xa198, 0x2be6, 0x231d, 0xa39c, 0x00ff, 0x6316, 0x20a9, 0x0004,
+	0xac98, 0x0006, 0x23a0, 0x40a4, 0x20a9, 0x0004, 0xac98, 0x000a,
+	0x23a0, 0x40a4, 0x603e, 0x6042, 0x604e, 0x6052, 0x6056, 0x605a,
+	0x605e, 0x6062, 0x6066, 0x606a, 0x606e, 0x6072, 0x6076, 0x607a,
+	0x607e, 0x6082, 0x6086, 0x608a, 0x608e, 0x6092, 0x6096, 0x609a,
+	0x609e, 0x60ae, 0x61a2, 0x00d6, 0x60a4, 0xa06d, 0x0110, 0x080c,
+	0x15f0, 0x60a7, 0x0000, 0x60a8, 0xa06d, 0x0110, 0x080c, 0x15f0,
+	0x60ab, 0x0000, 0x00de, 0xa006, 0x604a, 0x6810, 0x603a, 0x680c,
+	0x6046, 0x6814, 0xa084, 0x00ff, 0x6042, 0x014e, 0x013e, 0x015e,
+	0x003e, 0x00de, 0x0005, 0x0126, 0x2091, 0x8000, 0x6944, 0x6e48,
+	0xa684, 0x3fff, 0xa082, 0x4000, 0x1a04, 0x4a49, 0xa18c, 0xff00,
+	0x810f, 0xa182, 0x00ff, 0x1a04, 0x4a4e, 0x2001, 0xad0c, 0x2004,
+	0xa084, 0x0003, 0x01c0, 0x2001, 0xad0c, 0x2004, 0xd084, 0x1904,
+	0x4a31, 0xa188, 0xae34, 0x2104, 0xa065, 0x0904, 0x4a31, 0x6004,
+	0xa084, 0x00ff, 0xa08e, 0x0006, 0x1904, 0x4a31, 0x6000, 0xd0c4,
+	0x0904, 0x4a31, 0x0068, 0xa188, 0xae34, 0x2104, 0xa065, 0x0904,
+	0x4a15, 0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, 0x1904, 0x4a1a,
+	0x60a4, 0xa00d, 0x0118, 0x080c, 0x4ef9, 0x05d0, 0x60a8, 0xa00d,
+	0x0188, 0x080c, 0x4f43, 0x1170, 0x694c, 0xd1fc, 0x1118, 0x080c,
+	0x4c11, 0x0448, 0x080c, 0x4bd3, 0x694c, 0xd1ec, 0x1520, 0x080c,
+	0x4ded, 0x0408, 0x694c, 0xa184, 0xa000, 0x0178, 0xd1ec, 0x0140,
+	0xd1fc, 0x0118, 0x080c, 0x4dfc, 0x0028, 0x080c, 0x4dfc, 0x0028,
+	0xd1fc, 0x0118, 0x080c, 0x4bd3, 0x0070, 0x6050, 0xa00d, 0x0130,
+	0x2d00, 0x200a, 0x6803, 0x0000, 0x6052, 0x0028, 0x2d00, 0x6052,
+	0x604e, 0x6803, 0x0000, 0x080c, 0x67c5, 0xa006, 0x012e, 0x0005,
+	0x2001, 0x0005, 0x2009, 0x0000, 0x04e8, 0x2001, 0x0028, 0x2009,
+	0x0000, 0x04c0, 0xa082, 0x0006, 0x12a0, 0x2001, 0xad34, 0x2004,
+	0xd0ac, 0x1160, 0x60a0, 0xd0bc, 0x1148, 0x6100, 0xd1fc, 0x0904,
+	0x49d0, 0x2001, 0x0029, 0x2009, 0x1000, 0x0420, 0x2001, 0x0028,
+	0x00a8, 0x2009, 0xad0c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004,
+	0x0068, 0xd184, 0x0118, 0x2001, 0x0004, 0x0040, 0x2001, 0x0029,
+	0x6100, 0xd1fc, 0x0118, 0x2009, 0x1000, 0x0060, 0x2009, 0x0000,
+	0x0048, 0x2001, 0x0029, 0x2009, 0x0000, 0x0020, 0x2001, 0x0029,
+	0x2009, 0x0000, 0xa005, 0x012e, 0x0005, 0x00e6, 0x0126, 0x2091,
+	0x8000, 0x6844, 0x8007, 0xa084, 0x00ff, 0x2008, 0xa182, 0x00ff,
+	0x1a04, 0x4aa8, 0xa188, 0xae34, 0x2104, 0xa065, 0x01c0, 0x6004,
+	0xa084, 0x00ff, 0xa08e, 0x0006, 0x11a8, 0x2c70, 0x080c, 0x8022,
+	0x05e8, 0x2e00, 0x601a, 0x2d00, 0x6012, 0x600b, 0xffff, 0x601f,
+	0x000a, 0x2009, 0x0003, 0x080c, 0x80a7, 0xa006, 0x0460, 0x2001,
+	0x0028, 0x0440, 0xa082, 0x0006, 0x1298, 0x2001, 0xad34, 0x2004,
+	0xd0ac, 0x1158, 0x60a0, 0xd0bc, 0x1140, 0x6100, 0xd1fc, 0x09e8,
+	0x2001, 0x0029, 0x2009, 0x1000, 0x00a8, 0x2001, 0x0028, 0x0090,
+	0x2009, 0xad0c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0050,
+	0xd184, 0x0118, 0x2001, 0x0004, 0x0028, 0x2001, 0x0029, 0x0010,
+	0x2001, 0x0029, 0xa005, 0x012e, 0x00ee, 0x0005, 0x2001, 0x002c,
+	0x0cc8, 0x00f6, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2011, 0x0000,
+	0x2079, 0xad00, 0x6944, 0xa18c, 0xff00, 0x810f, 0xa182, 0x00ff,
+	0x1a04, 0x4b77, 0x2001, 0xad0c, 0x2004, 0xa084, 0x0003, 0x1904,
+	0x4b65, 0x080c, 0x4cdc, 0x1180, 0x6004, 0xa084, 0x00ff, 0xa082,
+	0x0006, 0x1250, 0x2001, 0xad34, 0x2004, 0xd0ac, 0x1904, 0x4b60,
+	0x60a0, 0xd0bc, 0x1904, 0x4b60, 0x6864, 0xa0c6, 0x006f, 0x0118,
+	0x2008, 0x0804, 0x4b28, 0x6968, 0x2140, 0xa18c, 0xff00, 0x810f,
+	0x78d0, 0xd0ac, 0x1118, 0xa182, 0x0080, 0x06d0, 0xa182, 0x00ff,
+	0x16b8, 0x6a70, 0x6b6c, 0x786c, 0xa306, 0x1160, 0x7870, 0xa24e,
+	0x1118, 0x2208, 0x2310, 0x0460, 0xa9cc, 0xff00, 0x1118, 0x2208,
+	0x2310, 0x0430, 0x080c, 0x3b58, 0x2c70, 0x0550, 0x2009, 0x0000,
+	0x2011, 0x0000, 0xa0c6, 0x4000, 0x1160, 0x0006, 0x2e60, 0x080c,
+	0x4f6e, 0x1108, 0xc185, 0x7000, 0xd0bc, 0x0108, 0xc18d, 0x000e,
+	0x0088, 0xa0c6, 0x4007, 0x1110, 0x2408, 0x0060, 0xa0c6, 0x4008,
+	0x1118, 0x2708, 0x2610, 0x0030, 0xa0c6, 0x4009, 0x1108, 0x0010,
+	0x2001, 0x4006, 0x6866, 0x696a, 0x6a6e, 0x2001, 0x0030, 0x0458,
+	0x080c, 0x8022, 0x1138, 0x2001, 0x4005, 0x2009, 0x0003, 0x2011,
+	0x0000, 0x0c80, 0x2e00, 0x601a, 0x080c, 0x9956, 0x2d00, 0x6012,
+	0x601f, 0x0001, 0xa006, 0xd88c, 0x0110, 0x2001, 0x4000, 0x683a,
+	0x0126, 0x2091, 0x8000, 0x080c, 0x2ad9, 0x012e, 0x2001, 0x0000,
+	0x080c, 0x4c1e, 0x2001, 0x0002, 0x080c, 0x4c30, 0x2009, 0x0002,
+	0x080c, 0x80a7, 0xa006, 0xa005, 0x012e, 0x00ee, 0x00fe, 0x0005,
+	0x2001, 0x0028, 0x2009, 0x0000, 0x0cb0, 0x2009, 0xad0c, 0x210c,
+	0xd18c, 0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001,
+	0x0004, 0x0010, 0x2001, 0x0029, 0x2009, 0x0000, 0x0c20, 0x2001,
+	0x0029, 0x2009, 0x0000, 0x08f8, 0x6944, 0x6e48, 0xa684, 0x3fff,
+	0xa082, 0x4000, 0x16b8, 0xa18c, 0xff00, 0x810f, 0xa182, 0x00ff,
+	0x12e0, 0xa188, 0xae34, 0x2104, 0xa065, 0x01b8, 0x6004, 0xa084,
+	0x00ff, 0xa08e, 0x0006, 0x11b0, 0x684c, 0xd0ec, 0x0120, 0x080c,
+	0x4dfc, 0x04c9, 0x0030, 0x04b9, 0x684c, 0xd0fc, 0x0110, 0x080c,
+	0x4ded, 0x080c, 0x4e3a, 0xa006, 0x00c8, 0x2001, 0x0028, 0x2009,
+	0x0000, 0x00a0, 0xa082, 0x0006, 0x1240, 0x6100, 0xd1fc, 0x0d20,
+	0x2001, 0x0029, 0x2009, 0x1000, 0x0048, 0x2001, 0x0029, 0x2009,
+	0x0000, 0x0020, 0x2001, 0x0029, 0x2009, 0x0000, 0xa005, 0x0005,
+	0x0126, 0x2091, 0x8000, 0x6050, 0xa00d, 0x0138, 0x2d00, 0x200a,
+	0x6803, 0x0000, 0x6052, 0x012e, 0x0005, 0x2d00, 0x6052, 0x604e,
+	0x6803, 0x0000, 0x0cc0, 0x0126, 0x2091, 0x8000, 0x604c, 0xa005,
+	0x0170, 0x00e6, 0x2071, 0xafc7, 0x7004, 0xa086, 0x0002, 0x0168,
+	0x00ee, 0x604c, 0x6802, 0x2d00, 0x604e, 0x012e, 0x0005, 0x2d00,
+	0x6052, 0x604e, 0x6803, 0x0000, 0x0cc0, 0x701c, 0xac06, 0x1d80,
+	0x604c, 0x2070, 0x7000, 0x6802, 0x2d00, 0x7002, 0x00ee, 0x012e,
+	0x0005, 0x0126, 0x2091, 0x8000, 0x604c, 0xa06d, 0x0130, 0x6800,
+	0xa005, 0x1108, 0x6052, 0x604e, 0xad05, 0x012e, 0x0005, 0x604c,
+	0xa06d, 0x0130, 0x6800, 0xa005, 0x1108, 0x6052, 0x604e, 0xad05,
+	0x0005, 0x6803, 0x0000, 0x6084, 0xa00d, 0x0120, 0x2d00, 0x200a,
+	0x6086, 0x0005, 0x2d00, 0x6086, 0x6082, 0x0cd8, 0x0126, 0x00c6,
+	0x0026, 0x2091, 0x8000, 0x6218, 0x2260, 0x6200, 0xa005, 0x0110,
+	0xc285, 0x0008, 0xc284, 0x6202, 0x002e, 0x00ce, 0x012e, 0x0005,
+	0x0126, 0x00c6, 0x2091, 0x8000, 0x6218, 0x2260, 0x6204, 0x0006,
+	0xa086, 0x0006, 0x1180, 0x609c, 0xd0ac, 0x0168, 0x2001, 0xad52,
+	0x2004, 0xd0a4, 0x0140, 0xa284, 0xff00, 0x8007, 0xa086, 0x0007,
+	0x1110, 0x2011, 0x0600, 0x000e, 0xa294, 0xff00, 0xa215, 0x6206,
+	0x0006, 0xa086, 0x0006, 0x1128, 0x6290, 0x82ff, 0x1110, 0x080c,
+	0x14f6, 0x000e, 0x00ce, 0x012e, 0x0005, 0x0126, 0x00c6, 0x2091,
+	0x8000, 0x6218, 0x2260, 0x6204, 0x0006, 0xa086, 0x0006, 0x1178,
+	0x609c, 0xd0a4, 0x0160, 0x2001, 0xad52, 0x2004, 0xd0ac, 0x1138,
+	0xa284, 0x00ff, 0xa086, 0x0007, 0x1110, 0x2011, 0x0006, 0x000e,
+	0xa294, 0x00ff, 0x8007, 0xa215, 0x6206, 0x00ce, 0x012e, 0x0005,
+	0x0026, 0xa182, 0x00ff, 0x0218, 0xa085, 0x0001, 0x00b0, 0xa190,
+	0xae34, 0x2204, 0xa065, 0x1180, 0x0016, 0x00d6, 0x080c, 0x15c0,
+	0x2d60, 0x00de, 0x001e, 0x0d80, 0x2c00, 0x2012, 0x60a7, 0x0000,
+	0x60ab, 0x0000, 0x080c, 0x493a, 0xa006, 0x002e, 0x0005, 0x0126,
+	0x2091, 0x8000, 0x0026, 0xa182, 0x00ff, 0x0218, 0xa085, 0x0001,
+	0x0480, 0x00d6, 0xa190, 0xae34, 0x2204, 0xa06d, 0x0540, 0x2013,
+	0x0000, 0x00d6, 0x00c6, 0x2d60, 0x60a4, 0xa06d, 0x0110, 0x080c,
+	0x15f0, 0x60a8, 0xa06d, 0x0110, 0x080c, 0x15f0, 0x00ce, 0x00de,
+	0x00d6, 0x00c6, 0x68ac, 0x2060, 0x8cff, 0x0168, 0x600c, 0x0006,
+	0x6010, 0x2068, 0x080c, 0x9596, 0x0110, 0x080c, 0x1600, 0x080c,
+	0x8078, 0x00ce, 0x0c88, 0x00ce, 0x00de, 0x080c, 0x15f0, 0x00de,
+	0xa006, 0x002e, 0x012e, 0x0005, 0x0016, 0xa182, 0x00ff, 0x0218,
+	0xa085, 0x0001, 0x0030, 0xa188, 0xae34, 0x2104, 0xa065, 0x0dc0,
+	0xa006, 0x001e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x600b,
+	0x0000, 0x600f, 0x0000, 0x6000, 0xc08c, 0x6002, 0x080c, 0x574f,
+	0x1538, 0x60a0, 0xa086, 0x007e, 0x2069, 0xb290, 0x0130, 0x2001,
+	0xad34, 0x2004, 0xd0ac, 0x11e0, 0x0098, 0x2d04, 0xd0e4, 0x01c0,
+	0x00d6, 0x2069, 0xb28e, 0x00c6, 0x2061, 0xaf9f, 0x6810, 0x2062,
+	0x6814, 0x6006, 0x6818, 0x600a, 0x681c, 0x600e, 0x00ce, 0x00de,
+	0x8d69, 0x2d04, 0x2069, 0x0140, 0x6886, 0x2069, 0xad00, 0x68a2,
+	0x2069, 0xb28e, 0x6808, 0x605e, 0x6810, 0x6062, 0x6138, 0xa10a,
+	0x0208, 0x603a, 0x6814, 0x6066, 0x2099, 0xb296, 0xac88, 0x000a,
+	0x21a0, 0x20a9, 0x0004, 0x53a3, 0x2099, 0xb29a, 0xac88, 0x0006,
+	0x21a0, 0x20a9, 0x0004, 0x53a3, 0x2069, 0xb2ae, 0x6808, 0x606a,
+	0x690c, 0x616e, 0x6810, 0x6072, 0x6818, 0x6076, 0xa182, 0x0211,
+	0x1218, 0x2009, 0x0008, 0x0400, 0xa182, 0x0259, 0x1218, 0x2009,
+	0x0007, 0x00d0, 0xa182, 0x02c1, 0x1218, 0x2009, 0x0006, 0x00a0,
+	0xa182, 0x0349, 0x1218, 0x2009, 0x0005, 0x0070, 0xa182, 0x0421,
+	0x1218, 0x2009, 0x0004, 0x0040, 0xa182, 0x0581, 0x1218, 0x2009,
+	0x0003, 0x0010, 0x2009, 0x0002, 0x6192, 0x014e, 0x013e, 0x015e,
+	0x00de, 0x0005, 0x0016, 0x0026, 0x00e6, 0x2071, 0xb28d, 0x2e04,
+	0x6896, 0x2071, 0xb28e, 0x7004, 0x689a, 0x701c, 0x689e, 0x6a00,
+	0x2009, 0xad71, 0x210c, 0xd0bc, 0x0120, 0xd1ec, 0x0110, 0xc2ad,
+	0x0008, 0xc2ac, 0xd0c4, 0x0120, 0xd1e4, 0x0110, 0xc2bd, 0x0008,
+	0xc2bc, 0x6a02, 0x00ee, 0x002e, 0x001e, 0x0005, 0x00d6, 0x0126,
+	0x2091, 0x8000, 0x60a4, 0xa06d, 0x01c0, 0x6900, 0x81ff, 0x1540,
+	0x6a04, 0xa282, 0x0010, 0x1648, 0xad88, 0x0004, 0x20a9, 0x0010,
+	0x2104, 0xa086, 0xffff, 0x0128, 0x8108, 0x1f04, 0x4da8, 0x080c,
+	0x14f6, 0x260a, 0x8210, 0x6a06, 0x0098, 0x080c, 0x15d9, 0x01a8,
+	0x2d00, 0x60a6, 0x6803, 0x0000, 0xad88, 0x0004, 0x20a9, 0x0010,
+	0x200b, 0xffff, 0x8108, 0x1f04, 0x4dc0, 0x6807, 0x0001, 0x6e12,
+	0xa085, 0x0001, 0x012e, 0x00de, 0x0005, 0xa006, 0x0cd8, 0x0126,
+	0x2091, 0x8000, 0x00d6, 0x60a4, 0xa00d, 0x01a0, 0x2168, 0x6800,
+	0xa005, 0x1160, 0x080c, 0x4ef9, 0x1168, 0x200b, 0xffff, 0x6804,
+	0xa08a, 0x0002, 0x0218, 0x8001, 0x6806, 0x0020, 0x080c, 0x15f0,
+	0x60a7, 0x0000, 0x00de, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000,
+	0x080c, 0x4f56, 0x0010, 0x080c, 0x4bc0, 0x080c, 0x4e71, 0x1dd8,
+	0x080c, 0x4e3a, 0x012e, 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000,
+	0x60a8, 0xa06d, 0x01c0, 0x6950, 0x81ff, 0x1540, 0x6a54, 0xa282,
+	0x0010, 0x1670, 0xad88, 0x0018, 0x20a9, 0x0010, 0x2104, 0xa086,
+	0xffff, 0x0128, 0x8108, 0x1f04, 0x4e0e, 0x080c, 0x14f6, 0x260a,
+	0x8210, 0x6a56, 0x0098, 0x080c, 0x15d9, 0x01d0, 0x2d00, 0x60aa,
+	0x6853, 0x0000, 0xad88, 0x0018, 0x20a9, 0x0010, 0x200b, 0xffff,
+	0x8108, 0x1f04, 0x4e26, 0x6857, 0x0001, 0x6e62, 0x0010, 0x080c,
+	0x4c11, 0x0089, 0x1de0, 0xa085, 0x0001, 0x012e, 0x00de, 0x0005,
+	0xa006, 0x0cd8, 0x0126, 0x2091, 0x8000, 0x080c, 0x67c5, 0x012e,
+	0x0005, 0xa01e, 0x0010, 0x2019, 0x0001, 0xa00e, 0x0126, 0x2091,
+	0x8000, 0x604c, 0x2068, 0x6000, 0xd0dc, 0x1170, 0x8dff, 0x01e8,
+	0x83ff, 0x0120, 0x6848, 0xa606, 0x0158, 0x0030, 0x683c, 0xa406,
+	0x1118, 0x6840, 0xa506, 0x0120, 0x2d08, 0x6800, 0x2068, 0x0c70,
+	0x6a00, 0x604c, 0xad06, 0x1110, 0x624e, 0x0018, 0xa180, 0x0000,
+	0x2202, 0x82ff, 0x1110, 0x6152, 0x8dff, 0x012e, 0x0005, 0xa01e,
+	0x0010, 0x2019, 0x0001, 0xa00e, 0x6080, 0x2068, 0x8dff, 0x01e8,
+	0x83ff, 0x0120, 0x6848, 0xa606, 0x0158, 0x0030, 0x683c, 0xa406,
+	0x1118, 0x6840, 0xa506, 0x0120, 0x2d08, 0x6800, 0x2068, 0x0c70,
+	0x6a00, 0x6080, 0xad06, 0x1110, 0x6282, 0x0018, 0xa180, 0x0000,
+	0x2202, 0x82ff, 0x1110, 0x6186, 0x8dff, 0x0005, 0xa016, 0x080c,
+	0x4ef3, 0x1110, 0x2011, 0x0001, 0x080c, 0x4f3d, 0x1110, 0xa295,
+	0x0002, 0x0005, 0x080c, 0x4f6e, 0x0118, 0x080c, 0x964b, 0x0010,
+	0xa085, 0x0001, 0x0005, 0x080c, 0x4f6e, 0x0118, 0x080c, 0x95e4,
+	0x0010, 0xa085, 0x0001, 0x0005, 0x080c, 0x4f6e, 0x0118, 0x080c,
+	0x962e, 0x0010, 0xa085, 0x0001, 0x0005, 0x080c, 0x4f6e, 0x0118,
+	0x080c, 0x9600, 0x0010, 0xa085, 0x0001, 0x0005, 0x080c, 0x4f6e,
+	0x0118, 0x080c, 0x9667, 0x0010, 0xa085, 0x0001, 0x0005, 0x0126,
+	0x0006, 0x00d6, 0x2091, 0x8000, 0x6080, 0xa06d, 0x01a0, 0x6800,
+	0x0006, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x97fd,
+	0x0006, 0x6000, 0xd0fc, 0x0110, 0x080c, 0xac03, 0x000e, 0x080c,
+	0x510c, 0x000e, 0x0c50, 0x6083, 0x0000, 0x6087, 0x0000, 0x00de,
+	0x000e, 0x012e, 0x0005, 0x60a4, 0xa00d, 0x1118, 0xa085, 0x0001,
+	0x0005, 0x00e6, 0x2170, 0x7000, 0xa005, 0x1160, 0x20a9, 0x0010,
+	0xae88, 0x0004, 0x2104, 0xa606, 0x0128, 0x8108, 0x1f04, 0x4f02,
+	0xa085, 0x0001, 0xa006, 0x00ee, 0x0005, 0x00d6, 0x0126, 0x2091,
+	0x8000, 0x60a4, 0xa06d, 0x1128, 0x080c, 0x15d9, 0x01a0, 0x2d00,
+	0x60a6, 0x6803, 0x0001, 0x6807, 0x0000, 0xad88, 0x0004, 0x20a9,
+	0x0010, 0x200b, 0xffff, 0x8108, 0x1f04, 0x4f21, 0xa085, 0x0001,
+	0x012e, 0x00de, 0x0005, 0xa006, 0x0cd8, 0x00d6, 0x0126, 0x2091,
+	0x8000, 0x60a4, 0xa06d, 0x0130, 0x60a7, 0x0000, 0x080c, 0x15f0,
+	0xa085, 0x0001, 0x012e, 0x00de, 0x0005, 0x60a8, 0xa00d, 0x1118,
+	0xa085, 0x0001, 0x0005, 0x00e6, 0x2170, 0x7050, 0xa005, 0x1160,
+	0x20a9, 0x0010, 0xae88, 0x0018, 0x2104, 0xa606, 0x0128, 0x8108,
+	0x1f04, 0x4f4c, 0xa085, 0x0001, 0x00ee, 0x0005, 0x0126, 0x2091,
+	0x8000, 0x0c19, 0x1188, 0x200b, 0xffff, 0x00d6, 0x60a8, 0x2068,
+	0x6854, 0xa08a, 0x0002, 0x0218, 0x8001, 0x6856, 0x0020, 0x080c,
+	0x15f0, 0x60ab, 0x0000, 0x00de, 0x012e, 0x0005, 0x609c, 0xd0a4,
+	0x0005, 0x00f6, 0x080c, 0x574f, 0x01b0, 0x71b4, 0x81ff, 0x1198,
+	0x71d0, 0xd19c, 0x0180, 0x2001, 0x007e, 0xa080, 0xae34, 0x2004,
+	0xa07d, 0x0148, 0x7804, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1118,
+	0x7800, 0xc0ed, 0x7802, 0x2079, 0xad51, 0x7804, 0xd0a4, 0x01e8,
+	0x0156, 0x00c6, 0x20a9, 0x007f, 0x2009, 0x0000, 0x0016, 0x080c,
+	0x4cdc, 0x1168, 0x6004, 0xa084, 0xff00, 0x8007, 0xa096, 0x0004,
+	0x0118, 0xa086, 0x0006, 0x1118, 0x6000, 0xc0ed, 0x6002, 0x001e,
+	0x8108, 0x1f04, 0x4f96, 0x00ce, 0x015e, 0x080c, 0x502d, 0x0120,
+	0x2001, 0xafa2, 0x200c, 0x0038, 0x2079, 0xad51, 0x7804, 0xd0a4,
+	0x0130, 0x2009, 0x07d0, 0x2011, 0x4fc1, 0x080c, 0x6593, 0x00fe,
+	0x0005, 0x2011, 0x4fc1, 0x080c, 0x650d, 0x080c, 0x502d, 0x01f0,
+	0x2001, 0xaeb2, 0x2004, 0xa080, 0x0000, 0x200c, 0xc1ec, 0x2102,
+	0x2001, 0xad52, 0x2004, 0xd0a4, 0x0130, 0x2009, 0x07d0, 0x2011,
+	0x4fc1, 0x080c, 0x6593, 0x00e6, 0x2071, 0xad00, 0x706f, 0x0000,
+	0x7073, 0x0000, 0x080c, 0x28fa, 0x00ee, 0x04b0, 0x0156, 0x00c6,
+	0x20a9, 0x007f, 0x2009, 0x0000, 0x0016, 0x080c, 0x4cdc, 0x1530,
+	0x6000, 0xd0ec, 0x0518, 0x0046, 0x62a0, 0xa294, 0x00ff, 0x8227,
+	0xa006, 0x2009, 0x0029, 0x080c, 0xa96c, 0x6000, 0xc0e5, 0xc0ec,
+	0x6002, 0x6004, 0xa084, 0x00ff, 0xa085, 0x0700, 0x6006, 0x2019,
+	0x0029, 0x080c, 0x68e7, 0x0076, 0x2039, 0x0000, 0x080c, 0x681d,
+	0x2009, 0x0000, 0x080c, 0xa712, 0x007e, 0x004e, 0x001e, 0x8108,
+	0x1f04, 0x4fec, 0x00ce, 0x015e, 0x0005, 0x00c6, 0x6018, 0x2060,
+	0x6000, 0xc0ec, 0x6002, 0x00ce, 0x0005, 0x7818, 0x2004, 0xd0ac,
+	0x0005, 0x7818, 0x2004, 0xd0bc, 0x0005, 0x00f6, 0x2001, 0xaeb2,
+	0x2004, 0xa07d, 0x0110, 0x7800, 0xd0ec, 0x00fe, 0x0005, 0x0126,
+	0x0026, 0x2091, 0x8000, 0x6200, 0xa005, 0x0110, 0xc2fd, 0x0008,
+	0xc2fc, 0x6202, 0x002e, 0x012e, 0x0005, 0x2071, 0xae13, 0x7003,
+	0x0001, 0x7007, 0x0000, 0x7013, 0x0000, 0x7017, 0x0000, 0x701b,
+	0x0000, 0x701f, 0x0000, 0x700b, 0x0000, 0x704b, 0x0001, 0x704f,
+	0x0000, 0x705b, 0x0020, 0x705f, 0x0040, 0x707f, 0x0000, 0x2071,
+	0xaf7c, 0x7003, 0xae13, 0x7007, 0x0000, 0x700b, 0x0000, 0x700f,
+	0xaf5c, 0x7013, 0x0020, 0x7017, 0x0040, 0x7037, 0x0000, 0x0005,
+	0x0016, 0x00e6, 0x2071, 0xaf34, 0xa00e, 0x7186, 0x718a, 0x7097,
+	0x0001, 0x2001, 0xad52, 0x2004, 0xd0fc, 0x1150, 0x2001, 0xad52,
+	0x2004, 0xa00e, 0xd09c, 0x0108, 0x8108, 0x7102, 0x0804, 0x50d6,
+	0x2001, 0xad71, 0x200c, 0xa184, 0x000f, 0x2009, 0xad72, 0x210c,
+	0x0002, 0x507e, 0x50b1, 0x50b8, 0x50c2, 0x50c7, 0x507e, 0x507e,
+	0x507e, 0x50a1, 0x507e, 0x507e, 0x507e, 0x507e, 0x507e, 0x507e,
+	0x507e, 0x7003, 0x0004, 0x0136, 0x0146, 0x0156, 0x2099, 0xad75,
+	0x20a1, 0xaf85, 0x20a9, 0x0004, 0x53a3, 0x015e, 0x014e, 0x013e,
+	0x0428, 0x708f, 0x0005, 0x7007, 0x0122, 0x2001, 0x0002, 0x0030,
+	0x708f, 0x0002, 0x7007, 0x0121, 0x2001, 0x0003, 0x7002, 0x7097,
+	0x0001, 0x0088, 0x7007, 0x0122, 0x2001, 0x0002, 0x0020, 0x7007,
+	0x0121, 0x2001, 0x0003, 0x7002, 0xa006, 0x7096, 0x708e, 0xa184,
+	0xff00, 0x8007, 0x709a, 0xa184, 0x00ff, 0x7092, 0x00ee, 0x001e,
+	0x0005, 0x00e6, 0x2071, 0xae13, 0x684c, 0xa005, 0x1130, 0x7028,
+	0xc085, 0x702a, 0xa085, 0x0001, 0x0428, 0x6a60, 0x7236, 0x6b64,
+	0x733a, 0x6868, 0x703e, 0x7076, 0x686c, 0x7042, 0x707a, 0x684c,
+	0x702e, 0x6844, 0x7032, 0x2009, 0x000d, 0x200a, 0x700b, 0x0000,
+	0x8007, 0x8006, 0x8006, 0xa08c, 0x003f, 0xa084, 0xffc0, 0xa210,
+	0x2100, 0xa319, 0x726e, 0x7372, 0x7028, 0xc084, 0x702a, 0x7007,
+	0x0001, 0xa006, 0x00ee, 0x0005, 0x0156, 0x00e6, 0x0026, 0x6838,
+	0xd0fc, 0x1904, 0x5165, 0x6804, 0xa00d, 0x0188, 0x00d6, 0x2071,
+	0xad00, 0xa016, 0x702c, 0x2168, 0x6904, 0x206a, 0x8210, 0x2d00,
+	0x81ff, 0x1dc8, 0x702e, 0x70b0, 0xa200, 0x70b2, 0x00de, 0x2071,
+	0xae13, 0x701c, 0xa005, 0x1904, 0x5175, 0x20a9, 0x0032, 0x0f04,
+	0x5173, 0x0e04, 0x512f, 0x2071, 0xaf34, 0x7200, 0x82ff, 0x05d8,
+	0x6934, 0xa186, 0x0103, 0x1904, 0x5183, 0x6948, 0x6844, 0xa105,
+	0x1540, 0x2009, 0x8020, 0x2200, 0x0002, 0x5173, 0x514a, 0x519b,
+	0x51a7, 0x5173, 0x2071, 0x0000, 0x20a9, 0x0032, 0x0f04, 0x5173,
+	0x7018, 0xd084, 0x1dd8, 0x7122, 0x683c, 0x7026, 0x6840, 0x702a,
+	0x701b, 0x0001, 0x2091, 0x4080, 0x2071, 0xad00, 0x702c, 0x206a,
+	0x2d00, 0x702e, 0x70b0, 0x8000, 0x70b2, 0x002e, 0x00ee, 0x015e,
+	0x0005, 0x6844, 0xa086, 0x0100, 0x1130, 0x6868, 0xa005, 0x1118,
+	0x2009, 0x8020, 0x0880, 0x2071, 0xae13, 0x2d08, 0x206b, 0x0000,
+	0x7010, 0x8000, 0x7012, 0x7018, 0xa06d, 0x711a, 0x0110, 0x6902,
+	0x0008, 0x711e, 0x0c10, 0xa18c, 0x00ff, 0xa186, 0x0017, 0x0130,
+	0xa186, 0x001e, 0x0118, 0xa18e, 0x001f, 0x1d28, 0x684c, 0xd0cc,
+	0x0d10, 0x6850, 0xa084, 0x00ff, 0xa086, 0x0001, 0x19e0, 0x2009,
+	0x8021, 0x0804, 0x5143, 0x7084, 0x8008, 0xa092, 0x001e, 0x1a98,
+	0x7186, 0xae90, 0x0003, 0xa210, 0x683c, 0x2012, 0x0078, 0x7084,
+	0x8008, 0xa092, 0x000f, 0x1a38, 0x7186, 0xae90, 0x0003, 0x8003,
+	0xa210, 0x683c, 0x2012, 0x8210, 0x6840, 0x2012, 0x7088, 0xa10a,
+	0x0a04, 0x515c, 0x718c, 0x7084, 0xa10a, 0x0a04, 0x515c, 0x2071,
+	0x0000, 0x7018, 0xd084, 0x1904, 0x515c, 0x2071, 0xaf34, 0x7000,
+	0xa086, 0x0002, 0x1150, 0x080c, 0x5426, 0x2071, 0x0000, 0x701b,
+	0x0001, 0x2091, 0x4080, 0x0804, 0x515c, 0x080c, 0x5450, 0x2071,
+	0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0804, 0x515c, 0x0006,
+	0x684c, 0x0006, 0x6837, 0x0103, 0x20a9, 0x001c, 0xad80, 0x0011,
+	0x20a0, 0x2001, 0x0000, 0x40a4, 0x000e, 0xa084, 0x00ff, 0x684e,
+	0x000e, 0x684a, 0x6952, 0x0005, 0x2071, 0xae13, 0x7004, 0x0002,
+	0x5202, 0x5213, 0x5411, 0x5412, 0x541f, 0x5425, 0x5203, 0x5402,
+	0x5398, 0x53ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x0e04, 0x5212,
+	0x2009, 0x000d, 0x7030, 0x200a, 0x2091, 0x4080, 0x7007, 0x0001,
+	0x700b, 0x0000, 0x012e, 0x2069, 0xafda, 0x683c, 0xa005, 0x03f8,
+	0x11f0, 0x0126, 0x2091, 0x8000, 0x2069, 0x0000, 0x6934, 0x2001,
+	0xae1f, 0x2004, 0xa10a, 0x0170, 0x0e04, 0x5236, 0x2069, 0x0000,
+	0x6818, 0xd084, 0x1158, 0x2009, 0x8040, 0x6922, 0x681b, 0x0001,
+	0x2091, 0x4080, 0x2069, 0xafda, 0x683f, 0xffff, 0x012e, 0x2069,
+	0xad00, 0x6844, 0x6964, 0xa102, 0x2069, 0xaf34, 0x688a, 0x6984,
+	0x701c, 0xa06d, 0x0120, 0x81ff, 0x0904, 0x528c, 0x00a0, 0x81ff,
+	0x0904, 0x5352, 0x2071, 0xaf34, 0x7184, 0x7088, 0xa10a, 0x1258,
+	0x7190, 0x2071, 0xafda, 0x7038, 0xa005, 0x0128, 0x1b04, 0x5352,
+	0x713a, 0x0804, 0x5352, 0x2071, 0xaf34, 0x718c, 0x0126, 0x2091,
+	0x8000, 0x7084, 0xa10a, 0x0a04, 0x536d, 0x0e04, 0x530e, 0x2071,
+	0x0000, 0x7018, 0xd084, 0x1904, 0x530e, 0x2001, 0xffff, 0x2071,
+	0xafda, 0x703a, 0x2071, 0xaf34, 0x7000, 0xa086, 0x0002, 0x1150,
+	0x080c, 0x5426, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080,
+	0x0804, 0x530e, 0x080c, 0x5450, 0x2071, 0x0000, 0x701b, 0x0001,
+	0x2091, 0x4080, 0x0804, 0x530e, 0x2071, 0xaf34, 0x7000, 0xa005,
+	0x0904, 0x5334, 0x6934, 0xa186, 0x0103, 0x1904, 0x5311, 0x684c,
+	0xd0bc, 0x1904, 0x5334, 0x6948, 0x6844, 0xa105, 0x1904, 0x5329,
+	0x2009, 0x8020, 0x2071, 0xaf34, 0x7000, 0x0002, 0x5334, 0x52f4,
+	0x52cc, 0x52de, 0x52ab, 0x0136, 0x0146, 0x0156, 0x2099, 0xad75,
+	0x20a1, 0xaf85, 0x20a9, 0x0004, 0x53a3, 0x015e, 0x014e, 0x013e,
+	0x2071, 0xaf7c, 0xad80, 0x000f, 0x700e, 0x7013, 0x0002, 0x7007,
+	0x0002, 0x700b, 0x0000, 0x2e10, 0x080c, 0x1624, 0x2071, 0xae13,
+	0x7007, 0x0009, 0x0804, 0x5352, 0x7084, 0x8008, 0xa092, 0x001e,
+	0x1a04, 0x5352, 0xae90, 0x0003, 0xa210, 0x683c, 0x2012, 0x7186,
+	0x2071, 0xae13, 0x080c, 0x54a7, 0x0804, 0x5352, 0x7084, 0x8008,
+	0xa092, 0x000f, 0x1a04, 0x5352, 0xae90, 0x0003, 0x8003, 0xa210,
+	0x683c, 0x2012, 0x8210, 0x6840, 0x2012, 0x7186, 0x2071, 0xae13,
+	0x080c, 0x54a7, 0x0804, 0x5352, 0x0126, 0x2091, 0x8000, 0x0e04,
+	0x530e, 0x2071, 0x0000, 0x7018, 0xd084, 0x1180, 0x7122, 0x683c,
+	0x7026, 0x6840, 0x702a, 0x701b, 0x0001, 0x2091, 0x4080, 0x012e,
+	0x2071, 0xae13, 0x080c, 0x54a7, 0x0804, 0x5352, 0x012e, 0x0804,
+	0x5352, 0xa18c, 0x00ff, 0xa186, 0x0017, 0x0130, 0xa186, 0x001e,
+	0x0118, 0xa18e, 0x001f, 0x11c0, 0x684c, 0xd0cc, 0x01a8, 0x6850,
+	0xa084, 0x00ff, 0xa086, 0x0001, 0x1178, 0x2009, 0x8021, 0x0804,
+	0x52a2, 0x6844, 0xa086, 0x0100, 0x1138, 0x6868, 0xa005, 0x1120,
+	0x2009, 0x8020, 0x0804, 0x52a2, 0x2071, 0xae13, 0x080c, 0x54b9,
+	0x01c8, 0x2071, 0xae13, 0x700f, 0x0001, 0x6934, 0xa184, 0x00ff,
+	0xa086, 0x0003, 0x1130, 0x810f, 0xa18c, 0x00ff, 0x8101, 0x0108,
+	0x710e, 0x7007, 0x0003, 0x080c, 0x54d2, 0x7050, 0xa086, 0x0100,
+	0x0904, 0x5412, 0x0126, 0x2091, 0x8000, 0x2071, 0xae13, 0x7008,
+	0xa086, 0x0001, 0x1180, 0x0e04, 0x536b, 0x2009, 0x000d, 0x7030,
+	0x200a, 0x2091, 0x4080, 0x700b, 0x0000, 0x7004, 0xa086, 0x0006,
+	0x1110, 0x7007, 0x0001, 0x012e, 0x0005, 0x2071, 0xae13, 0x080c,
+	0x54b9, 0x0518, 0x2071, 0xaf34, 0x7084, 0x700a, 0x20a9, 0x0020,
+	0x2099, 0xaf35, 0x20a1, 0xaf5c, 0x53a3, 0x7087, 0x0000, 0x2071,
+	0xae13, 0x2069, 0xaf7c, 0x706c, 0x6826, 0x7070, 0x682a, 0x7074,
+	0x682e, 0x7078, 0x6832, 0x2d10, 0x080c, 0x1624, 0x7007, 0x0008,
+	0x2001, 0xffff, 0x2071, 0xafda, 0x703a, 0x012e, 0x0804, 0x5352,
+	0x2069, 0xaf7c, 0x6808, 0xa08e, 0x0000, 0x0904, 0x53ed, 0xa08e,
+	0x0200, 0x0904, 0x53eb, 0xa08e, 0x0100, 0x1904, 0x53ed, 0x0126,
+	0x2091, 0x8000, 0x0e04, 0x53e9, 0x2069, 0x0000, 0x6818, 0xd084,
+	0x15c0, 0x702c, 0x7130, 0x8108, 0xa102, 0x0230, 0xa00e, 0x7034,
+	0x706e, 0x7038, 0x7072, 0x0048, 0x706c, 0xa080, 0x0040, 0x706e,
+	0x1220, 0x7070, 0xa081, 0x0000, 0x7072, 0x7132, 0x6936, 0x700b,
+	0x0000, 0x2001, 0xaf59, 0x2004, 0xa005, 0x1190, 0x6934, 0x2069,
+	0xaf34, 0x689c, 0x699e, 0x2069, 0xafda, 0xa102, 0x1118, 0x683c,
+	0xa005, 0x1368, 0x2001, 0xaf5a, 0x200c, 0x810d, 0x693e, 0x0038,
+	0x2009, 0x8040, 0x6922, 0x681b, 0x0001, 0x2091, 0x4080, 0x7007,
+	0x0001, 0x012e, 0x0010, 0x7007, 0x0005, 0x0005, 0x2001, 0xaf7e,
+	0x2004, 0xa08e, 0x0100, 0x1128, 0x7007, 0x0001, 0x080c, 0x54a7,
+	0x0005, 0xa08e, 0x0000, 0x0de0, 0xa08e, 0x0200, 0x1dc8, 0x7007,
+	0x0005, 0x0005, 0x701c, 0xa06d, 0x0158, 0x080c, 0x54b9, 0x0140,
+	0x7007, 0x0003, 0x080c, 0x54d2, 0x7050, 0xa086, 0x0100, 0x0110,
+	0x0005, 0x0005, 0x7050, 0xa09e, 0x0100, 0x1118, 0x7007, 0x0004,
+	0x0030, 0xa086, 0x0200, 0x1110, 0x7007, 0x0005, 0x0005, 0x080c,
+	0x5475, 0x7006, 0x080c, 0x54a7, 0x0005, 0x0005, 0x00e6, 0x0156,
+	0x2071, 0xaf34, 0x7184, 0x81ff, 0x0500, 0xa006, 0x7086, 0xae80,
+	0x0003, 0x2071, 0x0000, 0x21a8, 0x2014, 0x7226, 0x8000, 0x0f04,
+	0x544a, 0x2014, 0x722a, 0x8000, 0x0f04, 0x544a, 0x2014, 0x722e,
+	0x8000, 0x0f04, 0x544a, 0x2014, 0x723a, 0x8000, 0x0f04, 0x544a,
+	0x2014, 0x723e, 0xa180, 0x8030, 0x7022, 0x015e, 0x00ee, 0x0005,
+	0x00e6, 0x0156, 0x2071, 0xaf34, 0x7184, 0x81ff, 0x01d8, 0xa006,
+	0x7086, 0xae80, 0x0003, 0x2071, 0x0000, 0x21a8, 0x2014, 0x7226,
+	0x8000, 0x2014, 0x722a, 0x8000, 0x0f04, 0x546c, 0x2014, 0x723a,
+	0x8000, 0x2014, 0x723e, 0x0018, 0x2001, 0x8020, 0x0010, 0x2001,
+	0x8042, 0x7022, 0x015e, 0x00ee, 0x0005, 0x702c, 0x7130, 0x8108,
+	0xa102, 0x0230, 0xa00e, 0x7034, 0x706e, 0x7038, 0x7072, 0x0048,
+	0x706c, 0xa080, 0x0040, 0x706e, 0x1220, 0x7070, 0xa081, 0x0000,
+	0x7072, 0x7132, 0x700c, 0x8001, 0x700e, 0x1180, 0x0126, 0x2091,
+	0x8000, 0x0e04, 0x54a1, 0x2001, 0x000d, 0x2102, 0x2091, 0x4080,
+	0x2001, 0x0001, 0x700b, 0x0000, 0x012e, 0x0005, 0x2001, 0x0007,
+	0x0005, 0x2001, 0x0006, 0x700b, 0x0001, 0x012e, 0x0005, 0x701c,
+	0xa06d, 0x0170, 0x0126, 0x2091, 0x8000, 0x7010, 0x8001, 0x7012,
+	0x2d04, 0x701e, 0xa005, 0x1108, 0x701a, 0x012e, 0x080c, 0x15f0,
+	0x0005, 0x2019, 0x000d, 0x2304, 0x230c, 0xa10e, 0x0130, 0x2304,
+	0x230c, 0xa10e, 0x0110, 0xa006, 0x0060, 0x732c, 0x8319, 0x7130,
+	0xa102, 0x1118, 0x2300, 0xa005, 0x0020, 0x0210, 0xa302, 0x0008,
+	0x8002, 0x0005, 0x2d00, 0x7026, 0xa080, 0x000d, 0x7056, 0x7053,
+	0x0000, 0x0126, 0x2091, 0x8000, 0x2009, 0xafec, 0x2104, 0xc08d,
+	0x200a, 0x012e, 0x080c, 0x163c, 0x0005, 0x7088, 0xa08a, 0x0029,
+	0x1220, 0xa082, 0x001d, 0x0033, 0x0010, 0x080c, 0x14f6, 0x6027,
+	0x1e00, 0x0005, 0x55c1, 0x555b, 0x5571, 0x5595, 0x55b4, 0x55e6,
+	0x55f8, 0x5571, 0x55d2, 0x54ff, 0x552d, 0x54fe, 0x0005, 0x00d6,
+	0x2069, 0x0200, 0x6804, 0xa005, 0x1180, 0x6808, 0xa005, 0x1518,
+	0x708b, 0x0028, 0x2069, 0xafac, 0x2d04, 0x7002, 0x080c, 0x584d,
+	0x6028, 0xa085, 0x0600, 0x602a, 0x00b0, 0x708b, 0x0028, 0x2069,
+	0xafac, 0x2d04, 0x7002, 0x6028, 0xa085, 0x0600, 0x602a, 0x00e6,
+	0x0036, 0x0046, 0x0056, 0x2071, 0xaffd, 0x080c, 0x1d22, 0x005e,
+	0x004e, 0x003e, 0x00ee, 0x00de, 0x0005, 0x00d6, 0x2069, 0x0200,
+	0x6804, 0xa005, 0x1180, 0x6808, 0xa005, 0x1518, 0x708b, 0x0028,
+	0x2069, 0xafac, 0x2d04, 0x7002, 0x080c, 0x58da, 0x6028, 0xa085,
+	0x0600, 0x602a, 0x00b0, 0x708b, 0x0028, 0x2069, 0xafac, 0x2d04,
+	0x7002, 0x6028, 0xa085, 0x0600, 0x602a, 0x00e6, 0x0036, 0x0046,
+	0x0056, 0x2071, 0xaffd, 0x080c, 0x1d22, 0x005e, 0x004e, 0x003e,
+	0x00ee, 0x00de, 0x0005, 0x6803, 0x0090, 0x6124, 0xd1e4, 0x1180,
+	0x080c, 0x5663, 0xd1d4, 0x1150, 0xd1dc, 0x1128, 0xd1cc, 0x0140,
+	0x708b, 0x0020, 0x0028, 0x708b, 0x001d, 0x0010, 0x708b, 0x001f,
+	0x0005, 0x6803, 0x0088, 0x6124, 0xd1cc, 0x11c8, 0xd1dc, 0x11a0,
+	0xd1e4, 0x1178, 0xa184, 0x1e00, 0x11b8, 0x60e3, 0x0001, 0x600c,
+	0xc0b4, 0x600e, 0x080c, 0x577f, 0x6803, 0x0080, 0x708b, 0x0028,
+	0x0058, 0x708b, 0x001e, 0x0040, 0x708b, 0x001d, 0x0028, 0x708b,
+	0x0020, 0x0010, 0x708b, 0x001f, 0x0005, 0x60e3, 0x0001, 0x600c,
+	0xc0b4, 0x600e, 0x080c, 0x577f, 0x6803, 0x0080, 0x6124, 0xd1d4,
+	0x1180, 0xd1dc, 0x1158, 0xd1e4, 0x1130, 0xa184, 0x1e00, 0x1158,
+	0x708b, 0x0028, 0x0040, 0x708b, 0x001e, 0x0028, 0x708b, 0x001d,
+	0x0010, 0x708b, 0x001f, 0x0005, 0x6803, 0x00a0, 0x6124, 0xd1dc,
+	0x1128, 0xd1e4, 0x0128, 0x708b, 0x001e, 0x0010, 0x708b, 0x001d,
+	0x0005, 0x080c, 0x568d, 0x6124, 0xd1dc, 0x1158, 0x080c, 0x5663,
+	0xd1d4, 0x1128, 0xd1e4, 0x0128, 0x708b, 0x001e, 0x0010, 0x708b,
+	0x001f, 0x0005, 0x6803, 0x00a0, 0x6124, 0xd1d4, 0x1160, 0xd1cc,
+	0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, 0x708b, 0x001e, 0x0028,
+	0x708b, 0x001d, 0x0010, 0x708b, 0x0021, 0x0005, 0x080c, 0x568d,
+	0x6124, 0xd1d4, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, 0x708b,
+	0x001e, 0x0028, 0x708b, 0x001d, 0x0010, 0x708b, 0x001f, 0x0005,
+	0x6803, 0x0090, 0x6124, 0xd1d4, 0x1178, 0xd1cc, 0x1150, 0xd1dc,
+	0x1128, 0xd1e4, 0x0158, 0x708b, 0x001e, 0x0040, 0x708b, 0x001d,
+	0x0028, 0x708b, 0x0020, 0x0010, 0x708b, 0x001f, 0x0005, 0x0016,
+	0x00c6, 0x00d6, 0x00e6, 0x0126, 0x2061, 0x0100, 0x2069, 0x0140,
+	0x2071, 0xad00, 0x2091, 0x8000, 0x080c, 0x574f, 0x11e8, 0x2001,
+	0xad0c, 0x200c, 0xd1b4, 0x01c0, 0xc1b4, 0x2102, 0x6027, 0x0200,
+	0xe000, 0xe000, 0x6024, 0xd0cc, 0x0158, 0x6803, 0x00a0, 0x2001,
+	0xaf9e, 0x2003, 0x0001, 0x2001, 0xad00, 0x2003, 0x0001, 0x0428,
+	0x6028, 0xc0cd, 0x602a, 0x0408, 0x080c, 0x576b, 0x0150, 0x080c,
+	0x5761, 0x1138, 0x2001, 0x0001, 0x080c, 0x261e, 0x080c, 0x5726,
+	0x00a0, 0x080c, 0x568a, 0x0178, 0x2001, 0x0001, 0x080c, 0x261e,
+	0x7088, 0xa086, 0x001e, 0x0120, 0x7088, 0xa086, 0x0022, 0x1118,
+	0x708b, 0x0025, 0x0010, 0x708b, 0x0021, 0x012e, 0x00ee, 0x00de,
+	0x00ce, 0x001e, 0x0005, 0x0016, 0x0026, 0x2009, 0x0064, 0x2011,
+	0x566e, 0x080c, 0x6501, 0x002e, 0x001e, 0x0005, 0x00e6, 0x00f6,
+	0x0016, 0x080c, 0x7834, 0x2071, 0xad00, 0x080c, 0x560f, 0x001e,
+	0x00fe, 0x00ee, 0x0005, 0x2001, 0xad00, 0x2004, 0xa086, 0x0004,
+	0x0140, 0x2001, 0xaf9d, 0x2003, 0xaaaa, 0x2001, 0xaf9e, 0x2003,
+	0x0000, 0x0005, 0x6020, 0xd09c, 0x0005, 0x6803, 0x00c0, 0x0156,
+	0x20a9, 0x002d, 0x1d04, 0x5692, 0x2091, 0x6000, 0x1f04, 0x5692,
+	0x015e, 0x0005, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069,
+	0x0140, 0x2071, 0xad00, 0x2001, 0xaf9e, 0x200c, 0xa186, 0x0000,
+	0x0158, 0xa186, 0x0001, 0x0158, 0xa186, 0x0002, 0x0158, 0xa186,
+	0x0003, 0x0158, 0x0804, 0x5714, 0x708b, 0x0022, 0x0040, 0x708b,
+	0x0021, 0x0028, 0x708b, 0x0023, 0x0020, 0x708b, 0x0024, 0x6043,
+	0x0000, 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, 0x080c,
+	0x26cb, 0x0026, 0x2011, 0x0003, 0x080c, 0x7adf, 0x2011, 0x0002,
+	0x080c, 0x7ae9, 0x002e, 0x7000, 0xa08e, 0x0004, 0x0118, 0x602b,
+	0x0028, 0x0010, 0x602b, 0x0020, 0x0156, 0x0126, 0x2091, 0x8000,
+	0x20a9, 0x0005, 0x6024, 0xd0ac, 0x0118, 0x012e, 0x015e, 0x04d0,
+	0x6800, 0xa084, 0x00a0, 0xc0bd, 0x6802, 0x6904, 0xd1d4, 0x1130,
+	0x6803, 0x0100, 0x1f04, 0x56e2, 0x080c, 0x57a0, 0x012e, 0x015e,
+	0x080c, 0x5761, 0x01a8, 0x6044, 0xa005, 0x0168, 0x6050, 0x0006,
+	0xa085, 0x0020, 0x6052, 0x080c, 0x57a0, 0xa006, 0x8001, 0x1df0,
+	0x000e, 0x6052, 0x0028, 0x6804, 0xd0d4, 0x1110, 0x080c, 0x57a0,
+	0x2001, 0xaf9e, 0x2003, 0x0004, 0x080c, 0x54e5, 0x080c, 0x5761,
+	0x0148, 0x6804, 0xd0d4, 0x1130, 0xd0dc, 0x1100, 0x2001, 0xaf9e,
+	0x2003, 0x0000, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6,
+	0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0xad00, 0x2001,
+	0xaf9d, 0x2003, 0x0000, 0x2001, 0xaf8e, 0x2003, 0x0000, 0x708b,
+	0x0000, 0x60e3, 0x0000, 0x6887, 0x0000, 0x2001, 0x0000, 0x080c,
+	0x26cb, 0x6803, 0x0000, 0x6043, 0x0090, 0x6043, 0x0010, 0x6027,
+	0xffff, 0x602b, 0x182f, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x0006,
+	0x2001, 0xaf9d, 0x2004, 0xa086, 0xaaaa, 0x000e, 0x0005, 0x0006,
+	0x2001, 0xad71, 0x2004, 0xa084, 0x0030, 0xa086, 0x0000, 0x000e,
+	0x0005, 0x0006, 0x2001, 0xad71, 0x2004, 0xa084, 0x0030, 0xa086,
+	0x0030, 0x000e, 0x0005, 0x0006, 0x2001, 0xad71, 0x2004, 0xa084,
+	0x0030, 0xa086, 0x0010, 0x000e, 0x0005, 0x0006, 0x2001, 0xad71,
+	0x2004, 0xa084, 0x0030, 0xa086, 0x0020, 0x000e, 0x0005, 0x2001,
+	0xad0c, 0x2004, 0xd0a4, 0x0170, 0x080c, 0x26eb, 0x0036, 0x0016,
+	0x2009, 0x0000, 0x2019, 0x0028, 0x080c, 0x2aac, 0x001e, 0x003e,
+	0xa006, 0x0009, 0x0005, 0x00e6, 0x2071, 0xad0c, 0x2e04, 0x0118,
+	0xa085, 0x0010, 0x0010, 0xa084, 0xffef, 0x2072, 0x00ee, 0x0005,
+	0x6050, 0x0006, 0x60f0, 0x0006, 0x60ec, 0x0006, 0x600c, 0x0006,
+	0x6004, 0x0006, 0x6028, 0x0006, 0x602f, 0x0100, 0x602f, 0x0000,
+	0x602f, 0x0040, 0x602f, 0x0000, 0x000e, 0x602a, 0x000e, 0x6006,
+	0x000e, 0x600e, 0x000e, 0x60ee, 0x000e, 0x60f2, 0x60e3, 0x0000,
+	0x6887, 0x0001, 0x2001, 0x0001, 0x080c, 0x26cb, 0x6800, 0xa084,
+	0x00a0, 0xc0bd, 0x6802, 0x6803, 0x00a0, 0x000e, 0x6052, 0x6050,
+	0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6,
+	0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0xad00, 0x6020, 0xa084,
+	0x0080, 0x0138, 0x2001, 0xad0c, 0x200c, 0xc1bd, 0x2102, 0x0804,
+	0x5845, 0x2001, 0xad0c, 0x200c, 0xc1bc, 0x2102, 0x6028, 0xa084,
+	0xe1ff, 0x602a, 0x6027, 0x0200, 0x6803, 0x0090, 0x20a9, 0x0384,
+	0x6024, 0xd0cc, 0x1518, 0x1d04, 0x57f8, 0x2091, 0x6000, 0x1f04,
+	0x57f8, 0x2011, 0x0003, 0x080c, 0x7adf, 0x2011, 0x0002, 0x080c,
+	0x7ae9, 0x080c, 0x79e1, 0x080c, 0x6581, 0x2019, 0x0000, 0x080c,
+	0x7a64, 0x6803, 0x00a0, 0x2001, 0xaf9e, 0x2003, 0x0001, 0x2001,
+	0xad00, 0x2003, 0x0001, 0xa085, 0x0001, 0x0438, 0x60e3, 0x0000,
+	0x2001, 0xaf8e, 0x2004, 0x080c, 0x26cb, 0x60e2, 0x6803, 0x0080,
+	0x20a9, 0x0384, 0x6027, 0x1e00, 0x2009, 0x1e00, 0xe000, 0x6024,
+	0xa10c, 0x0138, 0x1d04, 0x582a, 0x2091, 0x6000, 0x1f04, 0x582a,
+	0x0840, 0x6028, 0xa085, 0x1e00, 0x602a, 0x70a0, 0xa005, 0x1118,
+	0x6887, 0x0001, 0x0008, 0x6886, 0xa006, 0x00ee, 0x00de, 0x00ce,
+	0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026,
+	0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2071, 0xad00,
+	0x2069, 0x0140, 0x6020, 0xa084, 0x00c0, 0x0120, 0x6884, 0xa005,
+	0x1904, 0x58a1, 0x6803, 0x0088, 0x60e3, 0x0000, 0x6887, 0x0000,
+	0x2001, 0x0000, 0x080c, 0x26cb, 0x2069, 0x0200, 0x6804, 0xa005,
+	0x1118, 0x6808, 0xa005, 0x01c0, 0x6028, 0xa084, 0xfbff, 0x602a,
+	0x6027, 0x0400, 0x2069, 0xafac, 0x7000, 0x206a, 0x708b, 0x0026,
+	0x7003, 0x0001, 0x20a9, 0x0002, 0x1d04, 0x5884, 0x2091, 0x6000,
+	0x1f04, 0x5884, 0x0804, 0x58d2, 0x2069, 0x0140, 0x20a9, 0x0384,
+	0x6027, 0x1e00, 0x2009, 0x1e00, 0xe000, 0x6024, 0xa10c, 0x0530,
+	0xa084, 0x1a00, 0x1518, 0x1d04, 0x5890, 0x2091, 0x6000, 0x1f04,
+	0x5890, 0x2011, 0x0003, 0x080c, 0x7adf, 0x2011, 0x0002, 0x080c,
+	0x7ae9, 0x080c, 0x79e1, 0x080c, 0x6581, 0x2019, 0x0000, 0x080c,
+	0x7a64, 0x6803, 0x00a0, 0x2001, 0xaf9e, 0x2003, 0x0001, 0x2001,
+	0xad00, 0x2003, 0x0001, 0xa085, 0x0001, 0x00a0, 0x6803, 0x0080,
+	0x2069, 0x0140, 0x60e3, 0x0000, 0x70a0, 0xa005, 0x1118, 0x6887,
+	0x0001, 0x0008, 0x6886, 0x2001, 0xaf8e, 0x2004, 0x080c, 0x26cb,
+	0x60e2, 0xa006, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e,
+	0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6,
+	0x00e6, 0x2061, 0x0100, 0x2071, 0xad00, 0x6020, 0xa084, 0x00c0,
+	0x01f0, 0x2011, 0x0003, 0x080c, 0x7adf, 0x2011, 0x0002, 0x080c,
+	0x7ae9, 0x080c, 0x79e1, 0x080c, 0x6581, 0x2019, 0x0000, 0x080c,
+	0x7a64, 0x2069, 0x0140, 0x6803, 0x00a0, 0x2001, 0xaf9e, 0x2003,
+	0x0001, 0x2001, 0xad00, 0x2003, 0x0001, 0x0804, 0x5972, 0x2001,
+	0xad0c, 0x200c, 0xd1b4, 0x1150, 0xc1b5, 0x2102, 0x080c, 0x5663,
+	0x2069, 0x0140, 0x6803, 0x0080, 0x60e3, 0x0000, 0x2069, 0x0200,
+	0x6804, 0xa005, 0x1118, 0x6808, 0xa005, 0x01b8, 0x6028, 0xa084,
+	0xfdff, 0x602a, 0x6027, 0x0200, 0x2069, 0xafac, 0x7000, 0x206a,
+	0x708b, 0x0027, 0x7003, 0x0001, 0x20a9, 0x0002, 0x1d04, 0x592e,
+	0x2091, 0x6000, 0x1f04, 0x592e, 0x04e8, 0x6027, 0x1e00, 0x2009,
+	0x1e00, 0xe000, 0x6024, 0xa10c, 0x01c8, 0xa084, 0x1c00, 0x11b0,
+	0x1d04, 0x5935, 0x0006, 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x080c,
+	0x64a2, 0x00ee, 0x00de, 0x00ce, 0x001e, 0x000e, 0x00e6, 0x2071,
+	0xafda, 0x7018, 0x00ee, 0xa005, 0x1d00, 0x01e0, 0x0026, 0x2011,
+	0x566e, 0x080c, 0x650d, 0x002e, 0x2069, 0x0140, 0x60e3, 0x0000,
+	0x70a0, 0xa005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886, 0x2001,
+	0xaf8e, 0x2004, 0x080c, 0x26cb, 0x60e2, 0x2001, 0xad0c, 0x200c,
+	0xc1b4, 0x2102, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e,
+	0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x0046, 0x00c6,
+	0x00e6, 0x2061, 0x0100, 0x2071, 0xad00, 0x7130, 0xd184, 0x1180,
+	0x2011, 0xad52, 0x2214, 0xd2ec, 0x0138, 0xc18d, 0x7132, 0x2011,
+	0xad52, 0x2214, 0xd2ac, 0x1120, 0x7030, 0xd08c, 0x0904, 0x59df,
+	0x7130, 0xc185, 0x7132, 0x2011, 0xad52, 0x220c, 0xd1a4, 0x0530,
+	0x0016, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x663f, 0x2019,
+	0x000e, 0x080c, 0xa8eb, 0x0156, 0x20a9, 0x007f, 0x2009, 0x0000,
+	0xa186, 0x007e, 0x0170, 0xa186, 0x0080, 0x0158, 0x080c, 0x4cdc,
+	0x1140, 0x8127, 0xa006, 0x0016, 0x2009, 0x000e, 0x080c, 0xa96c,
+	0x001e, 0x8108, 0x1f04, 0x59b0, 0x015e, 0x001e, 0xd1ac, 0x1148,
+	0x0016, 0x2009, 0x0000, 0x2019, 0x0004, 0x080c, 0x2aac, 0x001e,
+	0x0070, 0x0156, 0x20a9, 0x007f, 0x2009, 0x0000, 0x080c, 0x4cdc,
+	0x1110, 0x080c, 0x493a, 0x8108, 0x1f04, 0x59d6, 0x015e, 0x2011,
+	0x0003, 0x080c, 0x7adf, 0x2011, 0x0002, 0x080c, 0x7ae9, 0x080c,
+	0x79e1, 0x080c, 0x6581, 0x0036, 0x2019, 0x0000, 0x080c, 0x7a64,
+	0x003e, 0x60e3, 0x0000, 0x2001, 0xad00, 0x2003, 0x0001, 0x080c,
+	0x569a, 0x00ee, 0x00ce, 0x004e, 0x003e, 0x002e, 0x001e, 0x015e,
+	0x0005, 0x2071, 0xade1, 0x7003, 0x0000, 0x7007, 0x0000, 0x700f,
+	0x0000, 0x702b, 0x0001, 0x704f, 0x0000, 0x7053, 0x0001, 0x705f,
+	0x0020, 0x7063, 0x0040, 0x7083, 0x0000, 0x708b, 0x0000, 0x708f,
+	0x0001, 0x70bf, 0x0000, 0x0005, 0x00e6, 0x2071, 0xade1, 0x6848,
+	0xa005, 0x1130, 0x7028, 0xc085, 0x702a, 0xa085, 0x0001, 0x0428,
+	0x6a50, 0x7236, 0x6b54, 0x733a, 0x6858, 0x703e, 0x707a, 0x685c,
+	0x7042, 0x707e, 0x6848, 0x702e, 0x6840, 0x7032, 0x2009, 0x000c,
+	0x200a, 0x8007, 0x8006, 0x8006, 0xa08c, 0x003f, 0xa084, 0xffc0,
+	0xa210, 0x2100, 0xa319, 0x7272, 0x7376, 0x7028, 0xc084, 0x702a,
+	0x7007, 0x0001, 0x700f, 0x0000, 0xa006, 0x00ee, 0x0005, 0x2b78,
+	0x2071, 0xade1, 0x7004, 0x0043, 0x700c, 0x0002, 0x5a5b, 0x5a52,
+	0x5a52, 0x5a52, 0x5a52, 0x0005, 0x5ab1, 0x5ab2, 0x5ae4, 0x5ae5,
+	0x5aaf, 0x5b33, 0x5b38, 0x5b69, 0x5b6a, 0x5b85, 0x5b86, 0x5b87,
+	0x5b88, 0x5b89, 0x5b8a, 0x5c40, 0x5c67, 0x700c, 0x0002, 0x5a74,
+	0x5aaf, 0x5aaf, 0x5ab0, 0x5ab0, 0x7830, 0x7930, 0xa106, 0x0120,
+	0x7830, 0x7930, 0xa106, 0x1510, 0x7030, 0xa10a, 0x01f8, 0x1210,
+	0x712c, 0xa10a, 0xa18a, 0x0002, 0x12d0, 0x080c, 0x15c0, 0x01b0,
+	0x2d00, 0x705a, 0x7063, 0x0040, 0x2001, 0x0003, 0x7057, 0x0000,
+	0x0126, 0x0006, 0x2091, 0x8000, 0x2009, 0xafec, 0x2104, 0xc085,
+	0x200a, 0x000e, 0x700e, 0x012e, 0x080c, 0x163c, 0x0005, 0x080c,
+	0x15c0, 0x0de0, 0x2d00, 0x705a, 0x080c, 0x15c0, 0x1108, 0x0c10,
+	0x2d00, 0x7086, 0x7063, 0x0080, 0x2001, 0x0004, 0x08f8, 0x0005,
+	0x0005, 0x0005, 0x700c, 0x0002, 0x5ab9, 0x5abc, 0x5aca, 0x5ae3,
+	0x5ae3, 0x080c, 0x5a6d, 0x0005, 0x0126, 0x8001, 0x700e, 0x7058,
+	0x0006, 0x080c, 0x5f90, 0x0120, 0x2091, 0x8000, 0x080c, 0x5a6d,
+	0x00de, 0x0048, 0x0126, 0x8001, 0x700e, 0x080c, 0x5f90, 0x7058,
+	0x2068, 0x7084, 0x705a, 0x6803, 0x0000, 0x6807, 0x0000, 0x6834,
+	0xa084, 0x00ff, 0xa08a, 0x003a, 0x1218, 0x00db, 0x012e, 0x0005,
+	0x012e, 0x080c, 0x5b8b, 0x0005, 0x0005, 0x0005, 0x00e6, 0x2071,
+	0xade1, 0x700c, 0x0002, 0x5af0, 0x5af0, 0x5af0, 0x5af2, 0x5af5,
+	0x00ee, 0x0005, 0x700f, 0x0001, 0x0010, 0x700f, 0x0002, 0x00ee,
+	0x0005, 0x5b8b, 0x5b8b, 0x5ba7, 0x5b8b, 0x5d22, 0x5b8b, 0x5b8b,
+	0x5b8b, 0x5b8b, 0x5b8b, 0x5ba7, 0x5d64, 0x5da7, 0x5df0, 0x5e04,
+	0x5b8b, 0x5b8b, 0x5bc3, 0x5ba7, 0x5b8b, 0x5b8b, 0x5c1d, 0x5ead,
+	0x5ec8, 0x5b8b, 0x5bc3, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5c13,
+	0x5ec8, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b,
+	0x5b8b, 0x5b8b, 0x5bd7, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b,
+	0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b,
+	0x5b8b, 0x5b8b, 0x5bec, 0x7020, 0x2068, 0x080c, 0x15f0, 0x0005,
+	0x700c, 0x0002, 0x5b3f, 0x5b42, 0x5b50, 0x5b68, 0x5b68, 0x080c,
+	0x5a6d, 0x0005, 0x0126, 0x8001, 0x700e, 0x7058, 0x0006, 0x080c,
+	0x5f90, 0x0120, 0x2091, 0x8000, 0x080c, 0x5a6d, 0x00de, 0x0048,
+	0x0126, 0x8001, 0x700e, 0x080c, 0x5f90, 0x7058, 0x2068, 0x7084,
+	0x705a, 0x6803, 0x0000, 0x6807, 0x0000, 0x6834, 0xa084, 0x00ff,
+	0xa08a, 0x001a, 0x1218, 0x003b, 0x012e, 0x0005, 0x012e, 0x0419,
+	0x0005, 0x0005, 0x0005, 0x5b8b, 0x5ba7, 0x5d0e, 0x5b8b, 0x5ba7,
+	0x5b8b, 0x5ba7, 0x5ba7, 0x5b8b, 0x5ba7, 0x5d0e, 0x5ba7, 0x5ba7,
+	0x5ba7, 0x5ba7, 0x5ba7, 0x5b8b, 0x5ba7, 0x5d0e, 0x5b8b, 0x5b8b,
+	0x5ba7, 0x5b8b, 0x5b8b, 0x5b8b, 0x5ba7, 0x0005, 0x0005, 0x0005,
+	0x0005, 0x0005, 0x0005, 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff,
+	0xc0d5, 0x683a, 0x0126, 0x2091, 0x8000, 0x080c, 0x510c, 0x012e,
+	0x0005, 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0e5, 0x683a,
+	0x0126, 0x2091, 0x8000, 0x080c, 0x510c, 0x012e, 0x0005, 0x7007,
+	0x0001, 0x6838, 0xa084, 0x00ff, 0xc0ed, 0x683a, 0x0126, 0x2091,
+	0x8000, 0x080c, 0x510c, 0x012e, 0x0005, 0x7007, 0x0001, 0x6838,
+	0xa084, 0x00ff, 0xc0dd, 0x683a, 0x0126, 0x2091, 0x8000, 0x080c,
+	0x510c, 0x012e, 0x0005, 0x6834, 0x8007, 0xa084, 0x00ff, 0x0988,
+	0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x5cd0, 0x7007, 0x0006,
+	0x7012, 0x2d00, 0x7016, 0x701a, 0x704b, 0x5cd0, 0x0005, 0x6834,
+	0x8007, 0xa084, 0x00ff, 0x0904, 0x5b99, 0x8001, 0x1120, 0x7007,
+	0x0001, 0x0804, 0x5ced, 0x7007, 0x0006, 0x7012, 0x2d00, 0x7016,
+	0x701a, 0x704b, 0x5ced, 0x0005, 0x6834, 0x8007, 0xa084, 0x00ff,
+	0xa086, 0x0001, 0x1904, 0x5b99, 0x7007, 0x0001, 0x2009, 0xad30,
+	0x210c, 0x81ff, 0x11a8, 0x6838, 0xa084, 0x00ff, 0x683a, 0x6853,
+	0x0000, 0x080c, 0x4ab1, 0x1108, 0x0005, 0x0126, 0x2091, 0x8000,
+	0x6837, 0x0139, 0x684a, 0x6952, 0x080c, 0x510c, 0x012e, 0x0ca0,
+	0x2001, 0x0028, 0x0c90, 0x684c, 0xa084, 0x00c0, 0xa086, 0x00c0,
+	0x1120, 0x7007, 0x0001, 0x0804, 0x5ee0, 0x2d00, 0x7016, 0x701a,
+	0x20a9, 0x0004, 0xa080, 0x0024, 0x2098, 0x20a1, 0xae0c, 0x53a3,
+	0x6858, 0x7012, 0xa082, 0x0401, 0x1a04, 0x5bb5, 0x6a84, 0xa28a,
+	0x0002, 0x1a04, 0x5bb5, 0x82ff, 0x1138, 0x6888, 0x698c, 0xa105,
+	0x0118, 0x2001, 0x5ca3, 0x0018, 0xa280, 0x5c99, 0x2005, 0x70c6,
+	0x7010, 0xa015, 0x0904, 0x5c85, 0x080c, 0x15c0, 0x1118, 0x7007,
+	0x000f, 0x0005, 0x2d00, 0x7022, 0x70c4, 0x2060, 0x2c05, 0x6836,
+	0xe004, 0xad00, 0x7096, 0xe008, 0xa20a, 0x1210, 0xa00e, 0x2200,
+	0x7112, 0xe20c, 0x8003, 0x800b, 0xa296, 0x0004, 0x0108, 0xa108,
+	0x719a, 0x810b, 0x719e, 0xae90, 0x0022, 0x080c, 0x1624, 0x7090,
+	0xa08e, 0x0100, 0x0170, 0xa086, 0x0200, 0x0118, 0x7007, 0x0010,
+	0x0005, 0x7020, 0x2068, 0x080c, 0x15f0, 0x7014, 0x2068, 0x0804,
+	0x5bb5, 0x7020, 0x2068, 0x7018, 0x6802, 0x6807, 0x0000, 0x2d08,
+	0x2068, 0x6906, 0x711a, 0x0804, 0x5c40, 0x7014, 0x2068, 0x7007,
+	0x0001, 0x6884, 0xa005, 0x1128, 0x6888, 0x698c, 0xa105, 0x0108,
+	0x00b1, 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e, 0x0904, 0x5ee0,
+	0x04b8, 0x5c9b, 0x5c9f, 0x0002, 0x0011, 0x0007, 0x0004, 0x000a,
+	0x000f, 0x0005, 0x0006, 0x000a, 0x0011, 0x0005, 0x0004, 0x00f6,
+	0x00e6, 0x00c6, 0x0076, 0x0066, 0x6f88, 0x6e8c, 0x6804, 0x2060,
+	0xacf0, 0x0021, 0xacf8, 0x0027, 0x2009, 0x0005, 0x700c, 0x7816,
+	0x7008, 0x7812, 0x7004, 0x7806, 0x7000, 0x7802, 0x7e0e, 0x7f0a,
+	0x8109, 0x0128, 0xaef2, 0x0004, 0xaffa, 0x0006, 0x0c78, 0x6004,
+	0xa065, 0x1d30, 0x006e, 0x007e, 0x00ce, 0x00ee, 0x00fe, 0x0005,
+	0x2009, 0xad30, 0x210c, 0x81ff, 0x1198, 0x6838, 0xa084, 0x00ff,
+	0x683a, 0x080c, 0x4993, 0x1108, 0x0005, 0x080c, 0x51df, 0x0126,
+	0x2091, 0x8000, 0x080c, 0x97fd, 0x080c, 0x510c, 0x012e, 0x0ca0,
+	0x2001, 0x0028, 0x2009, 0x0000, 0x0c80, 0x2009, 0xad30, 0x210c,
+	0x81ff, 0x11b0, 0x6858, 0xa005, 0x01b0, 0x6838, 0xa084, 0x00ff,
+	0x683a, 0x6853, 0x0000, 0x080c, 0x4a55, 0x1108, 0x0005, 0x0126,
+	0x2091, 0x8000, 0x080c, 0x51df, 0x080c, 0x510c, 0x012e, 0x0cb0,
+	0x2001, 0x0028, 0x0ca0, 0x2001, 0x0000, 0x0c88, 0x7018, 0x6802,
+	0x2d08, 0x2068, 0x6906, 0x711a, 0x7010, 0x8001, 0x7012, 0x0118,
+	0x7007, 0x0006, 0x0030, 0x7014, 0x2068, 0x7007, 0x0001, 0x7048,
+	0x080f, 0x0005, 0x7007, 0x0001, 0x6944, 0x810f, 0xa18c, 0x00ff,
+	0x6848, 0xa084, 0x00ff, 0x20a9, 0x0001, 0xa096, 0x0001, 0x01b0,
+	0x2009, 0x0000, 0x20a9, 0x00ff, 0xa096, 0x0002, 0x0178, 0xa005,
+	0x11f0, 0x6944, 0x810f, 0xa18c, 0x00ff, 0x080c, 0x4cdc, 0x11b8,
+	0x0066, 0x6e50, 0x080c, 0x4dcf, 0x006e, 0x0088, 0x0046, 0x2011,
+	0xad0c, 0x2224, 0xc484, 0x2412, 0x004e, 0x00c6, 0x080c, 0x4cdc,
+	0x1110, 0x080c, 0x4f2d, 0x8108, 0x1f04, 0x5d4e, 0x00ce, 0x684c,
+	0xd084, 0x1118, 0x080c, 0x15f0, 0x0005, 0x0126, 0x2091, 0x8000,
+	0x080c, 0x510c, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x7007,
+	0x0001, 0x2001, 0xad52, 0x2004, 0xd0a4, 0x0580, 0x2061, 0xb048,
+	0x6100, 0xd184, 0x0178, 0x6858, 0xa084, 0x00ff, 0x1550, 0x6000,
+	0xd084, 0x0520, 0x6004, 0xa005, 0x1538, 0x6003, 0x0000, 0x600b,
+	0x0000, 0x00c8, 0x2011, 0x0001, 0x6860, 0xa005, 0x1110, 0x2001,
+	0x001e, 0x8000, 0x6016, 0x6858, 0xa084, 0x00ff, 0x0178, 0x6006,
+	0x6858, 0x8007, 0xa084, 0x00ff, 0x0148, 0x600a, 0x6858, 0x8000,
+	0x1108, 0xc28d, 0x6202, 0x012e, 0x0804, 0x5f7f, 0x012e, 0x0804,
+	0x5f79, 0x012e, 0x0804, 0x5f73, 0x012e, 0x0804, 0x5f76, 0x0126,
+	0x2091, 0x8000, 0x7007, 0x0001, 0x2001, 0xad52, 0x2004, 0xd0a4,
+	0x05e0, 0x2061, 0xb048, 0x6000, 0xd084, 0x05b8, 0x6204, 0x6308,
+	0xd08c, 0x1530, 0x6c48, 0xa484, 0x0003, 0x0170, 0x6958, 0xa18c,
+	0x00ff, 0x8001, 0x1120, 0x2100, 0xa210, 0x0620, 0x0028, 0x8001,
+	0x1508, 0x2100, 0xa212, 0x02f0, 0xa484, 0x000c, 0x0188, 0x6958,
+	0x810f, 0xa18c, 0x00ff, 0xa082, 0x0004, 0x1120, 0x2100, 0xa318,
+	0x0288, 0x0030, 0xa082, 0x0004, 0x1168, 0x2100, 0xa31a, 0x0250,
+	0x6860, 0xa005, 0x0110, 0x8000, 0x6016, 0x6206, 0x630a, 0x012e,
+	0x0804, 0x5f7f, 0x012e, 0x0804, 0x5f7c, 0x012e, 0x0804, 0x5f79,
+	0x0126, 0x2091, 0x8000, 0x7007, 0x0001, 0x2061, 0xb048, 0x6300,
+	0xd38c, 0x1120, 0x6308, 0x8318, 0x0220, 0x630a, 0x012e, 0x0804,
+	0x5f8d, 0x012e, 0x0804, 0x5f7c, 0x0126, 0x00c6, 0x2091, 0x8000,
+	0x7007, 0x0001, 0x684c, 0xd0ac, 0x0148, 0x00c6, 0x2061, 0xb048,
+	0x6000, 0xa084, 0xfcff, 0x6002, 0x00ce, 0x0448, 0x6858, 0xa005,
+	0x05d0, 0x685c, 0xa065, 0x0598, 0x2001, 0xad30, 0x2004, 0xa005,
+	0x0118, 0x080c, 0x974e, 0x0068, 0x6013, 0x0400, 0x6057, 0x0000,
+	0x694c, 0xd1a4, 0x0110, 0x6950, 0x6156, 0x2009, 0x0041, 0x080c,
+	0x80a7, 0x6958, 0xa18c, 0xff00, 0xa186, 0x2000, 0x1140, 0x0026,
+	0x2009, 0x0000, 0x2011, 0xfdff, 0x080c, 0x663f, 0x002e, 0x684c,
+	0xd0c4, 0x0148, 0x2061, 0xb048, 0x6000, 0xd08c, 0x1120, 0x6008,
+	0x8000, 0x0208, 0x600a, 0x00ce, 0x012e, 0x0804, 0x5f7f, 0x00ce,
+	0x012e, 0x0804, 0x5f79, 0x6954, 0xa186, 0x002e, 0x0d40, 0xa186,
+	0x002d, 0x0d28, 0xa186, 0x0045, 0x0510, 0xa186, 0x002a, 0x1130,
+	0x2001, 0xad0c, 0x200c, 0xc194, 0x2102, 0x08c8, 0xa186, 0x0020,
+	0x0170, 0xa186, 0x0029, 0x1d18, 0x6944, 0xa18c, 0xff00, 0x810f,
+	0x080c, 0x4cdc, 0x1960, 0x6000, 0xc0e4, 0x6002, 0x0840, 0x685c,
+	0xa065, 0x09a8, 0x2001, 0xafa3, 0x2004, 0x6016, 0x0800, 0x685c,
+	0xa065, 0x0968, 0x00e6, 0x6860, 0xa075, 0x2001, 0xad30, 0x2004,
+	0xa005, 0x0150, 0x080c, 0x974e, 0x8eff, 0x0118, 0x2e60, 0x080c,
+	0x974e, 0x00ee, 0x0804, 0x5e3f, 0x6020, 0xc0dc, 0xc0d5, 0x6022,
+	0x2e60, 0x6007, 0x003a, 0x6870, 0xa005, 0x0130, 0x6007, 0x003b,
+	0x6874, 0x602a, 0x6878, 0x6012, 0x6003, 0x0001, 0x080c, 0x67a8,
+	0x080c, 0x6c50, 0x00ee, 0x0804, 0x5e3f, 0x2061, 0xb048, 0x6000,
+	0xd084, 0x0190, 0xd08c, 0x1904, 0x5f8d, 0x0126, 0x2091, 0x8000,
+	0x6204, 0x8210, 0x0220, 0x6206, 0x012e, 0x0804, 0x5f8d, 0x012e,
+	0x6853, 0x0016, 0x0804, 0x5f86, 0x6853, 0x0007, 0x0804, 0x5f86,
+	0x6834, 0x8007, 0xa084, 0x00ff, 0x1118, 0x080c, 0x5b99, 0x0078,
+	0x2030, 0x8001, 0x1120, 0x7007, 0x0001, 0x0051, 0x0040, 0x7007,
+	0x0006, 0x7012, 0x2d00, 0x7016, 0x701a, 0x704b, 0x5ee0, 0x0005,
+	0x00e6, 0x0126, 0x2091, 0x8000, 0x2009, 0xad30, 0x210c, 0x81ff,
+	0x1904, 0x5f5b, 0x2009, 0xad0c, 0x210c, 0xd194, 0x1904, 0x5f63,
+	0x6848, 0x2070, 0xae82, 0xb400, 0x0a04, 0x5f4f, 0x2001, 0xad16,
+	0x2004, 0xae02, 0x1a04, 0x5f4f, 0x2061, 0xb048, 0x6100, 0xa184,
+	0x0301, 0xa086, 0x0001, 0x15a8, 0x711c, 0xa186, 0x0006, 0x15b0,
+	0x7018, 0xa005, 0x0904, 0x5f5b, 0x2004, 0xd0e4, 0x1904, 0x5f5e,
+	0x7020, 0xd0dc, 0x1904, 0x5f66, 0x6853, 0x0000, 0x6803, 0x0000,
+	0x2d08, 0x7010, 0xa005, 0x1158, 0x7112, 0x684c, 0xd0f4, 0x1904,
+	0x5f69, 0x2e60, 0x080c, 0x65aa, 0x012e, 0x00ee, 0x0005, 0x2068,
+	0x6800, 0xa005, 0x1de0, 0x6902, 0x2168, 0x684c, 0xd0f4, 0x15c8,
+	0x012e, 0x00ee, 0x0005, 0x012e, 0x00ee, 0x6853, 0x0006, 0x0804,
+	0x5f86, 0xd184, 0x0dc0, 0xd1c4, 0x11a8, 0x00b8, 0x6944, 0xa18c,
+	0xff00, 0x810f, 0x080c, 0x4cdc, 0x11c8, 0x6000, 0xd0e4, 0x11b0,
+	0x711c, 0xa186, 0x0007, 0x1118, 0x6853, 0x0002, 0x0088, 0x6853,
+	0x0008, 0x0070, 0x6853, 0x000e, 0x0058, 0x6853, 0x0017, 0x0040,
+	0x6853, 0x0035, 0x0028, 0x6853, 0x0028, 0x0010, 0x6853, 0x0029,
+	0x012e, 0x00ee, 0x0418, 0x6853, 0x002a, 0x0cd0, 0x6853, 0x0045,
+	0x0cb8, 0x2e60, 0x2019, 0x0002, 0x6017, 0x0014, 0x080c, 0xa566,
+	0x012e, 0x00ee, 0x0005, 0x2009, 0x003e, 0x0058, 0x2009, 0x0004,
+	0x0040, 0x2009, 0x0006, 0x0028, 0x2009, 0x0016, 0x0010, 0x2009,
+	0x0001, 0x6854, 0xa084, 0xff00, 0xa105, 0x6856, 0x0126, 0x2091,
+	0x8000, 0x080c, 0x510c, 0x012e, 0x0005, 0x080c, 0x15f0, 0x0005,
+	0x702c, 0x7130, 0x8108, 0xa102, 0x0230, 0xa00e, 0x7034, 0x7072,
+	0x7038, 0x7076, 0x0058, 0x7070, 0xa080, 0x0040, 0x7072, 0x1230,
+	0x7074, 0xa081, 0x0000, 0x7076, 0xa085, 0x0001, 0x7932, 0x7132,
+	0x0005, 0x00d6, 0x080c, 0x65a1, 0x00de, 0x0005, 0x00d6, 0x2011,
+	0x0004, 0x2204, 0xa085, 0x8002, 0x2012, 0x00de, 0x0005, 0x20e1,
+	0x0002, 0x3d08, 0x20e1, 0x2000, 0x3d00, 0xa084, 0x7000, 0x0118,
+	0xa086, 0x1000, 0x1540, 0x20e1, 0x0000, 0x3d00, 0xa094, 0xff00,
+	0x8217, 0xa084, 0xf000, 0xa086, 0x3000, 0x1118, 0x080c, 0x61c6,
+	0x00b0, 0x20e1, 0x0004, 0x3d60, 0xd1bc, 0x1108, 0x3e60, 0xac84,
+	0x0007, 0x1188, 0xac82, 0xb400, 0x0270, 0x6858, 0xac02, 0x1258,
+	0x6120, 0xd1f4, 0x1160, 0x2009, 0x0047, 0x080c, 0x80a7, 0x7a1c,
+	0xd284, 0x1968, 0x0005, 0xa016, 0x080c, 0x1824, 0x0cc0, 0x0cd8,
+	0x781c, 0xd08c, 0x0500, 0x0156, 0x0136, 0x0146, 0x20e1, 0x3000,
+	0x3d20, 0x3e28, 0xa584, 0x0076, 0x1530, 0xa484, 0x7000, 0xa086,
+	0x1000, 0x11a8, 0x080c, 0x604e, 0x01f0, 0x20e1, 0x3000, 0x7828,
+	0x7828, 0x080c, 0x606a, 0x014e, 0x013e, 0x015e, 0x2009, 0xafcf,
+	0x2104, 0xa005, 0x1108, 0x0005, 0x080c, 0x6c50, 0x0ce0, 0xa484,
+	0x7000, 0x1518, 0x0499, 0x01b8, 0x7000, 0xa084, 0xff00, 0xa086,
+	0x8100, 0x0d18, 0x0080, 0xd5a4, 0x0158, 0x080c, 0x1d86, 0x20e1,
+	0x9010, 0x2001, 0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x0048,
+	0x00e9, 0x6883, 0x0000, 0x080c, 0xac59, 0x20e1, 0x3000, 0x7828,
+	0x7828, 0x014e, 0x013e, 0x015e, 0x08b0, 0x0081, 0x1130, 0x7000,
+	0xa084, 0xff00, 0xa086, 0x8100, 0x1d70, 0x080c, 0xac59, 0x20e1,
+	0x3000, 0x7828, 0x7828, 0x080c, 0x642d, 0x0c58, 0xa484, 0x01ff,
+	0x6882, 0xa005, 0x0160, 0xa080, 0x001f, 0xa084, 0x03f8, 0x80ac,
+	0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5, 0x0005, 0x20a9,
+	0x000c, 0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5, 0xa085,
+	0x0001, 0x0ca0, 0x7000, 0xa084, 0xff00, 0xa08c, 0xf000, 0x8007,
+	0xa196, 0x0000, 0x1118, 0x0804, 0x62cf, 0x0005, 0xa196, 0x2000,
+	0x1148, 0x6900, 0xa18e, 0x0001, 0x1118, 0x080c, 0x41d1, 0x0ca8,
+	0x0039, 0x0c98, 0xa196, 0x8000, 0x1d80, 0x080c, 0x6372, 0x0c68,
+	0x00c6, 0x6a80, 0x82ff, 0x0904, 0x61c0, 0x7110, 0xa18c, 0xff00,
+	0x810f, 0xa196, 0x0001, 0x0120, 0xa196, 0x0023, 0x1904, 0x61c0,
+	0xa08e, 0x0023, 0x1570, 0x080c, 0x6408, 0x0904, 0x61c0, 0x7124,
+	0x610a, 0x7030, 0xa08e, 0x0200, 0x1150, 0x7034, 0xa005, 0x1904,
+	0x61c0, 0x2009, 0x0015, 0x080c, 0x80a7, 0x0804, 0x61c0, 0xa08e,
+	0x0214, 0x0118, 0xa08e, 0x0210, 0x1130, 0x2009, 0x0015, 0x080c,
+	0x80a7, 0x0804, 0x61c0, 0xa08e, 0x0100, 0x1904, 0x61c0, 0x7034,
+	0xa005, 0x1904, 0x61c0, 0x2009, 0x0016, 0x080c, 0x80a7, 0x0804,
+	0x61c0, 0xa08e, 0x0022, 0x1904, 0x61c0, 0x7030, 0xa08e, 0x0300,
+	0x1580, 0x68d0, 0xd0a4, 0x0528, 0xc0b5, 0x68d2, 0x7100, 0xa18c,
+	0x00ff, 0x696e, 0x7004, 0x6872, 0x00f6, 0x2079, 0x0100, 0x79e6,
+	0x78ea, 0x0006, 0xa084, 0x00ff, 0x0016, 0x2008, 0x080c, 0x26a0,
+	0x7932, 0x7936, 0x001e, 0x000e, 0x00fe, 0x080c, 0x2676, 0x694e,
+	0x703c, 0x00e6, 0x2071, 0x0140, 0x7086, 0x2071, 0xad00, 0x70a2,
+	0x00ee, 0x7034, 0xa005, 0x1904, 0x61c0, 0x2009, 0x0017, 0x0804,
+	0x6193, 0xa08e, 0x0400, 0x1158, 0x7034, 0xa005, 0x1904, 0x61c0,
+	0x68d0, 0xc0a5, 0x68d2, 0x2009, 0x0030, 0x0804, 0x6193, 0xa08e,
+	0x0500, 0x1140, 0x7034, 0xa005, 0x1904, 0x61c0, 0x2009, 0x0018,
+	0x0804, 0x6193, 0xa08e, 0x2010, 0x1120, 0x2009, 0x0019, 0x0804,
+	0x6193, 0xa08e, 0x2110, 0x1120, 0x2009, 0x001a, 0x0804, 0x6193,
+	0xa08e, 0x5200, 0x1140, 0x7034, 0xa005, 0x1904, 0x61c0, 0x2009,
+	0x001b, 0x0804, 0x6193, 0xa08e, 0x5000, 0x1140, 0x7034, 0xa005,
+	0x1904, 0x61c0, 0x2009, 0x001c, 0x0804, 0x6193, 0xa08e, 0x1300,
+	0x1120, 0x2009, 0x0034, 0x0804, 0x6193, 0xa08e, 0x1200, 0x1140,
+	0x7034, 0xa005, 0x1904, 0x61c0, 0x2009, 0x0024, 0x0804, 0x6193,
+	0xa08c, 0xff00, 0xa18e, 0x2400, 0x1118, 0x2009, 0x002d, 0x04d8,
+	0xa08c, 0xff00, 0xa18e, 0x5300, 0x1118, 0x2009, 0x002a, 0x0498,
+	0xa08e, 0x0f00, 0x1118, 0x2009, 0x0020, 0x0468, 0xa08e, 0x5300,
+	0x1108, 0x00d8, 0xa08e, 0x6104, 0x11c0, 0x2011, 0xb28d, 0x8208,
+	0x2204, 0xa082, 0x0004, 0x20a8, 0x95ac, 0x95ac, 0x2011, 0x8015,
+	0x211c, 0x8108, 0x0046, 0x2124, 0x080c, 0x3c5c, 0x004e, 0x8108,
+	0x1f04, 0x6176, 0x2009, 0x0023, 0x0070, 0xa08e, 0x6000, 0x1118,
+	0x2009, 0x003f, 0x0040, 0xa08e, 0x7800, 0x1118, 0x2009, 0x0045,
+	0x0010, 0x2009, 0x001d, 0x0016, 0x2011, 0xb283, 0x2204, 0x8211,
+	0x220c, 0x080c, 0x2676, 0x1530, 0x080c, 0x4c80, 0x1518, 0x6612,
+	0x6516, 0x86ff, 0x0180, 0x001e, 0x0016, 0xa186, 0x0017, 0x1158,
+	0x686c, 0xa606, 0x1140, 0x6870, 0xa506, 0xa084, 0xff00, 0x1118,
+	0x6000, 0xc0f5, 0x6002, 0x00c6, 0x080c, 0x8022, 0x0168, 0x001e,
+	0x611a, 0x601f, 0x0004, 0x7120, 0x610a, 0x001e, 0x080c, 0x80a7,
+	0x00ce, 0x0005, 0x001e, 0x0ce0, 0x00ce, 0x0ce0, 0x00c6, 0x0046,
+	0x080c, 0x6221, 0x1904, 0x621e, 0xa184, 0xff00, 0x8007, 0xa086,
+	0x0008, 0x1904, 0x621e, 0xa28e, 0x0033, 0x11e8, 0x080c, 0x6408,
+	0x0904, 0x621e, 0x7124, 0x610a, 0x7030, 0xa08e, 0x0200, 0x1140,
+	0x7034, 0xa005, 0x15d8, 0x2009, 0x0015, 0x080c, 0x80a7, 0x04b0,
+	0xa08e, 0x0100, 0x1598, 0x7034, 0xa005, 0x1580, 0x2009, 0x0016,
+	0x080c, 0x80a7, 0x0458, 0xa28e, 0x0032, 0x1540, 0x7030, 0xa08e,
+	0x1400, 0x1520, 0x2009, 0x0038, 0x0016, 0x2011, 0xb283, 0x2204,
+	0x8211, 0x220c, 0x080c, 0x2676, 0x11c0, 0x080c, 0x4c80, 0x11a8,
+	0x6612, 0x6516, 0x00c6, 0x080c, 0x8022, 0x0170, 0x001e, 0x611a,
+	0x080c, 0x9956, 0x601f, 0x0004, 0x7120, 0x610a, 0x001e, 0x080c,
+	0x80a7, 0x080c, 0x6c50, 0x0010, 0x00ce, 0x001e, 0x004e, 0x00ce,
+	0x0005, 0x00f6, 0x00d6, 0x0026, 0x0016, 0x0136, 0x0146, 0x0156,
+	0x3c00, 0x0006, 0x2079, 0x0030, 0x2069, 0x0200, 0x080c, 0x1df2,
+	0x1590, 0x080c, 0x1ce2, 0x05c8, 0x04d9, 0x1130, 0x7908, 0xa18c,
+	0x1fff, 0xa182, 0x0011, 0x1688, 0x20a9, 0x000c, 0x20e1, 0x0000,
+	0x2ea0, 0x2099, 0x020a, 0x53a5, 0x20e1, 0x2000, 0x2001, 0x020a,
+	0x2004, 0x7a0c, 0x7808, 0xa080, 0x0007, 0xa084, 0x1ff8, 0x0401,
+	0x1120, 0xa08a, 0x0140, 0x1a0c, 0x14f6, 0x80ac, 0x20e1, 0x6000,
+	0x2099, 0x020a, 0x53a5, 0x20e1, 0x7000, 0x6828, 0x6828, 0x7803,
+	0x0004, 0xa294, 0x0070, 0x000e, 0x20e0, 0x015e, 0x014e, 0x013e,
+	0x001e, 0x002e, 0x00de, 0x00fe, 0x0005, 0xa085, 0x0001, 0x0c98,
+	0x0006, 0x2001, 0x0111, 0x2004, 0xa084, 0x0003, 0x000e, 0x0005,
+	0x0046, 0x00e6, 0x00d6, 0x2028, 0x2130, 0xa696, 0x00ff, 0x1198,
+	0xa596, 0xfffd, 0x1120, 0x2009, 0x007f, 0x0804, 0x62ca, 0xa596,
+	0xfffe, 0x1118, 0x2009, 0x007e, 0x04e8, 0xa596, 0xfffc, 0x1118,
+	0x2009, 0x0080, 0x04b8, 0x2011, 0x0000, 0x2019, 0xad34, 0x231c,
+	0xd3ac, 0x0138, 0x2021, 0x0000, 0x20a9, 0x00ff, 0x2071, 0xae34,
+	0x0030, 0x2021, 0x0081, 0x20a9, 0x007e, 0x2071, 0xaeb5, 0x2e1c,
+	0x83ff, 0x1128, 0x82ff, 0x1198, 0x2410, 0xc2fd, 0x0080, 0x2368,
+	0x6f10, 0x0006, 0x2100, 0xa706, 0x000e, 0x6b14, 0x1120, 0xa346,
+	0x1110, 0x2408, 0x0078, 0x87ff, 0x1110, 0x83ff, 0x0d58, 0x8420,
+	0x8e70, 0x1f04, 0x62a7, 0x82ff, 0x1118, 0xa085, 0x0001, 0x0018,
+	0xc2fc, 0x2208, 0xa006, 0x00de, 0x00ee, 0x004e, 0x0005, 0xa084,
+	0x0007, 0x000a, 0x0005, 0x62db, 0x62db, 0x62db, 0x641a, 0x62db,
+	0x62dc, 0x62f1, 0x635d, 0x0005, 0x7110, 0xd1bc, 0x0188, 0x7120,
+	0x2160, 0xac8c, 0x0007, 0x1160, 0xac8a, 0xb400, 0x0248, 0x6858,
+	0xac02, 0x1230, 0x7124, 0x610a, 0x2009, 0x0046, 0x080c, 0x80a7,
+	0x0005, 0x00c6, 0x7110, 0xd1bc, 0x1904, 0x6344, 0x2011, 0xb283,
+	0x2204, 0x8211, 0x220c, 0x080c, 0x2676, 0x1904, 0x6344, 0x080c,
+	0x4c80, 0x1904, 0x6344, 0x6612, 0x6516, 0x6000, 0xd0ec, 0x15e0,
+	0x6204, 0xa294, 0xff00, 0x8217, 0xa286, 0x0006, 0x0160, 0x080c,
+	0x574f, 0x11d0, 0x6204, 0xa294, 0x00ff, 0xa286, 0x0006, 0x11a0,
+	0xa295, 0x0600, 0x6206, 0x00c6, 0x080c, 0x8022, 0x001e, 0x0530,
+	0x611a, 0x601f, 0x0006, 0x7120, 0x610a, 0x7130, 0x6152, 0x2009,
+	0x0044, 0x080c, 0x80a7, 0x00c0, 0x00c6, 0x080c, 0x8022, 0x001e,
+	0x0198, 0x611a, 0x601f, 0x0004, 0x7120, 0x610a, 0xa286, 0x0004,
+	0x1118, 0x6007, 0x0005, 0x0010, 0x6007, 0x0001, 0x6003, 0x0001,
+	0x080c, 0x67ee, 0x080c, 0x6c50, 0x00ce, 0x0005, 0x00c6, 0x080c,
+	0x9807, 0x001e, 0x0dc8, 0x611a, 0x601f, 0x0006, 0x7120, 0x610a,
+	0x7130, 0x6152, 0x6013, 0x0300, 0x6003, 0x0001, 0x6007, 0x0041,
+	0x080c, 0x67a8, 0x080c, 0x6c50, 0x0c38, 0x7110, 0xd1bc, 0x0188,
+	0x7020, 0x2060, 0xac84, 0x0007, 0x1160, 0xac82, 0xb400, 0x0248,
+	0x6858, 0xac02, 0x1230, 0x7124, 0x610a, 0x2009, 0x0045, 0x080c,
+	0x80a7, 0x0005, 0x7110, 0xa18c, 0xff00, 0x810f, 0xa18e, 0x0000,
+	0x1130, 0xa084, 0x000f, 0xa08a, 0x0006, 0x1208, 0x000b, 0x0005,
+	0x6386, 0x6387, 0x6386, 0x6386, 0x63f0, 0x63fc, 0x0005, 0x7110,
+	0xd1bc, 0x0120, 0x702c, 0xd084, 0x0904, 0x63ef, 0x700c, 0x7108,
+	0x080c, 0x2676, 0x1904, 0x63ef, 0x080c, 0x4c80, 0x1904, 0x63ef,
+	0x6612, 0x6516, 0x6204, 0x7110, 0xd1bc, 0x01f8, 0xa28c, 0x00ff,
+	0xa186, 0x0004, 0x0118, 0xa186, 0x0006, 0x15c8, 0x00c6, 0x080c,
+	0x6408, 0x00ce, 0x0904, 0x63ef, 0x00c6, 0x080c, 0x8022, 0x001e,
+	0x05f0, 0x611a, 0x080c, 0x9956, 0x601f, 0x0002, 0x7120, 0x610a,
+	0x2009, 0x0088, 0x080c, 0x80a7, 0x0490, 0xa28c, 0x00ff, 0xa186,
+	0x0006, 0x0160, 0xa186, 0x0004, 0x0148, 0xa294, 0xff00, 0x8217,
+	0xa286, 0x0004, 0x0118, 0xa286, 0x0006, 0x1188, 0x00c6, 0x080c,
+	0x8022, 0x001e, 0x01e0, 0x611a, 0x080c, 0x9956, 0x601f, 0x0005,
+	0x7120, 0x610a, 0x2009, 0x0088, 0x080c, 0x80a7, 0x0080, 0x00c6,
+	0x080c, 0x8022, 0x001e, 0x0158, 0x611a, 0x080c, 0x9956, 0x601f,
+	0x0004, 0x7120, 0x610a, 0x2009, 0x0001, 0x080c, 0x80a7, 0x0005,
+	0x7110, 0xd1bc, 0x0140, 0x00a1, 0x0130, 0x7124, 0x610a, 0x2009,
+	0x0089, 0x080c, 0x80a7, 0x0005, 0x7110, 0xd1bc, 0x0140, 0x0041,
+	0x0130, 0x7124, 0x610a, 0x2009, 0x008a, 0x080c, 0x80a7, 0x0005,
+	0x7020, 0x2060, 0xac84, 0x0007, 0x1158, 0xac82, 0xb400, 0x0240,
+	0x2001, 0xad16, 0x2004, 0xac02, 0x1218, 0xa085, 0x0001, 0x0005,
+	0xa006, 0x0ce8, 0x7110, 0xd1bc, 0x1178, 0x7024, 0x2060, 0xac84,
+	0x0007, 0x1150, 0xac82, 0xb400, 0x0238, 0x6858, 0xac02, 0x1220,
+	0x2009, 0x0051, 0x080c, 0x80a7, 0x0005, 0x2031, 0x0105, 0x0069,
+	0x0005, 0x2031, 0x0206, 0x0049, 0x0005, 0x2031, 0x0207, 0x0029,
+	0x0005, 0x2031, 0x0213, 0x0009, 0x0005, 0x00c6, 0x00d6, 0x00f6,
+	0x7000, 0xa084, 0xf000, 0xa086, 0xc000, 0x05b0, 0x080c, 0x8022,
+	0x0598, 0x0066, 0x00c6, 0x0046, 0x2011, 0xb283, 0x2204, 0x8211,
+	0x220c, 0x080c, 0x2676, 0x1580, 0x080c, 0x4c80, 0x1568, 0x6612,
+	0x6516, 0x2c00, 0x004e, 0x00ce, 0x601a, 0x080c, 0x9956, 0x080c,
+	0x15d9, 0x01f0, 0x2d00, 0x6056, 0x6803, 0x0000, 0x6837, 0x0000,
+	0x6c3a, 0xadf8, 0x000f, 0x20a9, 0x000e, 0x2fa0, 0x2e98, 0x53a3,
+	0x006e, 0x6612, 0x6007, 0x003e, 0x601f, 0x0001, 0x6003, 0x0001,
+	0x080c, 0x67ee, 0x080c, 0x6c50, 0x00fe, 0x00de, 0x00ce, 0x0005,
+	0x080c, 0x8078, 0x006e, 0x0cc0, 0x004e, 0x00ce, 0x0cc8, 0x2071,
+	0xafda, 0x7003, 0x0003, 0x700f, 0x0361, 0xa006, 0x701a, 0x7012,
+	0x7017, 0xb400, 0x7007, 0x0000, 0x7026, 0x702b, 0x7841, 0x7032,
+	0x7037, 0x789d, 0x703b, 0xffff, 0x703f, 0xffff, 0x7042, 0x7047,
+	0x41b3, 0x0005, 0x2071, 0xafda, 0x1d04, 0x64fc, 0x2091, 0x6000,
+	0x700c, 0x8001, 0x700e, 0x1180, 0x700f, 0x0361, 0x7007, 0x0001,
+	0x0126, 0x2091, 0x8000, 0x7040, 0xa00d, 0x0148, 0x8109, 0x7142,
+	0x1130, 0x7044, 0x080f, 0x0018, 0x0126, 0x2091, 0x8000, 0x7024,
+	0xa00d, 0x0188, 0x7020, 0x8001, 0x7022, 0x1168, 0x7023, 0x0009,
+	0x8109, 0x7126, 0xa186, 0x03e8, 0x1110, 0x7028, 0x080f, 0x81ff,
+	0x1110, 0x7028, 0x080f, 0x7030, 0xa00d, 0x0158, 0x702c, 0x8001,
+	0x702e, 0x1138, 0x702f, 0x0009, 0x8109, 0x7132, 0x1110, 0x7034,
+	0x080f, 0x7038, 0xa005, 0x0118, 0x0310, 0x8001, 0x703a, 0x703c,
+	0xa005, 0x0118, 0x0310, 0x8001, 0x703e, 0x7018, 0xa00d, 0x0158,
+	0x7008, 0x8001, 0x700a, 0x1138, 0x700b, 0x0009, 0x8109, 0x711a,
+	0x1110, 0x701c, 0x080f, 0x012e, 0x7004, 0x0002, 0x6522, 0x6523,
+	0x653b, 0x00e6, 0x2071, 0xafda, 0x7018, 0xa005, 0x1120, 0x711a,
+	0x721e, 0x700b, 0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x2071,
+	0xafda, 0x701c, 0xa206, 0x1110, 0x701a, 0x701e, 0x000e, 0x00ee,
+	0x0005, 0x00e6, 0x2071, 0xafda, 0x6088, 0xa102, 0x0208, 0x618a,
+	0x00ee, 0x0005, 0x0005, 0x7110, 0x080c, 0x4cdc, 0x1158, 0x6088,
+	0x8001, 0x0240, 0x608a, 0x1130, 0x0126, 0x2091, 0x8000, 0x080c,
+	0x6c50, 0x012e, 0x8108, 0xa182, 0x00ff, 0x0218, 0xa00e, 0x7007,
+	0x0002, 0x7112, 0x0005, 0x7014, 0x2060, 0x0126, 0x2091, 0x8000,
+	0x603c, 0xa005, 0x0128, 0x8001, 0x603e, 0x1110, 0x080c, 0x9846,
+	0x6014, 0xa005, 0x0500, 0x8001, 0x6016, 0x11e8, 0x611c, 0xa186,
+	0x0003, 0x0118, 0xa186, 0x0006, 0x11a0, 0x6010, 0x2068, 0x6854,
+	0xa08a, 0x199a, 0x0270, 0xa082, 0x1999, 0x6856, 0xa08a, 0x199a,
+	0x0210, 0x2001, 0x1999, 0x8003, 0x800b, 0x810b, 0xa108, 0x6116,
+	0x0010, 0x080c, 0x9350, 0x012e, 0xac88, 0x0018, 0x7116, 0x2001,
+	0xe400, 0xa102, 0x0220, 0x7017, 0xb400, 0x7007, 0x0000, 0x0005,
+	0x00e6, 0x2071, 0xafda, 0x7027, 0x07d0, 0x7023, 0x0009, 0x00ee,
+	0x0005, 0x2001, 0xafe3, 0x2003, 0x0000, 0x0005, 0x00e6, 0x2071,
+	0xafda, 0x7132, 0x702f, 0x0009, 0x00ee, 0x0005, 0x2011, 0xafe6,
+	0x2013, 0x0000, 0x0005, 0x00e6, 0x2071, 0xafda, 0x711a, 0x721e,
+	0x700b, 0x0009, 0x00ee, 0x0005, 0x00c6, 0x2061, 0xb048, 0x00ce,
+	0x0005, 0xa184, 0x000f, 0x8003, 0x8003, 0x8003, 0xa080, 0xb048,
+	0x2060, 0x0005, 0x6854, 0xa08a, 0x199a, 0x0210, 0x2001, 0x1999,
+	0xa005, 0x1150, 0x00c6, 0x2061, 0xb048, 0x6014, 0x00ce, 0xa005,
+	0x1138, 0x2001, 0x001e, 0x0020, 0xa08e, 0xffff, 0x1108, 0xa006,
+	0x8003, 0x800b, 0x810b, 0xa108, 0x6116, 0x684c, 0xa08c, 0x00c0,
+	0xa18e, 0x00c0, 0x05b0, 0xd0b4, 0x1138, 0xd0bc, 0x1528, 0x2009,
+	0x0006, 0x080c, 0x661a, 0x0005, 0xd0fc, 0x0130, 0xa084, 0x0003,
+	0x0118, 0xa086, 0x0003, 0x15c0, 0x6020, 0xd0d4, 0x0130, 0xc0d4,
+	0x6022, 0x6860, 0x602a, 0x685c, 0x602e, 0x2009, 0xad73, 0x2104,
+	0xd084, 0x0128, 0x2009, 0x0042, 0x080c, 0x80a7, 0x0005, 0x2009,
+	0x0043, 0x080c, 0x80a7, 0x0005, 0xd0fc, 0x0130, 0xa084, 0x0003,
+	0x0118, 0xa086, 0x0003, 0x11c0, 0x2009, 0x0042, 0x080c, 0x80a7,
+	0x0005, 0xd0fc, 0x0150, 0xa084, 0x0003, 0xa08e, 0x0002, 0x0138,
+	0x2009, 0x0041, 0x080c, 0x80a7, 0x0005, 0x0051, 0x0ce8, 0x2009,
+	0x0043, 0x080c, 0x80a7, 0x0cc0, 0x2009, 0x0004, 0x0019, 0x0005,
+	0x2009, 0x0001, 0x00d6, 0x6010, 0xa0ec, 0xf000, 0x01f0, 0x2068,
+	0x6952, 0x6800, 0x6012, 0xa186, 0x0001, 0x1188, 0x694c, 0xa18c,
+	0x8100, 0xa18e, 0x8100, 0x1158, 0x00c6, 0x2061, 0xb048, 0x6200,
+	0xd28c, 0x1120, 0x6204, 0x8210, 0x0208, 0x6206, 0x00ce, 0x080c,
+	0x510c, 0x6010, 0xa06d, 0x190c, 0x65aa, 0x00de, 0x0005, 0x0156,
+	0x00c6, 0x2061, 0xb048, 0x6000, 0x81ff, 0x0110, 0xa205, 0x0008,
+	0xa204, 0x6002, 0x00ce, 0x015e, 0x0005, 0x6800, 0xd08c, 0x1138,
+	0x6808, 0xa005, 0x0120, 0x8001, 0x680a, 0xa085, 0x0001, 0x0005,
+	0x20a9, 0x0010, 0xa006, 0x8004, 0x8086, 0x818e, 0x1208, 0xa200,
+	0x1f04, 0x665c, 0x8086, 0x818e, 0x0005, 0x0156, 0x20a9, 0x0010,
+	0xa005, 0x01b8, 0xa11a, 0x12a8, 0x8213, 0x818d, 0x0228, 0xa11a,
+	0x1220, 0x1f04, 0x666c, 0x0028, 0xa11a, 0x2308, 0x8210, 0x1f04,
+	0x666c, 0x0006, 0x3200, 0xa084, 0xefff, 0x2080, 0x000e, 0x015e,
+	0x0005, 0x0006, 0x3200, 0xa085, 0x1000, 0x0cb8, 0x0126, 0x2091,
+	0x2800, 0x2079, 0xafc7, 0x012e, 0x00d6, 0x2069, 0xafc7, 0x6803,
+	0x0005, 0x2069, 0x0004, 0x2d04, 0xa085, 0x8001, 0x206a, 0x00de,
+	0x0005, 0x00c6, 0x6027, 0x0001, 0x7804, 0xa084, 0x0007, 0x0002,
+	0x66aa, 0x66cb, 0x671e, 0x66b0, 0x66cb, 0x66aa, 0x66a8, 0x66a8,
+	0x080c, 0x14f6, 0x080c, 0x6581, 0x080c, 0x6c50, 0x00ce, 0x0005,
+	0x62c0, 0x82ff, 0x1110, 0x00ce, 0x0005, 0x2011, 0x481b, 0x080c,
+	0x650d, 0x7828, 0xa092, 0x00c8, 0x1228, 0x8000, 0x782a, 0x080c,
+	0x4855, 0x0c88, 0x080c, 0x481b, 0x7807, 0x0003, 0x7827, 0x0000,
+	0x782b, 0x0000, 0x0c40, 0x080c, 0x6581, 0x3c00, 0x0006, 0x2011,
+	0x0209, 0x20e1, 0x4000, 0x2214, 0x000e, 0x20e0, 0x82ff, 0x0178,
+	0x62c0, 0x82ff, 0x1160, 0x782b, 0x0000, 0x7824, 0xa065, 0x090c,
+	0x14f6, 0x2009, 0x0013, 0x080c, 0x80a7, 0x00ce, 0x0005, 0x3900,
+	0xa082, 0xb0e8, 0x1210, 0x080c, 0x7d8d, 0x00c6, 0x7824, 0xa065,
+	0x090c, 0x14f6, 0x7804, 0xa086, 0x0004, 0x0904, 0x675e, 0x7828,
+	0xa092, 0x2710, 0x1230, 0x8000, 0x782a, 0x00ce, 0x080c, 0x7827,
+	0x0c20, 0x6104, 0xa186, 0x0003, 0x1188, 0x00e6, 0x2071, 0xad00,
+	0x70dc, 0x00ee, 0xd08c, 0x0150, 0x00c6, 0x00e6, 0x2061, 0x0100,
+	0x2071, 0xad00, 0x080c, 0x485e, 0x00ee, 0x00ce, 0x080c, 0xaca2,
+	0x2009, 0x0014, 0x080c, 0x80a7, 0x00ce, 0x0838, 0x2001, 0xafe3,
+	0x2003, 0x0000, 0x62c0, 0x82ff, 0x1160, 0x782b, 0x0000, 0x7824,
+	0xa065, 0x090c, 0x14f6, 0x2009, 0x0013, 0x080c, 0x80fb, 0x00ce,
+	0x0005, 0x00c6, 0x00d6, 0x3900, 0xa082, 0xb0e8, 0x1210, 0x080c,
+	0x7d8d, 0x7824, 0xa005, 0x090c, 0x14f6, 0x781c, 0xa06d, 0x090c,
+	0x14f6, 0x6800, 0xc0dc, 0x6802, 0x7924, 0x2160, 0x080c, 0x8078,
+	0x693c, 0x81ff, 0x090c, 0x14f6, 0x8109, 0x693e, 0x6854, 0xa015,
+	0x0110, 0x7a1e, 0x0010, 0x7918, 0x791e, 0x7807, 0x0000, 0x7827,
+	0x0000, 0x00de, 0x00ce, 0x080c, 0x6c50, 0x0888, 0x6104, 0xa186,
+	0x0002, 0x0128, 0xa186, 0x0004, 0x0110, 0x0804, 0x66f7, 0x7808,
+	0xac06, 0x0904, 0x66f7, 0x080c, 0x6b73, 0x080c, 0x67ee, 0x00ce,
+	0x080c, 0x6c50, 0x0804, 0x66e5, 0x00c6, 0x6027, 0x0002, 0x62c8,
+	0x60c4, 0xa205, 0x1178, 0x793c, 0xa1e5, 0x0000, 0x0130, 0x2009,
+	0x0049, 0x080c, 0x80a7, 0x00ce, 0x0005, 0x2011, 0xafe6, 0x2013,
+	0x0000, 0x0cc8, 0x3908, 0xa192, 0xb0e8, 0x1210, 0x080c, 0x7d8d,
+	0x793c, 0x81ff, 0x0d90, 0x793c, 0xa188, 0x0007, 0x210c, 0xa18e,
+	0x0006, 0x1138, 0x6014, 0xa084, 0x0184, 0xa085, 0x0012, 0x6016,
+	0x0c10, 0x6014, 0xa084, 0x0184, 0xa085, 0x0016, 0x6016, 0x08d8,
+	0x0006, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x600f, 0x0000,
+	0x2c08, 0x2061, 0xafc7, 0x6020, 0x8000, 0x6022, 0x6010, 0xa005,
+	0x0148, 0xa080, 0x0003, 0x2102, 0x6112, 0x012e, 0x00ce, 0x001e,
+	0x000e, 0x0005, 0x6116, 0x6112, 0x0cc0, 0x00d6, 0x2069, 0xafc7,
+	0x6000, 0xd0d4, 0x0168, 0x6820, 0x8000, 0x6822, 0xa086, 0x0001,
+	0x1110, 0x2c00, 0x681e, 0x6804, 0xa084, 0x0007, 0x0804, 0x6c56,
+	0xc0d5, 0x6002, 0x6818, 0xa005, 0x0158, 0x6056, 0x605b, 0x0000,
+	0x0006, 0x2c00, 0x681a, 0x00de, 0x685a, 0x2069, 0xafc7, 0x0c18,
+	0x6056, 0x605a, 0x2c00, 0x681a, 0x681e, 0x08e8, 0x0006, 0x0016,
+	0x00c6, 0x0126, 0x2091, 0x8000, 0x600f, 0x0000, 0x2c08, 0x2061,
+	0xafc7, 0x6020, 0x8000, 0x6022, 0x6008, 0xa005, 0x0148, 0xa080,
+	0x0003, 0x2102, 0x610a, 0x012e, 0x00ce, 0x001e, 0x000e, 0x0005,
+	0x610e, 0x610a, 0x0cc0, 0x00c6, 0x600f, 0x0000, 0x2c08, 0x2061,
+	0xafc7, 0x6034, 0xa005, 0x0130, 0xa080, 0x0003, 0x2102, 0x6136,
+	0x00ce, 0x0005, 0x613a, 0x6136, 0x0cd8, 0x00f6, 0x00e6, 0x00d6,
+	0x00c6, 0x0076, 0x0066, 0x0026, 0x0016, 0x0006, 0x0126, 0x2071,
+	0xafc7, 0x7638, 0x2660, 0x2678, 0x2091, 0x8000, 0x8cff, 0x0904,
+	0x6889, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x1904, 0x6884,
+	0x87ff, 0x0120, 0x6050, 0xa106, 0x1904, 0x6884, 0x703c, 0xac06,
+	0x1170, 0x0036, 0x2019, 0x0001, 0x080c, 0x7a64, 0x7033, 0x0000,
+	0x703f, 0x0000, 0x7043, 0x0000, 0x7047, 0x0000, 0x003e, 0x7038,
+	0xac36, 0x1110, 0x660c, 0x763a, 0x7034, 0xac36, 0x1140, 0x2c00,
+	0xaf36, 0x0118, 0x2f00, 0x7036, 0x0010, 0x7037, 0x0000, 0x660c,
+	0x0066, 0x2c00, 0xaf06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f,
+	0x0000, 0x080c, 0x9596, 0x0198, 0x6010, 0x2068, 0x601c, 0xa086,
+	0x0003, 0x1510, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c,
+	0x97fd, 0x080c, 0xabfa, 0x080c, 0x510c, 0x080c, 0x9742, 0x080c,
+	0x974e, 0x00ce, 0x0804, 0x682e, 0x2c78, 0x600c, 0x2060, 0x0804,
+	0x682e, 0x012e, 0x000e, 0x001e, 0x002e, 0x006e, 0x007e, 0x00ce,
+	0x00de, 0x00ee, 0x00fe, 0x0005, 0x601c, 0xa086, 0x0006, 0x19d0,
+	0x080c, 0xabfa, 0x080c, 0xa91f, 0x0c10, 0x0006, 0x0066, 0x00c6,
+	0x00d6, 0x00f6, 0x2031, 0x0000, 0x0126, 0x2091, 0x8000, 0x2079,
+	0xafc7, 0x7838, 0xa065, 0x0558, 0x600c, 0x0006, 0x600f, 0x0000,
+	0x783c, 0xac06, 0x1170, 0x0036, 0x2019, 0x0001, 0x080c, 0x7a64,
+	0x7833, 0x0000, 0x783f, 0x0000, 0x7843, 0x0000, 0x7847, 0x0000,
+	0x003e, 0x080c, 0x9596, 0x0178, 0x6010, 0x2068, 0x601c, 0xa086,
+	0x0003, 0x11b0, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c,
+	0x510c, 0x080c, 0x9742, 0x080c, 0x974e, 0x000e, 0x0898, 0x7e3a,
+	0x7e36, 0x012e, 0x00fe, 0x00de, 0x00ce, 0x006e, 0x000e, 0x0005,
+	0x601c, 0xa086, 0x0006, 0x1d30, 0x080c, 0xa91f, 0x0c60, 0x0016,
+	0x0026, 0x0086, 0x2041, 0x0000, 0x0099, 0x080c, 0x69a9, 0x008e,
+	0x002e, 0x001e, 0x0005, 0x00f6, 0x0126, 0x2079, 0xafc7, 0x2091,
+	0x8000, 0x080c, 0x6a36, 0x080c, 0x6aa8, 0x012e, 0x00fe, 0x0005,
+	0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0016, 0x0006, 0x0126,
+	0x2091, 0x8000, 0x2071, 0xafc7, 0x7614, 0x2660, 0x2678, 0x8cff,
+	0x0904, 0x6985, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x1904,
+	0x6980, 0x88ff, 0x0120, 0x6050, 0xa106, 0x1904, 0x6980, 0x7024,
+	0xac06, 0x1538, 0x2069, 0x0100, 0x68c0, 0xa005, 0x01f0, 0x080c,
+	0x6581, 0x080c, 0x7834, 0x68c3, 0x0000, 0x080c, 0x7ca8, 0x7027,
+	0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0120,
+	0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084,
+	0x0110, 0x6827, 0x0001, 0x003e, 0x0020, 0x6003, 0x0009, 0x630a,
+	0x04b8, 0x7014, 0xac36, 0x1110, 0x660c, 0x7616, 0x7010, 0xac36,
+	0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7012, 0x0010, 0x7013,
+	0x0000, 0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110, 0x7e0e, 0x0008,
+	0x2678, 0x600f, 0x0000, 0x6010, 0x2068, 0x080c, 0x9596, 0x0188,
+	0x601c, 0xa086, 0x0003, 0x1510, 0x6837, 0x0103, 0x6b4a, 0x6847,
+	0x0000, 0x080c, 0x97fd, 0x080c, 0xabfa, 0x080c, 0x510c, 0x080c,
+	0x9742, 0x080c, 0x974e, 0x080c, 0x7b88, 0x00ce, 0x0804, 0x690f,
+	0x2c78, 0x600c, 0x2060, 0x0804, 0x690f, 0x012e, 0x000e, 0x001e,
+	0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601c, 0xa086,
+	0x0006, 0x1128, 0x080c, 0xabfa, 0x080c, 0xa91f, 0x0c10, 0x601c,
+	0xa086, 0x0002, 0x1128, 0x6004, 0xa086, 0x0085, 0x0968, 0x08c8,
+	0x601c, 0xa086, 0x0005, 0x19a8, 0x6004, 0xa086, 0x0085, 0x0d50,
+	0x0880, 0x00c6, 0x0006, 0x0126, 0x2091, 0x8000, 0xa280, 0xae34,
+	0x2004, 0xa065, 0x0904, 0x6a32, 0x00f6, 0x00e6, 0x00d6, 0x0066,
+	0x2071, 0xafc7, 0x6654, 0x7018, 0xac06, 0x1108, 0x761a, 0x701c,
+	0xac06, 0x1130, 0x86ff, 0x1118, 0x7018, 0x701e, 0x0008, 0x761e,
+	0x6058, 0xa07d, 0x0108, 0x7e56, 0xa6ed, 0x0000, 0x0110, 0x2f00,
+	0x685a, 0x6057, 0x0000, 0x605b, 0x0000, 0x6000, 0xc0d4, 0xc0dc,
+	0x6002, 0x080c, 0x4c07, 0x0904, 0x6a2e, 0x7624, 0x86ff, 0x05e8,
+	0xa680, 0x0004, 0x2004, 0xad06, 0x15c0, 0x00d6, 0x2069, 0x0100,
+	0x68c0, 0xa005, 0x0548, 0x080c, 0x6581, 0x080c, 0x7834, 0x68c3,
+	0x0000, 0x080c, 0x7ca8, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140,
+	0x6b04, 0xa384, 0x1000, 0x0120, 0x6803, 0x0100, 0x6803, 0x0000,
+	0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e,
+	0x00de, 0x00c6, 0x603c, 0xa005, 0x0110, 0x8001, 0x603e, 0x2660,
+	0x080c, 0x974e, 0x00ce, 0x0048, 0x00de, 0x00c6, 0x2660, 0x6003,
+	0x0009, 0x630a, 0x00ce, 0x0804, 0x69d9, 0x8dff, 0x0158, 0x6837,
+	0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x97fd, 0x080c, 0xabfa,
+	0x080c, 0x510c, 0x080c, 0x7b88, 0x0804, 0x69d9, 0x006e, 0x00de,
+	0x00ee, 0x00fe, 0x012e, 0x000e, 0x00ce, 0x0005, 0x0006, 0x0066,
+	0x00c6, 0x00d6, 0x2031, 0x0000, 0x7814, 0xa065, 0x0904, 0x6a88,
+	0x600c, 0x0006, 0x600f, 0x0000, 0x7824, 0xac06, 0x1540, 0x2069,
+	0x0100, 0x68c0, 0xa005, 0x01f0, 0x080c, 0x6581, 0x080c, 0x7834,
+	0x68c3, 0x0000, 0x080c, 0x7ca8, 0x7827, 0x0000, 0x0036, 0x2069,
+	0x0140, 0x6b04, 0xa384, 0x1000, 0x0120, 0x6803, 0x0100, 0x6803,
+	0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001,
+	0x003e, 0x0028, 0x6003, 0x0009, 0x630a, 0x2c30, 0x00b0, 0x6010,
+	0x2068, 0x080c, 0x9596, 0x0168, 0x601c, 0xa086, 0x0003, 0x11b8,
+	0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x510c, 0x080c,
+	0x9742, 0x080c, 0x974e, 0x080c, 0x7b88, 0x000e, 0x0804, 0x6a3d,
+	0x7e16, 0x7e12, 0x00de, 0x00ce, 0x006e, 0x000e, 0x0005, 0x601c,
+	0xa086, 0x0006, 0x1118, 0x080c, 0xa91f, 0x0c58, 0x601c, 0xa086,
+	0x0002, 0x1128, 0x6004, 0xa086, 0x0085, 0x09d0, 0x0c10, 0x601c,
+	0xa086, 0x0005, 0x19f0, 0x6004, 0xa086, 0x0085, 0x0d60, 0x08c8,
+	0x0006, 0x0066, 0x00c6, 0x00d6, 0x7818, 0xa065, 0x0904, 0x6b0e,
+	0x6054, 0x0006, 0x6057, 0x0000, 0x605b, 0x0000, 0x6000, 0xc0d4,
+	0xc0dc, 0x6002, 0x080c, 0x4c07, 0x0904, 0x6b0b, 0x7e24, 0x86ff,
+	0x05e8, 0xa680, 0x0004, 0x2004, 0xad06, 0x15c0, 0x00d6, 0x2069,
+	0x0100, 0x68c0, 0xa005, 0x0548, 0x080c, 0x6581, 0x080c, 0x7834,
+	0x68c3, 0x0000, 0x080c, 0x7ca8, 0x7827, 0x0000, 0x0036, 0x2069,
+	0x0140, 0x6b04, 0xa384, 0x1000, 0x0120, 0x6803, 0x0100, 0x6803,
+	0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001,
+	0x003e, 0x00de, 0x00c6, 0x603c, 0xa005, 0x0110, 0x8001, 0x603e,
+	0x2660, 0x080c, 0x974e, 0x00ce, 0x0048, 0x00de, 0x00c6, 0x2660,
+	0x6003, 0x0009, 0x630a, 0x00ce, 0x0804, 0x6aba, 0x8dff, 0x0138,
+	0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x510c, 0x080c,
+	0x7b88, 0x0804, 0x6aba, 0x000e, 0x0804, 0x6aad, 0x781e, 0x781a,
+	0x00de, 0x00ce, 0x006e, 0x000e, 0x0005, 0x00e6, 0x00d6, 0x0066,
+	0x6000, 0xd0dc, 0x0188, 0x604c, 0xa06d, 0x0170, 0x6848, 0xa606,
+	0x1158, 0x2071, 0xafc7, 0x7024, 0xa035, 0x0130, 0xa080, 0x0004,
+	0x2004, 0xad06, 0x1108, 0x0021, 0x006e, 0x00de, 0x00ee, 0x0005,
+	0x00f6, 0x2079, 0x0100, 0x78c0, 0xa005, 0x1138, 0x00c6, 0x2660,
+	0x6003, 0x0009, 0x630a, 0x00ce, 0x04a0, 0x080c, 0x7834, 0x78c3,
+	0x0000, 0x080c, 0x7ca8, 0x7027, 0x0000, 0x0036, 0x2079, 0x0140,
+	0x7b04, 0xa384, 0x1000, 0x0120, 0x7803, 0x0100, 0x7803, 0x0000,
+	0x2079, 0x0100, 0x7824, 0xd084, 0x0110, 0x7827, 0x0001, 0x080c,
+	0x7ca8, 0x003e, 0x080c, 0x4c07, 0x00c6, 0x603c, 0xa005, 0x0110,
+	0x8001, 0x603e, 0x2660, 0x080c, 0x8078, 0x00ce, 0x6837, 0x0103,
+	0x6b4a, 0x6847, 0x0000, 0x080c, 0x97fd, 0x080c, 0x510c, 0x080c,
+	0x7b88, 0x00fe, 0x0005, 0x00e6, 0x00c6, 0x2071, 0xafc7, 0x7004,
+	0xa084, 0x0007, 0x0002, 0x6b85, 0x6b88, 0x6b9e, 0x6bb7, 0x6bf0,
+	0x6b85, 0x6b83, 0x6b83, 0x080c, 0x14f6, 0x00ce, 0x00ee, 0x0005,
+	0x7024, 0xa065, 0x0148, 0x7020, 0x8001, 0x7022, 0x600c, 0xa015,
+	0x0150, 0x7216, 0x600f, 0x0000, 0x7007, 0x0000, 0x7027, 0x0000,
+	0x00ce, 0x00ee, 0x0005, 0x7216, 0x7212, 0x0cb0, 0x6018, 0x2060,
+	0x080c, 0x4c07, 0x6000, 0xc0dc, 0x6002, 0x7020, 0x8001, 0x7022,
+	0x0120, 0x6054, 0xa015, 0x0140, 0x721e, 0x7007, 0x0000, 0x7027,
+	0x0000, 0x00ce, 0x00ee, 0x0005, 0x7218, 0x721e, 0x0cb0, 0x7024,
+	0xa065, 0x0598, 0x700c, 0xac06, 0x1160, 0x080c, 0x7b88, 0x600c,
+	0xa015, 0x0120, 0x720e, 0x600f, 0x0000, 0x0428, 0x720e, 0x720a,
+	0x0410, 0x7014, 0xac06, 0x1160, 0x080c, 0x7b88, 0x600c, 0xa015,
+	0x0120, 0x7216, 0x600f, 0x0000, 0x00b0, 0x7216, 0x7212, 0x0098,
+	0x6018, 0x2060, 0x080c, 0x4c07, 0x6000, 0xc0dc, 0x6002, 0x080c,
+	0x7b88, 0x701c, 0xa065, 0x0138, 0x6054, 0xa015, 0x0110, 0x721e,
+	0x0010, 0x7218, 0x721e, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x0005,
+	0x7024, 0xa065, 0x0140, 0x080c, 0x7b88, 0x600c, 0xa015, 0x0150,
+	0x720e, 0x600f, 0x0000, 0x080c, 0x7ca8, 0x7027, 0x0000, 0x00ce,
+	0x00ee, 0x0005, 0x720e, 0x720a, 0x0cb0, 0x00d6, 0x2069, 0xafc7,
+	0x6830, 0xa084, 0x0003, 0x0002, 0x6c12, 0x6c14, 0x6c38, 0x6c10,
+	0x080c, 0x14f6, 0x00de, 0x0005, 0x00c6, 0x6840, 0xa086, 0x0001,
+	0x01b8, 0x683c, 0xa065, 0x0130, 0x600c, 0xa015, 0x0170, 0x6a3a,
+	0x600f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000, 0x2011, 0xafe6,
+	0x2013, 0x0000, 0x00ce, 0x00de, 0x0005, 0x683a, 0x6836, 0x0c90,
+	0x6843, 0x0000, 0x6838, 0xa065, 0x0d68, 0x6003, 0x0003, 0x0c50,
+	0x00c6, 0x6843, 0x0000, 0x6847, 0x0000, 0x683c, 0xa065, 0x0168,
+	0x600c, 0xa015, 0x0130, 0x6a3a, 0x600f, 0x0000, 0x683f, 0x0000,
+	0x0020, 0x683f, 0x0000, 0x683a, 0x6836, 0x00ce, 0x00de, 0x0005,
+	0x00d6, 0x2069, 0xafc7, 0x6804, 0xa084, 0x0007, 0x0002, 0x6c61,
+	0x6cfd, 0x6cfd, 0x6cfd, 0x6cfd, 0x6cff, 0x6c5f, 0x6c5f, 0x080c,
+	0x14f6, 0x6820, 0xa005, 0x1110, 0x00de, 0x0005, 0x00c6, 0x680c,
+	0xa065, 0x0150, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, 0x080c,
+	0x6d49, 0x00ce, 0x00de, 0x0005, 0x6814, 0xa065, 0x0150, 0x6807,
+	0x0001, 0x6826, 0x682b, 0x0000, 0x080c, 0x6d49, 0x00ce, 0x00de,
+	0x0005, 0x00e6, 0x0036, 0x6a1c, 0xa2f5, 0x0000, 0x0904, 0x6cf9,
+	0x704c, 0xa00d, 0x0118, 0x7088, 0xa005, 0x01a0, 0x7054, 0xa075,
+	0x0120, 0xa20e, 0x0904, 0x6cf9, 0x0028, 0x6818, 0xa20e, 0x0904,
+	0x6cf9, 0x2070, 0x704c, 0xa00d, 0x0d88, 0x7088, 0xa005, 0x1d70,
+	0x2e00, 0x681e, 0x733c, 0x7038, 0xa302, 0x1e40, 0x080c, 0x804f,
+	0x0904, 0x6cf9, 0x8318, 0x733e, 0x6112, 0x2e10, 0x621a, 0xa180,
+	0x0014, 0x2004, 0xa084, 0x00ff, 0x605a, 0xa180, 0x0014, 0x2003,
+	0x0000, 0xa180, 0x0015, 0x2004, 0xa08a, 0x199a, 0x0210, 0x2001,
+	0x1999, 0x8003, 0x801b, 0x831b, 0xa318, 0x6316, 0x003e, 0x00f6,
+	0x2c78, 0x71a0, 0x2001, 0xad34, 0x2004, 0xd0ac, 0x1110, 0xd1bc,
+	0x0150, 0x7100, 0xd1f4, 0x0120, 0x7114, 0xa18c, 0x00ff, 0x0040,
+	0x2009, 0x0000, 0x0028, 0xa1e0, 0x2be6, 0x2c0d, 0xa18c, 0x00ff,
+	0x2061, 0x0100, 0x619a, 0x080c, 0x736f, 0x7300, 0xc3dd, 0x7302,
+	0x6807, 0x0002, 0x2f18, 0x6b26, 0x682b, 0x0000, 0x781f, 0x0003,
+	0x7803, 0x0001, 0x7807, 0x0040, 0x00fe, 0x00ee, 0x00ce, 0x00de,
+	0x0005, 0x003e, 0x00ee, 0x00ce, 0x0cd0, 0x00de, 0x0005, 0x00c6,
+	0x680c, 0xa065, 0x0138, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000,
+	0x080c, 0x6d49, 0x00ce, 0x00de, 0x0005, 0x00f6, 0x00d6, 0x2069,
+	0xafc7, 0x6830, 0xa086, 0x0000, 0x11c0, 0x2001, 0xad0c, 0x200c,
+	0xd1bc, 0x1550, 0x6838, 0xa07d, 0x0180, 0x6833, 0x0001, 0x683e,
+	0x6847, 0x0000, 0x0126, 0x00f6, 0x2091, 0x2400, 0x002e, 0x080c,
+	0x1ee6, 0x1130, 0x012e, 0x080c, 0x76a5, 0x00de, 0x00fe, 0x0005,
+	0x012e, 0xe000, 0x6843, 0x0000, 0x7803, 0x0002, 0x780c, 0xa015,
+	0x0140, 0x6a3a, 0x780f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000,
+	0x0c60, 0x683a, 0x6836, 0x0cc0, 0xc1bc, 0x2102, 0x080c, 0x57d1,
+	0x0888, 0x601c, 0xa084, 0x000f, 0x000b, 0x0005, 0x6d57, 0x6d5c,
+	0x7210, 0x732c, 0x6d5c, 0x7210, 0x732c, 0x6d57, 0x6d5c, 0x080c,
+	0x6b73, 0x080c, 0x6c50, 0x0005, 0x0156, 0x0136, 0x0146, 0x00c6,
+	0x00f6, 0x6004, 0xa08a, 0x0080, 0x1a0c, 0x14f6, 0x6118, 0x2178,
+	0x79a0, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1110, 0xd1bc, 0x0150,
+	0x7900, 0xd1f4, 0x0120, 0x7914, 0xa18c, 0x00ff, 0x0040, 0x2009,
+	0x0000, 0x0028, 0xa1f8, 0x2be6, 0x2f0d, 0xa18c, 0x00ff, 0x2c78,
+	0x2061, 0x0100, 0x619a, 0xa08a, 0x0040, 0x1a04, 0x6dd0, 0x0033,
+	0x00fe, 0x00ce, 0x014e, 0x013e, 0x015e, 0x0005, 0x6e7c, 0x6ec7,
+	0x6ef4, 0x6fc1, 0x6fef, 0x6ff7, 0x701d, 0x702e, 0x703f, 0x7047,
+	0x705d, 0x7047, 0x70b7, 0x702e, 0x70d8, 0x70e0, 0x703f, 0x70e0,
+	0x70f1, 0x6dce, 0x6dce, 0x6dce, 0x6dce, 0x6dce, 0x6dce, 0x6dce,
+	0x6dce, 0x6dce, 0x6dce, 0x6dce, 0x790d, 0x7932, 0x7947, 0x796a,
+	0x798b, 0x701d, 0x6dce, 0x701d, 0x7047, 0x6dce, 0x6ef4, 0x6fc1,
+	0x6dce, 0x7daa, 0x7047, 0x6dce, 0x7dca, 0x7047, 0x6dce, 0x703f,
+	0x6e75, 0x6de0, 0x6dce, 0x7def, 0x7e64, 0x7f3b, 0x6dce, 0x7f4c,
+	0x7018, 0x7f68, 0x6dce, 0x79a0, 0x7fc3, 0x6dce, 0x080c, 0x14f6,
+	0x2100, 0x0033, 0x00fe, 0x00ce, 0x014e, 0x013e, 0x015e, 0x0005,
+	0x6dde, 0x6dde, 0x6dde, 0x6e14, 0x6e32, 0x6e48, 0x080c, 0x14f6,
+	0x00d6, 0x20a1, 0x020b, 0x080c, 0x710e, 0x7810, 0x2068, 0x20a3,
+	0x2414, 0x20a3, 0x0018, 0x20a3, 0x0800, 0x683c, 0x20a2, 0x20a3,
+	0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x6850,
+	0x20a2, 0x6854, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3,
+	0x0018, 0x080c, 0x7821, 0x00de, 0x0005, 0x00d6, 0x7818, 0x2068,
+	0x68a0, 0x2069, 0xad00, 0x6ad0, 0xd2ac, 0x1110, 0xd0bc, 0x0110,
+	0xa085, 0x0001, 0x00de, 0x0005, 0x00d6, 0x20a1, 0x020b, 0x080c,
+	0x710e, 0x20a3, 0x0500, 0x20a3, 0x0000, 0x7810, 0xa0e8, 0x000f,
+	0x6808, 0x20a2, 0x680c, 0x20a2, 0x6810, 0x20a2, 0x6814, 0x20a2,
+	0x6818, 0x20a2, 0x681c, 0x20a2, 0x60c3, 0x0010, 0x080c, 0x7821,
+	0x00de, 0x0005, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x710e,
+	0x20a3, 0x7800, 0x20a3, 0x0000, 0x7808, 0x8007, 0x20a2, 0x20a3,
+	0x0000, 0x60c3, 0x0008, 0x080c, 0x7821, 0x014e, 0x015e, 0x0005,
+	0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x71aa, 0x20a3, 0x0200,
+	0x20a3, 0x0000, 0x20a3, 0xdf10, 0x20a3, 0x0034, 0x2099, 0xad05,
+	0x20a9, 0x0004, 0x53a6, 0x2099, 0xad01, 0x20a9, 0x0004, 0x53a6,
+	0x2099, 0xafad, 0x20a9, 0x001a, 0x3304, 0x8007, 0x20a2, 0x9398,
+	0x1f04, 0x6e64, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x004c,
+	0x080c, 0x7821, 0x014e, 0x015e, 0x0005, 0x2001, 0xad14, 0x2004,
+	0x609a, 0x080c, 0x7821, 0x0005, 0x20a1, 0x020b, 0x080c, 0x710e,
+	0x20a3, 0x5200, 0x20a3, 0x0000, 0x00d6, 0x2069, 0xad51, 0x6804,
+	0xd084, 0x0150, 0x6828, 0x20a3, 0x0000, 0x0016, 0x080c, 0x268a,
+	0x21a2, 0x001e, 0x00de, 0x0028, 0x00de, 0x20a3, 0x0000, 0x20a3,
+	0x0000, 0x20a9, 0x0004, 0x2099, 0xad05, 0x53a6, 0x20a9, 0x0004,
+	0x2099, 0xad01, 0x53a6, 0x2001, 0xad34, 0x2004, 0xd0ac, 0x1138,
+	0x7818, 0xa080, 0x0028, 0x2004, 0xa082, 0x007f, 0x0238, 0x2001,
+	0xad1b, 0x20a6, 0x2001, 0xad1c, 0x20a6, 0x0040, 0x20a3, 0x0000,
+	0x2001, 0xad14, 0x2004, 0xa084, 0x00ff, 0x20a2, 0x20a3, 0x0000,
+	0x20a3, 0x0000, 0x60c3, 0x001c, 0x080c, 0x7821, 0x0005, 0x20a1,
+	0x020b, 0x080c, 0x710e, 0x20a3, 0x0500, 0x20a3, 0x0000, 0x2001,
+	0xad34, 0x2004, 0xd0ac, 0x1138, 0x7818, 0xa080, 0x0028, 0x2004,
+	0xa082, 0x007f, 0x0238, 0x2001, 0xad1b, 0x20a6, 0x2001, 0xad1c,
+	0x20a6, 0x0040, 0x20a3, 0x0000, 0x2001, 0xad14, 0x2004, 0xa084,
+	0x00ff, 0x20a2, 0x20a9, 0x0004, 0x2099, 0xad05, 0x53a6, 0x60c3,
+	0x0010, 0x080c, 0x7821, 0x0005, 0x20a1, 0x020b, 0x080c, 0x710e,
+	0x00c6, 0x7818, 0x2060, 0x2001, 0x0000, 0x080c, 0x5037, 0x00ce,
+	0x7818, 0xa080, 0x0028, 0x2004, 0xa086, 0x007e, 0x1130, 0x20a3,
+	0x0400, 0x620c, 0xc2b4, 0x620e, 0x0010, 0x20a3, 0x0300, 0x20a3,
+	0x0000, 0x7818, 0xa080, 0x0028, 0x2004, 0xa086, 0x007e, 0x1904,
+	0x6f83, 0x2001, 0xad34, 0x2004, 0xd0a4, 0x01c8, 0x2099, 0xaf8d,
+	0x33a6, 0x9398, 0x20a3, 0x0000, 0x9398, 0x3304, 0xa084, 0x2000,
+	0x20a2, 0x9398, 0x33a6, 0x9398, 0x20a3, 0x0000, 0x9398, 0x2001,
+	0x2710, 0x20a2, 0x9398, 0x33a6, 0x9398, 0x33a6, 0x00d0, 0x2099,
+	0xaf8d, 0x33a6, 0x9398, 0x33a6, 0x9398, 0x3304, 0x080c, 0x574f,
+	0x1118, 0xa084, 0x37ff, 0x0010, 0xa084, 0x3fff, 0x20a2, 0x9398,
+	0x33a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+	0x0000, 0x20a9, 0x0004, 0x2099, 0xad05, 0x53a6, 0x20a9, 0x0004,
+	0x2099, 0xad01, 0x53a6, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x1f04,
+	0x6f5d, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x1f04, 0x6f63, 0x2099,
+	0xaf95, 0x3304, 0xc0dd, 0x20a2, 0x2001, 0xad71, 0x2004, 0xd0e4,
+	0x0158, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x9398, 0x9398, 0x9398,
+	0x33a6, 0x20a9, 0x0004, 0x0010, 0x20a9, 0x0007, 0x20a3, 0x0000,
+	0x1f04, 0x6f7e, 0x0468, 0x2001, 0xad34, 0x2004, 0xd0a4, 0x0140,
+	0x2001, 0xaf8e, 0x2004, 0x60e3, 0x0000, 0x080c, 0x26cb, 0x60e2,
+	0x2099, 0xaf8d, 0x20a9, 0x0008, 0x53a6, 0x20a9, 0x0004, 0x2099,
+	0xad05, 0x53a6, 0x20a9, 0x0004, 0x2099, 0xad01, 0x53a6, 0x20a9,
+	0x0008, 0x20a3, 0x0000, 0x1f04, 0x6fa1, 0x20a9, 0x0008, 0x20a3,
+	0x0000, 0x1f04, 0x6fa7, 0x2099, 0xaf95, 0x20a9, 0x0008, 0x53a6,
+	0x20a9, 0x0008, 0x20a3, 0x0000, 0x1f04, 0x6fb2, 0x20a9, 0x000a,
+	0x20a3, 0x0000, 0x1f04, 0x6fb8, 0x60c3, 0x0074, 0x080c, 0x7821,
+	0x0005, 0x20a1, 0x020b, 0x080c, 0x710e, 0x20a3, 0x2010, 0x20a3,
+	0x0014, 0x20a3, 0x0800, 0x20a3, 0x2000, 0xa006, 0x20a2, 0x20a2,
+	0x20a2, 0x20a2, 0x20a2, 0x00f6, 0x2079, 0xad51, 0x7904, 0x00fe,
+	0xd1ac, 0x1110, 0xa085, 0x0020, 0xd1a4, 0x0110, 0xa085, 0x0010,
+	0xa085, 0x0002, 0x00d6, 0x0804, 0x7099, 0x20a2, 0x20a3, 0x0000,
+	0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, 0x7821, 0x0005, 0x20a1,
+	0x020b, 0x080c, 0x710e, 0x20a3, 0x5000, 0x0804, 0x6f0f, 0x20a1,
+	0x020b, 0x080c, 0x710e, 0x20a3, 0x2110, 0x20a3, 0x0014, 0x20a3,
+	0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+	0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+	0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, 0x7821, 0x0005,
+	0x20a1, 0x020b, 0x080c, 0x71a2, 0x0020, 0x20a1, 0x020b, 0x080c,
+	0x71aa, 0x20a3, 0x0200, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+	0x0000, 0x60c3, 0x0004, 0x080c, 0x7821, 0x0005, 0x20a1, 0x020b,
+	0x080c, 0x71aa, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x0003,
+	0x20a3, 0x2a00, 0x60c3, 0x0008, 0x080c, 0x7821, 0x0005, 0x20a1,
+	0x020b, 0x080c, 0x71aa, 0x20a3, 0x0200, 0x0804, 0x6f0f, 0x20a1,
+	0x020b, 0x080c, 0x71aa, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x7828,
+	0xa005, 0x0110, 0x20a2, 0x0010, 0x20a3, 0x0003, 0x7810, 0x20a2,
+	0x60c3, 0x0008, 0x080c, 0x7821, 0x0005, 0x00d6, 0x20a1, 0x020b,
+	0x080c, 0x71aa, 0x20a3, 0x0210, 0x20a3, 0x0014, 0x20a3, 0x0800,
+	0x7818, 0x2068, 0x6894, 0xa086, 0x0014, 0x1178, 0x6998, 0xa184,
+	0xc000, 0x1140, 0xd1ec, 0x0118, 0x20a3, 0x2100, 0x0040, 0x20a3,
+	0x0100, 0x0028, 0x20a3, 0x0400, 0x0010, 0x20a3, 0x0700, 0xa006,
+	0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x00f6, 0x2079, 0xad51,
+	0x7904, 0x00fe, 0xd1ac, 0x1110, 0xa085, 0x0020, 0xd1a4, 0x0110,
+	0xa085, 0x0010, 0x2009, 0xad73, 0x210c, 0xd184, 0x1110, 0xa085,
+	0x0002, 0x0026, 0x2009, 0xad71, 0x210c, 0xd1e4, 0x0130, 0xc0c5,
+	0xa094, 0x0030, 0xa296, 0x0010, 0x0140, 0xd1ec, 0x0130, 0xa094,
+	0x0030, 0xa296, 0x0010, 0x0108, 0xc0bd, 0x002e, 0x20a2, 0x20a2,
+	0x20a2, 0x60c3, 0x0014, 0x080c, 0x7821, 0x00de, 0x0005, 0x20a1,
+	0x020b, 0x080c, 0x71aa, 0x20a3, 0x0210, 0x20a3, 0x0014, 0x20a3,
+	0x0000, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+	0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+	0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, 0x7821, 0x0005,
+	0x20a1, 0x020b, 0x080c, 0x71aa, 0x20a3, 0x0200, 0x0804, 0x6e82,
+	0x20a1, 0x020b, 0x080c, 0x71aa, 0x20a3, 0x0100, 0x20a3, 0x0000,
+	0x20a3, 0x0003, 0x20a3, 0x2a00, 0x60c3, 0x0008, 0x080c, 0x7821,
+	0x0005, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a1, 0x020b, 0x080c,
+	0x71aa, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x000b, 0x20a3,
+	0x0000, 0x60c3, 0x0008, 0x080c, 0x7821, 0x0005, 0x0026, 0x0036,
+	0x0046, 0x2019, 0x3200, 0x2021, 0x0800, 0x0038, 0x0026, 0x0036,
+	0x0046, 0x2019, 0x2200, 0x2021, 0x0100, 0x20e1, 0x9080, 0x20e1,
+	0x4000, 0x7818, 0xa080, 0x0028, 0x2014, 0xa286, 0x007e, 0x11a0,
+	0xa385, 0x00ff, 0x20a2, 0x20a3, 0xfffe, 0x20a3, 0x0000, 0x2011,
+	0xad14, 0x2214, 0x2001, 0xaf9d, 0x2004, 0xa005, 0x0118, 0x2011,
+	0xad1c, 0x2214, 0x22a2, 0x04d0, 0xa286, 0x007f, 0x1138, 0x00d6,
+	0xa385, 0x00ff, 0x20a2, 0x20a3, 0xfffd, 0x00c8, 0x2001, 0xad34,
+	0x2004, 0xd0ac, 0x1110, 0xd2bc, 0x01c8, 0xa286, 0x0080, 0x00d6,
+	0x1130, 0xa385, 0x00ff, 0x20a2, 0x20a3, 0xfffc, 0x0040, 0xa2e8,
+	0xae34, 0x2d6c, 0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x2069,
+	0xad1b, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0080, 0x00d6, 0xa2e8,
+	0xae34, 0x2d6c, 0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x00de,
+	0x20a3, 0x0000, 0x2011, 0xad14, 0x2214, 0x22a2, 0xa485, 0x0029,
+	0x20a2, 0x004e, 0x003e, 0x20a3, 0x0000, 0x080c, 0x7810, 0x22a2,
+	0x20a3, 0x0000, 0x2fa2, 0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3,
+	0x0000, 0x002e, 0x0005, 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000,
+	0x20a3, 0x02ff, 0x2011, 0xfffc, 0x22a2, 0x00d6, 0x2069, 0xad1b,
+	0x2da6, 0x8d68, 0x2da6, 0x00de, 0x20a3, 0x2029, 0x20a3, 0x0000,
+	0x08e0, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0xfc02, 0x20a3,
+	0x0000, 0x0005, 0x0026, 0x0036, 0x0046, 0x2019, 0x3300, 0x2021,
+	0x0800, 0x0038, 0x0026, 0x0036, 0x0046, 0x2019, 0x2300, 0x2021,
+	0x0100, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028,
+	0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1118, 0xa092, 0x007e,
+	0x02d8, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa305, 0x20a2,
+	0x6814, 0x20a2, 0x6810, 0xa005, 0x1140, 0x6814, 0xa005, 0x1128,
+	0x20a3, 0x00ff, 0x20a3, 0xfffe, 0x0028, 0x2069, 0xad1b, 0x2da6,
+	0x8d68, 0x2da6, 0x00de, 0x0080, 0x00d6, 0xa0e8, 0xae34, 0x2d6c,
+	0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000,
+	0x2011, 0xad14, 0x2214, 0x22a2, 0xa485, 0x0098, 0x20a2, 0x20a3,
+	0x0000, 0x004e, 0x003e, 0x080c, 0x7810, 0x22a2, 0x20a3, 0x0000,
+	0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x002e,
+	0x0005, 0x080c, 0x7810, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2,
+	0x7810, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x002e, 0x0005,
+	0x00c6, 0x00f6, 0x6004, 0xa08a, 0x0085, 0x0a0c, 0x14f6, 0xa08a,
+	0x008c, 0x1a0c, 0x14f6, 0x6118, 0x2178, 0x79a0, 0x2011, 0xad34,
+	0x2214, 0xd2ac, 0x1110, 0xd1bc, 0x0150, 0x7900, 0xd1f4, 0x0120,
+	0x7914, 0xa18c, 0x00ff, 0x0040, 0x2009, 0x0000, 0x0028, 0xa1f8,
+	0x2be6, 0x2f0d, 0xa18c, 0x00ff, 0x2c78, 0x2061, 0x0100, 0x619a,
+	0xa082, 0x0085, 0x001b, 0x00fe, 0x00ce, 0x0005, 0x7247, 0x7251,
+	0x726c, 0x7245, 0x7245, 0x7245, 0x7247, 0x080c, 0x14f6, 0x0146,
+	0x20a1, 0x020b, 0x04a1, 0x60c3, 0x0000, 0x080c, 0x7821, 0x014e,
+	0x0005, 0x0146, 0x20a1, 0x020b, 0x080c, 0x72b8, 0x20a3, 0x0000,
+	0x20a3, 0x0000, 0x7808, 0x20a2, 0x7810, 0x20a2, 0x20a3, 0x0000,
+	0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x000c,
+	0x080c, 0x7821, 0x014e, 0x0005, 0x0146, 0x20a1, 0x020b, 0x080c,
+	0x72f2, 0x20a3, 0x0003, 0x20a3, 0x0300, 0x20a3, 0x0000, 0x20a3,
+	0x0000, 0x60c3, 0x0004, 0x080c, 0x7821, 0x014e, 0x0005, 0x0026,
+	0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004,
+	0x2011, 0xad34, 0x2214, 0xd2ac, 0x1118, 0xa092, 0x007e, 0x0288,
+	0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x8100, 0x20a2,
+	0x6814, 0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6, 0x00de,
+	0x0088, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x8100,
+	0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xad14,
+	0x2214, 0x22a2, 0x20a3, 0x0009, 0x20a3, 0x0000, 0x0804, 0x7175,
+	0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028,
+	0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1118, 0xa092, 0x007e,
+	0x0288, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x8400,
+	0x20a2, 0x6814, 0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6,
+	0x00de, 0x0088, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085,
+	0x8400, 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011,
+	0xad14, 0x2214, 0x22a2, 0x2001, 0x0099, 0x20a2, 0x20a3, 0x0000,
+	0x0804, 0x7201, 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818,
+	0xa080, 0x0028, 0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1118,
+	0xa092, 0x007e, 0x0288, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810,
+	0xa085, 0x8500, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xad1b, 0x2da6,
+	0x8d68, 0x2da6, 0x00de, 0x0088, 0x00d6, 0xa0e8, 0xae34, 0x2d6c,
+	0x6810, 0xa085, 0x8500, 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3,
+	0x0000, 0x2011, 0xad14, 0x2214, 0x22a2, 0x2001, 0x0099, 0x20a2,
+	0x20a3, 0x0000, 0x0804, 0x7201, 0x00c6, 0x00f6, 0x2c78, 0x7804,
+	0xa08a, 0x0040, 0x0a0c, 0x14f6, 0xa08a, 0x0053, 0x1a0c, 0x14f6,
+	0x7918, 0x2160, 0x61a0, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1110,
+	0xd1bc, 0x0150, 0x6100, 0xd1f4, 0x0120, 0x6114, 0xa18c, 0x00ff,
+	0x0040, 0x2009, 0x0000, 0x0028, 0xa1e0, 0x2be6, 0x2c0d, 0xa18c,
+	0x00ff, 0x2061, 0x0100, 0x619a, 0xa082, 0x0040, 0x001b, 0x00fe,
+	0x00ce, 0x0005, 0x736f, 0x747b, 0x7418, 0x761a, 0x736d, 0x736d,
+	0x736d, 0x736d, 0x736d, 0x736d, 0x736d, 0x7b41, 0x7b51, 0x7b61,
+	0x7b71, 0x736d, 0x7f79, 0x736d, 0x7b30, 0x080c, 0x14f6, 0x00d6,
+	0x0156, 0x0146, 0x780b, 0xffff, 0x20a1, 0x020b, 0x080c, 0x73cf,
+	0x7910, 0x2168, 0x6948, 0x7952, 0x21a2, 0xa016, 0x22a2, 0x22a2,
+	0x22a2, 0x694c, 0xa184, 0x000f, 0x1118, 0x2001, 0x0005, 0x0040,
+	0xd184, 0x0118, 0x2001, 0x0004, 0x0018, 0xa084, 0x0006, 0x8004,
+	0x0016, 0x2008, 0x7858, 0xa084, 0x00ff, 0x8007, 0xa105, 0x001e,
+	0x20a2, 0xd1ac, 0x0118, 0x20a3, 0x0002, 0x0048, 0xd1b4, 0x0118,
+	0x20a3, 0x0001, 0x0020, 0x20a3, 0x0000, 0x2230, 0x0010, 0x6a80,
+	0x6e7c, 0x20a9, 0x0008, 0x0136, 0xad88, 0x0017, 0x2198, 0x20a1,
+	0x021b, 0x53a6, 0x013e, 0x20a1, 0x020b, 0x22a2, 0x26a2, 0x60c3,
+	0x0020, 0x20e1, 0x9080, 0x6014, 0xa084, 0x0004, 0xa085, 0x0009,
+	0x6016, 0x2001, 0xafe3, 0x2003, 0x07d0, 0x2001, 0xafe2, 0x2003,
+	0x0009, 0x080c, 0x17bf, 0x014e, 0x015e, 0x00de, 0x0005, 0x20e1,
+	0x9080, 0x20e1, 0x4000, 0x7a18, 0xa280, 0x0023, 0x2014, 0x8210,
+	0xa294, 0x00ff, 0x2202, 0x8217, 0x7818, 0xa080, 0x0028, 0x2004,
+	0x2019, 0xad34, 0x231c, 0xd3ac, 0x1110, 0xd0bc, 0x0188, 0x00d6,
+	0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0600, 0x20a2, 0x6814,
+	0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088,
+	0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0600, 0x20a2,
+	0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2009, 0xad14, 0x210c,
+	0x21a2, 0x20a3, 0x0829, 0x20a3, 0x0000, 0x22a2, 0x20a3, 0x0000,
+	0x2fa2, 0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x0005,
+	0x00d6, 0x0156, 0x0136, 0x0146, 0x20a1, 0x020b, 0x00c1, 0x7810,
+	0x2068, 0x6860, 0x20a2, 0x685c, 0x20a2, 0x6880, 0x20a2, 0x687c,
+	0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x60c3, 0x000c,
+	0x080c, 0x7821, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005, 0x0026,
+	0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004,
+	0x2011, 0xad34, 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188, 0x00d6,
+	0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0500, 0x20a2, 0x6814,
+	0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088,
+	0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0500, 0x20a2,
+	0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xad14, 0x2214,
+	0x22a2, 0x20a3, 0x0889, 0x20a3, 0x0000, 0x080c, 0x7810, 0x22a2,
+	0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3,
+	0x0000, 0x002e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x7810,
+	0xa06d, 0x080c, 0x5025, 0x0148, 0x684c, 0xa084, 0x2020, 0xa086,
+	0x2020, 0x1118, 0x7820, 0xc0cd, 0x7822, 0x20a1, 0x020b, 0x080c,
+	0x75d0, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x7810,
+	0xa084, 0xf000, 0x1130, 0x7810, 0xa084, 0x0700, 0x8007, 0x0043,
+	0x0010, 0xa006, 0x002b, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005,
+	0x74b2, 0x7547, 0x7550, 0x7579, 0x758c, 0x75a7, 0x75b0, 0x74b0,
+	0x080c, 0x14f6, 0x0016, 0x0036, 0x694c, 0xa18c, 0x0003, 0x0118,
+	0xa186, 0x0003, 0x1170, 0x6b78, 0x7820, 0xd0cc, 0x0108, 0xc3e5,
+	0x23a2, 0x6868, 0x20a2, 0x6864, 0x20a2, 0x003e, 0x001e, 0x0804,
+	0x7583, 0xa186, 0x0001, 0x190c, 0x14f6, 0x6b78, 0x7820, 0xd0cc,
+	0x0108, 0xc3e5, 0x23a2, 0x6868, 0x20a2, 0x6864, 0x20a2, 0x22a2,
+	0x6874, 0x20a2, 0x22a2, 0x687c, 0x20a2, 0x2009, 0x0018, 0xa384,
+	0x0300, 0x0904, 0x7541, 0xd3c4, 0x0110, 0x687c, 0xa108, 0xd3cc,
+	0x0110, 0x6874, 0xa108, 0x0156, 0x20a9, 0x000d, 0xad80, 0x0020,
+	0x201c, 0x831f, 0x23a2, 0x8000, 0x1f04, 0x74f0, 0x015e, 0x22a2,
+	0x22a2, 0x22a2, 0xa184, 0x0003, 0x0904, 0x7541, 0x20a1, 0x020b,
+	0x20e1, 0x9080, 0x20e1, 0x4000, 0x0006, 0x7818, 0xa080, 0x0028,
+	0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188,
+	0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2,
+	0x6814, 0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6, 0x00de,
+	0x0088, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0700,
+	0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xad14,
+	0x2214, 0x22a2, 0x000e, 0x7b20, 0xd3cc, 0x0118, 0x20a3, 0x0889,
+	0x0010, 0x20a3, 0x0898, 0x20a2, 0x080c, 0x7810, 0x22a2, 0x20a3,
+	0x0000, 0x61c2, 0x003e, 0x001e, 0x080c, 0x7821, 0x0005, 0x2011,
+	0x0008, 0x7820, 0xd0cc, 0x0108, 0xc2e5, 0x22a2, 0xa016, 0x0488,
+	0x2011, 0x0302, 0x7820, 0xd0cc, 0x0108, 0xc2e5, 0x22a2, 0xa016,
+	0x22a2, 0x22a2, 0x22a2, 0x20a3, 0x0012, 0x22a2, 0x20a3, 0x0008,
+	0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x20a3, 0x7000, 0x20a3, 0x0500,
+	0x22a2, 0x20a3, 0x000a, 0x22a2, 0x22a2, 0x20a3, 0x2500, 0x22a2,
+	0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0032, 0x080c, 0x7821,
+	0x0005, 0x2011, 0x0028, 0x7820, 0xd0cc, 0x0108, 0xc2e5, 0x22a2,
+	0xa016, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3,
+	0x0018, 0x080c, 0x7821, 0x0005, 0x2011, 0x0100, 0x7820, 0xd0cc,
+	0x0108, 0xc2e5, 0x22a2, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x22a2,
+	0x22a2, 0x20a3, 0x0008, 0x22a2, 0x7854, 0xa084, 0x00ff, 0x20a2,
+	0x22a2, 0x22a2, 0x60c3, 0x0020, 0x080c, 0x7821, 0x0005, 0x2011,
+	0x0008, 0x7820, 0xd0cc, 0x0108, 0xc2e5, 0x22a2, 0xa016, 0x0888,
+	0x0036, 0x7b10, 0xa384, 0xff00, 0x7812, 0xa384, 0x00ff, 0x8001,
+	0x1138, 0x7820, 0xd0cc, 0x0108, 0xc2e5, 0x22a2, 0x003e, 0x0808,
+	0x0046, 0x2021, 0x0800, 0x0006, 0x7820, 0xd0cc, 0x000e, 0x0108,
+	0xc4e5, 0x24a2, 0x004e, 0x22a2, 0x20a2, 0x003e, 0x0804, 0x7583,
+	0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028,
+	0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188,
+	0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2,
+	0x6814, 0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6, 0x00de,
+	0x0088, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0700,
+	0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xad14,
+	0x2214, 0x22a2, 0x7820, 0xd0cc, 0x0118, 0x20a3, 0x0889, 0x0010,
+	0x20a3, 0x0898, 0x20a3, 0x0000, 0x080c, 0x7810, 0x22a2, 0x20a3,
+	0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000,
+	0x002e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x0016, 0x0036,
+	0x7810, 0xa084, 0x0700, 0x8007, 0x003b, 0x003e, 0x001e, 0x014e,
+	0x013e, 0x015e, 0x00de, 0x0005, 0x7634, 0x7634, 0x7636, 0x7634,
+	0x7634, 0x7634, 0x7658, 0x7634, 0x080c, 0x14f6, 0x7910, 0xa18c,
+	0xf8ff, 0xa18d, 0x0600, 0x7912, 0x20a1, 0x020b, 0x2009, 0x0003,
+	0x00f9, 0x00d6, 0x2069, 0xad51, 0x6804, 0xd0bc, 0x0130, 0x682c,
+	0xa084, 0x00ff, 0x8007, 0x20a2, 0x0010, 0x20a3, 0x3f00, 0x00de,
+	0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0001, 0x080c, 0x7821, 0x0005,
+	0x20a1, 0x020b, 0x2009, 0x0003, 0x0019, 0x20a3, 0x7f00, 0x0c80,
+	0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028,
+	0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188,
+	0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0100, 0x20a2,
+	0x6814, 0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6, 0x00de,
+	0x0088, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0100,
+	0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xad14,
+	0x2214, 0x22a2, 0x20a3, 0x0888, 0xa18d, 0x0008, 0x21a2, 0x080c,
+	0x7810, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3,
+	0x0000, 0x20a3, 0x0000, 0x002e, 0x0005, 0x00e6, 0x00d6, 0x00c6,
+	0x0056, 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0xad00, 0x7150,
+	0x7818, 0x2068, 0x68a0, 0x2028, 0x76d0, 0xd6ac, 0x1130, 0xd0bc,
+	0x1120, 0x6910, 0x6a14, 0x7450, 0x0020, 0x6910, 0x6a14, 0x736c,
+	0x7470, 0x781c, 0xa0be, 0x0006, 0x0904, 0x775b, 0xa0be, 0x000a,
+	0x15e8, 0xa185, 0x0200, 0x6062, 0x6266, 0x636a, 0x646e, 0x6073,
+	0x2029, 0x6077, 0x0000, 0x688c, 0x8000, 0xa084, 0x00ff, 0x688e,
+	0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6082, 0x7808, 0x6086,
+	0x7810, 0x2070, 0x7014, 0x608a, 0x7010, 0x608e, 0x700c, 0x60c6,
+	0x7008, 0x60ca, 0x686c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000,
+	0x609f, 0x0000, 0x080c, 0x8014, 0x2009, 0x07d0, 0x60c4, 0xa084,
+	0xfff0, 0xa005, 0x0110, 0x2009, 0x1b58, 0x080c, 0x6586, 0x003e,
+	0x004e, 0x005e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x70d0, 0xd0ac,
+	0x1110, 0xd5bc, 0x0138, 0xa185, 0x0100, 0x6062, 0x6266, 0x636a,
+	0x646e, 0x0038, 0xa185, 0x0100, 0x6062, 0x6266, 0x606b, 0x0000,
+	0x646e, 0x6073, 0x0809, 0x6077, 0x0008, 0x688c, 0x8000, 0xa084,
+	0x00ff, 0x688e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6082,
+	0x7808, 0x6086, 0x7810, 0x2070, 0x7014, 0x608a, 0x7010, 0x608e,
+	0x700c, 0x60c6, 0x7008, 0x60ca, 0x686c, 0x60ce, 0x60af, 0x95d5,
+	0x60d7, 0x0000, 0xa582, 0x0080, 0x0248, 0x6a00, 0xd2f4, 0x0120,
+	0x6a14, 0xa294, 0x00ff, 0x0010, 0x2011, 0x0000, 0x629e, 0x080c,
+	0x8014, 0x2009, 0x07d0, 0x60c4, 0xa084, 0xfff0, 0xa005, 0x0110,
+	0x2009, 0x1b58, 0x080c, 0x6586, 0x003e, 0x004e, 0x005e, 0x00ce,
+	0x00de, 0x00ee, 0x0005, 0x7810, 0x2070, 0x704c, 0xa084, 0x0003,
+	0xa086, 0x0002, 0x0904, 0x77b1, 0x2001, 0xad34, 0x2004, 0xd0ac,
+	0x1110, 0xd5bc, 0x0138, 0xa185, 0x0100, 0x6062, 0x6266, 0x636a,
+	0x646e, 0x0038, 0xa185, 0x0100, 0x6062, 0x6266, 0x606b, 0x0000,
+	0x646e, 0x6073, 0x0880, 0x6077, 0x0008, 0x688c, 0x8000, 0xa084,
+	0x00ff, 0x688e, 0x8007, 0x607a, 0x7834, 0x607e, 0x2f00, 0x6086,
+	0x7808, 0x6082, 0x7060, 0x608a, 0x705c, 0x608e, 0x7080, 0x60c6,
+	0x707c, 0x60ca, 0x707c, 0x792c, 0xa108, 0x792e, 0x7080, 0x7928,
+	0xa109, 0x792a, 0x686c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000,
+	0xa582, 0x0080, 0x0248, 0x6a00, 0xd2f4, 0x0120, 0x6a14, 0xa294,
+	0x00ff, 0x0010, 0x2011, 0x0000, 0x629e, 0x080c, 0x8011, 0x0804,
+	0x7749, 0x2001, 0xad34, 0x2004, 0xd0ac, 0x1110, 0xd5bc, 0x0138,
+	0xa185, 0x0700, 0x6062, 0x6266, 0x636a, 0x646e, 0x0038, 0xa185,
+	0x0700, 0x6062, 0x6266, 0x606b, 0x0000, 0x646e, 0x080c, 0x5025,
+	0x0180, 0x00d6, 0x7810, 0xa06d, 0x684c, 0x00de, 0xa084, 0x2020,
+	0xa086, 0x2020, 0x1130, 0x7820, 0xc0cd, 0x7822, 0x6073, 0x0889,
+	0x0010, 0x6073, 0x0898, 0x6077, 0x0000, 0x688c, 0x8000, 0xa084,
+	0x00ff, 0x688e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6086,
+	0x7808, 0x6082, 0x7014, 0x608a, 0x7010, 0x608e, 0x700c, 0x60c6,
+	0x7008, 0x60ca, 0x686c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000,
+	0xa582, 0x0080, 0x0248, 0x6a00, 0xd2f4, 0x0120, 0x6a14, 0xa294,
+	0x00ff, 0x0010, 0x2011, 0x0000, 0x629e, 0x7820, 0xd0cc, 0x0120,
+	0x080c, 0x8014, 0x0804, 0x7749, 0x080c, 0x8011, 0x0804, 0x7749,
+	0x7a18, 0xa280, 0x0023, 0x2014, 0x8210, 0xa294, 0x00ff, 0x2202,
+	0x8217, 0x0005, 0x00d6, 0x2069, 0xafc7, 0x6843, 0x0001, 0x00de,
+	0x0005, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x0019,
+	0x080c, 0x6578, 0x0005, 0x0006, 0x6014, 0xa084, 0x0004, 0xa085,
+	0x0009, 0x6016, 0x000e, 0x0005, 0x0006, 0x00c6, 0x2061, 0x0100,
+	0x6014, 0xa084, 0x0004, 0xa085, 0x0008, 0x6016, 0x00ce, 0x000e,
+	0x0005, 0x00c6, 0x00d6, 0x0016, 0x0026, 0x2061, 0x0100, 0x2069,
+	0x0140, 0x080c, 0x574f, 0x1178, 0x2001, 0xafe3, 0x2004, 0xa005,
+	0x1598, 0x080c, 0x57d1, 0x1118, 0x080c, 0x6578, 0x0468, 0x00c6,
+	0x2061, 0xafc7, 0x00d8, 0x6904, 0xa194, 0x4000, 0x0550, 0x08a1,
+	0x6803, 0x1000, 0x6803, 0x0000, 0x00c6, 0x2061, 0xafc7, 0x6128,
+	0xa192, 0x00c8, 0x1258, 0x8108, 0x612a, 0x6124, 0x00ce, 0x81ff,
+	0x0198, 0x080c, 0x6578, 0x080c, 0x782b, 0x0070, 0x6124, 0xa1e5,
+	0x0000, 0x0140, 0x080c, 0xaca2, 0x2009, 0x0014, 0x080c, 0x80a7,
+	0x080c, 0x6581, 0x00ce, 0x0000, 0x002e, 0x001e, 0x00de, 0x00ce,
+	0x0005, 0x2001, 0xafe3, 0x2004, 0xa005, 0x1db0, 0x00c6, 0x2061,
+	0xafc7, 0x6128, 0xa192, 0x0003, 0x1e08, 0x8108, 0x612a, 0x00ce,
+	0x080c, 0x6578, 0x080c, 0x485e, 0x0c38, 0x00c6, 0x00d6, 0x00e6,
+	0x0016, 0x0026, 0x080c, 0x658e, 0x2071, 0xafc7, 0x713c, 0x81ff,
+	0x0570, 0x2061, 0x0100, 0x2069, 0x0140, 0x080c, 0x574f, 0x1188,
+	0x0036, 0x2019, 0x0001, 0x080c, 0x7a64, 0x003e, 0x713c, 0x2160,
+	0x080c, 0xaca2, 0x2009, 0x004a, 0x080c, 0x80a7, 0x080c, 0x57d1,
+	0x00b0, 0x6904, 0xa194, 0x4000, 0x01c0, 0x6803, 0x1000, 0x6803,
+	0x0000, 0x0036, 0x2019, 0x0001, 0x080c, 0x7a64, 0x003e, 0x713c,
+	0x2160, 0x080c, 0xaca2, 0x2009, 0x004a, 0x080c, 0x80a7, 0x002e,
+	0x001e, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x0c58, 0x00e6, 0x00d6,
+	0x00c6, 0x0066, 0x0056, 0x0046, 0x0006, 0x0126, 0x2091, 0x8000,
+	0x6018, 0x2068, 0x6ca0, 0x2071, 0xafc7, 0x7018, 0x2068, 0x8dff,
+	0x0198, 0x68a0, 0xa406, 0x0118, 0x6854, 0x2068, 0x0cc0, 0x6010,
+	0x2060, 0x643c, 0x6540, 0x6e48, 0x2d60, 0x080c, 0x4e41, 0x0120,
+	0x080c, 0x7b88, 0xa085, 0x0001, 0x012e, 0x000e, 0x004e, 0x005e,
+	0x006e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x20a1, 0x020b, 0x080c,
+	0x710e, 0x20a3, 0x1200, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x781c,
+	0xa086, 0x0004, 0x1110, 0x6098, 0x0018, 0x2001, 0xad14, 0x2004,
+	0x20a2, 0x7834, 0x20a2, 0x7838, 0x20a2, 0x20a9, 0x0010, 0xa006,
+	0x20a2, 0x1f04, 0x7928, 0x20a2, 0x20a2, 0x60c3, 0x002c, 0x080c,
+	0x7821, 0x0005, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x710e,
+	0x20a3, 0x0f00, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808, 0x20a2,
+	0x60c3, 0x0008, 0x080c, 0x7821, 0x014e, 0x015e, 0x0005, 0x0156,
+	0x0146, 0x20a1, 0x020b, 0x080c, 0x71aa, 0x20a3, 0x0200, 0x20a3,
+	0x0000, 0x20a9, 0x0006, 0x2011, 0xad40, 0x2019, 0xad41, 0x23a6,
+	0x22a6, 0xa398, 0x0002, 0xa290, 0x0002, 0x1f04, 0x7957, 0x20a3,
+	0x0000, 0x20a3, 0x0000, 0x60c3, 0x001c, 0x080c, 0x7821, 0x014e,
+	0x015e, 0x0005, 0x0156, 0x0146, 0x0016, 0x0026, 0x20a1, 0x020b,
+	0x080c, 0x7183, 0x080c, 0x7199, 0x7810, 0xa080, 0x0000, 0x2004,
+	0xa080, 0x0015, 0x2098, 0x7808, 0xa088, 0x0002, 0x21a8, 0x53a6,
+	0xa080, 0x0004, 0x8003, 0x60c2, 0x080c, 0x7821, 0x002e, 0x001e,
+	0x014e, 0x015e, 0x0005, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c,
+	0x710e, 0x20a3, 0x6200, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808,
+	0x20a2, 0x60c3, 0x0008, 0x080c, 0x7821, 0x014e, 0x015e, 0x0005,
+	0x0156, 0x0146, 0x0016, 0x0026, 0x20a1, 0x020b, 0x080c, 0x710e,
+	0x7810, 0xa080, 0x0000, 0x2004, 0xa080, 0x0017, 0x2098, 0x7808,
+	0xa088, 0x0002, 0x21a8, 0x53a6, 0x8003, 0x60c2, 0x080c, 0x7821,
+	0x002e, 0x001e, 0x014e, 0x015e, 0x0005, 0x00e6, 0x00c6, 0x0006,
+	0x0126, 0x2091, 0x8000, 0x2071, 0xafc7, 0x700c, 0x2060, 0x8cff,
+	0x0178, 0x080c, 0x9789, 0x1110, 0x080c, 0x85f3, 0x600c, 0x0006,
+	0x080c, 0x994e, 0x080c, 0x8078, 0x080c, 0x7b88, 0x00ce, 0x0c78,
+	0x700f, 0x0000, 0x700b, 0x0000, 0x012e, 0x000e, 0x00ce, 0x00ee,
+	0x0005, 0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0026,
+	0x0016, 0x0006, 0x2091, 0x8000, 0x2069, 0x0100, 0x2079, 0x0140,
+	0x2071, 0xafc7, 0x7024, 0x2060, 0x8cff, 0x05a0, 0x080c, 0x7834,
+	0x68c3, 0x0000, 0x080c, 0x6581, 0x2009, 0x0013, 0x080c, 0x80a7,
+	0x20a9, 0x01f4, 0x6824, 0xd094, 0x0158, 0x6827, 0x0004, 0x7804,
+	0xa084, 0x4000, 0x01a0, 0x7803, 0x1000, 0x7803, 0x0000, 0x0078,
+	0xd084, 0x0118, 0x6827, 0x0001, 0x0010, 0x1f04, 0x7a02, 0x7804,
+	0xa084, 0x1000, 0x0120, 0x7803, 0x0100, 0x7803, 0x0000, 0x6824,
+	0x000e, 0x001e, 0x002e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x015e,
+	0x012e, 0x0005, 0x2001, 0xad00, 0x2004, 0xa096, 0x0001, 0x0550,
+	0xa096, 0x0004, 0x0538, 0x6817, 0x0008, 0x68c3, 0x0000, 0x2011,
+	0x481b, 0x080c, 0x650d, 0x20a9, 0x01f4, 0x6824, 0xd094, 0x0158,
+	0x6827, 0x0004, 0x7804, 0xa084, 0x4000, 0x01a0, 0x7803, 0x1000,
+	0x7803, 0x0000, 0x0078, 0xd084, 0x0118, 0x6827, 0x0001, 0x0010,
+	0x1f04, 0x7a3d, 0x7804, 0xa084, 0x1000, 0x0120, 0x7803, 0x0100,
+	0x7803, 0x0000, 0x000e, 0x001e, 0x002e, 0x00ce, 0x00de, 0x00ee,
+	0x00fe, 0x015e, 0x012e, 0x0005, 0x0126, 0x0156, 0x00f6, 0x00e6,
+	0x00d6, 0x00c6, 0x0026, 0x0016, 0x0006, 0x2091, 0x8000, 0x2069,
+	0x0100, 0x2079, 0x0140, 0x2071, 0xafc7, 0x703c, 0x2060, 0x8cff,
+	0x0904, 0x7ad5, 0x6817, 0x0010, 0x2009, 0x00fa, 0x8109, 0x1df0,
+	0x68c7, 0x0000, 0x68cb, 0x0008, 0x080c, 0x658e, 0x080c, 0x20b5,
+	0x0046, 0x2009, 0x017f, 0x200b, 0x00a5, 0x2021, 0x0169, 0x2404,
+	0xa084, 0x000f, 0xa086, 0x0004, 0x11b0, 0x68c7, 0x0000, 0x68cb,
+	0x0008, 0x00e6, 0x00f6, 0x2079, 0x0020, 0x2071, 0xb01e, 0x6814,
+	0xa084, 0x0184, 0xa085, 0x0012, 0x6816, 0x7803, 0x0008, 0x7003,
+	0x0000, 0x00fe, 0x00ee, 0x200b, 0x0000, 0x004e, 0xa39d, 0x0000,
+	0x1120, 0x2009, 0x0049, 0x080c, 0x80a7, 0x20a9, 0x03e8, 0x6824,
+	0xd094, 0x0158, 0x6827, 0x0004, 0x7804, 0xa084, 0x4000, 0x01a0,
+	0x7803, 0x1000, 0x7803, 0x0000, 0x0078, 0xd08c, 0x0118, 0x6827,
+	0x0002, 0x0010, 0x1f04, 0x7ab7, 0x7804, 0xa084, 0x1000, 0x0120,
+	0x7803, 0x0100, 0x7803, 0x0000, 0x6824, 0x000e, 0x001e, 0x002e,
+	0x00ce, 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x00d6,
+	0x0126, 0x2091, 0x8000, 0x2069, 0xafc7, 0x6a06, 0x012e, 0x00de,
+	0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, 0x2069, 0xafc7, 0x6a32,
+	0x012e, 0x00de, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0066, 0x0006,
+	0x0126, 0x2071, 0xafc7, 0x7614, 0x2660, 0x2678, 0x2091, 0x8000,
+	0x8cff, 0x0538, 0x601c, 0xa206, 0x1500, 0x7014, 0xac36, 0x1110,
+	0x660c, 0x7616, 0x7010, 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118,
+	0x2f00, 0x7012, 0x0010, 0x7013, 0x0000, 0x660c, 0x0066, 0x2c00,
+	0xaf06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x080c,
+	0x974e, 0x080c, 0x7b88, 0x00ce, 0x08d8, 0x2c78, 0x600c, 0x2060,
+	0x08b8, 0x012e, 0x000e, 0x006e, 0x00ce, 0x00ee, 0x00fe, 0x0005,
+	0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x73cf, 0x7810, 0x20a2,
+	0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x1000, 0x0804,
+	0x7b80, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x73cf, 0x7810,
+	0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x4000,
+	0x0478, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x73cf, 0x7810,
+	0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x2000,
+	0x00f8, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x73cf, 0x7810,
+	0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0400,
+	0x0078, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x73cf, 0x7810,
+	0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0200,
+	0x0089, 0x60c3, 0x0020, 0x080c, 0x7821, 0x014e, 0x015e, 0x0005,
+	0x00e6, 0x2071, 0xafc7, 0x7020, 0xa005, 0x0110, 0x8001, 0x7022,
+	0x00ee, 0x0005, 0x20a9, 0x0008, 0x20a2, 0x1f04, 0x7b94, 0x20a2,
+	0x20a2, 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066,
+	0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0xafc7, 0x7614, 0x2660,
+	0x2678, 0x2039, 0x0001, 0x87ff, 0x0904, 0x7c24, 0x8cff, 0x0904,
+	0x7c24, 0x601c, 0xa086, 0x0006, 0x1904, 0x7c1f, 0x88ff, 0x0138,
+	0x2800, 0xac06, 0x1904, 0x7c1f, 0x2039, 0x0000, 0x0050, 0x6018,
+	0xa206, 0x1904, 0x7c1f, 0x85ff, 0x0120, 0x6050, 0xa106, 0x1904,
+	0x7c1f, 0x7024, 0xac06, 0x1538, 0x2069, 0x0100, 0x68c0, 0xa005,
+	0x01f0, 0x080c, 0x6581, 0x6817, 0x0008, 0x68c3, 0x0000, 0x080c,
+	0x7ca8, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0xa384,
+	0x1000, 0x0120, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100,
+	0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x0020, 0x6003,
+	0x0009, 0x630a, 0x0460, 0x7014, 0xac36, 0x1110, 0x660c, 0x7616,
+	0x7010, 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7012,
+	0x0010, 0x7013, 0x0000, 0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110,
+	0x7e0e, 0x0008, 0x2678, 0x89ff, 0x1158, 0x600f, 0x0000, 0x6010,
+	0x2068, 0x080c, 0x9596, 0x0110, 0x080c, 0xa91f, 0x080c, 0x974e,
+	0x080c, 0x7b88, 0x88ff, 0x1190, 0x00ce, 0x0804, 0x7bab, 0x2c78,
+	0x600c, 0x2060, 0x0804, 0x7bab, 0xa006, 0x012e, 0x000e, 0x006e,
+	0x007e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x6017, 0x0000,
+	0x00ce, 0xa8c5, 0x0001, 0x0c88, 0x00f6, 0x00e6, 0x00d6, 0x00c6,
+	0x0066, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0xafc7,
+	0x7638, 0x2660, 0x2678, 0x8cff, 0x0904, 0x7c98, 0x601c, 0xa086,
+	0x0006, 0x1904, 0x7c93, 0x87ff, 0x0128, 0x2700, 0xac06, 0x1904,
+	0x7c93, 0x0040, 0x6018, 0xa206, 0x15f0, 0x85ff, 0x0118, 0x6050,
+	0xa106, 0x15c8, 0x703c, 0xac06, 0x1170, 0x0036, 0x2019, 0x0001,
+	0x080c, 0x7a64, 0x7033, 0x0000, 0x703f, 0x0000, 0x7043, 0x0000,
+	0x7047, 0x0000, 0x003e, 0x7038, 0xac36, 0x1110, 0x660c, 0x763a,
+	0x7034, 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7036,
+	0x0010, 0x7037, 0x0000, 0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110,
+	0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x6010, 0x2068, 0x080c,
+	0x9596, 0x0110, 0x080c, 0xa91f, 0x080c, 0x974e, 0x87ff, 0x1190,
+	0x00ce, 0x0804, 0x7c43, 0x2c78, 0x600c, 0x2060, 0x0804, 0x7c43,
+	0xa006, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee,
+	0x00fe, 0x0005, 0x6017, 0x0000, 0x00ce, 0xa7bd, 0x0001, 0x0c88,
+	0x00e6, 0x2071, 0xafc7, 0x2001, 0xad00, 0x2004, 0xa086, 0x0002,
+	0x1118, 0x7007, 0x0005, 0x0010, 0x7007, 0x0000, 0x00ee, 0x0005,
+	0x00f6, 0x00e6, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091,
+	0x8000, 0x2071, 0xafc7, 0x2c10, 0x7638, 0x2660, 0x2678, 0x8cff,
+	0x0518, 0x2200, 0xac06, 0x11e0, 0x7038, 0xac36, 0x1110, 0x660c,
+	0x763a, 0x7034, 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00,
+	0x7036, 0x0010, 0x7037, 0x0000, 0x660c, 0x2c00, 0xaf06, 0x0110,
+	0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0xa085, 0x0001, 0x0020,
+	0x2c78, 0x600c, 0x2060, 0x08d8, 0x012e, 0x000e, 0x002e, 0x006e,
+	0x00ce, 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6,
+	0x0066, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0xafc7, 0x760c,
+	0x2660, 0x2678, 0x8cff, 0x0904, 0x7d7e, 0x6018, 0xa080, 0x0028,
+	0x2004, 0xa206, 0x1904, 0x7d79, 0x7024, 0xac06, 0x1508, 0x2069,
+	0x0100, 0x68c0, 0xa005, 0x0904, 0x7d55, 0x080c, 0x7834, 0x68c3,
+	0x0000, 0x080c, 0x7ca8, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140,
+	0x6b04, 0xa384, 0x1000, 0x0120, 0x6803, 0x0100, 0x6803, 0x0000,
+	0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e,
+	0x700c, 0xac36, 0x1110, 0x660c, 0x760e, 0x7008, 0xac36, 0x1140,
+	0x2c00, 0xaf36, 0x0118, 0x2f00, 0x700a, 0x0010, 0x700b, 0x0000,
+	0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110, 0x7e0e, 0x0008, 0x2678,
+	0x600f, 0x0000, 0x080c, 0x9778, 0x1158, 0x080c, 0x2aff, 0x080c,
+	0x9789, 0x11f0, 0x080c, 0x85f3, 0x00d8, 0x080c, 0x7ca8, 0x08c0,
+	0x080c, 0x9789, 0x1118, 0x080c, 0x85f3, 0x0090, 0x6010, 0x2068,
+	0x080c, 0x9596, 0x0168, 0x601c, 0xa086, 0x0003, 0x11f8, 0x6837,
+	0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x510c, 0x080c, 0x9742,
+	0x080c, 0x994e, 0x080c, 0x974e, 0x080c, 0x7b88, 0x00ce, 0x0804,
+	0x7d02, 0x2c78, 0x600c, 0x2060, 0x0804, 0x7d02, 0x012e, 0x000e,
+	0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601c, 0xa086,
+	0x0006, 0x1d30, 0x080c, 0xa91f, 0x0c18, 0x0036, 0x0156, 0x0136,
+	0x0146, 0x3908, 0xa006, 0xa190, 0x0020, 0x221c, 0xa39e, 0x28f9,
+	0x1118, 0x8210, 0x8000, 0x0cc8, 0xa005, 0x0138, 0x20a9, 0x0020,
+	0x2198, 0xa110, 0x22a0, 0x22c8, 0x53a3, 0x014e, 0x013e, 0x015e,
+	0x003e, 0x0005, 0x00d6, 0x20a1, 0x020b, 0x080c, 0x71aa, 0x20a3,
+	0x0200, 0x20a3, 0x0014, 0x60c3, 0x0014, 0x20a3, 0x0000, 0x20a3,
+	0x0000, 0x2099, 0xafa6, 0x20a9, 0x0004, 0x53a6, 0x20a3, 0x0004,
+	0x20a3, 0x7878, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x080c, 0x7821,
+	0x00de, 0x0005, 0x20a1, 0x020b, 0x080c, 0x71aa, 0x20a3, 0x0214,
+	0x20a3, 0x0018, 0x20a3, 0x0800, 0x7810, 0xa084, 0xff00, 0x20a2,
+	0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000,
+	0x7810, 0xa084, 0x00ff, 0x20a2, 0x7828, 0x20a2, 0x20a3, 0x0000,
+	0x20a3, 0x0000, 0x60c3, 0x0018, 0x080c, 0x7821, 0x0005, 0x00d6,
+	0x0016, 0x2f68, 0x2009, 0x0035, 0x080c, 0x9a34, 0x1904, 0x7e5d,
+	0x20a1, 0x020b, 0x080c, 0x710e, 0x20a3, 0x1300, 0x20a3, 0x0000,
+	0x7828, 0x2068, 0x681c, 0xa086, 0x0003, 0x0580, 0x7818, 0xa080,
+	0x0028, 0x2014, 0x2001, 0xad34, 0x2004, 0xd0ac, 0x11d0, 0xa286,
+	0x007e, 0x1128, 0x20a3, 0x00ff, 0x20a3, 0xfffe, 0x04b8, 0xa286,
+	0x007f, 0x1128, 0x20a3, 0x00ff, 0x20a3, 0xfffd, 0x0478, 0xd2bc,
+	0x0180, 0xa286, 0x0080, 0x1128, 0x20a3, 0x00ff, 0x20a3, 0xfffc,
+	0x0428, 0xa2e8, 0xae34, 0x2d6c, 0x6810, 0x20a2, 0x6814, 0x20a2,
+	0x00e8, 0x20a3, 0x0000, 0x6098, 0x20a2, 0x00c0, 0x2001, 0xad34,
+	0x2004, 0xd0ac, 0x1138, 0x7818, 0xa080, 0x0028, 0x2004, 0xa082,
+	0x007e, 0x0240, 0x00d6, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6,
+	0x00de, 0x0020, 0x20a3, 0x0000, 0x6034, 0x20a2, 0x7834, 0x20a2,
+	0x7838, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x000c,
+	0x080c, 0x7821, 0x001e, 0x00de, 0x0005, 0x7817, 0x0001, 0x7803,
+	0x0006, 0x001e, 0x00de, 0x0005, 0x00d6, 0x0026, 0x7928, 0x2168,
+	0x691c, 0xa186, 0x0006, 0x01c0, 0xa186, 0x0003, 0x0904, 0x7ed3,
+	0xa186, 0x0005, 0x0904, 0x7ebc, 0xa186, 0x0004, 0x05b8, 0xa186,
+	0x0008, 0x0904, 0x7ec4, 0x7807, 0x0037, 0x7813, 0x1700, 0x080c,
+	0x7f3b, 0x002e, 0x00de, 0x0005, 0x080c, 0x7ef7, 0x2009, 0x4000,
+	0x6800, 0x0002, 0x7e9d, 0x7ea8, 0x7e9f, 0x7ea8, 0x7ea4, 0x7e9d,
+	0x7e9d, 0x7ea8, 0x7ea8, 0x7ea8, 0x7ea8, 0x7e9d, 0x7e9d, 0x7e9d,
+	0x7e9d, 0x7e9d, 0x7ea8, 0x7e9d, 0x7ea8, 0x080c, 0x14f6, 0x6820,
+	0xd0e4, 0x0110, 0xd0cc, 0x0110, 0xa00e, 0x0010, 0x2009, 0x2000,
+	0x6828, 0x20a2, 0x682c, 0x20a2, 0x0804, 0x7eed, 0x080c, 0x7ef7,
+	0x20a3, 0x0000, 0x20a3, 0x0000, 0x2009, 0x4000, 0x6a00, 0xa286,
+	0x0002, 0x1108, 0xa00e, 0x0488, 0x04d1, 0x20a3, 0x0000, 0x20a3,
+	0x0000, 0x2009, 0x4000, 0x0448, 0x0491, 0x20a3, 0x0000, 0x20a3,
+	0x0000, 0x2009, 0x4000, 0xa286, 0x0005, 0x0118, 0xa286, 0x0002,
+	0x1108, 0xa00e, 0x00d0, 0x0419, 0x6810, 0x2068, 0x697c, 0x6810,
+	0xa112, 0x6980, 0x6814, 0xa103, 0x20a2, 0x22a2, 0x7928, 0xa180,
+	0x0000, 0x2004, 0xa08e, 0x0002, 0x0130, 0xa08e, 0x0004, 0x0118,
+	0x2009, 0x4000, 0x0010, 0x2009, 0x0000, 0x21a2, 0x20a3, 0x0000,
+	0x60c3, 0x0018, 0x080c, 0x7821, 0x002e, 0x00de, 0x0005, 0x0036,
+	0x0046, 0x0056, 0x0066, 0x20a1, 0x020b, 0x080c, 0x71aa, 0xa006,
+	0x20a3, 0x0200, 0x20a2, 0x7934, 0x21a2, 0x7938, 0x21a2, 0x7818,
+	0xa080, 0x0028, 0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1118,
+	0xa092, 0x007e, 0x0268, 0x00d6, 0x2069, 0xad1b, 0x2d2c, 0x8d68,
+	0x2d34, 0xa0e8, 0xae34, 0x2d6c, 0x6b10, 0x6c14, 0x00de, 0x0030,
+	0x2019, 0x0000, 0x6498, 0x2029, 0x0000, 0x6634, 0x7828, 0xa080,
+	0x0007, 0x2004, 0xa086, 0x0003, 0x1128, 0x25a2, 0x26a2, 0x23a2,
+	0x24a2, 0x0020, 0x23a2, 0x24a2, 0x25a2, 0x26a2, 0x006e, 0x005e,
+	0x004e, 0x003e, 0x0005, 0x20a1, 0x020b, 0x080c, 0x71aa, 0x20a3,
+	0x0100, 0x20a3, 0x0000, 0x20a3, 0x0009, 0x7810, 0x20a2, 0x60c3,
+	0x0008, 0x080c, 0x7821, 0x0005, 0x20a1, 0x020b, 0x080c, 0x7106,
+	0x20a3, 0x1400, 0x20a3, 0x0000, 0x7834, 0x20a2, 0x7838, 0x20a2,
+	0x7828, 0x20a2, 0x782c, 0x20a2, 0x7830, 0xa084, 0x00ff, 0x8007,
+	0x20a2, 0x20a3, 0x0000, 0x60c3, 0x0010, 0x080c, 0x7821, 0x0005,
+	0x20a1, 0x020b, 0x080c, 0x71a2, 0x20a3, 0x0100, 0x20a3, 0x0000,
+	0x7828, 0x20a2, 0x7810, 0x20a2, 0x60c3, 0x0008, 0x080c, 0x7821,
+	0x0005, 0x0146, 0x20a1, 0x020b, 0x0031, 0x60c3, 0x0000, 0x080c,
+	0x7821, 0x014e, 0x0005, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818,
+	0xa080, 0x0028, 0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1110,
+	0xd0bc, 0x0188, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085,
+	0x0300, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68,
+	0x2da6, 0x00de, 0x0078, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810,
+	0xa085, 0x0300, 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000,
+	0x6234, 0x22a2, 0x20a3, 0x0819, 0x20a3, 0x0000, 0x080c, 0x7810,
+	0x22a2, 0x20a3, 0x0000, 0x2fa2, 0x7a08, 0x22a2, 0x20a3, 0x0000,
+	0x20a3, 0x0000, 0x0005, 0x20a1, 0x020b, 0x0079, 0x7910, 0x21a2,
+	0x20a3, 0x0000, 0x60c3, 0x0000, 0x20e1, 0x9080, 0x60a7, 0x9575,
+	0x080c, 0x782b, 0x080c, 0x6578, 0x0005, 0x0156, 0x0136, 0x0036,
+	0x00d6, 0x00e6, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7854, 0x2068,
+	0xadf0, 0x000f, 0x7210, 0xa296, 0x00c0, 0xa294, 0xfffd, 0x7212,
+	0x7214, 0xa294, 0x0300, 0x7216, 0x7100, 0xa194, 0x00ff, 0x7308,
+	0xa384, 0x00ff, 0xa08d, 0xc200, 0x7102, 0xa384, 0xff00, 0xa215,
+	0x720a, 0x7004, 0x720c, 0x700e, 0x7206, 0x20a9, 0x000a, 0x2e98,
+	0x53a6, 0x60a3, 0x0035, 0x6a38, 0xa294, 0x7000, 0xa286, 0x3000,
+	0x0110, 0x60a3, 0x0037, 0x00ee, 0x00de, 0x003e, 0x013e, 0x015e,
+	0x0005, 0x2009, 0x0092, 0x0010, 0x2009, 0x0096, 0x60ab, 0x0036,
+	0x6116, 0x0005, 0x2061, 0xb400, 0x2a70, 0x7064, 0x7046, 0x704b,
+	0xb400, 0x0005, 0x00e6, 0x0126, 0x2071, 0xad00, 0x2091, 0x8000,
+	0x7544, 0xa582, 0x0010, 0x0608, 0x7048, 0x2060, 0x6000, 0xa086,
+	0x0000, 0x0148, 0xace0, 0x0018, 0x7058, 0xac02, 0x1208, 0x0cb0,
+	0x2061, 0xb400, 0x0c98, 0x6003, 0x0008, 0x8529, 0x7546, 0xaca8,
+	0x0018, 0x7058, 0xa502, 0x1230, 0x754a, 0xa085, 0x0001, 0x012e,
+	0x00ee, 0x0005, 0x704b, 0xb400, 0x0cc0, 0xa006, 0x0cc0, 0x00e6,
+	0x2071, 0xad00, 0x7544, 0xa582, 0x0010, 0x0600, 0x7048, 0x2060,
+	0x6000, 0xa086, 0x0000, 0x0148, 0xace0, 0x0018, 0x7058, 0xac02,
+	0x1208, 0x0cb0, 0x2061, 0xb400, 0x0c98, 0x6003, 0x0008, 0x8529,
+	0x7546, 0xaca8, 0x0018, 0x7058, 0xa502, 0x1228, 0x754a, 0xa085,
+	0x0001, 0x00ee, 0x0005, 0x704b, 0xb400, 0x0cc8, 0xa006, 0x0cc8,
+	0xac82, 0xb400, 0x0a0c, 0x14f6, 0x2001, 0xad16, 0x2004, 0xac02,
+	0x1a0c, 0x14f6, 0xa006, 0x6006, 0x600a, 0x600e, 0x6012, 0x6016,
+	0x601a, 0x601f, 0x0000, 0x6003, 0x0000, 0x6052, 0x6056, 0x6022,
+	0x6026, 0x602a, 0x602e, 0x6032, 0x6036, 0x603a, 0x603e, 0x2061,
+	0xad00, 0x6044, 0x8000, 0x6046, 0xa086, 0x0001, 0x0108, 0x0005,
+	0x0126, 0x2091, 0x8000, 0x080c, 0x6c50, 0x012e, 0x0cc0, 0x601c,
+	0xa084, 0x000f, 0x0002, 0x80b6, 0x80c5, 0x80e0, 0x80fb, 0x9a61,
+	0x9a7c, 0x9a97, 0x80b6, 0x80c5, 0x80b6, 0x8116, 0xa186, 0x0013,
+	0x1128, 0x080c, 0x6b73, 0x080c, 0x6c50, 0x0005, 0xa18e, 0x0047,
+	0x1118, 0xa016, 0x080c, 0x1824, 0x0005, 0x0066, 0x6000, 0xa0b2,
+	0x0010, 0x1a0c, 0x14f6, 0x0013, 0x006e, 0x0005, 0x80de, 0x8478,
+	0x862d, 0x80de, 0x86a2, 0x81cf, 0x80de, 0x80de, 0x840a, 0x8a91,
+	0x80de, 0x80de, 0x80de, 0x80de, 0x80de, 0x80de, 0x080c, 0x14f6,
+	0x0066, 0x6000, 0xa0b2, 0x0010, 0x1a0c, 0x14f6, 0x0013, 0x006e,
+	0x0005, 0x80f9, 0x909a, 0x80f9, 0x80f9, 0x80f9, 0x80f9, 0x80f9,
+	0x80f9, 0x9045, 0x9200, 0x80f9, 0x90c7, 0x913e, 0x90c7, 0x913e,
+	0x80f9, 0x080c, 0x14f6, 0x0066, 0x6000, 0xa0b2, 0x0010, 0x1a0c,
+	0x14f6, 0x0013, 0x006e, 0x0005, 0x8114, 0x8ad2, 0x8b98, 0x8cb8,
+	0x8e12, 0x8114, 0x8114, 0x8114, 0x8aac, 0x8ff5, 0x8ff8, 0x8114,
+	0x8114, 0x8114, 0x8114, 0x9022, 0x080c, 0x14f6, 0x0066, 0x6000,
+	0xa0b2, 0x0010, 0x1a0c, 0x14f6, 0x0013, 0x006e, 0x0005, 0x812f,
+	0x812f, 0x812f, 0x8152, 0x81a5, 0x812f, 0x812f, 0x812f, 0x8131,
+	0x812f, 0x812f, 0x812f, 0x812f, 0x812f, 0x812f, 0x812f, 0x080c,
+	0x14f6, 0xa186, 0x0003, 0x190c, 0x14f6, 0x00d6, 0x6003, 0x0003,
+	0x6106, 0x6010, 0x2068, 0x684f, 0x0040, 0x687c, 0x680a, 0x6880,
+	0x680e, 0x6813, 0x0000, 0x6817, 0x0000, 0x00de, 0x2c10, 0x080c,
+	0x1e6e, 0x080c, 0x680b, 0x0126, 0x2091, 0x8000, 0x080c, 0x6d0d,
+	0x012e, 0x0005, 0xa182, 0x0047, 0x0002, 0x815e, 0x815e, 0x8160,
+	0x817f, 0x815e, 0x815e, 0x815e, 0x815e, 0x8191, 0x080c, 0x14f6,
+	0x00d6, 0x0016, 0x080c, 0x6c05, 0x080c, 0x6d0d, 0x6003, 0x0004,
+	0x6110, 0x2168, 0x6854, 0x8003, 0x800b, 0x810b, 0xa108, 0x6116,
+	0x684f, 0x0020, 0x685c, 0x685a, 0x6874, 0x687e, 0x6878, 0x6882,
+	0x6897, 0x0000, 0x689b, 0x0000, 0x001e, 0x00de, 0x0005, 0x080c,
+	0x6c05, 0x00d6, 0x6110, 0x2168, 0x080c, 0x9596, 0x0120, 0x684b,
+	0x0006, 0x080c, 0x510c, 0x00de, 0x080c, 0x8078, 0x080c, 0x6d0d,
+	0x0005, 0x080c, 0x6c05, 0x080c, 0x2ad9, 0x00d6, 0x6110, 0x2168,
+	0x080c, 0x9596, 0x0120, 0x684b, 0x0029, 0x080c, 0x510c, 0x00de,
+	0x080c, 0x8078, 0x080c, 0x6d0d, 0x0005, 0xa182, 0x0047, 0x0002,
+	0x81b3, 0x81c2, 0x81b1, 0x81b1, 0x81b1, 0x81b1, 0x81b1, 0x81b1,
+	0x81b1, 0x080c, 0x14f6, 0x00d6, 0x6010, 0x2068, 0x684c, 0xc0f4,
+	0x684e, 0x00de, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c,
+	0x1824, 0x0005, 0x00d6, 0x6110, 0x2168, 0x684b, 0x0000, 0x6853,
+	0x0000, 0x080c, 0x510c, 0x00de, 0x080c, 0x8078, 0x0005, 0xa1b6,
+	0x0015, 0x1118, 0x080c, 0x8078, 0x0030, 0xa1b6, 0x0016, 0x190c,
+	0x14f6, 0x080c, 0x8078, 0x0005, 0x20a9, 0x000e, 0x2e98, 0x6010,
+	0x20a0, 0x53a3, 0x20a9, 0x0006, 0x3310, 0x3420, 0x9398, 0x94a0,
+	0x3318, 0x3428, 0x222e, 0x2326, 0xa290, 0x0002, 0xa5a8, 0x0002,
+	0xa398, 0x0002, 0xa4a0, 0x0002, 0x1f04, 0x81ea, 0x00e6, 0x080c,
+	0x9596, 0x0130, 0x6010, 0x2070, 0x7007, 0x0000, 0x7037, 0x0103,
+	0x00ee, 0x080c, 0x8078, 0x0005, 0x00d6, 0x0036, 0x7330, 0xa386,
+	0x0200, 0x1130, 0x6018, 0x2068, 0x6813, 0x00ff, 0x6817, 0xfffd,
+	0x6010, 0xa005, 0x0130, 0x2068, 0x6807, 0x0000, 0x6837, 0x0103,
+	0x6b32, 0x080c, 0x8078, 0x003e, 0x00de, 0x0005, 0x0016, 0x20a9,
+	0x002a, 0xae80, 0x000c, 0x2098, 0x6010, 0xa080, 0x0002, 0x20a0,
+	0x53a3, 0x20a9, 0x002a, 0x6010, 0xa080, 0x0001, 0x2004, 0xa080,
+	0x0002, 0x20a0, 0x53a3, 0x00e6, 0x6010, 0x2004, 0x2070, 0x7037,
+	0x0103, 0x00ee, 0x080c, 0x8078, 0x001e, 0x0005, 0x0016, 0x2009,
+	0x0000, 0x7030, 0xa086, 0x0100, 0x0140, 0x7038, 0xa084, 0x00ff,
+	0x808e, 0x703c, 0xa084, 0x00ff, 0x8086, 0xa080, 0x0004, 0xa108,
+	0x21a8, 0xae80, 0x000c, 0x2098, 0x6010, 0xa080, 0x0002, 0x20a0,
+	0x080c, 0x48be, 0x00e6, 0x080c, 0x9596, 0x0140, 0x6010, 0x2070,
+	0x7007, 0x0000, 0x7034, 0x70b2, 0x7037, 0x0103, 0x00ee, 0x080c,
+	0x8078, 0x001e, 0x0005, 0x00e6, 0x00d6, 0x603f, 0x0000, 0x2c68,
+	0x0016, 0x2009, 0x0035, 0x080c, 0x9a34, 0x001e, 0x1168, 0x0026,
+	0x6228, 0x2268, 0x002e, 0x2071, 0xb28c, 0x6b1c, 0xa386, 0x0003,
+	0x0130, 0xa386, 0x0006, 0x0128, 0x080c, 0x8078, 0x0020, 0x0031,
+	0x0010, 0x080c, 0x8323, 0x00de, 0x00ee, 0x0005, 0x00f6, 0x6810,
+	0x2078, 0xa186, 0x0015, 0x0904, 0x830c, 0xa18e, 0x0016, 0x1904,
+	0x8321, 0x700c, 0xa084, 0xff00, 0xa086, 0x1700, 0x1904, 0x82eb,
+	0x8fff, 0x0904, 0x831f, 0x6808, 0xa086, 0xffff, 0x1904, 0x830e,
+	0x784c, 0xa084, 0x0060, 0xa086, 0x0020, 0x1150, 0x797c, 0x7810,
+	0xa106, 0x1904, 0x830e, 0x7980, 0x7814, 0xa106, 0x1904, 0x830e,
+	0x080c, 0x9742, 0x6858, 0x7852, 0x784c, 0xc0dc, 0xc0f4, 0xc0d4,
+	0x784e, 0x0026, 0xa00e, 0x6a14, 0x2001, 0x000a, 0x080c, 0x6665,
+	0x7854, 0xa20a, 0x0208, 0x8011, 0x7a56, 0x82ff, 0x002e, 0x1138,
+	0x00c6, 0x2d60, 0x080c, 0x9374, 0x00ce, 0x0804, 0x831f, 0x00c6,
+	0x00d6, 0x2f68, 0x6838, 0xd0fc, 0x1118, 0x080c, 0x4993, 0x0010,
+	0x080c, 0x4b7c, 0x00de, 0x00ce, 0x1548, 0x00c6, 0x2d60, 0x080c,
+	0x8078, 0x00ce, 0x04a0, 0x7008, 0xa086, 0x000b, 0x11a0, 0x6018,
+	0x200c, 0xc1bc, 0x2102, 0x00c6, 0x2d60, 0x7853, 0x0003, 0x6007,
+	0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x080c, 0x67a8, 0x080c,
+	0x6c50, 0x00ce, 0x00e0, 0x700c, 0xa086, 0x2a00, 0x1138, 0x2001,
+	0xafa5, 0x2004, 0x683e, 0x0098, 0x0471, 0x0098, 0x8fff, 0x090c,
+	0x14f6, 0x00c6, 0x00d6, 0x2d60, 0x2f68, 0x684b, 0x0003, 0x080c,
+	0x926f, 0x080c, 0x9742, 0x080c, 0x974e, 0x00de, 0x00ce, 0x080c,
+	0x8078, 0x00fe, 0x0005, 0xa186, 0x0015, 0x1128, 0x2001, 0xafa5,
+	0x2004, 0x683e, 0x0068, 0xa18e, 0x0016, 0x1160, 0x00c6, 0x2d00,
+	0x2060, 0x080c, 0xabb4, 0x080c, 0x6618, 0x080c, 0x8078, 0x00ce,
+	0x080c, 0x8078, 0x0005, 0x0026, 0x0036, 0x0046, 0x7228, 0x7c80,
+	0x7b7c, 0xd2f4, 0x0130, 0x2001, 0xafa5, 0x2004, 0x683e, 0x0804,
+	0x839d, 0x00c6, 0x2d60, 0x080c, 0x928f, 0x00ce, 0x6804, 0xa086,
+	0x0050, 0x1168, 0x00c6, 0x2d00, 0x2060, 0x6003, 0x0001, 0x6007,
+	0x0050, 0x080c, 0x67a8, 0x080c, 0x6c50, 0x00ce, 0x04f0, 0x6800,
+	0xa086, 0x000f, 0x01c8, 0x8fff, 0x090c, 0x14f6, 0x6820, 0xd0dc,
+	0x1198, 0x6800, 0xa086, 0x0004, 0x1198, 0x784c, 0xd0ac, 0x0180,
+	0x784c, 0xc0dc, 0xc0f4, 0x784e, 0x7850, 0xc0f4, 0xc0fc, 0x7852,
+	0x2001, 0x0001, 0x682e, 0x00e0, 0x2001, 0x0007, 0x682e, 0x00c0,
+	0x784c, 0xd0b4, 0x1130, 0xd0ac, 0x0db8, 0x784c, 0xd0f4, 0x1da0,
+	0x0c38, 0xd2ec, 0x1d88, 0x7024, 0xa306, 0x1118, 0x7020, 0xa406,
+	0x0d58, 0x7020, 0x6836, 0x7024, 0x683a, 0x2001, 0x0005, 0x682e,
+	0x080c, 0x9894, 0x080c, 0x6c50, 0x0010, 0x080c, 0x8078, 0x004e,
+	0x003e, 0x002e, 0x0005, 0x00e6, 0x00d6, 0x0026, 0x6034, 0x2068,
+	0x6a1c, 0xa286, 0x0007, 0x0904, 0x83ee, 0xa286, 0x0002, 0x05f0,
+	0xa286, 0x0000, 0x05d8, 0x6808, 0x6338, 0xa306, 0x15b8, 0x2071,
+	0xb28c, 0xa186, 0x0015, 0x0560, 0xa18e, 0x0016, 0x1190, 0x6030,
+	0xa084, 0x00ff, 0xa086, 0x0001, 0x1160, 0x700c, 0xa086, 0x2a00,
+	0x1140, 0x6034, 0xa080, 0x0008, 0x200c, 0xc1dd, 0xc1f5, 0x2102,
+	0x00b8, 0x00c6, 0x6034, 0x2060, 0x6010, 0x2068, 0x080c, 0x9596,
+	0x090c, 0x14f6, 0x6853, 0x0003, 0x6007, 0x0085, 0x6003, 0x000b,
+	0x601f, 0x0002, 0x080c, 0x67a8, 0x080c, 0x6c50, 0x00ce, 0x0030,
+	0x6034, 0x2070, 0x2001, 0xafa5, 0x2004, 0x703e, 0x080c, 0x8078,
+	0x002e, 0x00de, 0x00ee, 0x0005, 0x00d6, 0x20a9, 0x000e, 0x2e98,
+	0x6010, 0x20a0, 0x53a3, 0xa1b6, 0x0015, 0x1148, 0x6018, 0x2068,
+	0x7038, 0x680a, 0x703c, 0x680e, 0x6800, 0xc08d, 0x6802, 0x00de,
+	0x0804, 0x81f6, 0x2100, 0xa1b2, 0x0080, 0x1a0c, 0x14f6, 0xa1b2,
+	0x0040, 0x1a04, 0x846e, 0x0002, 0x8462, 0x8456, 0x8462, 0x8462,
+	0x8462, 0x8462, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454,
+	0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454,
+	0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454,
+	0x8454, 0x8454, 0x8454, 0x8462, 0x8454, 0x8462, 0x8462, 0x8454,
+	0x8454, 0x8454, 0x8454, 0x8454, 0x8462, 0x8454, 0x8454, 0x8454,
+	0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8462, 0x8462,
+	0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454,
+	0x8454, 0x8462, 0x8454, 0x8454, 0x080c, 0x14f6, 0x6003, 0x0001,
+	0x6106, 0x080c, 0x67ee, 0x0126, 0x2091, 0x8000, 0x080c, 0x6c50,
+	0x012e, 0x0005, 0x6003, 0x0001, 0x6106, 0x080c, 0x67ee, 0x0126,
+	0x2091, 0x8000, 0x080c, 0x6c50, 0x012e, 0x0005, 0x2600, 0x0002,
+	0x8462, 0x8476, 0x8476, 0x8462, 0x8462, 0x8476, 0x080c, 0x14f6,
+	0x6004, 0xa0b2, 0x0080, 0x1a0c, 0x14f6, 0xa1b6, 0x0013, 0x0904,
+	0x8518, 0xa1b6, 0x0027, 0x1904, 0x84de, 0x080c, 0x6b73, 0x6004,
+	0x080c, 0x9778, 0x0188, 0x080c, 0x9789, 0x0904, 0x84d8, 0xa08e,
+	0x0021, 0x0904, 0x84db, 0xa08e, 0x0022, 0x0904, 0x84d8, 0xa08e,
+	0x003d, 0x0904, 0x84db, 0x04a8, 0x080c, 0x2aff, 0x2001, 0x0007,
+	0x080c, 0x4c30, 0x6018, 0xa080, 0x0028, 0x200c, 0x080c, 0x85f3,
+	0xa186, 0x007e, 0x1148, 0x2001, 0xad34, 0x2014, 0xc285, 0x080c,
+	0x574f, 0x1108, 0xc2ad, 0x2202, 0x0016, 0x0026, 0x0036, 0x2110,
+	0x2019, 0x0028, 0x080c, 0x68e7, 0x0076, 0x2039, 0x0000, 0x080c,
+	0x681d, 0x00c6, 0x6018, 0xa065, 0x0110, 0x080c, 0x4ecf, 0x00ce,
+	0x2c08, 0x080c, 0xa712, 0x007e, 0x003e, 0x002e, 0x001e, 0x080c,
+	0x4c9f, 0x080c, 0x994e, 0x080c, 0x8078, 0x080c, 0x6c50, 0x0005,
+	0x080c, 0x85f3, 0x0cb0, 0x080c, 0x8621, 0x0c98, 0xa186, 0x0014,
+	0x1db0, 0x080c, 0x6b73, 0x080c, 0x2ad9, 0x080c, 0x9778, 0x1188,
+	0x080c, 0x2aff, 0x6018, 0xa080, 0x0028, 0x200c, 0x080c, 0x85f3,
+	0xa186, 0x007e, 0x1128, 0x2001, 0xad34, 0x200c, 0xc185, 0x2102,
+	0x08c0, 0x080c, 0x9789, 0x1118, 0x080c, 0x85f3, 0x0890, 0x6004,
+	0xa08e, 0x0032, 0x1158, 0x00e6, 0x00f6, 0x2071, 0xad81, 0x2079,
+	0x0000, 0x080c, 0x2df1, 0x00fe, 0x00ee, 0x0818, 0x6004, 0xa08e,
+	0x0021, 0x0d50, 0xa08e, 0x0022, 0x090c, 0x85f3, 0x0804, 0x84d1,
+	0xa0b2, 0x0040, 0x1a04, 0x85db, 0x2008, 0x0002, 0x8560, 0x8561,
+	0x8564, 0x8567, 0x856a, 0x856d, 0x855e, 0x855e, 0x855e, 0x855e,
+	0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e,
+	0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e,
+	0x855e, 0x855e, 0x855e, 0x855e, 0x8570, 0x857f, 0x855e, 0x8581,
+	0x857f, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x857f, 0x857f,
+	0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e,
+	0x85bb, 0x857f, 0x855e, 0x857b, 0x855e, 0x855e, 0x855e, 0x857c,
+	0x855e, 0x855e, 0x855e, 0x857f, 0x85b2, 0x855e, 0x080c, 0x14f6,
+	0x00f0, 0x2001, 0x000b, 0x0460, 0x2001, 0x0003, 0x0448, 0x2001,
+	0x0005, 0x0430, 0x2001, 0x0001, 0x0418, 0x2001, 0x0009, 0x0400,
+	0x080c, 0x6b73, 0x6003, 0x0005, 0x2001, 0xafa5, 0x2004, 0x603e,
+	0x080c, 0x6c50, 0x00a0, 0x0018, 0x0010, 0x080c, 0x4c30, 0x0804,
+	0x85cc, 0x080c, 0x6b73, 0x2001, 0xafa3, 0x2004, 0x6016, 0x2001,
+	0xafa5, 0x2004, 0x603e, 0x6003, 0x0004, 0x080c, 0x6c50, 0x0005,
+	0x080c, 0x4c30, 0x080c, 0x6b73, 0x6003, 0x0002, 0x2001, 0xafa5,
+	0x2004, 0x603e, 0x0036, 0x2019, 0xad5c, 0x2304, 0xa084, 0xff00,
+	0x1120, 0x2001, 0xafa3, 0x201c, 0x0040, 0x8007, 0xa09a, 0x0004,
+	0x0ec0, 0x8003, 0x801b, 0x831b, 0xa318, 0x6316, 0x003e, 0x080c,
+	0x6c50, 0x08e8, 0x080c, 0x6b73, 0x080c, 0x994e, 0x080c, 0x8078,
+	0x080c, 0x6c50, 0x08a0, 0x00e6, 0x00f6, 0x2071, 0xad81, 0x2079,
+	0x0000, 0x080c, 0x2df1, 0x00fe, 0x00ee, 0x080c, 0x6b73, 0x080c,
+	0x8078, 0x080c, 0x6c50, 0x0818, 0x080c, 0x6b73, 0x2001, 0xafa5,
+	0x2004, 0x603e, 0x6003, 0x0002, 0x2001, 0xafa3, 0x2004, 0x6016,
+	0x080c, 0x6c50, 0x0005, 0x2600, 0x2008, 0x0002, 0x85e6, 0x85e4,
+	0x85e4, 0x85cc, 0x85cc, 0x85e4, 0x080c, 0x14f6, 0x080c, 0x6b73,
+	0x00d6, 0x6010, 0x2068, 0x080c, 0x15f0, 0x00de, 0x080c, 0x8078,
+	0x080c, 0x6c50, 0x0005, 0x00e6, 0x0026, 0x0016, 0x080c, 0x9596,
+	0x0508, 0x6010, 0x2070, 0x7034, 0xa086, 0x0139, 0x1148, 0x2001,
+	0x0030, 0x2009, 0x0000, 0x2011, 0x4005, 0x080c, 0x9a05, 0x0090,
+	0x7038, 0xd0fc, 0x0178, 0x7007, 0x0000, 0x0016, 0x6004, 0xa08e,
+	0x0021, 0x0160, 0xa08e, 0x003d, 0x0148, 0x001e, 0x7037, 0x0103,
+	0x7033, 0x0100, 0x001e, 0x002e, 0x00ee, 0x0005, 0x001e, 0x0009,
+	0x0cc8, 0x00e6, 0xacf0, 0x0004, 0x2e74, 0x7000, 0x2070, 0x7037,
+	0x0103, 0x7023, 0x8001, 0x00ee, 0x0005, 0x00d6, 0x6618, 0x2668,
+	0x6804, 0xa084, 0x00ff, 0x00de, 0xa0b2, 0x000c, 0x1a0c, 0x14f6,
+	0x6604, 0xa6b6, 0x0043, 0x1120, 0x080c, 0x99c1, 0x0804, 0x8692,
+	0x6604, 0xa6b6, 0x0033, 0x1120, 0x080c, 0x9971, 0x0804, 0x8692,
+	0x6604, 0xa6b6, 0x0028, 0x1120, 0x080c, 0x97b9, 0x0804, 0x8692,
+	0x6604, 0xa6b6, 0x0029, 0x1118, 0x080c, 0x97d0, 0x04d8, 0x6604,
+	0xa6b6, 0x001f, 0x1118, 0x080c, 0x81dc, 0x04a0, 0x6604, 0xa6b6,
+	0x0000, 0x1118, 0x080c, 0x83f4, 0x0468, 0x6604, 0xa6b6, 0x0022,
+	0x1118, 0x080c, 0x8204, 0x0430, 0x6604, 0xa6b6, 0x0035, 0x1118,
+	0x080c, 0x826b, 0x00f8, 0x6604, 0xa6b6, 0x0039, 0x1118, 0x080c,
+	0x83a3, 0x00c0, 0x6604, 0xa6b6, 0x003d, 0x1118, 0x080c, 0x821e,
+	0x0088, 0x6604, 0xa6b6, 0x0044, 0x1118, 0x080c, 0x823e, 0x0050,
+	0xa1b6, 0x0015, 0x1110, 0x0053, 0x0028, 0xa1b6, 0x0016, 0x1118,
+	0x0804, 0x883f, 0x0005, 0x080c, 0x80be, 0x0ce0, 0x86b9, 0x86bc,
+	0x86b9, 0x86fe, 0x86b9, 0x87cc, 0x884d, 0x86b9, 0x86b9, 0x881b,
+	0x86b9, 0x882f, 0xa1b6, 0x0048, 0x0140, 0x20e1, 0x0005, 0x3d18,
+	0x3e20, 0x2c10, 0x080c, 0x1824, 0x0005, 0x00e6, 0xacf0, 0x0004,
+	0x2e74, 0x7000, 0x2070, 0x7037, 0x0103, 0x00ee, 0x080c, 0x8078,
+	0x0005, 0xe000, 0xe000, 0x0005, 0x00e6, 0x2071, 0xad00, 0x7080,
+	0xa086, 0x0074, 0x1530, 0x080c, 0xa6e9, 0x11b0, 0x00d6, 0x6018,
+	0x2068, 0x7030, 0xd08c, 0x0128, 0x6800, 0xd0bc, 0x0110, 0xc0c5,
+	0x6802, 0x00d9, 0x00de, 0x2001, 0x0006, 0x080c, 0x4c30, 0x080c,
+	0x2aff, 0x080c, 0x8078, 0x0078, 0x2001, 0x000a, 0x080c, 0x4c30,
+	0x080c, 0x2aff, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x67ee,
+	0x0010, 0x080c, 0x87bd, 0x00ee, 0x0005, 0x6800, 0xd084, 0x0168,
+	0x2001, 0x0000, 0x080c, 0x4c1e, 0x2069, 0xad51, 0x6804, 0xd0a4,
+	0x0120, 0x2001, 0x0006, 0x080c, 0x4c5d, 0x0005, 0x00d6, 0x2011,
+	0xad20, 0x2204, 0xa086, 0x0074, 0x1904, 0x87ba, 0x6018, 0x2068,
+	0x6aa0, 0xa286, 0x007e, 0x1120, 0x080c, 0x894d, 0x0804, 0x875e,
+	0x080c, 0x8943, 0x6018, 0x2068, 0xa080, 0x0028, 0x2014, 0xa286,
+	0x0080, 0x11c0, 0x6813, 0x00ff, 0x6817, 0xfffc, 0x6010, 0xa005,
+	0x0138, 0x2068, 0x6807, 0x0000, 0x6837, 0x0103, 0x6833, 0x0200,
+	0x2001, 0x0006, 0x080c, 0x4c30, 0x080c, 0x2aff, 0x080c, 0x8078,
+	0x0804, 0x87bb, 0x00e6, 0x2071, 0xad34, 0x2e04, 0xd09c, 0x0188,
+	0x2071, 0xb280, 0x7108, 0x720c, 0xa18c, 0x00ff, 0x1118, 0xa284,
+	0xff00, 0x0138, 0x6018, 0x2070, 0x70a0, 0xd0bc, 0x1110, 0x7112,
+	0x7216, 0x00ee, 0x6010, 0xa005, 0x0128, 0x2068, 0x6838, 0xd0f4,
+	0x0108, 0x0880, 0x2001, 0x0004, 0x080c, 0x4c30, 0x6003, 0x0001,
+	0x6007, 0x0003, 0x080c, 0x67ee, 0x0804, 0x87bb, 0x685c, 0xd0e4,
+	0x01d0, 0x080c, 0x9903, 0x080c, 0x574f, 0x0110, 0xd0dc, 0x1900,
+	0x2011, 0xad34, 0x2204, 0xc0ad, 0x2012, 0x2001, 0xaf8e, 0x2004,
+	0x00f6, 0x2079, 0x0100, 0x78e3, 0x0000, 0x080c, 0x26cb, 0x78e2,
+	0x00fe, 0x0804, 0x8728, 0x080c, 0x9937, 0x2011, 0xad34, 0x2204,
+	0xc0a5, 0x2012, 0x0006, 0x080c, 0xa801, 0x000e, 0x1904, 0x8728,
+	0xc0b5, 0x2012, 0x2001, 0x0000, 0x080c, 0x4c1e, 0x00c6, 0x2009,
+	0x00ef, 0x00f6, 0x2079, 0x0100, 0x79ea, 0x7932, 0x7936, 0x00fe,
+	0x080c, 0x26a0, 0x00f6, 0x2079, 0xad00, 0x7972, 0x2100, 0x2009,
+	0x0000, 0x080c, 0x2676, 0x794e, 0x00fe, 0x8108, 0x080c, 0x4c80,
+	0x2c00, 0x00ce, 0x1904, 0x8728, 0x601a, 0x2001, 0x0002, 0x080c,
+	0x4c30, 0x601f, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c,
+	0x67ee, 0x0008, 0x0011, 0x00de, 0x0005, 0x2001, 0xad00, 0x2004,
+	0xa086, 0x0003, 0x0120, 0x2001, 0x0007, 0x080c, 0x4c30, 0x080c,
+	0x2aff, 0x080c, 0x8078, 0x0005, 0x00e6, 0x0026, 0x0016, 0x2071,
+	0xad00, 0x7080, 0xa086, 0x0014, 0x15f0, 0x7000, 0xa086, 0x0003,
+	0x1128, 0x6010, 0xa005, 0x1110, 0x080c, 0x3cce, 0x00d6, 0x6018,
+	0x2068, 0x080c, 0x4d72, 0x080c, 0x86ed, 0x00de, 0x080c, 0x89f7,
+	0x1550, 0x00d6, 0x6018, 0x2068, 0x6890, 0x00de, 0xa005, 0x0518,
+	0x2001, 0x0006, 0x080c, 0x4c30, 0x00e6, 0x6010, 0xa075, 0x01a8,
+	0x7034, 0xa084, 0x00ff, 0xa086, 0x0039, 0x1148, 0x2001, 0x0000,
+	0x2009, 0x0000, 0x2011, 0x4000, 0x080c, 0x9a05, 0x0030, 0x7007,
+	0x0000, 0x7037, 0x0103, 0x7033, 0x0200, 0x00ee, 0x080c, 0x2aff,
+	0x080c, 0x8078, 0x0020, 0x080c, 0x85f3, 0x080c, 0x87bd, 0x001e,
+	0x002e, 0x00ee, 0x0005, 0x2011, 0xad20, 0x2204, 0xa086, 0x0014,
+	0x1158, 0x2001, 0x0002, 0x080c, 0x4c30, 0x6003, 0x0001, 0x6007,
+	0x0001, 0x080c, 0x67ee, 0x0010, 0x080c, 0x87bd, 0x0005, 0x2011,
+	0xad20, 0x2204, 0xa086, 0x0004, 0x1138, 0x2001, 0x0007, 0x080c,
+	0x4c30, 0x080c, 0x8078, 0x0010, 0x080c, 0x87bd, 0x0005, 0x000b,
+	0x0005, 0x86b9, 0x8854, 0x86b9, 0x888a, 0x86b9, 0x88ff, 0x884d,
+	0x86b9, 0x86b9, 0x8912, 0x86b9, 0x8922, 0x6604, 0xa6b6, 0x001e,
+	0x1110, 0x080c, 0x8078, 0x0005, 0x00d6, 0x00c6, 0x080c, 0x8932,
+	0x1178, 0x2001, 0x0000, 0x080c, 0x4c1e, 0x2001, 0x0002, 0x080c,
+	0x4c30, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x67ee, 0x00f8,
+	0x2009, 0xb28e, 0x2104, 0xa086, 0x0009, 0x1160, 0x6018, 0x2068,
+	0x6840, 0xa084, 0x00ff, 0xa005, 0x0180, 0x8001, 0x6842, 0x6017,
+	0x000a, 0x0068, 0x2009, 0xb28f, 0x2104, 0xa084, 0xff00, 0xa086,
+	0x1900, 0x1118, 0x080c, 0x8078, 0x0010, 0x080c, 0x87bd, 0x00ce,
+	0x00de, 0x0005, 0x080c, 0x8940, 0x00d6, 0x2069, 0xaf9d, 0x2d04,
+	0xa005, 0x0168, 0x6018, 0x2068, 0x68a0, 0xa086, 0x007e, 0x1138,
+	0x2069, 0xad1c, 0x2d04, 0x8000, 0x206a, 0x00de, 0x0010, 0x00de,
+	0x0078, 0x2001, 0x0000, 0x080c, 0x4c1e, 0x2001, 0x0002, 0x080c,
+	0x4c30, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x67ee, 0x0428,
+	0x080c, 0x85f3, 0x2009, 0xb28e, 0x2134, 0xa6b4, 0x00ff, 0xa686,
+	0x0005, 0x01e0, 0xa686, 0x000b, 0x01b0, 0x2009, 0xb28f, 0x2104,
+	0xa084, 0xff00, 0x1118, 0xa686, 0x0009, 0x0180, 0xa086, 0x1900,
+	0x1150, 0xa686, 0x0009, 0x0150, 0x2001, 0x0004, 0x080c, 0x4c30,
+	0x080c, 0x8078, 0x0010, 0x080c, 0x87bd, 0x0005, 0x00d6, 0x6010,
+	0x2068, 0x080c, 0x9596, 0x0128, 0x6838, 0xd0fc, 0x0110, 0x00de,
+	0x0c90, 0x6018, 0x2068, 0x6840, 0xa084, 0x00ff, 0xa005, 0x0140,
+	0x8001, 0x6842, 0x6017, 0x000a, 0x6007, 0x0016, 0x00de, 0x0c28,
+	0x68a0, 0xa086, 0x007e, 0x1138, 0x00e6, 0x2071, 0xad00, 0x080c,
+	0x48f5, 0x00ee, 0x0010, 0x080c, 0x2ad9, 0x00de, 0x08a0, 0x080c,
+	0x8940, 0x1158, 0x2001, 0x0004, 0x080c, 0x4c30, 0x6003, 0x0001,
+	0x6007, 0x0003, 0x080c, 0x67ee, 0x0020, 0x080c, 0x85f3, 0x080c,
+	0x87bd, 0x0005, 0x0469, 0x1158, 0x2001, 0x0008, 0x080c, 0x4c30,
+	0x6003, 0x0001, 0x6007, 0x0005, 0x080c, 0x67ee, 0x0010, 0x080c,
+	0x87bd, 0x0005, 0x00e9, 0x1158, 0x2001, 0x000a, 0x080c, 0x4c30,
+	0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x67ee, 0x0010, 0x080c,
+	0x87bd, 0x0005, 0x2009, 0xb28e, 0x2104, 0xa086, 0x0003, 0x1138,
+	0x2009, 0xb28f, 0x2104, 0xa084, 0xff00, 0xa086, 0x2a00, 0x0005,
+	0xa085, 0x0001, 0x0005, 0x00c6, 0x0016, 0xac88, 0x0006, 0x2164,
+	0x080c, 0x4ceb, 0x001e, 0x00ce, 0x0005, 0x00f6, 0x00e6, 0x00d6,
+	0x0036, 0x0016, 0x6018, 0x2068, 0x2071, 0xad34, 0x2e04, 0xa085,
+	0x0003, 0x2072, 0x080c, 0x89cc, 0x0538, 0x2001, 0xad52, 0x2004,
+	0xd0a4, 0x0158, 0xa006, 0x2020, 0x2009, 0x002a, 0x080c, 0xa96c,
+	0x2001, 0xad0c, 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x2009,
+	0x0001, 0x080c, 0x2aac, 0x2071, 0xad00, 0x080c, 0x28fa, 0x00c6,
+	0x0156, 0x20a9, 0x0081, 0x2009, 0x007f, 0x080c, 0x2bc9, 0x8108,
+	0x1f04, 0x897d, 0x015e, 0x00ce, 0x080c, 0x8943, 0x6813, 0x00ff,
+	0x6817, 0xfffe, 0x2071, 0xb280, 0x2079, 0x0100, 0x2e04, 0xa084,
+	0x00ff, 0x2069, 0xad1b, 0x206a, 0x78e6, 0x0006, 0x8e70, 0x2e04,
+	0x2069, 0xad1c, 0x206a, 0x78ea, 0x7832, 0x7836, 0x2010, 0xa084,
+	0xff00, 0x001e, 0xa105, 0x2009, 0xad27, 0x200a, 0x2200, 0xa084,
+	0x00ff, 0x2008, 0x080c, 0x26a0, 0x080c, 0x574f, 0x0170, 0x2069,
+	0xb28e, 0x2071, 0xaf9f, 0x6810, 0x2072, 0x6814, 0x7006, 0x6818,
+	0x700a, 0x681c, 0x700e, 0x080c, 0x9903, 0x0040, 0x2001, 0x0006,
+	0x080c, 0x4c30, 0x080c, 0x2aff, 0x080c, 0x8078, 0x001e, 0x003e,
+	0x00de, 0x00ee, 0x00fe, 0x0005, 0x0026, 0x0036, 0x00e6, 0x0156,
+	0x2019, 0xad27, 0x231c, 0x83ff, 0x01e8, 0x2071, 0xb280, 0x2e14,
+	0xa294, 0x00ff, 0x7004, 0xa084, 0xff00, 0xa205, 0xa306, 0x1190,
+	0x2011, 0xb296, 0xad98, 0x000a, 0x20a9, 0x0004, 0x080c, 0x8a7c,
+	0x1148, 0x2011, 0xb29a, 0xad98, 0x0006, 0x20a9, 0x0004, 0x080c,
+	0x8a7c, 0x1100, 0x015e, 0x00ee, 0x003e, 0x002e, 0x0005, 0x00e6,
+	0x2071, 0xb28c, 0x7004, 0xa086, 0x0014, 0x11a8, 0x7008, 0xa086,
+	0x0800, 0x1188, 0x700c, 0xd0ec, 0x0160, 0xa084, 0x0f00, 0xa086,
+	0x0100, 0x1138, 0x7024, 0xd0a4, 0x1110, 0xd0ac, 0x0110, 0xa006,
+	0x0010, 0xa085, 0x0001, 0x00ee, 0x0005, 0x00e6, 0x00d6, 0x00c6,
+	0x0076, 0x0056, 0x0046, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000,
+	0x2029, 0xafd0, 0x252c, 0x2021, 0xafd6, 0x2424, 0x2061, 0xb400,
+	0x2071, 0xad00, 0x7244, 0x7064, 0xa202, 0x16f0, 0x080c, 0xa990,
+	0x05a0, 0x671c, 0xa786, 0x0001, 0x0580, 0xa786, 0x0007, 0x0568,
+	0x2500, 0xac06, 0x0550, 0x2400, 0xac06, 0x0538, 0x00c6, 0x6000,
+	0xa086, 0x0004, 0x1110, 0x080c, 0x190b, 0xa786, 0x0008, 0x1148,
+	0x080c, 0x9789, 0x1130, 0x00ce, 0x080c, 0x85f3, 0x080c, 0x974e,
+	0x00a0, 0x6010, 0x2068, 0x080c, 0x9596, 0x0160, 0xa786, 0x0003,
+	0x11e8, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x510c,
+	0x080c, 0x9742, 0x080c, 0x974e, 0x00ce, 0xace0, 0x0018, 0x7058,
+	0xac02, 0x1210, 0x0804, 0x8a2a, 0x012e, 0x000e, 0x002e, 0x004e,
+	0x005e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0xa786, 0x0006,
+	0x1d00, 0x080c, 0xa91f, 0x0c30, 0x220c, 0x2304, 0xa106, 0x1130,
+	0x8210, 0x8318, 0x1f04, 0x8a7c, 0xa006, 0x0005, 0x2304, 0xa102,
+	0x0218, 0x2001, 0x0001, 0x0010, 0x2001, 0x0000, 0xa18d, 0x0001,
+	0x0005, 0x6004, 0xa08a, 0x0080, 0x1a0c, 0x14f6, 0x080c, 0x9778,
+	0x0120, 0x080c, 0x9789, 0x0168, 0x0028, 0x080c, 0x2aff, 0x080c,
+	0x9789, 0x0138, 0x080c, 0x6b73, 0x080c, 0x8078, 0x080c, 0x6c50,
+	0x0005, 0x080c, 0x85f3, 0x0cb0, 0xa182, 0x0040, 0x0002, 0x8ac2,
+	0x8ac2, 0x8ac2, 0x8ac2, 0x8ac2, 0x8ac2, 0x8ac2, 0x8ac2, 0x8ac2,
+	0x8ac2, 0x8ac2, 0x8ac4, 0x8ac4, 0x8ac4, 0x8ac4, 0x8ac2, 0x8ac2,
+	0x8ac2, 0x8ac4, 0x080c, 0x14f6, 0x600b, 0xffff, 0x6003, 0x0001,
+	0x6106, 0x080c, 0x67a8, 0x0126, 0x2091, 0x8000, 0x080c, 0x6c50,
+	0x012e, 0x0005, 0xa186, 0x0013, 0x1128, 0x6004, 0xa082, 0x0040,
+	0x0804, 0x8b5e, 0xa186, 0x0027, 0x11e8, 0x080c, 0x6b73, 0x080c,
+	0x2ad9, 0x00d6, 0x6110, 0x2168, 0x080c, 0x9596, 0x0168, 0x6837,
+	0x0103, 0x684b, 0x0029, 0x6847, 0x0000, 0x694c, 0xc1c5, 0x694e,
+	0x080c, 0x510c, 0x080c, 0x9742, 0x00de, 0x080c, 0x8078, 0x080c,
+	0x6c50, 0x0005, 0xa186, 0x0014, 0x1120, 0x6004, 0xa082, 0x0040,
+	0x0428, 0xa186, 0x0046, 0x0138, 0xa186, 0x0045, 0x0120, 0xa186,
+	0x0047, 0x190c, 0x14f6, 0x2001, 0x0109, 0x2004, 0xd084, 0x0198,
+	0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x080c, 0x6699,
+	0x002e, 0x001e, 0x000e, 0x012e, 0xe000, 0x6000, 0xa086, 0x0002,
+	0x1110, 0x0804, 0x8b98, 0x080c, 0x80be, 0x0005, 0x0002, 0x8b3c,
+	0x8b3a, 0x8b3a, 0x8b3a, 0x8b3a, 0x8b3a, 0x8b3a, 0x8b3a, 0x8b3a,
+	0x8b3a, 0x8b3a, 0x8b57, 0x8b57, 0x8b57, 0x8b57, 0x8b3a, 0x8b57,
+	0x8b3a, 0x8b57, 0x080c, 0x14f6, 0x080c, 0x6b73, 0x00d6, 0x6110,
+	0x2168, 0x080c, 0x9596, 0x0168, 0x6837, 0x0103, 0x684b, 0x0006,
+	0x6847, 0x0000, 0x6850, 0xc0ec, 0x6852, 0x080c, 0x510c, 0x080c,
+	0x9742, 0x00de, 0x080c, 0x8078, 0x080c, 0x6c50, 0x0005, 0x080c,
+	0x6b73, 0x080c, 0x8078, 0x080c, 0x6c50, 0x0005, 0x0002, 0x8b74,
+	0x8b72, 0x8b72, 0x8b72, 0x8b72, 0x8b72, 0x8b72, 0x8b72, 0x8b72,
+	0x8b72, 0x8b72, 0x8b86, 0x8b86, 0x8b86, 0x8b86, 0x8b72, 0x8b91,
+	0x8b72, 0x8b86, 0x080c, 0x14f6, 0x080c, 0x6b73, 0x2001, 0xafa5,
+	0x2004, 0x603e, 0x6003, 0x0002, 0x080c, 0x6c50, 0x6010, 0xa088,
+	0x0013, 0x2104, 0xa085, 0x0400, 0x200a, 0x0005, 0x080c, 0x6b73,
+	0x2001, 0xafa5, 0x2004, 0x603e, 0x6003, 0x000f, 0x080c, 0x6c50,
+	0x0005, 0x080c, 0x6b73, 0x080c, 0x8078, 0x080c, 0x6c50, 0x0005,
+	0xa182, 0x0040, 0x0002, 0x8bae, 0x8bae, 0x8bae, 0x8bae, 0x8bae,
+	0x8bb0, 0x8c88, 0x8ca9, 0x8bae, 0x8bae, 0x8bae, 0x8bae, 0x8bae,
+	0x8bae, 0x8bae, 0x8bae, 0x8bae, 0x8bae, 0x8bae, 0x080c, 0x14f6,
+	0x00e6, 0x00d6, 0x603f, 0x0000, 0x2071, 0xb280, 0x7124, 0x610a,
+	0x2071, 0xb28c, 0x6110, 0x2168, 0x7614, 0xa6b4, 0x0fff, 0x86ff,
+	0x0904, 0x8c54, 0xa68c, 0x0c00, 0x01e8, 0x00f6, 0x2c78, 0x080c,
+	0x5029, 0x00fe, 0x0198, 0x684c, 0xd0ac, 0x0180, 0x6020, 0xd0dc,
+	0x1168, 0x6850, 0xd0bc, 0x1150, 0x7318, 0x6814, 0xa306, 0x1904,
+	0x8c66, 0x731c, 0x6810, 0xa306, 0x1904, 0x8c66, 0x7318, 0x6b62,
+	0x731c, 0x6b5e, 0xa68c, 0x00ff, 0xa186, 0x0002, 0x0518, 0xa186,
+	0x0028, 0x1128, 0x080c, 0x9767, 0x684b, 0x001c, 0x00e8, 0xd6dc,
+	0x01a0, 0x684b, 0x0015, 0x684c, 0xd0ac, 0x0170, 0x6914, 0x6a10,
+	0x2100, 0xa205, 0x0148, 0x7018, 0xa106, 0x1118, 0x701c, 0xa206,
+	0x0118, 0x6962, 0x6a5e, 0xc6dc, 0x0038, 0xd6d4, 0x0118, 0x684b,
+	0x0007, 0x0010, 0x684b, 0x0000, 0x6837, 0x0103, 0x6e46, 0xa01e,
+	0xd6c4, 0x01f0, 0xa686, 0x0100, 0x1140, 0x2001, 0xb299, 0x2004,
+	0xa005, 0x1118, 0xc6c4, 0x0804, 0x8bbf, 0x7328, 0x732c, 0x6b56,
+	0x83ff, 0x0170, 0xa38a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036,
+	0x2308, 0x2019, 0xb298, 0xad90, 0x0019, 0x080c, 0x927f, 0x003e,
+	0xd6cc, 0x0904, 0x8c79, 0x7124, 0x695a, 0x81ff, 0x0904, 0x8c79,
+	0xa192, 0x0021, 0x1250, 0x2071, 0xb298, 0x831c, 0x2300, 0xae18,
+	0xad90, 0x001d, 0x080c, 0x927f, 0x04a0, 0x6838, 0xd0fc, 0x0120,
+	0x2009, 0x0020, 0x695a, 0x0c78, 0x00f6, 0x2d78, 0x080c, 0x9224,
+	0x00fe, 0x080c, 0x926f, 0x0438, 0x00f6, 0x2c78, 0x080c, 0x5029,
+	0x00fe, 0x0188, 0x684c, 0xd0ac, 0x0170, 0x6020, 0xd0dc, 0x1158,
+	0x6850, 0xd0bc, 0x1140, 0x684c, 0xd0f4, 0x1128, 0x080c, 0x9866,
+	0x00de, 0x00ee, 0x00e0, 0x684b, 0x0000, 0x6837, 0x0103, 0x6e46,
+	0x684c, 0xd0ac, 0x0130, 0x6810, 0x6914, 0xa115, 0x0110, 0x080c,
+	0x8e04, 0x080c, 0x510c, 0x6218, 0x2268, 0x6a3c, 0x8211, 0x6a3e,
+	0x080c, 0x9834, 0x00de, 0x00ee, 0x1110, 0x080c, 0x8078, 0x0005,
+	0x00f6, 0x6003, 0x0003, 0x2079, 0xb28c, 0x7c04, 0x7b00, 0x7e0c,
+	0x7d08, 0x6010, 0x2078, 0x784c, 0xd0ac, 0x0120, 0x6003, 0x0002,
+	0x00fe, 0x0005, 0x7c12, 0x7b16, 0x7e0a, 0x7d0e, 0x00fe, 0x603f,
+	0x0000, 0x2c10, 0x080c, 0x1e6e, 0x080c, 0x680b, 0x080c, 0x6d0d,
+	0x0005, 0x2001, 0xafa5, 0x2004, 0x603e, 0x6003, 0x0004, 0x6110,
+	0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x1824, 0x0005,
+	0xa182, 0x0040, 0x0002, 0x8cce, 0x8cce, 0x8cce, 0x8cce, 0x8cce,
+	0x8cd0, 0x8d61, 0x8cce, 0x8cce, 0x8d77, 0x8ddb, 0x8cce, 0x8cce,
+	0x8cce, 0x8cce, 0x8dea, 0x8cce, 0x8cce, 0x8cce, 0x080c, 0x14f6,
+	0x0076, 0x00f6, 0x00e6, 0x00d6, 0x2071, 0xb28c, 0x6110, 0x2178,
+	0x7614, 0xa6b4, 0x0fff, 0x7e46, 0x7f4c, 0xc7e5, 0x7f4e, 0x6218,
+	0x2268, 0x6a3c, 0x8211, 0x6a3e, 0x86ff, 0x0904, 0x8d5c, 0xa694,
+	0xff00, 0xa284, 0x0c00, 0x0120, 0x7018, 0x7862, 0x701c, 0x785e,
+	0xa284, 0x0300, 0x0904, 0x8d5c, 0x080c, 0x15d9, 0x090c, 0x14f6,
+	0x2d00, 0x784a, 0x7f4c, 0xc7cd, 0x7f4e, 0x6837, 0x0103, 0x7838,
+	0x683a, 0x783c, 0x683e, 0x7840, 0x6842, 0x6e46, 0xa68c, 0x0c00,
+	0x0120, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff, 0xa186,
+	0x0002, 0x0180, 0xa186, 0x0028, 0x1118, 0x684b, 0x001c, 0x0060,
+	0xd6dc, 0x0118, 0x684b, 0x0015, 0x0038, 0xd6d4, 0x0118, 0x684b,
+	0x0007, 0x0010, 0x684b, 0x0000, 0x6f4e, 0x7850, 0x6852, 0x7854,
+	0x6856, 0xa01e, 0xd6c4, 0x0198, 0x7328, 0x732c, 0x6b56, 0x83ff,
+	0x0170, 0xa38a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036, 0x2308,
+	0x2019, 0xb298, 0xad90, 0x0019, 0x080c, 0x927f, 0x003e, 0xd6cc,
+	0x01d8, 0x7124, 0x695a, 0x81ff, 0x01b8, 0xa192, 0x0021, 0x1250,
+	0x2071, 0xb298, 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x080c,
+	0x927f, 0x0050, 0x7838, 0xd0fc, 0x0120, 0x2009, 0x0020, 0x695a,
+	0x0c78, 0x2d78, 0x080c, 0x9224, 0x00de, 0x00ee, 0x00fe, 0x007e,
+	0x0005, 0x00f6, 0x6003, 0x0003, 0x2079, 0xb28c, 0x7c04, 0x7b00,
+	0x7e0c, 0x7d08, 0x6010, 0x2078, 0x7c12, 0x7b16, 0x7e0a, 0x7d0e,
+	0x00fe, 0x2c10, 0x080c, 0x1e6e, 0x080c, 0x781a, 0x0005, 0x00d6,
+	0x00f6, 0x2c78, 0x080c, 0x5029, 0x00fe, 0x0120, 0x2001, 0xafa5,
+	0x2004, 0x603e, 0x6003, 0x0002, 0x080c, 0x6c05, 0x080c, 0x6d0d,
+	0x6110, 0x2168, 0x694c, 0xd1e4, 0x0904, 0x8dd9, 0xd1cc, 0x0540,
+	0x6948, 0x6838, 0xd0fc, 0x01e8, 0x0016, 0x684c, 0x0006, 0x6850,
+	0x0006, 0xad90, 0x000d, 0xa198, 0x000d, 0x2009, 0x0020, 0x0156,
+	0x21a8, 0x2304, 0x2012, 0x8318, 0x8210, 0x1f04, 0x8da1, 0x015e,
+	0x000e, 0x6852, 0x000e, 0x684e, 0x001e, 0x2168, 0x080c, 0x1600,
+	0x0418, 0x0016, 0x080c, 0x1600, 0x00de, 0x080c, 0x926f, 0x00e0,
+	0x6837, 0x0103, 0x6944, 0xa184, 0x00ff, 0xa0b6, 0x0002, 0x0180,
+	0xa086, 0x0028, 0x1118, 0x684b, 0x001c, 0x0060, 0xd1dc, 0x0118,
+	0x684b, 0x0015, 0x0038, 0xd1d4, 0x0118, 0x684b, 0x0007, 0x0010,
+	0x684b, 0x0000, 0x080c, 0x510c, 0x080c, 0x9834, 0x1110, 0x080c,
+	0x8078, 0x00de, 0x0005, 0x2019, 0x0001, 0x080c, 0x7a64, 0x6003,
+	0x0002, 0x2001, 0xafa5, 0x2004, 0x603e, 0x080c, 0x6c05, 0x080c,
+	0x6d0d, 0x0005, 0x080c, 0x6c05, 0x080c, 0x2ad9, 0x00d6, 0x6110,
+	0x2168, 0x080c, 0x9596, 0x0150, 0x6837, 0x0103, 0x684b, 0x0029,
+	0x6847, 0x0000, 0x080c, 0x510c, 0x080c, 0x9742, 0x00de, 0x080c,
+	0x8078, 0x080c, 0x6d0d, 0x0005, 0x684b, 0x0015, 0xd1fc, 0x0138,
+	0x684b, 0x0007, 0x8002, 0x8000, 0x810a, 0xa189, 0x0000, 0x6962,
+	0x685e, 0x0005, 0xa182, 0x0040, 0x0002, 0x8e28, 0x8e28, 0x8e28,
+	0x8e28, 0x8e28, 0x8e2a, 0x8e28, 0x8ee3, 0x8eef, 0x8e28, 0x8e28,
+	0x8e28, 0x8e28, 0x8e28, 0x8e28, 0x8e28, 0x8e28, 0x8e28, 0x8e28,
+	0x080c, 0x14f6, 0x0076, 0x00f6, 0x00e6, 0x00d6, 0x2071, 0xb28c,
+	0x6110, 0x2178, 0x7614, 0xa6b4, 0x0fff, 0x00f6, 0x2c78, 0x080c,
+	0x5029, 0x00fe, 0x0150, 0xa684, 0x00ff, 0x1138, 0x6020, 0xd0f4,
+	0x0120, 0x080c, 0x9866, 0x0804, 0x8ede, 0x7e46, 0x7f4c, 0xc7e5,
+	0x7f4e, 0x6218, 0x2268, 0x6a3c, 0x8211, 0x6a3e, 0x86ff, 0x0904,
+	0x8ed4, 0xa694, 0xff00, 0xa284, 0x0c00, 0x0120, 0x7018, 0x7862,
+	0x701c, 0x785e, 0xa284, 0x0300, 0x0904, 0x8ed2, 0xa686, 0x0100,
+	0x1140, 0x2001, 0xb299, 0x2004, 0xa005, 0x1118, 0xc6c4, 0x7e46,
+	0x0c28, 0x080c, 0x15d9, 0x090c, 0x14f6, 0x2d00, 0x784a, 0x7f4c,
+	0xa7bd, 0x0200, 0x7f4e, 0x6837, 0x0103, 0x7838, 0x683a, 0x783c,
+	0x683e, 0x7840, 0x6842, 0x6e46, 0xa68c, 0x0c00, 0x0120, 0x7318,
+	0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff, 0xa186, 0x0002, 0x0180,
+	0xa186, 0x0028, 0x1118, 0x684b, 0x001c, 0x0060, 0xd6dc, 0x0118,
+	0x684b, 0x0015, 0x0038, 0xd6d4, 0x0118, 0x684b, 0x0007, 0x0010,
+	0x684b, 0x0000, 0x6f4e, 0x7850, 0x6852, 0x7854, 0x6856, 0xa01e,
+	0xd6c4, 0x0198, 0x7328, 0x732c, 0x6b56, 0x83ff, 0x0170, 0xa38a,
+	0x0009, 0x0210, 0x2019, 0x0008, 0x0036, 0x2308, 0x2019, 0xb298,
+	0xad90, 0x0019, 0x080c, 0x927f, 0x003e, 0xd6cc, 0x01d8, 0x7124,
+	0x695a, 0x81ff, 0x01b8, 0xa192, 0x0021, 0x1250, 0x2071, 0xb298,
+	0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x080c, 0x927f, 0x0050,
+	0x7838, 0xd0fc, 0x0120, 0x2009, 0x0020, 0x695a, 0x0c78, 0x2d78,
+	0x080c, 0x9224, 0xd6dc, 0x1110, 0xa006, 0x0030, 0x2001, 0x0001,
+	0x2071, 0xb28c, 0x7218, 0x731c, 0x080c, 0x186f, 0x00de, 0x00ee,
+	0x00fe, 0x007e, 0x0005, 0x2001, 0xafa5, 0x2004, 0x603e, 0x20e1,
+	0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x1824, 0x0005, 0x2001,
+	0xafa5, 0x2004, 0x603e, 0x00d6, 0x6003, 0x0002, 0x6110, 0x2168,
+	0x694c, 0xd1e4, 0x0904, 0x8ff3, 0x603f, 0x0000, 0x00f6, 0x2c78,
+	0x080c, 0x5029, 0x00fe, 0x0548, 0x6814, 0x6910, 0xa115, 0x0528,
+	0x6a60, 0xa206, 0x1118, 0x685c, 0xa106, 0x01f8, 0x684c, 0xc0e4,
+	0x684e, 0x6847, 0x0000, 0x6863, 0x0000, 0x685f, 0x0000, 0x697c,
+	0x6810, 0xa102, 0x603a, 0x6980, 0x6814, 0xa103, 0x6036, 0x6020,
+	0xc0f5, 0x6022, 0x00d6, 0x6018, 0x2068, 0x683c, 0x8000, 0x683e,
+	0x00de, 0x080c, 0x9866, 0x0804, 0x8ff3, 0x694c, 0xd1cc, 0x0904,
+	0x8fc3, 0x6948, 0x6838, 0xd0fc, 0x0904, 0x8f88, 0x0016, 0x684c,
+	0x0006, 0x6850, 0x0006, 0x00f6, 0x2178, 0x7944, 0xa184, 0x00ff,
+	0xa0b6, 0x0002, 0x01e0, 0xa086, 0x0028, 0x1128, 0x684b, 0x001c,
+	0x784b, 0x001c, 0x00e8, 0xd1dc, 0x0158, 0x684b, 0x0015, 0x784b,
+	0x0015, 0x080c, 0x99ee, 0x0118, 0x7944, 0xc1dc, 0x7946, 0x0080,
+	0xd1d4, 0x0128, 0x684b, 0x0007, 0x784b, 0x0007, 0x0048, 0x684c,
+	0xd0ac, 0x0130, 0x6810, 0x6914, 0xa115, 0x0110, 0x080c, 0x8e04,
+	0x6848, 0x784a, 0x6860, 0x7862, 0x685c, 0x785e, 0xad90, 0x000d,
+	0xaf98, 0x000d, 0x2009, 0x0020, 0x0156, 0x21a8, 0x2304, 0x2012,
+	0x8318, 0x8210, 0x1f04, 0x8f76, 0x015e, 0x00fe, 0x000e, 0x6852,
+	0x000e, 0x684e, 0x001e, 0x2168, 0x080c, 0x1600, 0x0804, 0x8fee,
+	0x0016, 0x00f6, 0x2178, 0x7944, 0xa184, 0x00ff, 0xa0b6, 0x0002,
+	0x01e0, 0xa086, 0x0028, 0x1128, 0x684b, 0x001c, 0x784b, 0x001c,
+	0x00e8, 0xd1dc, 0x0158, 0x684b, 0x0015, 0x784b, 0x0015, 0x080c,
+	0x99ee, 0x0118, 0x7944, 0xc1dc, 0x7946, 0x0080, 0xd1d4, 0x0128,
+	0x684b, 0x0007, 0x784b, 0x0007, 0x0048, 0x684c, 0xd0ac, 0x0130,
+	0x6810, 0x6914, 0xa115, 0x0110, 0x080c, 0x8e04, 0x6860, 0x7862,
+	0x685c, 0x785e, 0x684c, 0x784e, 0x00fe, 0x080c, 0x1600, 0x00de,
+	0x080c, 0x926f, 0x0458, 0x6837, 0x0103, 0x6944, 0xa184, 0x00ff,
+	0xa0b6, 0x0002, 0x01b0, 0xa086, 0x0028, 0x1118, 0x684b, 0x001c,
+	0x00d8, 0xd1dc, 0x0148, 0x684b, 0x0015, 0x080c, 0x99ee, 0x0118,
+	0x6944, 0xc1dc, 0x6946, 0x0080, 0xd1d4, 0x0118, 0x684b, 0x0007,
+	0x0058, 0x684b, 0x0000, 0x684c, 0xd0ac, 0x0130, 0x6810, 0x6914,
+	0xa115, 0x0110, 0x080c, 0x8e04, 0x080c, 0x510c, 0x080c, 0x9834,
+	0x1110, 0x080c, 0x8078, 0x00de, 0x0005, 0x080c, 0x6b73, 0x0010,
+	0x080c, 0x6c05, 0x080c, 0x9596, 0x01c0, 0x00d6, 0x6110, 0x2168,
+	0x6837, 0x0103, 0x2009, 0xad0c, 0x210c, 0xd18c, 0x11c0, 0xd184,
+	0x1198, 0x6108, 0x694a, 0xa18e, 0x0029, 0x1110, 0x080c, 0xabfa,
+	0x6847, 0x0000, 0x080c, 0x510c, 0x00de, 0x080c, 0x8078, 0x080c,
+	0x6c50, 0x080c, 0x6d0d, 0x0005, 0x684b, 0x0004, 0x0c88, 0x684b,
+	0x0004, 0x0c70, 0xa182, 0x0040, 0x0002, 0x9038, 0x9038, 0x9038,
+	0x9038, 0x9038, 0x903a, 0x9038, 0x903d, 0x9038, 0x9038, 0x9038,
+	0x9038, 0x9038, 0x9038, 0x9038, 0x9038, 0x9038, 0x9038, 0x9038,
+	0x080c, 0x14f6, 0x080c, 0x8078, 0x0005, 0x0006, 0x0026, 0xa016,
+	0x080c, 0x1824, 0x002e, 0x000e, 0x0005, 0xa182, 0x0085, 0x0002,
+	0x9051, 0x904f, 0x904f, 0x905d, 0x904f, 0x904f, 0x904f, 0x080c,
+	0x14f6, 0x6003, 0x0001, 0x6106, 0x080c, 0x67a8, 0x0126, 0x2091,
+	0x8000, 0x080c, 0x6c50, 0x012e, 0x0005, 0x0026, 0x0056, 0x00d6,
+	0x00e6, 0x2071, 0xb280, 0x7224, 0x6212, 0x7220, 0x080c, 0x9586,
+	0x01a0, 0x2268, 0x6800, 0xa086, 0x0000, 0x0178, 0x6018, 0x6d18,
+	0xa52e, 0x1158, 0x00c6, 0x2d60, 0x080c, 0x928f, 0x00ce, 0x0128,
+	0x6803, 0x0002, 0x6007, 0x0086, 0x0010, 0x6007, 0x0087, 0x6003,
+	0x0001, 0x080c, 0x67a8, 0x080c, 0x6c50, 0x00f6, 0x2278, 0x080c,
+	0x5029, 0x00fe, 0x0150, 0x6820, 0xd0ec, 0x0138, 0x00c6, 0x2260,
+	0x603f, 0x0000, 0x080c, 0x9866, 0x00ce, 0x00ee, 0x00de, 0x005e,
+	0x002e, 0x0005, 0xa186, 0x0013, 0x1160, 0x6004, 0xa08a, 0x0085,
+	0x0a0c, 0x14f6, 0xa08a, 0x008c, 0x1a0c, 0x14f6, 0xa082, 0x0085,
+	0x0072, 0xa186, 0x0027, 0x0120, 0xa186, 0x0014, 0x190c, 0x14f6,
+	0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50, 0x0005, 0x90be,
+	0x90c0, 0x90c0, 0x90be, 0x90be, 0x90be, 0x90be, 0x080c, 0x14f6,
+	0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50, 0x0005, 0xa186,
+	0x0013, 0x1128, 0x6004, 0xa082, 0x0085, 0x2008, 0x04a8, 0xa186,
+	0x0027, 0x11e8, 0x080c, 0x6b73, 0x080c, 0x2ad9, 0x00d6, 0x6010,
+	0x2068, 0x080c, 0x9596, 0x0150, 0x6837, 0x0103, 0x6847, 0x0000,
+	0x684b, 0x0029, 0x080c, 0x510c, 0x080c, 0x9742, 0x00de, 0x080c,
+	0x8078, 0x080c, 0x6c50, 0x0005, 0x080c, 0x80be, 0x0ce0, 0xa186,
+	0x0014, 0x1dd0, 0x080c, 0x6b73, 0x00d6, 0x6010, 0x2068, 0x080c,
+	0x9596, 0x0d60, 0x6837, 0x0103, 0x6847, 0x0000, 0x684b, 0x0006,
+	0x6850, 0xc0ec, 0x6852, 0x08f0, 0x0002, 0x910e, 0x910c, 0x910c,
+	0x910c, 0x910c, 0x910c, 0x9126, 0x080c, 0x14f6, 0x080c, 0x6b73,
+	0x6030, 0xa08c, 0xff00, 0x810f, 0xa186, 0x0039, 0x0118, 0xa186,
+	0x0035, 0x1118, 0x2001, 0xafa3, 0x0010, 0x2001, 0xafa4, 0x2004,
+	0x6016, 0x6003, 0x000c, 0x080c, 0x6c50, 0x0005, 0x080c, 0x6b73,
+	0x6030, 0xa08c, 0xff00, 0x810f, 0xa186, 0x0039, 0x0118, 0xa186,
+	0x0035, 0x1118, 0x2001, 0xafa3, 0x0010, 0x2001, 0xafa4, 0x2004,
+	0x6016, 0x6003, 0x000e, 0x080c, 0x6c50, 0x0005, 0xa182, 0x008c,
+	0x1220, 0xa182, 0x0085, 0x0208, 0x001a, 0x080c, 0x80be, 0x0005,
+	0x914f, 0x914f, 0x914f, 0x914f, 0x9151, 0x91a4, 0x914f, 0x080c,
+	0x14f6, 0x00d6, 0x00f6, 0x2c78, 0x080c, 0x5029, 0x00fe, 0x0168,
+	0x6030, 0xa08c, 0xff00, 0x810f, 0xa186, 0x0039, 0x0118, 0xa186,
+	0x0035, 0x1118, 0x00de, 0x0804, 0x91b7, 0x080c, 0x9742, 0x080c,
+	0x9596, 0x01c8, 0x6010, 0x2068, 0x6837, 0x0103, 0x6850, 0xd0b4,
+	0x0128, 0x684b, 0x0006, 0xc0ec, 0x6852, 0x0048, 0xd0bc, 0x0118,
+	0x684b, 0x0002, 0x0020, 0x684b, 0x0005, 0x080c, 0x9803, 0x6847,
+	0x0000, 0x080c, 0x510c, 0x2c68, 0x080c, 0x8022, 0x01c0, 0x6003,
+	0x0001, 0x6007, 0x001e, 0x600b, 0xffff, 0x2009, 0xb28e, 0x210c,
+	0x6136, 0x2009, 0xb28f, 0x210c, 0x613a, 0x6918, 0x611a, 0x080c,
+	0x9956, 0x6950, 0x6152, 0x601f, 0x0001, 0x080c, 0x67a8, 0x2d60,
+	0x080c, 0x8078, 0x00de, 0x0005, 0x00f6, 0x2c78, 0x080c, 0x5029,
+	0x00fe, 0x0598, 0x6030, 0xa08c, 0xff00, 0x810f, 0xa186, 0x0035,
+	0x0130, 0xa186, 0x001e, 0x0118, 0xa186, 0x0039, 0x1530, 0x00d6,
+	0x2c68, 0x080c, 0x9a34, 0x1904, 0x91fc, 0x080c, 0x8022, 0x01d8,
+	0x6106, 0x6003, 0x0001, 0x601f, 0x0001, 0x6918, 0x611a, 0x6928,
+	0x612a, 0x692c, 0x612e, 0x6930, 0xa18c, 0x00ff, 0x6132, 0x6934,
+	0x6136, 0x6938, 0x613a, 0x6950, 0x6152, 0x080c, 0x9956, 0x080c,
+	0x67a8, 0x080c, 0x6c50, 0x2d60, 0x00f8, 0x00d6, 0x6010, 0x2068,
+	0x080c, 0x9596, 0x01c8, 0x6837, 0x0103, 0x6850, 0xd0b4, 0x0128,
+	0xc0ec, 0x6852, 0x684b, 0x0006, 0x0048, 0xd0bc, 0x0118, 0x684b,
+	0x0002, 0x0020, 0x684b, 0x0005, 0x080c, 0x9803, 0x6847, 0x0000,
+	0x080c, 0x510c, 0x080c, 0x9742, 0x00de, 0x080c, 0x8078, 0x0005,
+	0x0016, 0x00d6, 0x6010, 0x2068, 0x080c, 0x9596, 0x0140, 0x6837,
+	0x0103, 0x684b, 0x0028, 0x6847, 0x0000, 0x080c, 0x510c, 0x00de,
+	0x001e, 0xa186, 0x0013, 0x0148, 0xa186, 0x0014, 0x0130, 0xa186,
+	0x0027, 0x0118, 0x080c, 0x80be, 0x0030, 0x080c, 0x6b73, 0x080c,
+	0x974e, 0x080c, 0x6c50, 0x0005, 0x0056, 0x0066, 0x00d6, 0x00f6,
+	0x2029, 0x0001, 0xa182, 0x0101, 0x1208, 0x0010, 0x2009, 0x0100,
+	0x2130, 0x2069, 0xb298, 0x831c, 0x2300, 0xad18, 0x2009, 0x0020,
+	0xaf90, 0x001d, 0x080c, 0x927f, 0xa6b2, 0x0020, 0x7804, 0xa06d,
+	0x0110, 0x080c, 0x1600, 0x080c, 0x15d9, 0x0500, 0x8528, 0x6837,
+	0x0110, 0x683b, 0x0000, 0x2d20, 0x7c06, 0xa68a, 0x003d, 0x1228,
+	0x2608, 0xad90, 0x000f, 0x0459, 0x0088, 0xa6b2, 0x003c, 0x2009,
+	0x003c, 0x2d78, 0xad90, 0x000f, 0x0411, 0x0c28, 0x00fe, 0x852f,
+	0xa5ad, 0x0003, 0x7d36, 0xa5ac, 0x0000, 0x0028, 0x00fe, 0x852f,
+	0xa5ad, 0x0003, 0x7d36, 0x00de, 0x006e, 0x005e, 0x0005, 0x00f6,
+	0x8dff, 0x0158, 0x6804, 0xa07d, 0x0130, 0x6807, 0x0000, 0x080c,
+	0x510c, 0x2f68, 0x0cb8, 0x080c, 0x510c, 0x00fe, 0x0005, 0x0156,
+	0xa184, 0x0001, 0x0108, 0x8108, 0x810c, 0x21a8, 0x2304, 0x8007,
+	0x2012, 0x8318, 0x8210, 0x1f04, 0x9286, 0x015e, 0x0005, 0x0066,
+	0x0126, 0x2091, 0x8000, 0x2031, 0x0001, 0x601c, 0xa084, 0x000f,
+	0x0083, 0x012e, 0x006e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0066,
+	0x2031, 0x0000, 0x601c, 0xa084, 0x000f, 0x001b, 0x006e, 0x012e,
+	0x0005, 0x92c3, 0x92c3, 0x92be, 0x92e5, 0x92b1, 0x92be, 0x92e5,
+	0x92be, 0x080c, 0x14f6, 0x0036, 0x2019, 0x0010, 0x080c, 0xa566,
+	0x601f, 0x0006, 0x6003, 0x0007, 0x003e, 0x0005, 0xa006, 0x0005,
+	0xa085, 0x0001, 0x0005, 0x00d6, 0x86ff, 0x11d8, 0x6010, 0x2068,
+	0x080c, 0x9596, 0x01c0, 0x6834, 0xa086, 0x0139, 0x1128, 0x684b,
+	0x0005, 0x6853, 0x0000, 0x0028, 0xa00e, 0x2001, 0x0005, 0x080c,
+	0x51df, 0x080c, 0x9803, 0x080c, 0x510c, 0x080c, 0x8078, 0xa085,
+	0x0001, 0x00de, 0x0005, 0xa006, 0x0ce0, 0x6000, 0xa08a, 0x0010,
+	0x1a0c, 0x14f6, 0x000b, 0x0005, 0x92fc, 0x9319, 0x92fe, 0x9338,
+	0x9316, 0x92fc, 0x92be, 0x92c3, 0x92c3, 0x92be, 0x92be, 0x92be,
+	0x92be, 0x92be, 0x92be, 0x92be, 0x080c, 0x14f6, 0x86ff, 0x1198,
+	0x00d6, 0x6010, 0x2068, 0x080c, 0x9596, 0x0110, 0x080c, 0x9803,
+	0x00de, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x080c,
+	0x67a8, 0x080c, 0x6c50, 0xa085, 0x0001, 0x0005, 0x080c, 0x190b,
+	0x0c28, 0x00e6, 0x2071, 0xafc7, 0x7024, 0xac06, 0x1110, 0x080c,
+	0x79e1, 0x601c, 0xa084, 0x000f, 0xa086, 0x0006, 0x1150, 0x0086,
+	0x0096, 0x2049, 0x0001, 0x2c40, 0x080c, 0x7b9a, 0x009e, 0x008e,
+	0x0010, 0x080c, 0x78de, 0x00ee, 0x1948, 0x080c, 0x92be, 0x0005,
+	0x0036, 0x00e6, 0x2071, 0xafc7, 0x703c, 0xac06, 0x1140, 0x2019,
+	0x0000, 0x080c, 0x7a64, 0x00ee, 0x003e, 0x0804, 0x92fe, 0x080c,
+	0x7cb8, 0x00ee, 0x003e, 0x1904, 0x92fe, 0x080c, 0x92be, 0x0005,
+	0x00c6, 0x601c, 0xa084, 0x000f, 0x0013, 0x00ce, 0x0005, 0x9369,
+	0x93d3, 0x9501, 0x9374, 0x974e, 0x9369, 0xa558, 0x8078, 0x93d3,
+	0x9362, 0x955f, 0x080c, 0x14f6, 0x080c, 0x9789, 0x1110, 0x080c,
+	0x85f3, 0x0005, 0x080c, 0x6b73, 0x080c, 0x6c50, 0x080c, 0x8078,
+	0x0005, 0x6017, 0x0001, 0x0005, 0x6010, 0xa080, 0x0019, 0x2c02,
+	0x6000, 0xa08a, 0x0010, 0x1a0c, 0x14f6, 0x000b, 0x0005, 0x938f,
+	0x9391, 0x93b1, 0x93c3, 0x93d0, 0x938f, 0x9369, 0x9369, 0x9369,
+	0x93c3, 0x93c3, 0x938f, 0x938f, 0x938f, 0x938f, 0x93cd, 0x080c,
+	0x14f6, 0x00e6, 0x6010, 0x2070, 0x7050, 0xc0b5, 0x7052, 0x2071,
+	0xafc7, 0x7024, 0xac06, 0x0190, 0x080c, 0x78de, 0x6007, 0x0085,
+	0x6003, 0x000b, 0x601f, 0x0002, 0x2001, 0xafa4, 0x2004, 0x6016,
+	0x080c, 0x67a8, 0x080c, 0x6c50, 0x00ee, 0x0005, 0x6017, 0x0001,
+	0x0cd8, 0x00d6, 0x6010, 0x2068, 0x6850, 0xc0b5, 0x6852, 0x00de,
+	0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x080c, 0x67a8,
+	0x080c, 0x6c50, 0x0005, 0x00d6, 0x6017, 0x0001, 0x6010, 0x2068,
+	0x6850, 0xc0b5, 0x6852, 0x00de, 0x0005, 0x080c, 0x8078, 0x0005,
+	0x080c, 0x190b, 0x08f0, 0x6000, 0xa08a, 0x0010, 0x1a0c, 0x14f6,
+	0x000b, 0x0005, 0x93ea, 0x9371, 0x93ec, 0x93ea, 0x93ec, 0x93ec,
+	0x936a, 0x93ea, 0x9364, 0x9364, 0x93ea, 0x93ea, 0x93ea, 0x93ea,
+	0x93ea, 0x93ea, 0x080c, 0x14f6, 0x00d6, 0x6018, 0x2068, 0x6804,
+	0xa084, 0x00ff, 0x00de, 0xa08a, 0x000c, 0x1a0c, 0x14f6, 0x000b,
+	0x0005, 0x9405, 0x94a7, 0x9407, 0x9441, 0x9407, 0x9441, 0x9407,
+	0x9411, 0x9405, 0x9441, 0x9405, 0x942d, 0x080c, 0x14f6, 0x6004,
+	0xa08e, 0x0016, 0x0588, 0xa08e, 0x0004, 0x0570, 0xa08e, 0x0002,
+	0x0558, 0x6004, 0x080c, 0x9789, 0x0904, 0x94c0, 0xa08e, 0x0021,
+	0x0904, 0x94c4, 0xa08e, 0x0022, 0x0904, 0x94c0, 0xa08e, 0x003d,
+	0x0904, 0x94c4, 0xa08e, 0x0039, 0x0904, 0x94c8, 0xa08e, 0x0035,
+	0x0904, 0x94c8, 0xa08e, 0x001e, 0x0188, 0xa08e, 0x0001, 0x1150,
+	0x00d6, 0x6018, 0x2068, 0x6804, 0xa084, 0x00ff, 0x00de, 0xa086,
+	0x0006, 0x0110, 0x080c, 0x2ad9, 0x080c, 0x85f3, 0x080c, 0x974e,
+	0x0005, 0x00c6, 0x00d6, 0x6104, 0xa186, 0x0016, 0x0904, 0x9498,
+	0xa186, 0x0002, 0x1518, 0x6018, 0x2068, 0x2001, 0xad34, 0x2004,
+	0xd0ac, 0x1904, 0x94ea, 0x68a0, 0xd0bc, 0x1904, 0x94ea, 0x6840,
+	0xa084, 0x00ff, 0xa005, 0x0190, 0x8001, 0x6842, 0x6013, 0x0000,
+	0x601f, 0x0007, 0x6017, 0x0398, 0x603f, 0x0000, 0x080c, 0x8022,
+	0x0128, 0x2d00, 0x601a, 0x601f, 0x0001, 0x0450, 0x00de, 0x00ce,
+	0x6004, 0xa08e, 0x0002, 0x11a8, 0x6018, 0xa080, 0x0028, 0x2004,
+	0xa086, 0x007e, 0x1170, 0x2009, 0xad34, 0x2104, 0xc085, 0x200a,
+	0x00e6, 0x2071, 0xad00, 0x080c, 0x48f5, 0x00ee, 0x080c, 0x85f3,
+	0x0020, 0x080c, 0x85f3, 0x080c, 0x2ad9, 0x00e6, 0x0126, 0x2091,
+	0x8000, 0x080c, 0x2aff, 0x012e, 0x00ee, 0x080c, 0x974e, 0x0005,
+	0x2001, 0x0002, 0x080c, 0x4c30, 0x6003, 0x0001, 0x6007, 0x0002,
+	0x080c, 0x67ee, 0x080c, 0x6c50, 0x00de, 0x00ce, 0x0c80, 0x00c6,
+	0x00d6, 0x6104, 0xa186, 0x0016, 0x0d58, 0x6018, 0x2068, 0x6840,
+	0xa084, 0x00ff, 0xa005, 0x0904, 0x946e, 0x8001, 0x6842, 0x6003,
+	0x0001, 0x080c, 0x67ee, 0x080c, 0x6c50, 0x00de, 0x00ce, 0x08b8,
+	0x080c, 0x85f3, 0x0804, 0x943e, 0x080c, 0x8621, 0x0804, 0x943e,
+	0x00d6, 0x2c68, 0x6104, 0x080c, 0x9a34, 0x00de, 0x0118, 0x080c,
+	0x8078, 0x00b8, 0x6004, 0x8007, 0x6130, 0xa18c, 0x00ff, 0xa105,
+	0x6032, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x6038,
+	0x600a, 0x2001, 0xafa4, 0x2004, 0x6016, 0x080c, 0x67a8, 0x080c,
+	0x6c50, 0x0005, 0x00de, 0x00ce, 0x080c, 0x85f3, 0x080c, 0x2ad9,
+	0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x2aff, 0x6013, 0x0000,
+	0x601f, 0x0007, 0x6017, 0x0398, 0x603f, 0x0000, 0x012e, 0x00ee,
+	0x0005, 0x6000, 0xa08a, 0x0010, 0x1a0c, 0x14f6, 0x000b, 0x0005,
+	0x9518, 0x9518, 0x9518, 0x9518, 0x9518, 0x9518, 0x9518, 0x9518,
+	0x9518, 0x9369, 0x9518, 0x9371, 0x951a, 0x9371, 0x9527, 0x9518,
+	0x080c, 0x14f6, 0x6004, 0xa086, 0x008b, 0x0148, 0x6007, 0x008b,
+	0x6003, 0x000d, 0x080c, 0x67a8, 0x080c, 0x6c50, 0x0005, 0x080c,
+	0x9742, 0x080c, 0x9596, 0x0580, 0x080c, 0x2ad9, 0x00d6, 0x080c,
+	0x9596, 0x0168, 0x6010, 0x2068, 0x6837, 0x0103, 0x684b, 0x0006,
+	0x6847, 0x0000, 0x6850, 0xc0ed, 0x6852, 0x080c, 0x510c, 0x2c68,
+	0x080c, 0x8022, 0x0150, 0x6818, 0x601a, 0x080c, 0x9956, 0x00c6,
+	0x2d60, 0x080c, 0x974e, 0x00ce, 0x0008, 0x2d60, 0x00de, 0x6013,
+	0x0000, 0x601f, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c,
+	0x67ee, 0x080c, 0x6c50, 0x0010, 0x080c, 0x974e, 0x0005, 0x6000,
+	0xa08a, 0x0010, 0x1a0c, 0x14f6, 0x000b, 0x0005, 0x9576, 0x9576,
+	0x9576, 0x9578, 0x9579, 0x9576, 0x9576, 0x9576, 0x9576, 0x9576,
+	0x9576, 0x9576, 0x9576, 0x9576, 0x9576, 0x9576, 0x080c, 0x14f6,
+	0x0005, 0x080c, 0x7cb8, 0x190c, 0x14f6, 0x6110, 0x2168, 0x684b,
+	0x0006, 0x080c, 0x510c, 0x080c, 0x8078, 0x0005, 0xa284, 0x0007,
+	0x1158, 0xa282, 0xb400, 0x0240, 0x2001, 0xad16, 0x2004, 0xa202,
+	0x1218, 0xa085, 0x0001, 0x0005, 0xa006, 0x0ce8, 0x0026, 0x6210,
+	0xa294, 0xf000, 0x002e, 0x0005, 0x00e6, 0x00c6, 0x0036, 0x0006,
+	0x0126, 0x2091, 0x8000, 0x2061, 0xb400, 0x2071, 0xad00, 0x7344,
+	0x7064, 0xa302, 0x12a8, 0x601c, 0xa206, 0x1160, 0x080c, 0x98e3,
+	0x0148, 0x080c, 0x9789, 0x1110, 0x080c, 0x85f3, 0x00c6, 0x080c,
+	0x8078, 0x00ce, 0xace0, 0x0018, 0x7058, 0xac02, 0x1208, 0x0c38,
+	0x012e, 0x000e, 0x003e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6,
+	0x0016, 0xa188, 0xae34, 0x210c, 0x81ff, 0x0170, 0x2061, 0xb400,
+	0x2071, 0xad00, 0x0016, 0x080c, 0x8022, 0x001e, 0x0138, 0x611a,
+	0x080c, 0x2ad9, 0x080c, 0x8078, 0xa006, 0x0010, 0xa085, 0x0001,
+	0x001e, 0x00ce, 0x00ee, 0x0005, 0x00c6, 0x0056, 0x0126, 0x2091,
+	0x8000, 0x00c6, 0x080c, 0x8022, 0x005e, 0x0180, 0x6612, 0x651a,
+	0x080c, 0x9956, 0x601f, 0x0003, 0x2009, 0x004b, 0x080c, 0x80a7,
+	0xa085, 0x0001, 0x012e, 0x005e, 0x00ce, 0x0005, 0xa006, 0x0cd0,
+	0x00c6, 0x0056, 0x0126, 0x2091, 0x8000, 0x62a0, 0x00c6, 0x080c,
+	0x8022, 0x005e, 0x0508, 0x6013, 0x0000, 0x651a, 0x080c, 0x9956,
+	0x601f, 0x0003, 0x00c6, 0x2560, 0x080c, 0x4ecf, 0x00ce, 0x080c,
+	0x68e7, 0x0076, 0x2039, 0x0000, 0x080c, 0x681d, 0x2c08, 0x080c,
+	0xa712, 0x007e, 0x2009, 0x004c, 0x080c, 0x80a7, 0xa085, 0x0001,
+	0x012e, 0x005e, 0x00ce, 0x0005, 0xa006, 0x0cd0, 0x00f6, 0x00c6,
+	0x0046, 0x00c6, 0x080c, 0x8022, 0x2c78, 0x00ce, 0x0180, 0x7e12,
+	0x2c00, 0x781a, 0x781f, 0x0003, 0x2021, 0x0005, 0x080c, 0x9683,
+	0x2f60, 0x2009, 0x004d, 0x080c, 0x80a7, 0xa085, 0x0001, 0x004e,
+	0x00ce, 0x00fe, 0x0005, 0x00f6, 0x00c6, 0x0046, 0x00c6, 0x080c,
+	0x8022, 0x2c78, 0x00ce, 0x0178, 0x7e12, 0x2c00, 0x781a, 0x781f,
+	0x0003, 0x2021, 0x0005, 0x0439, 0x2f60, 0x2009, 0x004e, 0x080c,
+	0x80a7, 0xa085, 0x0001, 0x004e, 0x00ce, 0x00fe, 0x0005, 0x00f6,
+	0x00c6, 0x0046, 0x00c6, 0x080c, 0x8022, 0x2c78, 0x00ce, 0x0178,
+	0x7e12, 0x2c00, 0x781a, 0x781f, 0x0003, 0x2021, 0x0004, 0x0059,
+	0x2f60, 0x2009, 0x0052, 0x080c, 0x80a7, 0xa085, 0x0001, 0x004e,
+	0x00ce, 0x00fe, 0x0005, 0x0096, 0x0076, 0x0126, 0x2091, 0x8000,
+	0x080c, 0x4e71, 0x0118, 0x2001, 0x9688, 0x0028, 0x080c, 0x4e43,
+	0x0158, 0x2001, 0x968e, 0x0006, 0xa00e, 0x2400, 0x080c, 0x51df,
+	0x080c, 0x510c, 0x000e, 0x0807, 0x2418, 0x080c, 0x6b15, 0x62a0,
+	0x0086, 0x2041, 0x0001, 0x2039, 0x0001, 0x2608, 0x080c, 0x6900,
+	0x008e, 0x080c, 0x681d, 0x2f08, 0x2648, 0x080c, 0xa712, 0x613c,
+	0x81ff, 0x090c, 0x69a9, 0x012e, 0x007e, 0x009e, 0x0005, 0x00c6,
+	0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x8022, 0x001e, 0x0188,
+	0x660a, 0x611a, 0x080c, 0x9956, 0x601f, 0x0001, 0x2d00, 0x6012,
+	0x2009, 0x001f, 0x080c, 0x80a7, 0xa085, 0x0001, 0x012e, 0x00ce,
+	0x0005, 0xa006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6,
+	0x080c, 0x8022, 0x001e, 0x0188, 0x660a, 0x611a, 0x080c, 0x9956,
+	0x601f, 0x0008, 0x2d00, 0x6012, 0x2009, 0x0021, 0x080c, 0x80a7,
+	0xa085, 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006, 0x0cd8, 0x00c6,
+	0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x8022, 0x001e, 0x0188,
+	0x660a, 0x611a, 0x080c, 0x9956, 0x601f, 0x0001, 0x2d00, 0x6012,
+	0x2009, 0x003d, 0x080c, 0x80a7, 0xa085, 0x0001, 0x012e, 0x00ce,
+	0x0005, 0xa006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6,
+	0x080c, 0x9807, 0x001e, 0x0180, 0x611a, 0x080c, 0x9956, 0x601f,
+	0x0001, 0x2d00, 0x6012, 0x2009, 0x0000, 0x080c, 0x80a7, 0xa085,
+	0x0001, 0x012e, 0x00ce, 0x0005, 0xa006, 0x0cd8, 0x00c6, 0x0126,
+	0x2091, 0x8000, 0x00c6, 0x080c, 0x8022, 0x001e, 0x0188, 0x660a,
+	0x611a, 0x080c, 0x9956, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009,
+	0x0044, 0x080c, 0x80a7, 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005,
+	0xa006, 0x0cd8, 0x0026, 0x00d6, 0x6218, 0x2268, 0x6a3c, 0x82ff,
+	0x0110, 0x8211, 0x6a3e, 0x00de, 0x002e, 0x0005, 0x0006, 0x6000,
+	0xa086, 0x0000, 0x0190, 0x6013, 0x0000, 0x601f, 0x0007, 0x2001,
+	0xafa3, 0x2004, 0x0006, 0xa082, 0x0051, 0x000e, 0x0208, 0x8004,
+	0x6016, 0x080c, 0xabb4, 0x603f, 0x0000, 0x000e, 0x0005, 0x0066,
+	0x00c6, 0x00d6, 0x2031, 0xad52, 0x2634, 0xd6e4, 0x0128, 0x6618,
+	0x2660, 0x6e48, 0x080c, 0x4dfc, 0x00de, 0x00ce, 0x006e, 0x0005,
+	0x0006, 0x0016, 0x6004, 0xa08e, 0x0002, 0x0140, 0xa08e, 0x0003,
+	0x0128, 0xa08e, 0x0004, 0x0110, 0xa085, 0x0001, 0x001e, 0x000e,
+	0x0005, 0x0006, 0x00d6, 0x6010, 0xa06d, 0x0148, 0x6834, 0xa086,
+	0x0139, 0x0138, 0x6838, 0xd0fc, 0x0110, 0xa006, 0x0010, 0xa085,
+	0x0001, 0x00de, 0x000e, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000,
+	0x00c6, 0x080c, 0x8022, 0x001e, 0x0190, 0x611a, 0x080c, 0x9956,
+	0x601f, 0x0001, 0x2d00, 0x6012, 0x080c, 0x2ad9, 0x2009, 0x0028,
+	0x080c, 0x80a7, 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006,
+	0x0cd8, 0xa186, 0x0015, 0x1178, 0x2011, 0xad20, 0x2204, 0xa086,
+	0x0074, 0x1148, 0x080c, 0x8943, 0x6003, 0x0001, 0x6007, 0x0029,
+	0x080c, 0x67ee, 0x0020, 0x080c, 0x85f3, 0x080c, 0x8078, 0x0005,
+	0xa186, 0x0016, 0x1128, 0x2001, 0x0004, 0x080c, 0x4c30, 0x00e8,
+	0xa186, 0x0015, 0x11e8, 0x2011, 0xad20, 0x2204, 0xa086, 0x0014,
+	0x11b8, 0x00d6, 0x6018, 0x2068, 0x080c, 0x4d72, 0x00de, 0x080c,
+	0x89f7, 0x1170, 0x00d6, 0x6018, 0x2068, 0x6890, 0x00de, 0xa005,
+	0x0138, 0x2001, 0x0006, 0x080c, 0x4c30, 0x080c, 0x81f6, 0x0020,
+	0x080c, 0x85f3, 0x080c, 0x8078, 0x0005, 0x6848, 0xa086, 0x0005,
+	0x1108, 0x0009, 0x0005, 0x6850, 0xc0ad, 0x6852, 0x0005, 0x00e6,
+	0x0126, 0x2071, 0xad00, 0x2091, 0x8000, 0x7544, 0xa582, 0x0001,
+	0x0608, 0x7048, 0x2060, 0x6000, 0xa086, 0x0000, 0x0148, 0xace0,
+	0x0018, 0x7058, 0xac02, 0x1208, 0x0cb0, 0x2061, 0xb400, 0x0c98,
+	0x6003, 0x0008, 0x8529, 0x7546, 0xaca8, 0x0018, 0x7058, 0xa502,
+	0x1230, 0x754a, 0xa085, 0x0001, 0x012e, 0x00ee, 0x0005, 0x704b,
+	0xb400, 0x0cc0, 0xa006, 0x0cc0, 0x00e6, 0x2071, 0xb28c, 0x7014,
+	0xd0e4, 0x0150, 0x6013, 0x0000, 0x6003, 0x0001, 0x6007, 0x0050,
+	0x080c, 0x67a8, 0x080c, 0x6c50, 0x00ee, 0x0005, 0x00c6, 0x00f6,
+	0x2c78, 0x080c, 0x5029, 0x00fe, 0x0120, 0x601c, 0xa084, 0x000f,
+	0x0013, 0x00ce, 0x0005, 0x9369, 0x985e, 0x9861, 0x9864, 0xa9a7,
+	0xa9c2, 0xa9c5, 0x9369, 0x9369, 0x080c, 0x14f6, 0xe000, 0xe000,
+	0x0005, 0xe000, 0xe000, 0x0005, 0x0009, 0x0005, 0x00f6, 0x2c78,
+	0x080c, 0x5029, 0x0538, 0x080c, 0x8022, 0x1128, 0x2001, 0xafa5,
+	0x2004, 0x783e, 0x00f8, 0x7818, 0x601a, 0x080c, 0x9956, 0x781c,
+	0xa086, 0x0003, 0x0128, 0x7808, 0x6036, 0x2f00, 0x603a, 0x0020,
+	0x7808, 0x603a, 0x2f00, 0x6036, 0x602a, 0x601f, 0x0001, 0x6007,
+	0x0035, 0x6003, 0x0001, 0x7950, 0x6152, 0x080c, 0x67a8, 0x080c,
+	0x6c50, 0x2f60, 0x00fe, 0x0005, 0x0016, 0x00f6, 0x682c, 0x6032,
+	0xa08e, 0x0001, 0x0138, 0xa086, 0x0005, 0x0140, 0xa006, 0x602a,
+	0x602e, 0x00a0, 0x6820, 0xc0f4, 0xc0d5, 0x6822, 0x6810, 0x2078,
+	0x787c, 0x6938, 0xa102, 0x7880, 0x6934, 0xa103, 0x1e78, 0x6834,
+	0x602a, 0x6838, 0xa084, 0xfffc, 0x683a, 0x602e, 0x2d00, 0x6036,
+	0x6808, 0x603a, 0x6918, 0x611a, 0x6950, 0x6152, 0x601f, 0x0001,
+	0x6007, 0x0039, 0x6003, 0x0001, 0x080c, 0x67a8, 0x6803, 0x0002,
+	0x00fe, 0x001e, 0x0005, 0x00f6, 0x2c78, 0x080c, 0x5029, 0x1118,
+	0xa085, 0x0001, 0x0070, 0x6020, 0xd0f4, 0x1150, 0xc0f5, 0x6022,
+	0x6010, 0x2078, 0x7828, 0x603a, 0x782c, 0x6036, 0x080c, 0x190b,
+	0xa006, 0x00fe, 0x0005, 0x0006, 0x0016, 0x6004, 0xa08e, 0x0034,
+	0x01b8, 0xa08e, 0x0035, 0x01a0, 0xa08e, 0x0036, 0x0188, 0xa08e,
+	0x0037, 0x0170, 0xa08e, 0x0038, 0x0158, 0xa08e, 0x0039, 0x0140,
+	0xa08e, 0x003a, 0x0128, 0xa08e, 0x003b, 0x0110, 0xa085, 0x0001,
+	0x001e, 0x000e, 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x00e6,
+	0x2001, 0xaf9f, 0x200c, 0x8000, 0x2014, 0x2001, 0x0032, 0x080c,
+	0x6665, 0x2001, 0xafa3, 0x82ff, 0x1110, 0x2011, 0x0002, 0x2202,
+	0x2001, 0xafa1, 0x200c, 0x8000, 0x2014, 0x2071, 0xaf8d, 0x711a,
+	0x721e, 0x2001, 0x0064, 0x080c, 0x6665, 0x2001, 0xafa4, 0x82ff,
+	0x1110, 0x2011, 0x0002, 0x2202, 0x2009, 0xafa5, 0xa280, 0x000a,
+	0x200a, 0x00ee, 0x003e, 0x002e, 0x001e, 0x000e, 0x0005, 0x0006,
+	0x00e6, 0x2001, 0xafa3, 0x2003, 0x0028, 0x2001, 0xafa4, 0x2003,
+	0x0014, 0x2071, 0xaf8d, 0x701b, 0x0000, 0x701f, 0x07d0, 0x2001,
+	0xafa5, 0x2003, 0x001e, 0x00ee, 0x000e, 0x0005, 0x00d6, 0x6054,
+	0xa06d, 0x0110, 0x080c, 0x15f0, 0x00de, 0x0005, 0x0005, 0x00c6,
+	0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x8022, 0x001e, 0x0178,
+	0x611a, 0x0ca1, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x0033,
+	0x080c, 0x80a7, 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006,
+	0x0cd8, 0x00d6, 0x00e6, 0x00f6, 0x2071, 0xad00, 0xa186, 0x0015,
+	0x1500, 0x7080, 0xa086, 0x0018, 0x11e0, 0x6010, 0x2068, 0x6a3c,
+	0xd2e4, 0x1160, 0x2c78, 0x080c, 0x6e05, 0x01d8, 0x706c, 0x6a50,
+	0xa206, 0x1160, 0x7070, 0x6a54, 0xa206, 0x1140, 0x6218, 0xa290,
+	0x0028, 0x2214, 0x2009, 0x0000, 0x080c, 0x2b1e, 0x080c, 0x81f6,
+	0x0020, 0x080c, 0x85f3, 0x080c, 0x8078, 0x00fe, 0x00ee, 0x00de,
+	0x0005, 0x7050, 0x6a54, 0xa206, 0x0d48, 0x0c80, 0x00c6, 0x0126,
+	0x2091, 0x8000, 0x00c6, 0x080c, 0x8022, 0x001e, 0x0180, 0x611a,
+	0x080c, 0x9956, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x0043,
+	0x080c, 0x80a7, 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006,
+	0x0cd8, 0x00d6, 0x00e6, 0x00f6, 0x2071, 0xad00, 0xa186, 0x0015,
+	0x11c0, 0x7080, 0xa086, 0x0004, 0x11a0, 0x6010, 0xa0e8, 0x000f,
+	0x2c78, 0x080c, 0x6e05, 0x01a8, 0x706c, 0x6a08, 0xa206, 0x1130,
+	0x7070, 0x6a0c, 0xa206, 0x1110, 0x080c, 0x2ad9, 0x080c, 0x81f6,
+	0x0020, 0x080c, 0x85f3, 0x080c, 0x8078, 0x00fe, 0x00ee, 0x00de,
+	0x0005, 0x7050, 0x6a0c, 0xa206, 0x0d78, 0x0c80, 0x0016, 0x0026,
+	0x684c, 0xd0ac, 0x0178, 0x6914, 0x6a10, 0x2100, 0xa205, 0x0150,
+	0x6860, 0xa106, 0x1118, 0x685c, 0xa206, 0x0120, 0x6962, 0x6a5e,
+	0xa085, 0x0001, 0x002e, 0x001e, 0x0005, 0x00d6, 0x0036, 0x6310,
+	0x2368, 0x684a, 0x6952, 0xa29e, 0x4000, 0x1188, 0x00c6, 0x6318,
+	0x2360, 0x2009, 0x0000, 0x080c, 0x4f6e, 0x1108, 0xc185, 0x6000,
+	0xd0bc, 0x0108, 0xc18d, 0x6a66, 0x696a, 0x00ce, 0x0080, 0x6a66,
+	0x3918, 0xa398, 0x0006, 0x231c, 0x686b, 0x0004, 0x6b72, 0x00c6,
+	0x6318, 0x2360, 0x6004, 0xa084, 0x00ff, 0x686e, 0x00ce, 0x080c,
+	0x510c, 0x003e, 0x00de, 0x0005, 0x00c6, 0x0026, 0x0016, 0xa186,
+	0x0035, 0x0110, 0x6a34, 0x0008, 0x6a28, 0x080c, 0x9586, 0x01f0,
+	0x2260, 0x611c, 0xa186, 0x0003, 0x0118, 0xa186, 0x0006, 0x1190,
+	0x6834, 0xa206, 0x0140, 0x6838, 0xa206, 0x1160, 0x6108, 0x6834,
+	0xa106, 0x1140, 0x0020, 0x6008, 0x6938, 0xa106, 0x1118, 0x6018,
+	0x6918, 0xa106, 0x001e, 0x002e, 0x00ce, 0x0005, 0xa085, 0x0001,
+	0x0cc8, 0x0066, 0x6000, 0xa0b2, 0x0010, 0x1a0c, 0x14f6, 0x0013,
+	0x006e, 0x0005, 0x9a7a, 0x9eff, 0xa027, 0x9a7a, 0x9a7a, 0x9a7a,
+	0x9a7a, 0x9a7a, 0x9ab2, 0xa0a3, 0x9a7a, 0x9a7a, 0x9a7a, 0x9a7a,
+	0x9a7a, 0x9a7a, 0x080c, 0x14f6, 0x0066, 0x6000, 0xa0b2, 0x0010,
+	0x1a0c, 0x14f6, 0x0013, 0x006e, 0x0005, 0x9a95, 0xa4fd, 0x9a95,
+	0x9a95, 0x9a95, 0x9a95, 0x9a95, 0x9a95, 0xa4c1, 0xa545, 0x9a95,
+	0xaaea, 0xab1a, 0xaaea, 0xab1a, 0x9a95, 0x080c, 0x14f6, 0x0066,
+	0x6000, 0xa0b2, 0x0010, 0x1a0c, 0x14f6, 0x0013, 0x006e, 0x0005,
+	0x9ab0, 0xa1d8, 0xa295, 0xa2c2, 0xa346, 0x9ab0, 0xa433, 0xa3de,
+	0xa0af, 0xa497, 0xa4ac, 0x9ab0, 0x9ab0, 0x9ab0, 0x9ab0, 0x9ab0,
+	0x080c, 0x14f6, 0xa1b2, 0x0080, 0x1a0c, 0x14f6, 0x2100, 0xa1b2,
+	0x0040, 0x1a04, 0x9e79, 0x0002, 0x9afc, 0x9cab, 0x9afc, 0x9afc,
+	0x9afc, 0x9cb2, 0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9afc,
+	0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9afc,
+	0x9afc, 0x9afc, 0x9afc, 0x9afe, 0x9b5a, 0x9b65, 0x9ba6, 0x9bc0,
+	0x9c3e, 0x9c9c, 0x9afc, 0x9afc, 0x9cb5, 0x9afc, 0x9afc, 0x9cc4,
+	0x9ccb, 0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9d42, 0x9afc,
+	0x9afc, 0x9d4d, 0x9afc, 0x9afc, 0x9d18, 0x9afc, 0x9afc, 0x9afc,
+	0x9d61, 0x9afc, 0x9afc, 0x9afc, 0x9dd5, 0x9afc, 0x9afc, 0x9afc,
+	0x9afc, 0x9afc, 0x9afc, 0x9e40, 0x080c, 0x14f6, 0x080c, 0x502d,
+	0x1140, 0x2001, 0xad34, 0x2004, 0xa084, 0x0009, 0xa086, 0x0008,
+	0x1140, 0x6007, 0x0009, 0x602b, 0x0009, 0x6013, 0x0000, 0x0804,
+	0x9ca6, 0x080c, 0x501d, 0x00e6, 0x00c6, 0x0036, 0x0026, 0x0016,
+	0x6218, 0x2270, 0x72a0, 0x0026, 0x2019, 0x0029, 0x080c, 0x68e7,
+	0x0076, 0x2039, 0x0000, 0x080c, 0x681d, 0x2c08, 0x080c, 0xa712,
+	0x007e, 0x001e, 0x2e60, 0x080c, 0x4ecf, 0x001e, 0x002e, 0x003e,
+	0x00ce, 0x00ee, 0x6618, 0x00c6, 0x2660, 0x080c, 0x4ceb, 0x00ce,
+	0xa6b0, 0x0001, 0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x0278,
+	0x080c, 0xa656, 0x1904, 0x9ba0, 0x080c, 0xa5f6, 0x1120, 0x6007,
+	0x0008, 0x0804, 0x9ca6, 0x6007, 0x0009, 0x0804, 0x9ca6, 0x080c,
+	0xa801, 0x0128, 0x080c, 0xa656, 0x0d78, 0x0804, 0x9ba0, 0x6013,
+	0x1900, 0x0c88, 0x6106, 0x080c, 0xa5a6, 0x6007, 0x0006, 0x0804,
+	0x9ca6, 0x6007, 0x0007, 0x0804, 0x9ca6, 0x080c, 0xab4e, 0x1904,
+	0x9e76, 0x00d6, 0x6618, 0x2668, 0x6e04, 0xa6b4, 0xff00, 0x8637,
+	0xa686, 0x0006, 0x0188, 0xa686, 0x0004, 0x0170, 0x6e04, 0xa6b4,
+	0x00ff, 0xa686, 0x0006, 0x0140, 0xa686, 0x0004, 0x0128, 0xa686,
+	0x0005, 0x0110, 0x00de, 0x00e0, 0x080c, 0xa6b4, 0x11a0, 0xa686,
+	0x0006, 0x1150, 0x0026, 0x6218, 0xa290, 0x0028, 0x2214, 0x2009,
+	0x0000, 0x080c, 0x2b1e, 0x002e, 0x080c, 0x4d72, 0x6007, 0x000a,
+	0x00de, 0x0804, 0x9ca6, 0x6007, 0x000b, 0x00de, 0x0804, 0x9ca6,
+	0x080c, 0x2ad9, 0x6007, 0x0001, 0x0804, 0x9ca6, 0x080c, 0xab4e,
+	0x1904, 0x9e76, 0x6618, 0x00d6, 0x2668, 0x6e04, 0x00de, 0xa686,
+	0x0707, 0x0d70, 0x0026, 0x6218, 0xa290, 0x0028, 0x2214, 0x2009,
+	0x0000, 0x080c, 0x2b1e, 0x002e, 0x6007, 0x000c, 0x0804, 0x9ca6,
+	0x080c, 0x502d, 0x1140, 0x2001, 0xad34, 0x2004, 0xa084, 0x0009,
+	0xa086, 0x0008, 0x1110, 0x0804, 0x9b09, 0x080c, 0x501d, 0x6618,
+	0xa6b0, 0x0001, 0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x06e8,
+	0x1138, 0x0026, 0x2001, 0x0006, 0x080c, 0x4c5d, 0x002e, 0x0050,
+	0xa6b4, 0xff00, 0x8637, 0xa686, 0x0004, 0x0120, 0xa686, 0x0006,
+	0x1904, 0x9ba0, 0x080c, 0xa6c1, 0x1120, 0x6007, 0x000e, 0x0804,
+	0x9ca6, 0x0046, 0x6418, 0xa4a0, 0x0028, 0x2424, 0xa4a4, 0x00ff,
+	0x8427, 0x0046, 0x080c, 0x2ad9, 0x004e, 0x0016, 0xa006, 0x2009,
+	0xad52, 0x210c, 0xd1a4, 0x0158, 0x2009, 0x0029, 0x080c, 0xa96c,
+	0x6018, 0x00d6, 0x2068, 0x6800, 0xc0e5, 0x6802, 0x00de, 0x001e,
+	0x004e, 0x6007, 0x0001, 0x0804, 0x9ca6, 0x2001, 0x0001, 0x080c,
+	0x4c1e, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019,
+	0xad05, 0x2011, 0xb290, 0x080c, 0x8a7c, 0x003e, 0x002e, 0x001e,
+	0x015e, 0xa005, 0x0168, 0xa6b4, 0xff00, 0x8637, 0xa682, 0x0004,
+	0x0a04, 0x9ba0, 0xa682, 0x0007, 0x0a04, 0x9bea, 0x0804, 0x9ba0,
+	0x6013, 0x1900, 0x6007, 0x0009, 0x0804, 0x9ca6, 0x080c, 0x502d,
+	0x1140, 0x2001, 0xad34, 0x2004, 0xa084, 0x0009, 0xa086, 0x0008,
+	0x1110, 0x0804, 0x9b09, 0x080c, 0x501d, 0x6618, 0xa6b0, 0x0001,
+	0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x06b0, 0xa6b4, 0xff00,
+	0x8637, 0xa686, 0x0004, 0x0120, 0xa686, 0x0006, 0x1904, 0x9ba0,
+	0x080c, 0xa6e9, 0x1130, 0x080c, 0xa5f6, 0x1118, 0x6007, 0x0010,
+	0x04e8, 0x0046, 0x6418, 0xa4a0, 0x0028, 0x2424, 0xa4a4, 0x00ff,
+	0x8427, 0x0046, 0x080c, 0x2ad9, 0x004e, 0x0016, 0xa006, 0x2009,
+	0xad52, 0x210c, 0xd1a4, 0x0158, 0x2009, 0x0029, 0x080c, 0xa96c,
+	0x6018, 0x00d6, 0x2068, 0x6800, 0xc0e5, 0x6802, 0x00de, 0x001e,
+	0x004e, 0x6007, 0x0001, 0x00d0, 0x080c, 0xa801, 0x0140, 0xa6b4,
+	0xff00, 0x8637, 0xa686, 0x0006, 0x0958, 0x0804, 0x9ba0, 0x6013,
+	0x1900, 0x6007, 0x0009, 0x0050, 0x080c, 0xab4e, 0x1904, 0x9e76,
+	0x080c, 0x9e98, 0x1904, 0x9ba0, 0x6007, 0x0012, 0x6003, 0x0001,
+	0x080c, 0x67ee, 0x0005, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c,
+	0x67ee, 0x0cc0, 0x6007, 0x0005, 0x0cc0, 0x080c, 0xab4e, 0x1904,
+	0x9e76, 0x080c, 0x9e98, 0x1904, 0x9ba0, 0x6007, 0x0020, 0x6003,
+	0x0001, 0x080c, 0x67ee, 0x0005, 0x6007, 0x0023, 0x6003, 0x0001,
+	0x080c, 0x67ee, 0x0005, 0x080c, 0xab4e, 0x1904, 0x9e76, 0x080c,
+	0x9e98, 0x1904, 0x9ba0, 0x0016, 0x0026, 0x2011, 0xb291, 0x2214,
+	0xa286, 0xffff, 0x0190, 0x2c08, 0x080c, 0x9586, 0x01d8, 0x2260,
+	0x2011, 0xb290, 0x2214, 0x6008, 0xa206, 0x11a0, 0x6018, 0xa190,
+	0x0006, 0x2214, 0xa206, 0x01e0, 0x0068, 0x2011, 0xb290, 0x2214,
+	0x2c08, 0x080c, 0xa940, 0x11a0, 0x2011, 0xb291, 0x2214, 0xa286,
+	0xffff, 0x01a0, 0x2160, 0x6007, 0x0026, 0x6013, 0x1700, 0x2011,
+	0xb289, 0x2214, 0xa296, 0xffff, 0x1160, 0x6007, 0x0025, 0x0048,
+	0x601c, 0xa086, 0x0007, 0x1d70, 0x080c, 0x8078, 0x2160, 0x6007,
+	0x0025, 0x6003, 0x0001, 0x080c, 0x67ee, 0x002e, 0x001e, 0x0005,
+	0x2001, 0x0001, 0x080c, 0x4c1e, 0x0156, 0x0016, 0x0026, 0x0036,
+	0x20a9, 0x0004, 0x2019, 0xad05, 0x2011, 0xb296, 0x080c, 0x8a7c,
+	0x003e, 0x002e, 0x001e, 0x015e, 0x0120, 0x6007, 0x0031, 0x0804,
+	0x9ca6, 0x080c, 0x87bd, 0x080c, 0x574f, 0x1158, 0x0006, 0x0026,
+	0x0036, 0x080c, 0x576b, 0x0110, 0x080c, 0x5726, 0x003e, 0x002e,
+	0x000e, 0x0005, 0x6106, 0x080c, 0x9eb4, 0x6007, 0x002b, 0x0804,
+	0x9ca6, 0x6007, 0x002c, 0x0804, 0x9ca6, 0x080c, 0xab4e, 0x1904,
+	0x9e76, 0x080c, 0x9e98, 0x1904, 0x9ba0, 0x6106, 0x080c, 0x9eb8,
+	0x1120, 0x6007, 0x002e, 0x0804, 0x9ca6, 0x6007, 0x002f, 0x0804,
+	0x9ca6, 0x00e6, 0x00d6, 0x00c6, 0x6018, 0xa080, 0x0001, 0x200c,
+	0xa184, 0x00ff, 0xa086, 0x0006, 0x0158, 0xa184, 0xff00, 0x8007,
+	0xa086, 0x0006, 0x0128, 0x00ce, 0x00de, 0x00ee, 0x0804, 0x9cab,
+	0x2001, 0xad71, 0x2004, 0xd0e4, 0x0904, 0x9dd2, 0x2071, 0xb28c,
+	0x7010, 0x6036, 0x7014, 0x603a, 0x7108, 0x720c, 0x2001, 0xad52,
+	0x2004, 0xd0a4, 0x0140, 0x6018, 0x2068, 0x6810, 0xa106, 0x1118,
+	0x6814, 0xa206, 0x01f8, 0x2001, 0xad52, 0x2004, 0xd0ac, 0x1580,
+	0x2069, 0xad00, 0x6870, 0xa206, 0x1558, 0x686c, 0xa106, 0x1540,
+	0x7210, 0x080c, 0x9586, 0x0548, 0x080c, 0xa9d4, 0x0530, 0x622a,
+	0x6007, 0x0036, 0x6003, 0x0001, 0x080c, 0x67a8, 0x00ce, 0x00de,
+	0x00ee, 0x0005, 0x7214, 0xa286, 0xffff, 0x0150, 0x080c, 0x9586,
+	0x01a0, 0xa280, 0x0002, 0x2004, 0x7110, 0xa106, 0x1170, 0x0c08,
+	0x7210, 0x2c08, 0x080c, 0xa940, 0x2c10, 0x2160, 0x0130, 0x08c8,
+	0x6007, 0x0037, 0x6013, 0x1500, 0x08e8, 0x6007, 0x0037, 0x6013,
+	0x1700, 0x08c0, 0x6007, 0x0012, 0x08a8, 0x6018, 0xa080, 0x0001,
+	0x2004, 0xa084, 0xff00, 0x8007, 0xa086, 0x0006, 0x1904, 0x9cab,
+	0x00e6, 0x00d6, 0x00c6, 0x2001, 0xad71, 0x2004, 0xd0e4, 0x0904,
+	0x9e38, 0x2069, 0xad00, 0x2071, 0xb28c, 0x7008, 0x6036, 0x720c,
+	0x623a, 0xa286, 0xffff, 0x1140, 0x7208, 0x00c6, 0x2c08, 0x080c,
+	0xa940, 0x2c10, 0x00ce, 0x0588, 0x080c, 0x9586, 0x0570, 0x00c6,
+	0x0026, 0x2260, 0x080c, 0x928f, 0x002e, 0x00ce, 0x7118, 0xa18c,
+	0xff00, 0x810f, 0xa186, 0x0001, 0x0158, 0xa186, 0x0005, 0x0118,
+	0xa186, 0x0007, 0x1178, 0xa280, 0x0004, 0x2004, 0xa005, 0x0150,
+	0x0056, 0x7510, 0x7614, 0x080c, 0xa9eb, 0x005e, 0x00ce, 0x00de,
+	0x00ee, 0x0005, 0x6007, 0x003b, 0x602b, 0x0009, 0x6013, 0x2a00,
+	0x6003, 0x0001, 0x080c, 0x67a8, 0x0c88, 0x6007, 0x003b, 0x602b,
+	0x0009, 0x6013, 0x1700, 0x6003, 0x0001, 0x080c, 0x67a8, 0x0c30,
+	0x6007, 0x003b, 0x602b, 0x000b, 0x6013, 0x0000, 0x0804, 0x9daa,
+	0x00e6, 0x0026, 0x080c, 0x502d, 0x0558, 0x080c, 0x501d, 0x080c,
+	0xabc5, 0x1520, 0x2071, 0xad00, 0x70d0, 0xc085, 0x70d2, 0x00f6,
+	0x2079, 0x0100, 0x729c, 0xa284, 0x00ff, 0x706e, 0x78e6, 0xa284,
+	0xff00, 0x7270, 0xa205, 0x7072, 0x78ea, 0x00fe, 0x70db, 0x0000,
+	0x2001, 0xad52, 0x2004, 0xd0a4, 0x0120, 0x2011, 0xafe0, 0x2013,
+	0x07d0, 0xd0ac, 0x1128, 0x080c, 0x28fa, 0x0010, 0x080c, 0xabf1,
+	0x002e, 0x00ee, 0x080c, 0x8078, 0x0804, 0x9caa, 0x080c, 0x8078,
+	0x0005, 0x2600, 0x0002, 0x9e81, 0x9e81, 0x9e81, 0x9e81, 0x9e81,
+	0x9e83, 0x080c, 0x14f6, 0x080c, 0xab4e, 0x1d80, 0x0089, 0x1138,
+	0x6007, 0x0045, 0x6003, 0x0001, 0x080c, 0x67ee, 0x0005, 0x080c,
+	0x2ad9, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x67ee, 0x0005,
+	0x00d6, 0x0066, 0x6618, 0x2668, 0x6e04, 0xa6b4, 0xff00, 0x8637,
+	0xa686, 0x0006, 0x0170, 0xa686, 0x0004, 0x0158, 0x6e04, 0xa6b4,
+	0x00ff, 0xa686, 0x0006, 0x0128, 0xa686, 0x0004, 0x0110, 0xa085,
+	0x0001, 0x006e, 0x00de, 0x0005, 0x00d6, 0x0449, 0x00de, 0x0005,
+	0x00d6, 0x0491, 0x11f0, 0x680c, 0xa08c, 0xff00, 0x6820, 0xa084,
+	0x00ff, 0xa115, 0x6212, 0x6824, 0x602a, 0xd1e4, 0x0118, 0x2009,
+	0x0001, 0x0060, 0xd1ec, 0x0168, 0x6920, 0xa18c, 0x00ff, 0x6824,
+	0x080c, 0x2676, 0x1130, 0x2110, 0x2009, 0x0000, 0x080c, 0x2b1e,
+	0x0018, 0xa085, 0x0001, 0x0008, 0xa006, 0x00de, 0x0005, 0x2069,
+	0xb28d, 0x6800, 0xa082, 0x0010, 0x1228, 0x6013, 0x0000, 0xa085,
+	0x0001, 0x0008, 0xa006, 0x0005, 0x6013, 0x0000, 0x2069, 0xb28c,
+	0x6808, 0xa084, 0xff00, 0xa086, 0x0800, 0x1140, 0x6800, 0xa084,
+	0x00ff, 0xa08e, 0x0014, 0x0110, 0xa08e, 0x0010, 0x0005, 0x6004,
+	0xa0b2, 0x0080, 0x1a0c, 0x14f6, 0xa1b6, 0x0013, 0x1130, 0x2008,
+	0xa1b2, 0x0040, 0x1a04, 0x9ffb, 0x0092, 0xa1b6, 0x0027, 0x0120,
+	0xa1b6, 0x0014, 0x190c, 0x14f6, 0x2001, 0x0007, 0x080c, 0x4c5d,
+	0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50, 0x0005, 0x9f5f,
+	0x9f61, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f61, 0x9f6f, 0x9ff4, 0x9fbf,
+	0x9ff4, 0x9fd0, 0x9ff4, 0x9f6f, 0x9ff4, 0x9fec, 0x9ff4, 0x9fec,
+	0x9ff4, 0x9ff4, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f5f,
+	0x9f5f, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f61, 0x9f5f, 0x9ff4,
+	0x9f5f, 0x9f5f, 0x9ff4, 0x9f5f, 0x9ff1, 0x9ff4, 0x9f5f, 0x9f5f,
+	0x9f5f, 0x9f5f, 0x9ff4, 0x9ff4, 0x9f5f, 0x9ff4, 0x9ff4, 0x9f5f,
+	0x9f69, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f5f, 0x9ff0, 0x9ff4, 0x9f5f,
+	0x9f5f, 0x9ff4, 0x9ff4, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f5f, 0x080c,
+	0x14f6, 0x080c, 0x6b73, 0x6003, 0x0002, 0x080c, 0x6c50, 0x0804,
+	0x9ffa, 0x2001, 0x0000, 0x080c, 0x4c1e, 0x0804, 0x9ff4, 0x00f6,
+	0x2079, 0xad51, 0x7804, 0x00fe, 0xd0ac, 0x1904, 0x9ff4, 0x2001,
+	0x0000, 0x080c, 0x4c1e, 0x6018, 0xa080, 0x0004, 0x2004, 0xa086,
+	0x00ff, 0x1140, 0x00f6, 0x2079, 0xad00, 0x7894, 0x8000, 0x7896,
+	0x00fe, 0x00e0, 0x00c6, 0x6018, 0x2060, 0x6000, 0xd0f4, 0x1140,
+	0x6010, 0xa005, 0x0128, 0x00ce, 0x080c, 0x3cce, 0x0804, 0x9ff4,
+	0x00ce, 0x2001, 0xad00, 0x2004, 0xa086, 0x0002, 0x1138, 0x00f6,
+	0x2079, 0xad00, 0x7894, 0x8000, 0x7896, 0x00fe, 0x2001, 0x0002,
+	0x080c, 0x4c30, 0x080c, 0x6b73, 0x601f, 0x0001, 0x6003, 0x0001,
+	0x6007, 0x0002, 0x080c, 0x67ee, 0x080c, 0x6c50, 0x00c6, 0x6118,
+	0x2160, 0x2009, 0x0001, 0x080c, 0x6519, 0x00ce, 0x04d8, 0x6618,
+	0x00d6, 0x2668, 0x6e04, 0x00de, 0xa6b4, 0xff00, 0x8637, 0xa686,
+	0x0006, 0x0550, 0xa686, 0x0004, 0x0538, 0x2001, 0x0004, 0x0410,
+	0x2001, 0xad00, 0x2004, 0xa086, 0x0003, 0x1110, 0x080c, 0x3cce,
+	0x2001, 0x0006, 0x0489, 0x6618, 0x00d6, 0x2668, 0x6e04, 0x00de,
+	0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0170, 0x2001, 0x0006,
+	0x0048, 0x2001, 0x0004, 0x0030, 0x2001, 0x0006, 0x00e9, 0x0020,
+	0x0018, 0x0010, 0x080c, 0x4c5d, 0x080c, 0x6b73, 0x080c, 0x8078,
+	0x080c, 0x6c50, 0x0005, 0x2600, 0x0002, 0xa003, 0xa003, 0xa003,
+	0xa003, 0xa003, 0xa005, 0x080c, 0x14f6, 0x080c, 0x6b73, 0x080c,
+	0x8078, 0x080c, 0x6c50, 0x0005, 0x0016, 0x00d6, 0x6118, 0x2168,
+	0x6900, 0xd184, 0x0188, 0x6104, 0xa18e, 0x000a, 0x1128, 0x699c,
+	0xd1a4, 0x1110, 0x2001, 0x0007, 0x080c, 0x4c30, 0x2001, 0x0000,
+	0x080c, 0x4c1e, 0x080c, 0x2aff, 0x00de, 0x001e, 0x0005, 0x00d6,
+	0x6618, 0x2668, 0x6804, 0xa084, 0xff00, 0x8007, 0x00de, 0xa0b2,
+	0x000c, 0x1a0c, 0x14f6, 0xa1b6, 0x0015, 0x1110, 0x003b, 0x0028,
+	0xa1b6, 0x0016, 0x190c, 0x14f6, 0x006b, 0x0005, 0x86b9, 0x86b9,
+	0x86b9, 0x86b9, 0x86b9, 0x86b9, 0xa08f, 0xa056, 0x86b9, 0x86b9,
+	0x86b9, 0x86b9, 0x86b9, 0x86b9, 0x86b9, 0x86b9, 0x86b9, 0x86b9,
+	0xa08f, 0xa096, 0x86b9, 0x86b9, 0x86b9, 0x86b9, 0x00f6, 0x2079,
+	0xad51, 0x7804, 0xd0ac, 0x11e0, 0x6018, 0xa07d, 0x01c8, 0x7800,
+	0xd0f4, 0x1118, 0x7810, 0xa005, 0x1198, 0x2001, 0x0000, 0x080c,
+	0x4c1e, 0x2001, 0x0002, 0x080c, 0x4c30, 0x601f, 0x0001, 0x6003,
+	0x0001, 0x6007, 0x0002, 0x080c, 0x67ee, 0x080c, 0x6c50, 0x00a8,
+	0x2011, 0xb283, 0x2204, 0x8211, 0x220c, 0x080c, 0x2676, 0x1168,
+	0x00c6, 0x080c, 0x4cdc, 0x0120, 0x00ce, 0x080c, 0x8078, 0x0028,
+	0x080c, 0x493a, 0x00ce, 0x080c, 0x8078, 0x00fe, 0x0005, 0x6604,
+	0xa6b6, 0x001e, 0x1110, 0x080c, 0x8078, 0x0005, 0x080c, 0x8940,
+	0x1138, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x67ee, 0x0010,
+	0x080c, 0x8078, 0x0005, 0x6004, 0xa08a, 0x0080, 0x1a0c, 0x14f6,
+	0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50, 0x0005, 0xa182,
+	0x0040, 0x0002, 0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5, 0xa0c7, 0xa0c5,
+	0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5,
+	0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5, 0x080c, 0x14f6, 0x00d6,
+	0x00e6, 0x00f6, 0x0156, 0x0046, 0x0026, 0x6218, 0xa280, 0x002b,
+	0x2004, 0xa005, 0x0120, 0x2021, 0x0000, 0x080c, 0xab96, 0x6106,
+	0x2071, 0xb280, 0x7444, 0xa4a4, 0xff00, 0x0904, 0xa129, 0xa486,
+	0x2000, 0x1130, 0x2009, 0x0001, 0x2011, 0x0200, 0x080c, 0x663f,
+	0x080c, 0x15d9, 0x090c, 0x14f6, 0x6003, 0x0007, 0x2d00, 0x6837,
+	0x010d, 0x6803, 0x0000, 0x683b, 0x0000, 0x6c5a, 0x2c00, 0x685e,
+	0x6008, 0x68b2, 0x6018, 0x2078, 0x78a0, 0x8007, 0x7130, 0x694a,
+	0x0016, 0xa084, 0xff00, 0x6846, 0x684f, 0x0000, 0x6857, 0x0036,
+	0x080c, 0x510c, 0x001e, 0xa486, 0x2000, 0x1130, 0x2019, 0x0017,
+	0x080c, 0xa8eb, 0x0804, 0xa186, 0xa486, 0x0400, 0x1130, 0x2019,
+	0x0002, 0x080c, 0xa89d, 0x0804, 0xa186, 0xa486, 0x0200, 0x1110,
+	0x080c, 0xa882, 0xa486, 0x1000, 0x1110, 0x080c, 0xa8d0, 0x0804,
+	0xa186, 0x2069, 0xb048, 0x6a00, 0xd284, 0x0904, 0xa1d5, 0xa284,
+	0x0300, 0x1904, 0xa1cf, 0x6804, 0xa005, 0x0904, 0xa1c0, 0x2d78,
+	0x6003, 0x0007, 0x080c, 0x15c0, 0x0904, 0xa18d, 0x7800, 0xd08c,
+	0x1118, 0x7804, 0x8001, 0x7806, 0x6013, 0x0000, 0x6803, 0x0000,
+	0x6837, 0x0116, 0x683b, 0x0000, 0x6008, 0x68b2, 0x2c00, 0x684a,
+	0x6018, 0x2078, 0x78a0, 0x8007, 0x7130, 0x6986, 0x6846, 0x7928,
+	0x698a, 0x792c, 0x698e, 0x7930, 0x6992, 0x7934, 0x6996, 0x6853,
+	0x003d, 0x7244, 0xa294, 0x0003, 0xa286, 0x0002, 0x1118, 0x684f,
+	0x0040, 0x0040, 0xa286, 0x0001, 0x1118, 0x684f, 0x0080, 0x0010,
+	0x684f, 0x0000, 0x20a9, 0x000a, 0x2001, 0xb290, 0xad90, 0x0015,
+	0x200c, 0x810f, 0x2112, 0x8000, 0x8210, 0x1f04, 0xa178, 0x200c,
+	0x6982, 0x8000, 0x200c, 0x697e, 0x080c, 0x510c, 0x002e, 0x004e,
+	0x015e, 0x00fe, 0x00ee, 0x00de, 0x0005, 0x6013, 0x0100, 0x6003,
+	0x0001, 0x6007, 0x0041, 0x080c, 0x67a8, 0x080c, 0x6c50, 0x0c70,
+	0x2069, 0xb292, 0x2d04, 0xa084, 0xff00, 0xa086, 0x1200, 0x11a8,
+	0x2069, 0xb280, 0x686c, 0xa084, 0x00ff, 0x0016, 0x6110, 0xa18c,
+	0x0700, 0xa10d, 0x6112, 0x001e, 0x6003, 0x0001, 0x6007, 0x0043,
+	0x080c, 0x67a8, 0x080c, 0x6c50, 0x0888, 0x6013, 0x0200, 0x6003,
+	0x0001, 0x6007, 0x0041, 0x080c, 0x67a8, 0x080c, 0x6c50, 0x0830,
+	0x6013, 0x0300, 0x0010, 0x6013, 0x0100, 0x6003, 0x0001, 0x6007,
+	0x0041, 0x080c, 0x67a8, 0x080c, 0x6c50, 0x0804, 0xa186, 0x6013,
+	0x0500, 0x0c98, 0x6013, 0x0600, 0x0818, 0x6013, 0x0200, 0x0800,
+	0xa186, 0x0013, 0x1170, 0x6004, 0xa08a, 0x0040, 0x0a0c, 0x14f6,
+	0xa08a, 0x0053, 0x1a0c, 0x14f6, 0xa082, 0x0040, 0x2008, 0x0804,
+	0xa252, 0xa186, 0x0051, 0x0138, 0xa186, 0x0047, 0x11d8, 0x6004,
+	0xa086, 0x0041, 0x0518, 0x2001, 0x0109, 0x2004, 0xd084, 0x01f0,
+	0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x080c, 0x6699,
+	0x002e, 0x001e, 0x000e, 0x012e, 0x6000, 0xa086, 0x0002, 0x1170,
+	0x0804, 0xa295, 0xa186, 0x0027, 0x0120, 0xa186, 0x0014, 0x190c,
+	0x14f6, 0x6004, 0xa082, 0x0040, 0x2008, 0x001a, 0x080c, 0x80be,
+	0x0005, 0xa22c, 0xa22e, 0xa22e, 0xa22c, 0xa22c, 0xa22c, 0xa22c,
+	0xa22c, 0xa22c, 0xa22c, 0xa22c, 0xa22c, 0xa22c, 0xa22c, 0xa22c,
+	0xa22c, 0xa22c, 0xa22c, 0xa22c, 0x080c, 0x14f6, 0x080c, 0x6b73,
+	0x080c, 0x6c50, 0x0036, 0x00d6, 0x6010, 0xa06d, 0x01c0, 0xad84,
+	0xf000, 0x01a8, 0x6003, 0x0002, 0x6018, 0x2004, 0xd0bc, 0x1178,
+	0x2019, 0x0004, 0x080c, 0xa91f, 0x6013, 0x0000, 0x6014, 0xa005,
+	0x1120, 0x2001, 0xafa4, 0x2004, 0x6016, 0x6003, 0x0007, 0x00de,
+	0x003e, 0x0005, 0x0002, 0xa266, 0xa283, 0xa26f, 0xa28f, 0xa266,
+	0xa266, 0xa266, 0xa266, 0xa266, 0xa266, 0xa266, 0xa266, 0xa266,
+	0xa266, 0xa266, 0xa266, 0xa266, 0xa266, 0xa266, 0x080c, 0x14f6,
+	0x6010, 0xa088, 0x0013, 0x2104, 0xa085, 0x0400, 0x200a, 0x080c,
+	0x6b73, 0x6010, 0xa080, 0x0013, 0x2004, 0xd0b4, 0x0138, 0x6003,
+	0x0007, 0x2009, 0x0043, 0x080c, 0x80a7, 0x0010, 0x6003, 0x0002,
+	0x080c, 0x6c50, 0x0005, 0x080c, 0x6b73, 0x080c, 0xab55, 0x1120,
+	0x080c, 0x6618, 0x080c, 0x8078, 0x080c, 0x6c50, 0x0005, 0x080c,
+	0x6b73, 0x2009, 0x0041, 0x0804, 0xa3de, 0xa182, 0x0040, 0x0002,
+	0xa2ab, 0xa2ad, 0xa2ab, 0xa2ab, 0xa2ab, 0xa2ab, 0xa2ab, 0xa2ae,
+	0xa2ab, 0xa2ab, 0xa2ab, 0xa2ab, 0xa2ab, 0xa2ab, 0xa2ab, 0xa2ab,
+	0xa2ab, 0xa2b9, 0xa2ab, 0x080c, 0x14f6, 0x0005, 0x6003, 0x0004,
+	0x6110, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x1824,
+	0x0005, 0x00d6, 0x080c, 0x6618, 0x00de, 0x080c, 0xabb4, 0x080c,
+	0x8078, 0x0005, 0xa182, 0x0040, 0x0002, 0xa2d8, 0xa2d8, 0xa2d8,
+	0xa2d8, 0xa2d8, 0xa2d8, 0xa2d8, 0xa2da, 0xa2d8, 0xa2dd, 0xa316,
+	0xa2d8, 0xa2d8, 0xa2d8, 0xa2d8, 0xa316, 0xa2d8, 0xa2d8, 0xa2d8,
+	0x080c, 0x14f6, 0x080c, 0x80be, 0x0005, 0x2001, 0xad71, 0x2004,
+	0xd0e4, 0x0158, 0x2001, 0x0100, 0x2004, 0xa082, 0x0005, 0x0228,
+	0x2001, 0x011f, 0x2004, 0x6036, 0x0010, 0x6037, 0x0000, 0x080c,
+	0x6c05, 0x080c, 0x6d0d, 0x6010, 0x00d6, 0x2068, 0x684c, 0xd0fc,
+	0x0150, 0xa08c, 0x0003, 0xa18e, 0x0002, 0x0168, 0x2009, 0x0041,
+	0x00de, 0x0804, 0xa3de, 0x6003, 0x0007, 0x6017, 0x0000, 0x080c,
+	0x6618, 0x00de, 0x0005, 0x080c, 0xab55, 0x0110, 0x00de, 0x0005,
+	0x080c, 0x6618, 0x080c, 0x8078, 0x00de, 0x0ca0, 0x0036, 0x080c,
+	0x6c05, 0x080c, 0x6d0d, 0x6010, 0x00d6, 0x2068, 0x6018, 0x2004,
+	0xd0bc, 0x0188, 0x684c, 0xa084, 0x0003, 0xa086, 0x0002, 0x0140,
+	0x687c, 0x632c, 0xa31a, 0x632e, 0x6880, 0x6328, 0xa31b, 0x632a,
+	0x6003, 0x0002, 0x0080, 0x2019, 0x0004, 0x080c, 0xa91f, 0x6014,
+	0xa005, 0x1128, 0x2001, 0xafa4, 0x2004, 0x8003, 0x6016, 0x6013,
+	0x0000, 0x6003, 0x0007, 0x00de, 0x003e, 0x0005, 0xa186, 0x0013,
+	0x1150, 0x6004, 0xa086, 0x0042, 0x190c, 0x14f6, 0x080c, 0x6b73,
+	0x080c, 0x6c50, 0x0005, 0xa186, 0x0027, 0x0118, 0xa186, 0x0014,
+	0x1180, 0x6004, 0xa086, 0x0042, 0x190c, 0x14f6, 0x2001, 0x0007,
+	0x080c, 0x4c5d, 0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50,
+	0x0005, 0xa182, 0x0040, 0x0002, 0xa37f, 0xa37f, 0xa37f, 0xa37f,
+	0xa37f, 0xa37f, 0xa37f, 0xa381, 0xa38d, 0xa37f, 0xa37f, 0xa37f,
+	0xa37f, 0xa37f, 0xa37f, 0xa37f, 0xa37f, 0xa37f, 0xa37f, 0x080c,
+	0x14f6, 0x0036, 0x0046, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10,
+	0x080c, 0x1824, 0x004e, 0x003e, 0x0005, 0x6010, 0x00d6, 0x2068,
+	0x6810, 0x6a14, 0x0006, 0x0046, 0x0056, 0x6c7c, 0xa422, 0x6d80,
+	0x2200, 0xa52b, 0x602c, 0xa420, 0x642e, 0x6028, 0xa529, 0x652a,
+	0x005e, 0x004e, 0x000e, 0xa20d, 0x1178, 0x684c, 0xd0fc, 0x0120,
+	0x2009, 0x0041, 0x00de, 0x0490, 0x6003, 0x0007, 0x6017, 0x0000,
+	0x080c, 0x6618, 0x00de, 0x0005, 0x0006, 0x00f6, 0x2c78, 0x080c,
+	0x5029, 0x00fe, 0x000e, 0x0120, 0x6003, 0x0002, 0x00de, 0x0005,
+	0x2009, 0xad0d, 0x210c, 0xd19c, 0x0118, 0x6003, 0x0007, 0x0010,
+	0x6003, 0x0006, 0x0021, 0x080c, 0x661a, 0x00de, 0x0005, 0xd2fc,
+	0x0140, 0x8002, 0x8000, 0x8212, 0xa291, 0x0000, 0x2009, 0x0009,
+	0x0010, 0x2009, 0x0015, 0x6a6a, 0x6866, 0x0005, 0xa182, 0x0040,
+	0x0208, 0x0062, 0xa186, 0x0013, 0x0120, 0xa186, 0x0014, 0x190c,
+	0x14f6, 0x6020, 0xd0dc, 0x090c, 0x14f6, 0x0005, 0xa401, 0xa408,
+	0xa414, 0xa420, 0xa401, 0xa401, 0xa401, 0xa42f, 0xa401, 0xa403,
+	0xa403, 0xa401, 0xa401, 0xa401, 0xa401, 0xa403, 0xa401, 0xa403,
+	0xa401, 0x080c, 0x14f6, 0x6020, 0xd0dc, 0x090c, 0x14f6, 0x0005,
+	0x6003, 0x0001, 0x6106, 0x080c, 0x67a8, 0x0126, 0x2091, 0x8000,
+	0x080c, 0x6c50, 0x012e, 0x0005, 0x6003, 0x0001, 0x6106, 0x080c,
+	0x67a8, 0x0126, 0x2091, 0x8000, 0x080c, 0x6c50, 0x012e, 0x0005,
+	0x6003, 0x0003, 0x6106, 0x2c10, 0x080c, 0x1e6e, 0x0126, 0x2091,
+	0x8000, 0x080c, 0x680b, 0x080c, 0x6d0d, 0x012e, 0x0005, 0xa016,
+	0x080c, 0x1824, 0x0005, 0x0126, 0x2091, 0x8000, 0x0036, 0x00d6,
+	0xa182, 0x0040, 0x0023, 0x00de, 0x003e, 0x012e, 0x0005, 0xa44f,
+	0xa451, 0xa463, 0xa47e, 0xa44f, 0xa44f, 0xa44f, 0xa493, 0xa44f,
+	0xa44f, 0xa44f, 0xa44f, 0xa44f, 0xa44f, 0xa44f, 0xa44f, 0x080c,
+	0x14f6, 0x6010, 0x2068, 0x684c, 0xd0fc, 0x01f8, 0xa09c, 0x0003,
+	0xa39e, 0x0003, 0x01d0, 0x6003, 0x0001, 0x6106, 0x080c, 0x67a8,
+	0x080c, 0x6c50, 0x0498, 0x6010, 0x2068, 0x684c, 0xd0fc, 0x0168,
+	0xa09c, 0x0003, 0xa39e, 0x0003, 0x0140, 0x6003, 0x0001, 0x6106,
+	0x080c, 0x67a8, 0x080c, 0x6c50, 0x0408, 0x6013, 0x0000, 0x6017,
+	0x0000, 0x2019, 0x0004, 0x080c, 0xa91f, 0x00c0, 0x6010, 0x2068,
+	0x684c, 0xd0fc, 0x0d90, 0xa09c, 0x0003, 0xa39e, 0x0003, 0x0d68,
+	0x6003, 0x0003, 0x6106, 0x2c10, 0x080c, 0x1e6e, 0x080c, 0x680b,
+	0x080c, 0x6d0d, 0x0018, 0xa016, 0x080c, 0x1824, 0x0005, 0x080c,
+	0x6b73, 0x6110, 0x81ff, 0x0158, 0x00d6, 0x2168, 0x080c, 0xabfa,
+	0x0036, 0x2019, 0x0029, 0x080c, 0xa91f, 0x003e, 0x00de, 0x080c,
+	0x974e, 0x080c, 0x6c50, 0x0005, 0x080c, 0x6c05, 0x6110, 0x81ff,
+	0x0158, 0x00d6, 0x2168, 0x080c, 0xabfa, 0x0036, 0x2019, 0x0029,
+	0x080c, 0xa91f, 0x003e, 0x00de, 0x080c, 0x974e, 0x080c, 0x6d0d,
+	0x0005, 0xa182, 0x0085, 0x0002, 0xa4cd, 0xa4cb, 0xa4cb, 0xa4d9,
+	0xa4cb, 0xa4cb, 0xa4cb, 0x080c, 0x14f6, 0x6003, 0x000b, 0x6106,
+	0x080c, 0x67a8, 0x0126, 0x2091, 0x8000, 0x080c, 0x6c50, 0x012e,
+	0x0005, 0x0026, 0x00e6, 0x080c, 0xab4e, 0x0118, 0x080c, 0x8078,
+	0x00c8, 0x2071, 0xb280, 0x7224, 0x6212, 0x7220, 0x080c, 0xa7ce,
+	0x0118, 0x6007, 0x0086, 0x0040, 0x6007, 0x0087, 0x7224, 0xa296,
+	0xffff, 0x1110, 0x6007, 0x0086, 0x6003, 0x0001, 0x080c, 0x67a8,
+	0x080c, 0x6c50, 0x00ee, 0x002e, 0x0005, 0xa186, 0x0013, 0x1160,
+	0x6004, 0xa08a, 0x0085, 0x0a0c, 0x14f6, 0xa08a, 0x008c, 0x1a0c,
+	0x14f6, 0xa082, 0x0085, 0x00a2, 0xa186, 0x0027, 0x0130, 0xa186,
+	0x0014, 0x0118, 0x080c, 0x80be, 0x0050, 0x2001, 0x0007, 0x080c,
+	0x4c5d, 0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50, 0x0005,
+	0xa527, 0xa529, 0xa529, 0xa527, 0xa527, 0xa527, 0xa527, 0x080c,
+	0x14f6, 0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50, 0x0005,
+	0xa182, 0x0085, 0x0a0c, 0x14f6, 0xa182, 0x008c, 0x1a0c, 0x14f6,
+	0xa182, 0x0085, 0x0002, 0xa542, 0xa542, 0xa542, 0xa544, 0xa542,
+	0xa542, 0xa542, 0x080c, 0x14f6, 0x0005, 0xa186, 0x0013, 0x0148,
+	0xa186, 0x0014, 0x0130, 0xa186, 0x0027, 0x0118, 0x080c, 0x80be,
+	0x0030, 0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50, 0x0005,
+	0x0036, 0x080c, 0xabb4, 0x603f, 0x0000, 0x2019, 0x000b, 0x0031,
+	0x601f, 0x0006, 0x6003, 0x0007, 0x003e, 0x0005, 0x0126, 0x0036,
+	0x2091, 0x8000, 0x0086, 0x2c40, 0x0096, 0x2049, 0x0000, 0x080c,
+	0x7b9a, 0x009e, 0x008e, 0x1578, 0x0076, 0x2c38, 0x080c, 0x7c34,
+	0x007e, 0x1548, 0x6000, 0xa086, 0x0000, 0x0528, 0x601c, 0xa086,
+	0x0007, 0x0508, 0x00d6, 0x6000, 0xa086, 0x0004, 0x1150, 0x080c,
+	0xabb4, 0x601f, 0x0007, 0x2001, 0xafa3, 0x2004, 0x6016, 0x080c,
+	0x190b, 0x6010, 0x2068, 0x080c, 0x9596, 0x0110, 0x080c, 0xa91f,
+	0x00de, 0x6013, 0x0000, 0x080c, 0xabb4, 0x601f, 0x0007, 0x2001,
+	0xafa3, 0x2004, 0x6016, 0x003e, 0x012e, 0x0005, 0x00f6, 0x00c6,
+	0x0036, 0x0156, 0x2079, 0xb280, 0x7938, 0x783c, 0x080c, 0x2676,
+	0x1904, 0xa5f1, 0x0016, 0x00c6, 0x080c, 0x4cdc, 0x15c0, 0x2011,
+	0xb290, 0xac98, 0x000a, 0x20a9, 0x0004, 0x080c, 0x8a7c, 0x1578,
+	0x001e, 0x002e, 0x0026, 0x0016, 0x2019, 0x0029, 0x080c, 0x7cf4,
+	0x080c, 0x68e7, 0x0076, 0x2039, 0x0000, 0x080c, 0x681d, 0x007e,
+	0x001e, 0x0076, 0x2039, 0x0000, 0x080c, 0xa712, 0x007e, 0x080c,
+	0x4ecf, 0x0026, 0x6204, 0xa294, 0xff00, 0x8217, 0xa286, 0x0006,
+	0x0118, 0xa286, 0x0004, 0x1118, 0x62a0, 0x080c, 0x2b87, 0x002e,
+	0x001e, 0x080c, 0x493a, 0x6612, 0x6516, 0xa006, 0x0010, 0x00ce,
+	0x001e, 0x015e, 0x003e, 0x00ce, 0x00fe, 0x0005, 0x00c6, 0x00d6,
+	0x00e6, 0x0016, 0x2009, 0xad20, 0x2104, 0xa086, 0x0074, 0x1904,
+	0xa64b, 0x2069, 0xb28e, 0x690c, 0xa182, 0x0100, 0x06c0, 0x6908,
+	0xa184, 0x8000, 0x05e8, 0x2001, 0xaf9d, 0x2004, 0xa005, 0x1160,
+	0x6018, 0x2070, 0x7010, 0xa084, 0x00ff, 0x0118, 0x7000, 0xd0f4,
+	0x0118, 0xa184, 0x0800, 0x0560, 0x6910, 0xa18a, 0x0001, 0x0610,
+	0x6914, 0x2069, 0xb2ae, 0x6904, 0x81ff, 0x1198, 0x690c, 0xa182,
+	0x0100, 0x02a8, 0x6908, 0x81ff, 0x1178, 0x6910, 0xa18a, 0x0001,
+	0x0288, 0x6918, 0xa18a, 0x0001, 0x0298, 0x00d0, 0x6013, 0x0100,
+	0x00a0, 0x6013, 0x0300, 0x0088, 0x6013, 0x0500, 0x0070, 0x6013,
+	0x0700, 0x0058, 0x6013, 0x0900, 0x0040, 0x6013, 0x0b00, 0x0028,
+	0x6013, 0x0f00, 0x0010, 0x6013, 0x2d00, 0xa085, 0x0001, 0x0008,
+	0xa006, 0x001e, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6,
+	0x0026, 0x0036, 0x0156, 0x6218, 0x2268, 0x6b04, 0xa394, 0x00ff,
+	0xa286, 0x0006, 0x0190, 0xa286, 0x0004, 0x0178, 0xa394, 0xff00,
+	0x8217, 0xa286, 0x0006, 0x0148, 0xa286, 0x0004, 0x0130, 0x00c6,
+	0x2d60, 0x080c, 0x4ceb, 0x00ce, 0x04c0, 0x2011, 0xb296, 0xad98,
+	0x000a, 0x20a9, 0x0004, 0x080c, 0x8a7c, 0x1580, 0x2011, 0xb29a,
+	0xad98, 0x0006, 0x20a9, 0x0004, 0x080c, 0x8a7c, 0x1538, 0x0046,
+	0x0016, 0x6aa0, 0xa294, 0x00ff, 0x8227, 0xa006, 0x2009, 0xad52,
+	0x210c, 0xd1a4, 0x0138, 0x2009, 0x0029, 0x080c, 0xa96c, 0x6800,
+	0xc0e5, 0x6802, 0x2019, 0x0029, 0x080c, 0x68e7, 0x0076, 0x2039,
+	0x0000, 0x080c, 0x681d, 0x2c08, 0x080c, 0xa712, 0x007e, 0x2001,
+	0x0007, 0x080c, 0x4c5d, 0x001e, 0x004e, 0xa006, 0x015e, 0x003e,
+	0x002e, 0x00de, 0x00ce, 0x0005, 0x00d6, 0x2069, 0xb28e, 0x6800,
+	0xa086, 0x0800, 0x0118, 0x6013, 0x0000, 0x0008, 0xa006, 0x00de,
+	0x0005, 0x00c6, 0x00f6, 0x0016, 0x0026, 0x0036, 0x0156, 0x2079,
+	0xb28c, 0x7930, 0x7834, 0x080c, 0x2676, 0x11a0, 0x080c, 0x4cdc,
+	0x1188, 0x2011, 0xb290, 0xac98, 0x000a, 0x20a9, 0x0004, 0x080c,
+	0x8a7c, 0x1140, 0x2011, 0xb294, 0xac98, 0x0006, 0x20a9, 0x0004,
+	0x080c, 0x8a7c, 0x015e, 0x003e, 0x002e, 0x001e, 0x00fe, 0x00ce,
+	0x0005, 0x00c6, 0x0006, 0x0016, 0x0026, 0x0036, 0x0156, 0x2011,
+	0xb283, 0x2204, 0x8211, 0x220c, 0x080c, 0x2676, 0x11a0, 0x080c,
+	0x4cdc, 0x1188, 0x2011, 0xb296, 0xac98, 0x000a, 0x20a9, 0x0004,
+	0x080c, 0x8a7c, 0x1140, 0x2011, 0xb29a, 0xac98, 0x0006, 0x20a9,
+	0x0004, 0x080c, 0x8a7c, 0x015e, 0x003e, 0x002e, 0x001e, 0x000e,
+	0x00ce, 0x0005, 0x00e6, 0x00c6, 0x0086, 0x0076, 0x0066, 0x0056,
+	0x0046, 0x0026, 0x0126, 0x2091, 0x8000, 0x2740, 0x2029, 0xafd0,
+	0x252c, 0x2021, 0xafd6, 0x2424, 0x2061, 0xb400, 0x2071, 0xad00,
+	0x7644, 0x7064, 0x81ff, 0x0128, 0x8001, 0xa602, 0x1a04, 0xa78e,
+	0x0018, 0xa606, 0x0904, 0xa78e, 0x2100, 0xac06, 0x0904, 0xa785,
+	0x080c, 0xa990, 0x0904, 0xa785, 0x671c, 0xa786, 0x0001, 0x0904,
+	0xa7a5, 0xa786, 0x0004, 0x0904, 0xa7a5, 0xa786, 0x0007, 0x05e8,
+	0x2500, 0xac06, 0x05d0, 0x2400, 0xac06, 0x05b8, 0x080c, 0xa9a0,
+	0x15a0, 0x88ff, 0x0118, 0x6050, 0xa906, 0x1578, 0x00d6, 0x6000,
+	0xa086, 0x0004, 0x1120, 0x0016, 0x080c, 0x190b, 0x001e, 0xa786,
+	0x0008, 0x1148, 0x080c, 0x9789, 0x1130, 0x080c, 0x85f3, 0x00de,
+	0x080c, 0x974e, 0x00d0, 0x6010, 0x2068, 0x080c, 0x9596, 0x0190,
+	0xa786, 0x0003, 0x1528, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000,
+	0x080c, 0xabfa, 0x0016, 0x080c, 0x97fd, 0x080c, 0x510c, 0x001e,
+	0x080c, 0x9742, 0x00de, 0x080c, 0x974e, 0xace0, 0x0018, 0x2001,
+	0xad16, 0x2004, 0xac02, 0x1210, 0x0804, 0xa726, 0x012e, 0x002e,
+	0x004e, 0x005e, 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee, 0x0005,
+	0xa786, 0x0006, 0x19c0, 0xa386, 0x0005, 0x0128, 0x080c, 0xabfa,
+	0x080c, 0xa91f, 0x08f8, 0x00de, 0x0c00, 0x080c, 0xa9a0, 0x19e8,
+	0x81ff, 0x09d8, 0xa180, 0x0001, 0x2004, 0xa086, 0x0018, 0x0130,
+	0xa180, 0x0001, 0x2004, 0xa086, 0x002d, 0x1978, 0x6000, 0xa086,
+	0x0002, 0x1958, 0x080c, 0x9778, 0x0130, 0x080c, 0x9789, 0x1928,
+	0x080c, 0x85f3, 0x0038, 0x080c, 0x2aff, 0x080c, 0x9789, 0x1110,
+	0x080c, 0x85f3, 0x080c, 0x974e, 0x0804, 0xa785, 0x00c6, 0x00e6,
+	0x0016, 0x2c08, 0x2170, 0x080c, 0xa940, 0x001e, 0x0120, 0x601c,
+	0xa084, 0x000f, 0x001b, 0x00ee, 0x00ce, 0x0005, 0xa7e6, 0xa7e6,
+	0xa7e6, 0xa7e6, 0xa7e6, 0xa7e6, 0xa7e8, 0xa7e6, 0xa006, 0x0005,
+	0x0046, 0x0016, 0x7018, 0xa080, 0x0028, 0x2024, 0xa4a4, 0x00ff,
+	0x8427, 0x2c00, 0x2009, 0x0020, 0x080c, 0xa96c, 0x001e, 0x004e,
+	0x0036, 0x2019, 0x0002, 0x080c, 0xa566, 0x003e, 0xa085, 0x0001,
+	0x0005, 0x2001, 0x0001, 0x080c, 0x4c1e, 0x0156, 0x0016, 0x0026,
+	0x0036, 0x20a9, 0x0004, 0x2019, 0xad05, 0x2011, 0xb296, 0x080c,
+	0x8a7c, 0x003e, 0x002e, 0x001e, 0x015e, 0xa005, 0x0005, 0x00f6,
+	0x00e6, 0x00c6, 0x0086, 0x0076, 0x0066, 0x0026, 0x0126, 0x2091,
+	0x8000, 0x2740, 0x2061, 0xb400, 0x2079, 0x0001, 0x8fff, 0x0904,
+	0xa875, 0x2071, 0xad00, 0x7644, 0x7064, 0x8001, 0xa602, 0x1a04,
+	0xa875, 0x88ff, 0x0128, 0x2800, 0xac06, 0x15b0, 0x2079, 0x0000,
+	0x080c, 0xa990, 0x0588, 0x2400, 0xac06, 0x0570, 0x671c, 0xa786,
+	0x0006, 0x1550, 0xa786, 0x0007, 0x0538, 0x88ff, 0x1140, 0x6018,
+	0xa206, 0x1510, 0x85ff, 0x0118, 0x6050, 0xa106, 0x11e8, 0x00d6,
+	0x6000, 0xa086, 0x0004, 0x1150, 0x080c, 0xabb4, 0x601f, 0x0007,
+	0x2001, 0xafa3, 0x2004, 0x6016, 0x080c, 0x190b, 0x6010, 0x2068,
+	0x080c, 0x9596, 0x0120, 0x0046, 0x080c, 0xa91f, 0x004e, 0x00de,
+	0x080c, 0x974e, 0x88ff, 0x1198, 0xace0, 0x0018, 0x2001, 0xad16,
+	0x2004, 0xac02, 0x1210, 0x0804, 0xa826, 0xa006, 0x012e, 0x002e,
+	0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0xa8c5,
+	0x0001, 0x0ca0, 0x0076, 0x0056, 0x0086, 0x2041, 0x0000, 0x2029,
+	0x0001, 0x2c20, 0x2019, 0x0002, 0x6218, 0x0096, 0x2049, 0x0000,
+	0x080c, 0x7b9a, 0x009e, 0x008e, 0x2039, 0x0000, 0x080c, 0x7c34,
+	0x080c, 0xa817, 0x005e, 0x007e, 0x0005, 0x0026, 0x0046, 0x0056,
+	0x0076, 0x00c6, 0x0156, 0x2c20, 0x2128, 0x20a9, 0x007f, 0x2009,
+	0x0000, 0x0016, 0x0036, 0x080c, 0x4cdc, 0x11b0, 0x2c10, 0x0056,
+	0x0086, 0x2041, 0x0000, 0x2508, 0x2029, 0x0001, 0x0096, 0x2049,
+	0x0000, 0x080c, 0x7b9a, 0x009e, 0x008e, 0x2039, 0x0000, 0x080c,
+	0x7c34, 0x080c, 0xa817, 0x005e, 0x003e, 0x001e, 0x8108, 0x1f04,
+	0xa8a9, 0x015e, 0x00ce, 0x007e, 0x005e, 0x004e, 0x002e, 0x0005,
+	0x0076, 0x0056, 0x6218, 0x0086, 0x2041, 0x0000, 0x2029, 0x0001,
+	0x2019, 0x0048, 0x0096, 0x2049, 0x0000, 0x080c, 0x7b9a, 0x009e,
+	0x008e, 0x2039, 0x0000, 0x080c, 0x7c34, 0x2c20, 0x080c, 0xa817,
+	0x005e, 0x007e, 0x0005, 0x0026, 0x0046, 0x0056, 0x0076, 0x00c6,
+	0x0156, 0x2c20, 0x20a9, 0x007f, 0x2009, 0x0000, 0x0016, 0x0036,
+	0x080c, 0x4cdc, 0x11c0, 0x2c10, 0x0086, 0x2041, 0x0000, 0x2828,
+	0x0046, 0x2021, 0x0001, 0x080c, 0xab96, 0x004e, 0x0096, 0x2049,
+	0x0000, 0x080c, 0x7b9a, 0x009e, 0x008e, 0x2039, 0x0000, 0x080c,
+	0x7c34, 0x080c, 0xa817, 0x003e, 0x001e, 0x8108, 0x1f04, 0xa8f6,
+	0x015e, 0x00ce, 0x007e, 0x005e, 0x004e, 0x002e, 0x0005, 0x0016,
+	0x00f6, 0x3800, 0xd08c, 0x0130, 0xad82, 0x1000, 0x02b0, 0xad82,
+	0xad00, 0x0230, 0xad82, 0xe400, 0x0280, 0xad82, 0xffff, 0x1268,
+	0x6800, 0xa07d, 0x0138, 0x6803, 0x0000, 0x6b52, 0x080c, 0x510c,
+	0x2f68, 0x0cb0, 0x6b52, 0x080c, 0x510c, 0x00fe, 0x001e, 0x0005,
+	0x00e6, 0x0046, 0x0036, 0x2061, 0xb400, 0x2071, 0xad00, 0x7444,
+	0x7064, 0x8001, 0xa402, 0x12d8, 0x2100, 0xac06, 0x0168, 0x6000,
+	0xa086, 0x0000, 0x0148, 0x6008, 0xa206, 0x1130, 0x6018, 0xa1a0,
+	0x0006, 0x2424, 0xa406, 0x0140, 0xace0, 0x0018, 0x2001, 0xad16,
+	0x2004, 0xac02, 0x1220, 0x0c08, 0xa085, 0x0001, 0x0008, 0xa006,
+	0x003e, 0x004e, 0x00ee, 0x0005, 0x00d6, 0x0006, 0x080c, 0x15d9,
+	0x000e, 0x090c, 0x14f6, 0x6837, 0x010d, 0x685e, 0x0026, 0x2010,
+	0x080c, 0x9586, 0x2001, 0x0000, 0x0120, 0x2200, 0xa080, 0x0014,
+	0x2004, 0x002e, 0x684a, 0x6956, 0x6c46, 0x684f, 0x0000, 0xa006,
+	0x68b2, 0x6802, 0x683a, 0x685a, 0x080c, 0x510c, 0x00de, 0x0005,
+	0x6700, 0xa786, 0x0000, 0x0158, 0xa786, 0x0001, 0x0140, 0xa786,
+	0x000a, 0x0128, 0xa786, 0x0009, 0x0110, 0xa085, 0x0001, 0x0005,
+	0x00e6, 0x6018, 0x2070, 0x70a0, 0xa206, 0x00ee, 0x0005, 0x0016,
+	0x6004, 0xa08e, 0x001e, 0x11a0, 0x8007, 0x6130, 0xa18c, 0x00ff,
+	0xa105, 0x6032, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0005,
+	0x2001, 0xafa4, 0x2004, 0x6016, 0x080c, 0x67a8, 0x080c, 0x6c50,
+	0x001e, 0x0005, 0xe000, 0xe000, 0x0005, 0x6020, 0xd0e4, 0x0158,
+	0xd0cc, 0x0118, 0x080c, 0x9866, 0x0030, 0x080c, 0xabb4, 0x080c,
+	0x6618, 0x080c, 0x8078, 0x0005, 0xa280, 0x0007, 0x2004, 0xa084,
+	0x000f, 0x0002, 0xa9e3, 0xa9e3, 0xa9e3, 0xa9e8, 0xa9e3, 0xa9e5,
+	0xa9e5, 0xa9e3, 0xa9e5, 0xa006, 0x0005, 0x00c6, 0x2260, 0x00ce,
+	0xa085, 0x0001, 0x0005, 0xa280, 0x0007, 0x2004, 0xa084, 0x000f,
+	0x0002, 0xa9fa, 0xa9fa, 0xa9fa, 0xa9fa, 0xa9fa, 0xa9fa, 0xaa05,
+	0xa9fa, 0xa9fa, 0x6007, 0x003b, 0x602b, 0x0009, 0x6013, 0x2a00,
+	0x6003, 0x0001, 0x080c, 0x67a8, 0x0005, 0x00c6, 0x2260, 0x080c,
+	0xabb4, 0x603f, 0x0000, 0x6020, 0xc0f4, 0xc0cc, 0x6022, 0x6037,
+	0x0000, 0x00ce, 0x00d6, 0x2268, 0xa186, 0x0007, 0x1904, 0xaa60,
+	0x6810, 0xa005, 0x0138, 0xa080, 0x0013, 0x2004, 0xd0fc, 0x1110,
+	0x00de, 0x08c0, 0x6007, 0x003a, 0x6003, 0x0001, 0x080c, 0x67a8,
+	0x080c, 0x6c50, 0x00c6, 0x2d60, 0x6100, 0xa186, 0x0002, 0x1904,
+	0xaae7, 0x6010, 0xa005, 0x1138, 0x6000, 0xa086, 0x0007, 0x190c,
+	0x14f6, 0x0804, 0xaae7, 0xa08c, 0xf000, 0x1130, 0x0028, 0x2068,
+	0x6800, 0xa005, 0x1de0, 0x2d00, 0xa080, 0x0013, 0x2004, 0xa084,
+	0x0003, 0xa086, 0x0002, 0x1180, 0x6010, 0x2068, 0x684c, 0xc0dc,
+	0xc0f4, 0x684e, 0x6850, 0xc0f4, 0xc0fc, 0x6852, 0x2009, 0x0043,
+	0x080c, 0xa3de, 0x0804, 0xaae7, 0x2009, 0x0041, 0x0804, 0xaae1,
+	0xa186, 0x0005, 0x15f0, 0x6810, 0xa080, 0x0013, 0x2004, 0xd0bc,
+	0x1118, 0x00de, 0x0804, 0xa9fa, 0xd0b4, 0x0128, 0xd0fc, 0x090c,
+	0x14f6, 0x0804, 0xaa18, 0x6007, 0x003a, 0x6003, 0x0001, 0x080c,
+	0x67a8, 0x080c, 0x6c50, 0x00c6, 0x2d60, 0x6100, 0xa186, 0x0002,
+	0x0120, 0xa186, 0x0004, 0x1904, 0xaae7, 0x2071, 0xaffd, 0x7000,
+	0xa086, 0x0003, 0x1128, 0x7004, 0xac06, 0x1110, 0x7003, 0x0000,
+	0x6810, 0xa080, 0x0013, 0x200c, 0xc1f4, 0xc1dc, 0x2102, 0x8000,
+	0x200c, 0xc1f4, 0xc1fc, 0xc1bc, 0x2102, 0x2009, 0x0042, 0x0804,
+	0xaae1, 0x0036, 0x00d6, 0x00d6, 0x080c, 0x15d9, 0x003e, 0x090c,
+	0x14f6, 0x6837, 0x010d, 0x6803, 0x0000, 0x683b, 0x0000, 0x685b,
+	0x0000, 0x6b5e, 0x6857, 0x0045, 0x2c00, 0x6862, 0x6034, 0x6872,
+	0x2360, 0x6020, 0xc0dd, 0x6022, 0x6018, 0xa080, 0x0028, 0x2004,
+	0xa084, 0x00ff, 0x8007, 0x6350, 0x6b4a, 0x6846, 0x684f, 0x0000,
+	0x6d6a, 0x6e66, 0x686f, 0x0001, 0x080c, 0x510c, 0x2019, 0x0045,
+	0x6008, 0x2068, 0x080c, 0xa566, 0x2d00, 0x600a, 0x601f, 0x0006,
+	0x6003, 0x0007, 0x6017, 0x0000, 0x603f, 0x0000, 0x00de, 0x003e,
+	0x0038, 0x603f, 0x0000, 0x6003, 0x0007, 0x080c, 0xa3de, 0x00ce,
+	0x00de, 0x0005, 0xa186, 0x0013, 0x1128, 0x6004, 0xa082, 0x0085,
+	0x2008, 0x00c2, 0xa186, 0x0027, 0x1178, 0x080c, 0x6b73, 0x0036,
+	0x00d6, 0x6010, 0x2068, 0x2019, 0x0004, 0x080c, 0xa91f, 0x00de,
+	0x003e, 0x080c, 0x6c50, 0x0005, 0xa186, 0x0014, 0x0d70, 0x080c,
+	0x80be, 0x0005, 0xab13, 0xab11, 0xab11, 0xab11, 0xab11, 0xab11,
+	0xab13, 0x080c, 0x14f6, 0x080c, 0x6b73, 0x6003, 0x000c, 0x080c,
+	0x6c50, 0x0005, 0xa182, 0x008c, 0x1220, 0xa182, 0x0085, 0x0208,
+	0x001a, 0x080c, 0x80be, 0x0005, 0xab2b, 0xab2b, 0xab2b, 0xab2b,
+	0xab2d, 0xab4b, 0xab2b, 0x080c, 0x14f6, 0x00d6, 0x2c68, 0x080c,
+	0x8022, 0x01a0, 0x6003, 0x0001, 0x6007, 0x001e, 0x2009, 0xb28e,
+	0x210c, 0x6136, 0x2009, 0xb28f, 0x210c, 0x613a, 0x600b, 0xffff,
+	0x6918, 0x611a, 0x601f, 0x0004, 0x080c, 0x67a8, 0x2d60, 0x080c,
+	0x8078, 0x00de, 0x0005, 0x080c, 0x8078, 0x0005, 0x00e6, 0x6018,
+	0x2070, 0x7000, 0xd0ec, 0x00ee, 0x0005, 0x6010, 0xa080, 0x0013,
+	0x200c, 0xd1ec, 0x05d0, 0x2001, 0xad71, 0x2004, 0xd0ec, 0x05a8,
+	0x6003, 0x0002, 0x6020, 0xc0e5, 0x6022, 0xd1ac, 0x0180, 0x00f6,
+	0x2c78, 0x080c, 0x5025, 0x00fe, 0x0150, 0x2001, 0xafa5, 0x2004,
+	0x603e, 0x2009, 0xad71, 0x210c, 0xd1f4, 0x11e8, 0x0080, 0x2009,
+	0xad71, 0x210c, 0xd1f4, 0x0128, 0x6020, 0xc0e4, 0x6022, 0xa006,
+	0x00a0, 0x2001, 0xafa5, 0x200c, 0x8103, 0xa100, 0x603e, 0x6018,
+	0xa088, 0x002b, 0x2104, 0xa005, 0x0118, 0xa088, 0x0003, 0x0cd0,
+	0x2c0a, 0x600f, 0x0000, 0xa085, 0x0001, 0x0005, 0x0016, 0x00c6,
+	0x00e6, 0x6150, 0xa2f0, 0x002b, 0x2e04, 0x2060, 0x8cff, 0x0180,
+	0x84ff, 0x1118, 0x6050, 0xa106, 0x1138, 0x600c, 0x2072, 0x080c,
+	0x6618, 0x080c, 0x8078, 0x0010, 0xacf0, 0x0003, 0x2e64, 0x0c70,
+	0x00ee, 0x00ce, 0x001e, 0x0005, 0x00d6, 0x6018, 0xa0e8, 0x002b,
+	0x2d04, 0xa005, 0x0140, 0xac06, 0x0120, 0x2d04, 0xa0e8, 0x0003,
+	0x0cb8, 0x600c, 0x206a, 0x00de, 0x0005, 0x0026, 0x0036, 0x0156,
+	0x2011, 0xad27, 0x2204, 0xa084, 0x00ff, 0x2019, 0xb28e, 0x2334,
+	0xa636, 0x11d8, 0x8318, 0x2334, 0x2204, 0xa084, 0xff00, 0xa636,
+	0x11a0, 0x2011, 0xb290, 0x6018, 0xa098, 0x000a, 0x20a9, 0x0004,
+	0x080c, 0x8a7c, 0x1150, 0x2011, 0xb294, 0x6018, 0xa098, 0x0006,
+	0x20a9, 0x0004, 0x080c, 0x8a7c, 0x1100, 0x015e, 0x003e, 0x002e,
+	0x0005, 0x00e6, 0x2071, 0xad00, 0x080c, 0x48f5, 0x080c, 0x28fa,
+	0x00ee, 0x0005, 0x00e6, 0x6018, 0x2070, 0x7000, 0xd0fc, 0x0108,
+	0x0011, 0x00ee, 0x0005, 0x6850, 0xc0e5, 0x6852, 0x0005, 0x00e6,
+	0x00c6, 0x0076, 0x0066, 0x0056, 0x0046, 0x0026, 0x0016, 0x0126,
+	0x2091, 0x8000, 0x2029, 0xafd0, 0x252c, 0x2021, 0xafd6, 0x2424,
+	0x2061, 0xb400, 0x2071, 0xad00, 0x7644, 0x7064, 0xa606, 0x0578,
+	0x671c, 0xa786, 0x0001, 0x0118, 0xa786, 0x0008, 0x1500, 0x2500,
+	0xac06, 0x01e8, 0x2400, 0xac06, 0x01d0, 0x080c, 0xa990, 0x01b8,
+	0x080c, 0xa9a0, 0x11a0, 0x6000, 0xa086, 0x0004, 0x1120, 0x0016,
+	0x080c, 0x190b, 0x001e, 0x080c, 0x9778, 0x1110, 0x080c, 0x2aff,
+	0x080c, 0x9789, 0x1110, 0x080c, 0x85f3, 0x080c, 0x974e, 0xace0,
+	0x0018, 0x2001, 0xad16, 0x2004, 0xac02, 0x1208, 0x0858, 0x012e,
+	0x001e, 0x002e, 0x004e, 0x005e, 0x006e, 0x007e, 0x00ce, 0x00ee,
+	0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, 0x2071, 0xad40,
+	0xd5a4, 0x0118, 0x7034, 0x8000, 0x7036, 0xd5b4, 0x0118, 0x7030,
+	0x8000, 0x7032, 0xd5ac, 0x0118, 0x2071, 0xad4a, 0x0451, 0x00ee,
+	0x000e, 0x012e, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000,
+	0x2071, 0xad40, 0xd5a4, 0x0118, 0x7034, 0x8000, 0x7036, 0xd5b4,
+	0x0118, 0x7030, 0x8000, 0x7032, 0xd5ac, 0x0118, 0x2071, 0xad4a,
+	0x0081, 0x00ee, 0x000e, 0x012e, 0x0005, 0x0126, 0x0006, 0x00e6,
+	0x2091, 0x8000, 0x2071, 0xad42, 0x0021, 0x00ee, 0x000e, 0x012e,
+	0x0005, 0x2e04, 0x8000, 0x2072, 0x1220, 0x8e70, 0x2e04, 0x8000,
+	0x2072, 0x0005, 0x00e6, 0x2071, 0xad40, 0x0c99, 0x00ee, 0x0005,
+	0x00e6, 0x2071, 0xad44, 0x0c69, 0x00ee, 0x0005, 0x0001, 0x0002,
+	0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200,
+	0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0x8529
+};
+
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/scsi_error.c linux/drivers/scsi/scsi_error.c
--- v2.4.9/linux/drivers/scsi/scsi_error.c	Wed Jul 25 17:10:23 2001
+++ linux/drivers/scsi/scsi_error.c	Sun Sep  9 10:52:35 2001
@@ -421,6 +421,7 @@
 	static unsigned char generic_sense[6] =
 	{REQUEST_SENSE, 0, 0, 0, 255, 0};
 	unsigned char scsi_result0[256], *scsi_result = NULL;
+	int saved_result;
 
 	ASSERT_LOCK(&io_request_lock, 0);
 
@@ -446,6 +447,7 @@
 	memset((void *) SCpnt->sense_buffer, 0, sizeof(SCpnt->sense_buffer));
 	memset((void *) scsi_result, 0, 256);
 
+	saved_result = SCpnt->result;
 	SCpnt->request_buffer = scsi_result;
 	SCpnt->request_bufflen = 256;
 	SCpnt->use_sg = 0;
@@ -470,6 +472,7 @@
 	 */
 	memcpy((void *) SCpnt->cmnd, (void *) SCpnt->data_cmnd,
 	       sizeof(SCpnt->data_cmnd));
+	SCpnt->result = saved_result;
 	SCpnt->request_buffer = SCpnt->buffer;
 	SCpnt->request_bufflen = SCpnt->bufflen;
 	SCpnt->use_sg = SCpnt->old_use_sg;
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/sd.c linux/drivers/scsi/sd.c
--- v2.4.9/linux/drivers/scsi/sd.c	Sun Aug 12 13:28:00 2001
+++ linux/drivers/scsi/sd.c	Sun Sep  9 16:27:47 2001
@@ -238,8 +238,10 @@
 		case BLKFLSBUF:
 		case BLKSSZGET:
 		case BLKPG:
-                case BLKELVGET:
-                case BLKELVSET:
+		case BLKELVGET:
+		case BLKELVSET:
+		case BLKBSZGET:
+		case BLKBSZSET:
 			return blk_ioctl(inode->i_rdev, cmd, arg);
 
 		case BLKRRPART: /* Re-read partition tables */
@@ -561,22 +563,16 @@
 
 static struct gendisk sd_gendisk =
 {
-	SCSI_DISK0_MAJOR,	/* Major number */
-	"sd",			/* Major name */
-	4,			/* Bits to shift to get real from partition */
-	1 << 4,			/* Number of partitions per real */
-	NULL,			/* hd struct */
-	NULL,			/* block sizes */
-	0,			/* number */
-	NULL,			/* internal */
-	NULL,			/* next */
-        &sd_fops,		/* file operations */
+	major:		SCSI_DISK0_MAJOR,
+	major_name:	"sd",
+	minor_shift:	4,
+	max_p:		1 << 4,
+	fops:		&sd_fops,
 };
 
 static struct gendisk *sd_gendisks = &sd_gendisk;
 
 #define SD_GENDISK(i)    sd_gendisks[(i) / SCSI_DISKS_PER_MAJOR]
-#define LAST_SD_GENDISK  sd_gendisks[N_USED_SD_MAJORS - 1]
 
 /*
  * rw_intr is the interrupt routine for the device driver.
@@ -1020,7 +1016,7 @@
 		cmd[1] = (rscsi_disks[i].device->scsi_level <= SCSI_2) ?
 			 ((rscsi_disks[i].device->lun << 5) & 0xe0) : 0;
 		cmd[2] = 0x3f;	/* Get all pages */
-		cmd[4] = 8;     /* But we only want the 8 byte header */
+		cmd[4] = 255;   /* Ask for 255 bytes, even tho we want just the first 8 */
 		SRpnt->sr_cmd_len = 0;
 		SRpnt->sr_sense_buffer[0] = 0;
 		SRpnt->sr_sense_buffer[2] = 0;
@@ -1145,12 +1141,10 @@
 		sd_gendisks[i].part = sd + (i * SCSI_DISKS_PER_MAJOR << 4);
 		sd_gendisks[i].sizes = sd_sizes + (i * SCSI_DISKS_PER_MAJOR << 4);
 		sd_gendisks[i].nr_real = 0;
-		sd_gendisks[i].next = sd_gendisks + i + 1;
 		sd_gendisks[i].real_devices =
 		    (void *) (rscsi_disks + i * SCSI_DISKS_PER_MAJOR);
 	}
 
-	LAST_SD_GENDISK.next = NULL;
 	return 0;
 
 cleanup_gendisks_flags:
@@ -1182,19 +1176,13 @@
 
 static void sd_finish()
 {
-	struct gendisk *gendisk;
 	int i;
 
 	for (i = 0; i < N_USED_SD_MAJORS; i++) {
 		blk_dev[SD_MAJOR(i)].queue = sd_find_queue;
+		add_gendisk(&sd_gendisks[i]);
 	}
-	for (gendisk = gendisk_head; gendisk != NULL; gendisk = gendisk->next)
-		if (gendisk == sd_gendisks)
-			break;
-	if (gendisk == NULL) {
-		LAST_SD_GENDISK.next = gendisk_head;
-		gendisk_head = sd_gendisks;
-	}
+
 	for (i = 0; i < sd_template.dev_max; ++i)
 		if (!rscsi_disks[i].capacity && rscsi_disks[i].device) {
 			sd_init_onedisk(i);
@@ -1375,10 +1363,7 @@
 
 static void __exit exit_sd(void)
 {
-	struct gendisk **prev_sdgd_link;
-	struct gendisk *sdgd;
 	int i;
-	int removed = 0;
 
 	scsi_unregister_module(MODULE_SCSI_DEV, &sd_template);
 
@@ -1392,26 +1377,9 @@
 		kfree(sd_blocksizes);
 		kfree(sd_hardsizes);
 		kfree((char *) sd);
-
-		/*
-		 * Now remove sd_gendisks from the linked list
-		 */
-		prev_sdgd_link = &gendisk_head;
-		while ((sdgd = *prev_sdgd_link) != NULL) {
-			if (sdgd >= sd_gendisks && sdgd <= &LAST_SD_GENDISK) {
-				removed++;
-				*prev_sdgd_link = sdgd->next;
-				continue;
-			}
-			prev_sdgd_link = &sdgd->next;
-		}
-
-		if (removed != N_USED_SD_MAJORS)
-			printk("%s %d sd_gendisks in disk chain",
-			       removed > N_USED_SD_MAJORS ? "total" : "just", removed);
-
 	}
 	for (i = 0; i < N_USED_SD_MAJORS; i++) {
+		del_gendisk(&sd_gendisks[i]);
 		blk_size[SD_MAJOR(i)] = NULL;
 		hardsect_size[SD_MAJOR(i)] = NULL;
 		read_ahead[SD_MAJOR(i)] = 0;
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/seagate.c linux/drivers/scsi/seagate.c
--- v2.4.9/linux/drivers/scsi/seagate.c	Sat Nov 11 19:01:11 2000
+++ linux/drivers/scsi/seagate.c	Fri Sep  7 09:28:37 2001
@@ -123,7 +123,7 @@
 #define FAST
 #endif
 
-#undef LINKED		/* Linked commands are currently broken! */
+#undef LINKED			/* Linked commands are currently broken! */
 
 #if defined(OVERRIDE) && !defined(CONTROLLER)
 #error Please use -DCONTROLLER=SEAGATE or -DCONTROLLER=FD to override controller type
@@ -152,11 +152,11 @@
 	STATUS
 */
 #ifdef SWAPSTAT
-	#define STAT_MSG		0x08
-	#define STAT_CD			0x02
+#define STAT_MSG		0x08
+#define STAT_CD			0x02
 #else
-	#define STAT_MSG		0x02
-	#define STAT_CD			0x08
+#define STAT_MSG		0x02
+#define STAT_CD			0x08
 #endif
 
 #define STAT_BSY		0x01
@@ -181,9 +181,9 @@
 extern volatile int seagate_st0x_timeout;
 
 #ifdef PARITY
-	#define BASE_CMD CMD_EN_PARITY
+#define BASE_CMD CMD_EN_PARITY
 #else
-	#define BASE_CMD  0
+#define BASE_CMD  0
 #endif
 
 /*
@@ -193,7 +193,7 @@
 #define PHASE_BUS_FREE 1
 #define PHASE_ARBITRATION 2
 #define PHASE_SELECTION 4
-#define PHASE_DATAIN 8 
+#define PHASE_DATAIN 8
 #define PHASE_DATAOUT 0x10
 #define PHASE_CMDOUT 0x20
 #define PHASE_MSGIN 0x40
@@ -216,44 +216,43 @@
 #define ST0X_BUS_FREE_DELAY 25
 #define ST0X_SELECTION_DELAY 25
 
-#define SEAGATE 1	/* these determine the type of the controller */
+#define SEAGATE 1		/* these determine the type of the controller */
 #define FD	2
 
 #define ST0X_ID_STR	"Seagate ST-01/ST-02"
 #define FD_ID_STR	"TMC-8XX/TMC-950"
 
-
 static int internal_command (unsigned char target, unsigned char lun,
-                             const void *cmnd,
-                             void *buff, int bufflen, int reselect);
+			     const void *cmnd,
+			     void *buff, int bufflen, int reselect);
 
-static int incommand;                   /* set if arbitration has finished
-                                           and we are in some command phase. */
+static int incommand;		/* set if arbitration has finished
+				   and we are in some command phase. */
 
-static unsigned int base_address = 0;   /* Where the card ROM starts, used to 
-                                           calculate memory mapped register
-                                           location.  */
-
-static unsigned long st0x_cr_sr;        /* control register write, status
-                                           register read.  256 bytes in
-                                           length.
-                                           Read is status of SCSI BUS, as per 
-                                           STAT masks.  */
-
-static unsigned long st0x_dr;           /* data register, read write 256
-                                           bytes in length.  */
-
-static volatile int st0x_aborted = 0;   /* set when we are aborted, ie by a
-                                           time out, etc.  */
-
-static unsigned char controller_type = 0;       /* set to SEAGATE for ST0x
-                                                   boards or FD for TMC-8xx
-                                                   boards */
+static unsigned int base_address = 0;	/* Where the card ROM starts, used to 
+					   calculate memory mapped register
+					   location.  */
+
+static unsigned long st0x_cr_sr;	/* control register write, status
+					   register read.  256 bytes in
+					   length.
+					   Read is status of SCSI BUS, as per 
+					   STAT masks.  */
+
+static unsigned long st0x_dr;	/* data register, read write 256
+				   bytes in length.  */
+
+static volatile int st0x_aborted = 0;	/* set when we are aborted, ie by a
+					   time out, etc.  */
+
+static unsigned char controller_type = 0;	/* set to SEAGATE for ST0x
+						   boards or FD for TMC-8xx
+						   boards */
 static int irq = IRQ;
 
-MODULE_PARM(base_address, "i");
-MODULE_PARM(controller_type, "b");
-MODULE_PARM(irq, "i");
+MODULE_PARM (base_address, "i");
+MODULE_PARM (controller_type, "b");
+MODULE_PARM (irq, "i");
 
 #define retcode(result) (((result) << 16) | (message << 8) | status)
 #define STATUS ((u8) isa_readb(st0x_cr_sr))
@@ -261,40 +260,38 @@
 #define WRITE_CONTROL(d) { isa_writeb((d), st0x_cr_sr); }
 #define WRITE_DATA(d) { isa_writeb((d), st0x_dr); }
 
-void st0x_setup (char *str, int *ints)
+void
+st0x_setup (char *str, int *ints)
 {
-  controller_type = SEAGATE;
-  base_address = ints[1];
-  irq = ints[2];
+	controller_type = SEAGATE;
+	base_address = ints[1];
+	irq = ints[2];
 }
 
-void tmc8xx_setup (char *str, int *ints)
+void
+tmc8xx_setup (char *str, int *ints)
 {
-  controller_type = FD;
-  base_address = ints[1];
-  irq = ints[2];
+	controller_type = FD;
+	base_address = ints[1];
+	irq = ints[2];
 }
 
 #ifndef OVERRIDE
-static unsigned int seagate_bases[] =
-{
-  0xc8000, 0xca000, 0xcc000,
-  0xce000, 0xdc000, 0xde000
+static unsigned int seagate_bases[] = {
+	0xc8000, 0xca000, 0xcc000,
+	0xce000, 0xdc000, 0xde000
 };
 
-typedef struct
-{
-  const unsigned char *signature;
-  unsigned offset;
-  unsigned length;
-  unsigned char type;
-}
-Signature;
-
-static const Signature __initdata signatures[] =
-{
-  {"ST01 v1.7  (C) Copyright 1987 Seagate", 15, 37, SEAGATE},
-  {"SCSI BIOS 2.00  (C) Copyright 1987 Seagate", 15, 40, SEAGATE},
+typedef struct {
+	const unsigned char *signature;
+	unsigned offset;
+	unsigned length;
+	unsigned char type;
+} Signature;
+
+static Signature __initdata signatures[] = {
+	{"ST01 v1.7  (C) Copyright 1987 Seagate", 15, 37, SEAGATE},
+	{"SCSI BIOS 2.00  (C) Copyright 1987 Seagate", 15, 40, SEAGATE},
 
 /*
  * The following two lines are NOT mistakes.  One detects ROM revision
@@ -303,28 +300,28 @@
  * are probably "good enough"
  */
 
-  {"SEAGATE SCSI BIOS ", 16, 17, SEAGATE},
-  {"SEAGATE SCSI BIOS ", 17, 17, SEAGATE},
+	{"SEAGATE SCSI BIOS ", 16, 17, SEAGATE},
+	{"SEAGATE SCSI BIOS ", 17, 17, SEAGATE},
 
 /*
  * However, future domain makes several incompatible SCSI boards, so specific
  * signatures must be used.
  */
 
-  {"FUTURE DOMAIN CORP. (C) 1986-1989 V5.0C2/14/89", 5, 46, FD},
-  {"FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/89", 5, 46, FD},
-  {"FUTURE DOMAIN CORP. (C) 1986-1990 V6.0105/31/90", 5, 47, FD},
-  {"FUTURE DOMAIN CORP. (C) 1986-1990 V6.0209/18/90", 5, 47, FD},
-  {"FUTURE DOMAIN CORP. (C) 1986-1990 V7.009/18/90", 5, 46, FD},
-  {"FUTURE DOMAIN CORP. (C) 1992 V8.00.004/02/92", 5, 44, FD},
-  {"IBM F1 BIOS V1.1004/30/92", 5, 25, FD},
-  {"FUTURE DOMAIN TMC-950", 5, 21, FD},
-  /* Added for 2.2.16 by Matthias_Heidbrink@b.maus.de */
-  {"IBM F1 V1.2009/22/93", 5, 25, FD},
+	{"FUTURE DOMAIN CORP. (C) 1986-1989 V5.0C2/14/89", 5, 46, FD},
+	{"FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/89", 5, 46, FD},
+	{"FUTURE DOMAIN CORP. (C) 1986-1990 V6.0105/31/90", 5, 47, FD},
+	{"FUTURE DOMAIN CORP. (C) 1986-1990 V6.0209/18/90", 5, 47, FD},
+	{"FUTURE DOMAIN CORP. (C) 1986-1990 V7.009/18/90", 5, 46, FD},
+	{"FUTURE DOMAIN CORP. (C) 1992 V8.00.004/02/92", 5, 44, FD},
+	{"IBM F1 BIOS V1.1004/30/92", 5, 25, FD},
+	{"FUTURE DOMAIN TMC-950", 5, 21, FD},
+	/* Added for 2.2.16 by Matthias_Heidbrink@b.maus.de */
+	{"IBM F1 V1.2009/22/93", 5, 25, FD},
 };
 
 #define NUM_SIGNATURES (sizeof(signatures) / sizeof(Signature))
-#endif /* n OVERRIDE */
+#endif				/* n OVERRIDE */
 
 /*
  * hostno stores the hostnumber, as told to us by the init routine.
@@ -382,35 +379,37 @@
  */
 
 static int borken_calibration = 0;
+
 static void __init borken_init (void)
 {
-  register int count = 0, start = jiffies + 1, stop = start + 25;
+	register int count = 0, start = jiffies + 1, stop = start + 25;
 
-  while (time_before(jiffies, start)) ;
-  for (; time_before(jiffies, stop); ++count) ;
+	while (time_before (jiffies, start)) ;
+	for (; time_before (jiffies, stop); ++count) ;
 
 /*
  * Ok, we now have a count for .25 seconds.  Convert to a
  * count per second and divide by transfer rate in K.  */
 
-  borken_calibration = (count * 4) / (SLOW_RATE * 1024);
+	borken_calibration = (count * 4) / (SLOW_RATE * 1024);
 
-  if (borken_calibration < 1)
-    borken_calibration = 1;
+	if (borken_calibration < 1)
+		borken_calibration = 1;
 }
 
 static inline void borken_wait (void)
 {
-  register int count;
+	register int count;
 
-  for (count = borken_calibration; count && (STATUS & STAT_REQ); --count) ;
+	for (count = borken_calibration; count && (STATUS & STAT_REQ);
+	     --count) ;
 #if (DEBUG & DEBUG_BORKEN)
-  if (count)
-    printk ("scsi%d : borken timeout\n", hostno);
+	if (count)
+		printk ("scsi%d : borken timeout\n", hostno);
 #endif
 }
 
-#endif /* def SLOW_RATE */
+#endif				/* def SLOW_RATE */
 
 /* These beasts only live on ISA, and ISA means 8MHz. Each ULOOP()
  * contains at least one ISA access, which takes more than 0.125
@@ -422,33 +421,34 @@
 
 int __init seagate_st0x_detect (Scsi_Host_Template * tpnt)
 {
-  struct Scsi_Host *instance;
-  int i, j;
+	struct Scsi_Host *instance;
+	int i, j;
 
-  tpnt->proc_name = "seagate";
+	tpnt->proc_name = "seagate";
 /*
- *    First, we try for the manual override.  */
-  DANY ("Autodetecting ST0x / TMC-8xx\n");
+ *    First, we try for the manual override.
+ */
+	DANY ("Autodetecting ST0x / TMC-8xx\n");
 
-  if (hostno != -1) {
-    printk (KERN_ERR "seagate_st0x_detect() called twice?!\n");
-    return 0;
-  }
+	if (hostno != -1) {
+		printk (KERN_ERR "seagate_st0x_detect() called twice?!\n");
+		return 0;
+	}
 
 /* If the user specified the controller type from the command line,
    controller_type will be non-zero, so don't try to detect one */
 
-  if (!controller_type)
-  {
+	if (!controller_type) {
 #ifdef OVERRIDE
-    base_address = OVERRIDE;
-    controller_type = CONTROLLER;
+		base_address = OVERRIDE;
+		controller_type = CONTROLLER;
 
-    DANY("Base address overridden to %x, controller type is %s\n",
-            base_address, controller_type == SEAGATE ? "SEAGATE" : "FD");
-#else /* OVERRIDE */
+		DANY ("Base address overridden to %x, controller type is %s\n",
+		      base_address,
+		      controller_type == SEAGATE ? "SEAGATE" : "FD");
+#else				/* OVERRIDE */
 /*
- *    To detect this card, we simply look for the signature
+ * 	To detect this card, we simply look for the signature
  *      from the BIOS version notice in all the possible locations
  *      of the ROM's.  This has a nice side effect of not trashing
  *      any register locations that might be used by something else.
@@ -457,106 +457,112 @@
  * space for the on-board RAM instead.
  */
 
-    for (i = 0; i < (sizeof (seagate_bases) / sizeof (unsigned int)); ++i)
+		for (i = 0;
+		     i < (sizeof (seagate_bases) / sizeof (unsigned int)); ++i)
 
-      for (j = 0; !base_address && j < NUM_SIGNATURES; ++j)
-        if (isa_check_signature (seagate_bases[i] + signatures[j].offset,
-                             signatures[j].signature, signatures[j].length))
-        {
-          base_address = seagate_bases[i];
-          controller_type = signatures[j].type;
-        }
-#endif /* OVERRIDE */
-  }    /* (! controller_type) */
-
-  tpnt->this_id = (controller_type == SEAGATE) ? 7 : 6;
-  tpnt->name = (controller_type == SEAGATE) ? ST0X_ID_STR : FD_ID_STR;
-
-  if (!base_address) {
-    DANY ("ST0x / TMC-8xx not detected.\n");
-    return 0;
-  }
+			for (j = 0; !base_address && j < NUM_SIGNATURES; ++j)
+				if (isa_check_signature
+				    (seagate_bases[i] + signatures[j].offset,
+				     signatures[j].signature,
+				     signatures[j].length)) {
+					base_address = seagate_bases[i];
+					controller_type = signatures[j].type;
+				}
+#endif				/* OVERRIDE */
+	}
+	/* (! controller_type) */
+	tpnt->this_id = (controller_type == SEAGATE) ? 7 : 6;
+	tpnt->name = (controller_type == SEAGATE) ? ST0X_ID_STR : FD_ID_STR;
+
+	if (!base_address) {
+		DANY ("ST0x / TMC-8xx not detected.\n");
+		return 0;
+	}
 
-  st0x_cr_sr = base_address + (controller_type == SEAGATE ? 0x1a00 : 0x1c00);
-  st0x_dr = st0x_cr_sr + 0x200;
+	st0x_cr_sr =
+	    base_address + (controller_type == SEAGATE ? 0x1a00 : 0x1c00);
+	st0x_dr = st0x_cr_sr + 0x200;
 
-  DANY ("%s detected. Base address = %x, cr = %x, dr = %x\n",
-	tpnt->name, base_address, st0x_cr_sr, st0x_dr);
+	DANY ("%s detected. Base address = %x, cr = %x, dr = %x\n",
+	      tpnt->name, base_address, st0x_cr_sr, st0x_dr);
 
 /*
- *    At all times, we will use IRQ 5.  Should also check for IRQ3 if we
+ *	At all times, we will use IRQ 5.  Should also check for IRQ3 if we
  *      loose our first interrupt.
  */
-  instance = scsi_register (tpnt, 0);
-  if(instance == NULL)
-  	return 0;
-  	
-  hostno = instance->host_no;
-  if (request_irq (irq, do_seagate_reconnect_intr, SA_INTERRUPT,
-		   (controller_type == SEAGATE) ? "seagate" : "tmc-8xx", NULL)) {
-    printk ("scsi%d : unable to allocate IRQ%d\n", hostno, irq);
-    return 0;
-  }
-  instance->irq = irq;
-  instance->io_port = base_address;
+	instance = scsi_register (tpnt, 0);
+	if (instance == NULL)
+		return 0;
+
+	hostno = instance->host_no;
+	if (request_irq (irq, do_seagate_reconnect_intr, SA_INTERRUPT,
+			 (controller_type == SEAGATE) ? "seagate" : "tmc-8xx",
+			 NULL)) {
+		printk ("scsi%d : unable to allocate IRQ%d\n", hostno, irq);
+		return 0;
+	}
+	instance->irq = irq;
+	instance->io_port = base_address;
 #ifdef SLOW_RATE
-  printk( "Calibrating borken timer... " );
-  borken_init ();
-  printk( " %d cycles per transfer\n", borken_calibration );
+	printk (KERN_INFO "Calibrating borken timer... ");
+	borken_init ();
+	printk (" %d cycles per transfer\n", borken_calibration);
 #endif
 
-  printk( "This is one second... " );
-  {
-    int clock;
-    ULOOP( 1*1000*1000 ) {
-      STATUS;
-      if (TIMEOUT) break;
-    }
-  }
+	printk (KERN_INFO "This is one second... ");
+	{
+		int clock;
+		ULOOP (1 * 1000 * 1000) {
+			STATUS;
+			if (TIMEOUT)
+				break;
+		}
+	}
 
-  printk ("done, %s options:"
+	printk ("done, %s options:"
 #ifdef ARBITRATE
-            " ARBITRATE"
+		" ARBITRATE"
 #endif
 #ifdef DEBUG
-            " DEBUG"
+		" DEBUG"
 #endif
 #ifdef FAST
-            " FAST"
+		" FAST"
 #ifdef FAST32
-            "32"
+		"32"
 #endif
 #endif
 #ifdef LINKED
-            " LINKED"
+		" LINKED"
 #endif
 #ifdef PARITY
-            " PARITY"
+		" PARITY"
 #endif
 #ifdef SEAGATE_USE_ASM
-            " SEAGATE_USE_ASM"
+		" SEAGATE_USE_ASM"
 #endif
 #ifdef SLOW_RATE
-            " SLOW_RATE"
+		" SLOW_RATE"
 #endif
 #ifdef SWAPSTAT
-            " SWAPSTAT"
+		" SWAPSTAT"
 #endif
 #ifdef SWAPCNTDATA
-            " SWAPCNTDATA"
+		" SWAPCNTDATA"
 #endif
-	  "\n", tpnt->name);
-  return 1;
+		"\n", tpnt->name);
+	return 1;
 }
 
-const char *seagate_st0x_info (struct Scsi_Host *shpnt)
+const char *
+seagate_st0x_info (struct Scsi_Host *shpnt)
 {
-  static char buffer[64];
+	static char buffer[64];
 
-  sprintf (buffer, "%s at irq %d, address 0x%05X",
-           (controller_type == SEAGATE) ? ST0X_ID_STR : FD_ID_STR,
-           irq, base_address);
-  return buffer;
+	sprintf (buffer, "%s at irq %d, address 0x%05X",
+		 (controller_type == SEAGATE) ? ST0X_ID_STR : FD_ID_STR,
+		 irq, base_address);
+	return buffer;
 }
 
 /*
@@ -616,50 +622,50 @@
 
 static void do_seagate_reconnect_intr (int irq, void *dev_id, struct pt_regs *regs)
 {
-  unsigned long flags;
+	unsigned long flags;
 
-  spin_lock_irqsave(&io_request_lock, flags);
-  seagate_reconnect_intr(irq, dev_id, regs);
-  spin_unlock_irqrestore(&io_request_lock, flags);
+	spin_lock_irqsave (&io_request_lock, flags);
+	seagate_reconnect_intr (irq, dev_id, regs);
+	spin_unlock_irqrestore (&io_request_lock, flags);
 }
 
 static void seagate_reconnect_intr (int irq, void *dev_id, struct pt_regs *regs)
 {
-  int temp;
-  Scsi_Cmnd *SCtmp;
+	int temp;
+	Scsi_Cmnd *SCtmp;
 
-  DPRINTK (PHASE_RESELECT, "scsi%d : seagate_reconnect_intr() called\n", hostno);
+	DPRINTK (PHASE_RESELECT, "scsi%d : seagate_reconnect_intr() called\n",
+		 hostno);
 
-  if (!should_reconnect)
-    printk ("scsi%d: unexpected interrupt.\n", hostno);
-  else
-  {
-    should_reconnect = 0;
-
-    DPRINTK (PHASE_RESELECT, "scsi%d : internal_command("
-            "%d, %08x, %08x, RECONNECT_NOW\n", hostno,
-            current_target, current_data, current_bufflen);
-
-    temp = internal_command (current_target, current_lun, current_cmnd,
-                             current_data, current_bufflen, RECONNECT_NOW);
-
-    if (msg_byte (temp) != DISCONNECT)
-    {
-      if (done_fn)
-      {
-        DPRINTK (PHASE_RESELECT, "scsi%d : done_fn(%d,%08x)", hostno,
-                hostno, temp);
-        if (!SCint)
-          panic ("SCint == NULL in seagate");
-        SCtmp = SCint;
-        SCint = NULL;
-        SCtmp->result = temp;
-        done_fn (SCtmp);
-      }
-      else
-        printk ("done_fn() not defined.\n");
-    }
-  }
+	if (!should_reconnect)
+		printk ("scsi%d: unexpected interrupt.\n", hostno);
+	else {
+		should_reconnect = 0;
+
+		DPRINTK (PHASE_RESELECT, "scsi%d : internal_command("
+			 "%d, %08x, %08x, RECONNECT_NOW\n", hostno,
+			 current_target, current_data, current_bufflen);
+
+		temp =
+		    internal_command (current_target, current_lun, current_cmnd,
+				      current_data, current_bufflen,
+				      RECONNECT_NOW);
+
+		if (msg_byte (temp) != DISCONNECT) {
+			if (done_fn) {
+				DPRINTK (PHASE_RESELECT,
+					 "scsi%d : done_fn(%d,%08x)", hostno,
+					 hostno, temp);
+				if (!SCint)
+					panic ("SCint == NULL in seagate");
+				SCtmp = SCint;
+				SCint = NULL;
+				SCtmp->result = temp;
+				done_fn (SCtmp);
+			} else
+				printk ("done_fn() not defined.\n");
+		}
+	}
 }
 
 /*
@@ -677,212 +683,215 @@
 
 int seagate_st0x_queue_command (Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
 {
-  int result, reconnect;
-  Scsi_Cmnd *SCtmp;
+	int result, reconnect;
+	Scsi_Cmnd *SCtmp;
 
-  DANY( "seagate: que_command" );
-  done_fn = done;
-  current_target = SCpnt->target;
-  current_lun = SCpnt->lun;
-  (const void *) current_cmnd = SCpnt->cmnd;
-  current_data = (unsigned char *) SCpnt->request_buffer;
-  current_bufflen = SCpnt->request_bufflen;
-  SCint = SCpnt;
-  if (recursion_depth) return 0;
-  recursion_depth++;
-  do
-  {
+	DANY ("seagate: que_command");
+	done_fn = done;
+	current_target = SCpnt->target;
+	current_lun = SCpnt->lun;
+	(const void *) current_cmnd = SCpnt->cmnd;
+	current_data = (unsigned char *) SCpnt->request_buffer;
+	current_bufflen = SCpnt->request_bufflen;
+	SCint = SCpnt;
+	if (recursion_depth)
+		return 0;
+	recursion_depth++;
+	do {
 #ifdef LINKED
 /*
  * Set linked command bit in control field of SCSI command.
  */
 
-    current_cmnd[SCpnt->cmd_len] |= 0x01;
-    if (linked_connected)
-    {
-      DPRINTK (DEBUG_LINKED, 
-	       "scsi%d : using linked commands, current I_T_L nexus is ", hostno);
-      if ((linked_target == current_target) && (linked_lun == current_lun))
-      {
-        DPRINTK (DEBUG_LINKED, "correct\n");
-        reconnect = LINKED_RIGHT;
-      }
-      else
-      {
-        DPRINTK (DEBUG_LINKED, "incorrect\n");
-        reconnect = LINKED_WRONG;
-      }
-    }
-    else
-#endif /* LINKED */
-      reconnect = CAN_RECONNECT;
-
-    result = internal_command (SCint->target, SCint->lun, SCint->cmnd,
-                               SCint->request_buffer, SCint->request_bufflen, reconnect);
-    if (msg_byte (result) == DISCONNECT) break;
-    SCtmp = SCint;
-    SCint = NULL;
-    SCtmp->result = result;
-    done_fn (SCtmp);
-  }
-  while (SCint);
-  recursion_depth--;
-  return 0;
+		current_cmnd[SCpnt->cmd_len] |= 0x01;
+		if (linked_connected) {
+			DPRINTK (DEBUG_LINKED,
+				 "scsi%d : using linked commands, current I_T_L nexus is ",
+				 hostno);
+			if ((linked_target == current_target)
+			    && (linked_lun == current_lun)) {
+				DPRINTK (DEBUG_LINKED, "correct\n");
+				reconnect = LINKED_RIGHT;
+			} else {
+				DPRINTK (DEBUG_LINKED, "incorrect\n");
+				reconnect = LINKED_WRONG;
+			}
+		} else
+#endif				/* LINKED */
+			reconnect = CAN_RECONNECT;
+
+		result =
+		    internal_command (SCint->target, SCint->lun, SCint->cmnd,
+				      SCint->request_buffer,
+				      SCint->request_bufflen, reconnect);
+		if (msg_byte (result) == DISCONNECT)
+			break;
+		SCtmp = SCint;
+		SCint = NULL;
+		SCtmp->result = result;
+		done_fn (SCtmp);
+	}
+	while (SCint);
+	recursion_depth--;
+	return 0;
 }
 
 int seagate_st0x_command (Scsi_Cmnd * SCpnt)
 {
-  return internal_command (SCpnt->target, SCpnt->lun, SCpnt->cmnd,
-                           SCpnt->request_buffer, SCpnt->request_bufflen,
-                           (int) NO_RECONNECT);
+	return internal_command (SCpnt->target, SCpnt->lun, SCpnt->cmnd,
+				 SCpnt->request_buffer, SCpnt->request_bufflen,
+				 (int) NO_RECONNECT);
 }
 
-static int internal_command (unsigned char target, unsigned char lun, 
-                             const void *cmnd, void *buff, int bufflen, int reselect)
+static int internal_command (unsigned char target, unsigned char lun,
+		  const void *cmnd, void *buff, int bufflen, int reselect)
 {
-  unsigned char *data = NULL;
-  struct scatterlist *buffer = NULL;
-  int clock, temp, nobuffs = 0, done = 0, len = 0;
-  unsigned long flags;
+	unsigned char *data = NULL;
+	struct scatterlist *buffer = NULL;
+	int clock, temp, nobuffs = 0, done = 0, len = 0;
+	unsigned long flags;
 
 #ifdef DEBUG
-  int transfered = 0, phase = 0, newphase;
+	int transfered = 0, phase = 0, newphase;
 #endif
 
-  register unsigned char status_read;
-  unsigned char tmp_data, tmp_control, status = 0, message = 0;
+	register unsigned char status_read;
+	unsigned char tmp_data, tmp_control, status = 0, message = 0;
 
-  unsigned transfersize = 0, underflow = 0;
+	unsigned transfersize = 0, underflow = 0;
 
 #ifdef SLOW_RATE
-  int borken = (int) SCint->device->borken; /* Does the current target require
-					       Very Slow I/O ?  */
+	int borken = (int) SCint->device->borken;	/* Does the current target require
+							   Very Slow I/O ?  */
 #endif
 
-  incommand = 0;
-  st0x_aborted = 0;
+	incommand = 0;
+	st0x_aborted = 0;
 
 #if (DEBUG & PRINT_COMMAND)
-  printk ("scsi%d : target = %d, command = ", hostno, target);
-  print_command ((unsigned char *) cmnd);
+	printk ("scsi%d : target = %d, command = ", hostno, target);
+	print_command ((unsigned char *) cmnd);
 #endif
 
 #if (DEBUG & PHASE_RESELECT)
-  switch (reselect)
-  {
-    case RECONNECT_NOW:
-      printk ("scsi%d : reconnecting\n", hostno);
-      break;
+	switch (reselect) {
+	case RECONNECT_NOW:
+		printk ("scsi%d : reconnecting\n", hostno);
+		break;
 #ifdef LINKED
-    case LINKED_RIGHT:
-      printk ("scsi%d : connected, can reconnect\n", hostno);
-      break;
-    case LINKED_WRONG:
-      printk ("scsi%d : connected to wrong target, can reconnect\n", hostno);
-      break;
-#endif
-    case CAN_RECONNECT:
-      printk ("scsi%d : allowed to reconnect\n", hostno);
-      break;
-    default:
-      printk ("scsi%d : not allowed to reconnect\n", hostno);
-  }
+	case LINKED_RIGHT:
+		printk ("scsi%d : connected, can reconnect\n", hostno);
+		break;
+	case LINKED_WRONG:
+		printk ("scsi%d : connected to wrong target, can reconnect\n",
+			hostno);
+		break;
+#endif
+	case CAN_RECONNECT:
+		printk ("scsi%d : allowed to reconnect\n", hostno);
+		break;
+	default:
+		printk ("scsi%d : not allowed to reconnect\n", hostno);
+	}
 #endif
 
-  if (target == (controller_type == SEAGATE ? 7 : 6))
-    return DID_BAD_TARGET;
+	if (target == (controller_type == SEAGATE ? 7 : 6))
+		return DID_BAD_TARGET;
 
 /*
- *    We work it differently depending on if this is is "the first time,"
+ *	We work it differently depending on if this is is "the first time,"
  *      or a reconnect.  If this is a reselect phase, then SEL will
  *      be asserted, and we must skip selection / arbitration phases.
  */
 
-  switch (reselect)
-  {
-    case RECONNECT_NOW:
-      DPRINTK ( PHASE_RESELECT, "scsi%d : phase RESELECT \n", hostno);
+	switch (reselect) {
+	case RECONNECT_NOW:
+		DPRINTK (PHASE_RESELECT, "scsi%d : phase RESELECT \n", hostno);
 
 /*
- *    At this point, we should find the logical or of our ID and the original
+ *	At this point, we should find the logical or of our ID and the original
  *      target's ID on the BUS, with BSY, SEL, and I/O signals asserted.
  *
  *      After ARBITRATION phase is completed, only SEL, BSY, and the
  *      target ID are asserted.  A valid initiator ID is not on the bus
  *      until IO is asserted, so we must wait for that.
  */
-      ULOOP( 100*1000 ) {
-        temp = STATUS;
-        if ((temp & STAT_IO) && !(temp & STAT_BSY))
-          break;
-
-        if (TIMEOUT) {
-          DPRINTK (PHASE_RESELECT, 
-		   "scsi%d : RESELECT timed out while waiting for IO .\n", hostno);
-          return (DID_BAD_INTR << 16);
-        }
-      }
+		ULOOP (100 * 1000) {
+			temp = STATUS;
+			if ((temp & STAT_IO) && !(temp & STAT_BSY))
+				break;
+
+			if (TIMEOUT) {
+				DPRINTK (PHASE_RESELECT,
+					 "scsi%d : RESELECT timed out while waiting for IO .\n",
+					 hostno);
+				return (DID_BAD_INTR << 16);
+			}
+		}
 
 /*
- *    After I/O is asserted by the target, we can read our ID and its
+ *	After I/O is asserted by the target, we can read our ID and its
  *      ID off of the BUS.
  */
 
-      if (!((temp = DATA) & (controller_type == SEAGATE ? 0x80 : 0x40)))
-      {
-        DPRINTK (PHASE_RESELECT,
-		 "scsi%d : detected reconnect request to different target.\n"
-		 "\tData bus = %d\n", hostno, temp);
-        return (DID_BAD_INTR << 16);
-      }
-
-      if (!(temp & (1 << current_target)))
-      {
-        printk ("scsi%d : Unexpected reselect interrupt.  Data bus = %d\n",
-                hostno, temp);
-        return (DID_BAD_INTR << 16);
-      }
-
-      buffer = current_buffer;
-      cmnd = current_cmnd;              /* WDE add */
-      data = current_data;              /* WDE add */
-      len = current_bufflen;            /* WDE add */
-      nobuffs = current_nobuffs;
+		if (!
+		    ((temp =
+		      DATA) & (controller_type == SEAGATE ? 0x80 : 0x40))) {
+			DPRINTK (PHASE_RESELECT,
+				 "scsi%d : detected reconnect request to different target.\n"
+				 "\tData bus = %d\n", hostno, temp);
+			return (DID_BAD_INTR << 16);
+		}
+
+		if (!(temp & (1 << current_target))) {
+			printk
+			    ("scsi%d : Unexpected reselect interrupt.  Data bus = %d\n",
+			     hostno, temp);
+			return (DID_BAD_INTR << 16);
+		}
+
+		buffer = current_buffer;
+		cmnd = current_cmnd;	/* WDE add */
+		data = current_data;	/* WDE add */
+		len = current_bufflen;	/* WDE add */
+		nobuffs = current_nobuffs;
 
 /*
- *    We have determined that we have been selected.  At this point,
+ *	We have determined that we have been selected.  At this point,
  *      we must respond to the reselection by asserting BSY ourselves
  */
 
 #if 1
-      WRITE_CONTROL (BASE_CMD | CMD_DRVR_ENABLE | CMD_BSY);
+		WRITE_CONTROL (BASE_CMD | CMD_DRVR_ENABLE | CMD_BSY);
 #else
-      WRITE_CONTROL (BASE_CMD | CMD_BSY);
+		WRITE_CONTROL (BASE_CMD | CMD_BSY);
 #endif
 
 /*
- *    The target will drop SEL, and raise BSY, at which time we must drop
+ *	The target will drop SEL, and raise BSY, at which time we must drop
  *      BSY.
  */
 
-      ULOOP( 100*1000 ) {
-	if (!(STATUS & STAT_SEL)) break;
-	if (TIMEOUT) {
-	  WRITE_CONTROL (BASE_CMD | CMD_INTR);
-	  DPRINTK (PHASE_RESELECT,
-		   "scsi%d : RESELECT timed out while waiting for SEL.\n", hostno);
-	  return (DID_BAD_INTR << 16);
-	}
-      }
+		ULOOP (100 * 1000) {
+			if (!(STATUS & STAT_SEL))
+				break;
+			if (TIMEOUT) {
+				WRITE_CONTROL (BASE_CMD | CMD_INTR);
+				DPRINTK (PHASE_RESELECT,
+					 "scsi%d : RESELECT timed out while waiting for SEL.\n",
+					 hostno);
+				return (DID_BAD_INTR << 16);
+			}
+		}
 
-      WRITE_CONTROL (BASE_CMD);
+		WRITE_CONTROL (BASE_CMD);
 
 /*
- *    At this point, we have connected with the target and can get
+ *	At this point, we have connected with the target and can get
  *      on with our lives.
  */
-      break;
-    case CAN_RECONNECT:
+		break;
+	case CAN_RECONNECT:
 
 #ifdef LINKED
 /*
@@ -892,11 +901,12 @@
  * message on MESSAGE OUT phase, and then loop back to here.
  */
 
-    connect_loop:
+	      connect_loop:
 
 #endif
 
-      DPRINTK (PHASE_BUS_FREE, "scsi%d : phase = BUS FREE \n", hostno);
+		DPRINTK (PHASE_BUS_FREE, "scsi%d : phase = BUS FREE \n",
+			 hostno);
 
 /*
  *    BUS FREE PHASE
@@ -909,21 +919,22 @@
 
 #ifndef ARBITRATE
 #error FIXME: this is broken: we may not use jiffies here - we are under cli(). It will hardlock.
-      clock = jiffies + ST0X_BUS_FREE_DELAY;
+		clock = jiffies + ST0X_BUS_FREE_DELAY;
 
-      while (((STATUS | STATUS | STATUS) &
-              (STAT_BSY | STAT_SEL)) &&
-             (!st0x_aborted) && time_before(jiffies, clock));
+		while (((STATUS | STATUS | STATUS) &
+			(STAT_BSY | STAT_SEL)) &&
+		       (!st0x_aborted) && time_before (jiffies, clock)) ;
 
-      if (time_after(jiffies, clock))
-        return retcode (DID_BUS_BUSY);
-      else if (st0x_aborted)
-        return retcode (st0x_aborted);
+		if (time_after (jiffies, clock))
+			return retcode (DID_BUS_BUSY);
+		else if (st0x_aborted)
+			return retcode (st0x_aborted);
 #endif
 
-      DPRINTK (PHASE_SELECTION, "scsi%d : phase = SELECTION\n", hostno);
+		DPRINTK (PHASE_SELECTION, "scsi%d : phase = SELECTION\n",
+			 hostno);
 
-      clock = jiffies + ST0X_SELECTION_DELAY;
+		clock = jiffies + ST0X_SELECTION_DELAY;
 
 /*
  * Arbitration/selection procedure :
@@ -937,26 +948,30 @@
  */
 
 #ifdef ARBITRATE
-      save_flags (flags);
-      cli ();
-      WRITE_CONTROL (0);
-      WRITE_DATA ((controller_type == SEAGATE) ? 0x80 : 0x40);
-      WRITE_CONTROL (CMD_START_ARB);
-      restore_flags (flags);
-
-      ULOOP( ST0X_SELECTION_DELAY * 10000 ) {
-	status_read = STATUS;
-	if (status_read & STAT_ARB_CMPL) break;
-	if (st0x_aborted)	/* FIXME: What? We are going to do something even after abort? */
-	   break;
-	if (TIMEOUT || (status_read & STAT_SEL)) {
-	  printk( "scsi%d : arbitration lost or timeout.\n", hostno );
-	  WRITE_CONTROL (BASE_CMD);
-	  return retcode (DID_NO_CONNECT);
-	}
-      }
+		save_flags (flags);
+		cli ();
+		WRITE_CONTROL (0);
+		WRITE_DATA ((controller_type == SEAGATE) ? 0x80 : 0x40);
+		WRITE_CONTROL (CMD_START_ARB);
+		restore_flags (flags);
+
+		ULOOP (ST0X_SELECTION_DELAY * 10000) {
+			status_read = STATUS;
+			if (status_read & STAT_ARB_CMPL)
+				break;
+			if (st0x_aborted)	/* FIXME: What? We are going to do something even after abort? */
+				break;
+			if (TIMEOUT || (status_read & STAT_SEL)) {
+				printk
+				    ("scsi%d : arbitration lost or timeout.\n",
+				     hostno);
+				WRITE_CONTROL (BASE_CMD);
+				return retcode (DID_NO_CONNECT);
+			}
+		}
 
-      DPRINTK (PHASE_SELECTION, "scsi%d : arbitration complete\n", hostno);
+		DPRINTK (PHASE_SELECTION, "scsi%d : arbitration complete\n",
+			 hostno);
 #endif
 
 /*
@@ -971,92 +986,103 @@
  *    try this with a SCSI protocol or logic analyzer to see what is
  *    going on.
  */
-       tmp_data = (unsigned char) ((1 << target) | (controller_type == SEAGATE ? 0x80 : 0x40));
-       tmp_control = BASE_CMD | CMD_DRVR_ENABLE | CMD_SEL | (reselect ? CMD_ATTN : 0);
+		tmp_data =
+		    (unsigned char) ((1 << target) |
+				     (controller_type ==
+				      SEAGATE ? 0x80 : 0x40));
+		tmp_control =
+		    BASE_CMD | CMD_DRVR_ENABLE | CMD_SEL | (reselect ? CMD_ATTN
+							    : 0);
 
-       save_flags(flags);
-       cli();
+		save_flags (flags);
+		cli ();
 #ifdef OLDCNTDATASCEME
 #ifdef SWAPCNTDATA
-       WRITE_CONTROL (tmp_control);
-       WRITE_DATA (tmp_data);
+		WRITE_CONTROL (tmp_control);
+		WRITE_DATA (tmp_data);
 #else
-       WRITE_DATA (tmp_data);
-       WRITE_CONTROL (tmp_control);
+		WRITE_DATA (tmp_data);
+		WRITE_CONTROL (tmp_control);
 #endif
 #else
-       tmp_control ^= CMD_BSY;		/* This is guesswork. What used to be in driver	   */
-       WRITE_CONTROL (tmp_control);	/* could never work: it sent data into control	   */
-       WRITE_DATA (tmp_data);		/* register and control info into data. Hopefully  */
-       tmp_control ^= CMD_BSY;		/* fixed, but order of first two may be wrong.     */
-       WRITE_CONTROL (tmp_control);	                              /* -- pavel@ucw.cz   */
-#endif       
-
+		tmp_control ^= CMD_BSY;	/* This is guesswork. What used to be in driver    */
+		WRITE_CONTROL (tmp_control);	/* could never work: it sent data into control     */
+		WRITE_DATA (tmp_data);	/* register and control info into data. Hopefully  */
+		tmp_control ^= CMD_BSY;	/* fixed, but order of first two may be wrong.     */
+		WRITE_CONTROL (tmp_control);	/* -- pavel@ucw.cz   */
+#endif
 
-       restore_flags (flags);
+		restore_flags (flags);
 
-       ULOOP( 250*1000 ) {
-	 if (st0x_aborted) {
+		ULOOP (250 * 1000) {
+			if (st0x_aborted) {
 /*
- *    If we have been aborted, and we have a command in progress, IE the
+ *	If we have been aborted, and we have a command in progress, IE the
  *      target still has BSY asserted, then we will reset the bus, and
  *      notify the midlevel driver to expect sense.
  */
 
-	   WRITE_CONTROL (BASE_CMD);
-	   if (STATUS & STAT_BSY) {
-	     printk ("scsi%d : BST asserted after we've been aborted.\n", hostno);
-	     seagate_st0x_reset (NULL, 0);
-	     return retcode (DID_RESET);
-	   }
-	   return retcode (st0x_aborted);
-	 }
-	 if (STATUS & STAT_BSY) break;
-	 if (TIMEOUT) {
-	   DPRINTK (PHASE_SELECTION, "scsi%d : NO CONNECT with target %d, stat = %x \n",
-		    hostno, target, STATUS);
-	   return retcode (DID_NO_CONNECT);
-	 }
-       }
+				WRITE_CONTROL (BASE_CMD);
+				if (STATUS & STAT_BSY) {
+					printk
+					    ("scsi%d : BST asserted after we've been aborted.\n",
+					     hostno);
+					seagate_st0x_reset (NULL, 0);
+					return retcode (DID_RESET);
+				}
+				return retcode (st0x_aborted);
+			}
+			if (STATUS & STAT_BSY)
+				break;
+			if (TIMEOUT) {
+				DPRINTK (PHASE_SELECTION,
+					 "scsi%d : NO CONNECT with target %d, stat = %x \n",
+					 hostno, target, STATUS);
+				return retcode (DID_NO_CONNECT);
+			}
+		}
 
 /* Establish current pointers.  Take into account scatter / gather */
 
-      if ((nobuffs = SCint->use_sg))
-      {
+		if ((nobuffs = SCint->use_sg)) {
 #if (DEBUG & DEBUG_SG)
-        {
-          int i;
+			{
+				int i;
 
-          printk ("scsi%d : scatter gather requested, using %d buffers.\n",
-                  hostno, nobuffs);
-          for (i = 0; i < nobuffs; ++i)
-            printk ("scsi%d : buffer %d address = %08x length = %d\n",
-                    hostno, i, buffer[i].address, buffer[i].length);
-        }
-#endif
-
-        buffer = (struct scatterlist *) SCint->buffer;
-        len = buffer->length;
-        data = (unsigned char *) buffer->address;
-      }
-      else
-      {
-        DPRINTK (DEBUG_SG, "scsi%d : scatter gather not requested.\n", hostno);
-        buffer = NULL;
-        len = SCint->request_bufflen;
-        data = (unsigned char *) SCint->request_buffer;
-      }
+				printk
+				    ("scsi%d : scatter gather requested, using %d buffers.\n",
+				     hostno, nobuffs);
+				for (i = 0; i < nobuffs; ++i)
+					printk
+					    ("scsi%d : buffer %d address = %08x length = %d\n",
+					     hostno, i, buffer[i].address,
+					     buffer[i].length);
+			}
+#endif
+
+			buffer = (struct scatterlist *) SCint->buffer;
+			len = buffer->length;
+			data = (unsigned char *) buffer->address;
+		} else {
+			DPRINTK (DEBUG_SG,
+				 "scsi%d : scatter gather not requested.\n",
+				 hostno);
+			buffer = NULL;
+			len = SCint->request_bufflen;
+			data = (unsigned char *) SCint->request_buffer;
+		}
 
-      DPRINTK (PHASE_DATAIN | PHASE_DATAOUT, "scsi%d : len = %d\n", hostno, len);
+		DPRINTK (PHASE_DATAIN | PHASE_DATAOUT, "scsi%d : len = %d\n",
+			 hostno, len);
 
-      break;
+		break;
 #ifdef LINKED
-    case LINKED_RIGHT:
-      break;
-    case LINKED_WRONG:
-      break;
+	case LINKED_RIGHT:
+		break;
+	case LINKED_WRONG:
+		break;
 #endif
-  }                                     /* end of switch(reselect) */
+	}			/* end of switch(reselect) */
 
 /*
  *    There are several conditions under which we wish to send a message :
@@ -1069,14 +1095,14 @@
 
 /* GCC does not like an ifdef inside a macro, so do it the hard way. */
 #ifdef LINKED
-  WRITE_CONTROL (BASE_CMD | CMD_DRVR_ENABLE |
-                 (((reselect == CAN_RECONNECT)
-                   || (reselect == LINKED_WRONG)
-                  )? CMD_ATTN : 0));
+	WRITE_CONTROL (BASE_CMD | CMD_DRVR_ENABLE |
+		       (((reselect == CAN_RECONNECT)
+			 || (reselect == LINKED_WRONG)
+			)? CMD_ATTN : 0));
 #else
-  WRITE_CONTROL (BASE_CMD | CMD_DRVR_ENABLE |
-                 (((reselect == CAN_RECONNECT)
-                  )? CMD_ATTN : 0));
+	WRITE_CONTROL (BASE_CMD | CMD_DRVR_ENABLE |
+		       (((reselect == CAN_RECONNECT)
+			)? CMD_ATTN : 0));
 #endif
 
 /*
@@ -1091,134 +1117,145 @@
  *
  */
 
-  DPRINTK (PHASE_ETC, "scsi%d : phase = INFORMATION TRANSFER\n", hostno);
+	DPRINTK (PHASE_ETC, "scsi%d : phase = INFORMATION TRANSFER\n", hostno);
 
-  incommand = 1;
-  transfersize = SCint->transfersize;
-  underflow = SCint->underflow;
+	incommand = 1;
+	transfersize = SCint->transfersize;
+	underflow = SCint->underflow;
 
 /*
- *    Now, we poll the device for status information,
+ *	Now, we poll the device for status information,
  *      and handle any requests it makes.  Note that since we are unsure of
  *      how much data will be flowing across the system, etc and cannot
  *      make reasonable timeouts, that we will instead have the midlevel
  *      driver handle any timeouts that occur in this phase.
  */
 
-  while (((status_read = STATUS) & STAT_BSY) && !st0x_aborted && !done)
-  {
+	while (((status_read = STATUS) & STAT_BSY) && !st0x_aborted && !done) {
 #ifdef PARITY
-    if (status_read & STAT_PARITY)
-    {
-      printk ("scsi%d : got parity error\n", hostno);
-      st0x_aborted = DID_PARITY;
-    }
+		if (status_read & STAT_PARITY) {
+			printk ("scsi%d : got parity error\n", hostno);
+			st0x_aborted = DID_PARITY;
+		}
 #endif
 
-    if (status_read & STAT_REQ)
-    {
+		if (status_read & STAT_REQ) {
 #if ((DEBUG & PHASE_ETC) == PHASE_ETC)
-      if ((newphase = (status_read & REQ_MASK)) != phase)
-      {
-        phase = newphase;
-        switch (phase)
-        {
-          case REQ_DATAOUT:
-            printk ("scsi%d : phase = DATA OUT\n", hostno);
-            break;
-          case REQ_DATAIN:
-            printk ("scsi%d : phase = DATA IN\n", hostno);
-            break;
-          case REQ_CMDOUT:
-            printk ("scsi%d : phase = COMMAND OUT\n", hostno);
-            break;
-          case REQ_STATIN:
-            printk ("scsi%d : phase = STATUS IN\n", hostno);
-            break;
-          case REQ_MSGOUT:
-            printk ("scsi%d : phase = MESSAGE OUT\n", hostno);
-            break;
-          case REQ_MSGIN:
-            printk ("scsi%d : phase = MESSAGE IN\n", hostno);
-            break;
-          default:
-            printk ("scsi%d : phase = UNKNOWN\n", hostno);
-            st0x_aborted = DID_ERROR;
-        }
-      }
-#endif
-      switch (status_read & REQ_MASK)
-      {
-        case REQ_DATAOUT:
+			if ((newphase = (status_read & REQ_MASK)) != phase) {
+				phase = newphase;
+				switch (phase) {
+				case REQ_DATAOUT:
+					printk ("scsi%d : phase = DATA OUT\n",
+						hostno);
+					break;
+				case REQ_DATAIN:
+					printk ("scsi%d : phase = DATA IN\n",
+						hostno);
+					break;
+				case REQ_CMDOUT:
+					printk
+					    ("scsi%d : phase = COMMAND OUT\n",
+					     hostno);
+					break;
+				case REQ_STATIN:
+					printk ("scsi%d : phase = STATUS IN\n",
+						hostno);
+					break;
+				case REQ_MSGOUT:
+					printk
+					    ("scsi%d : phase = MESSAGE OUT\n",
+					     hostno);
+					break;
+				case REQ_MSGIN:
+					printk ("scsi%d : phase = MESSAGE IN\n",
+						hostno);
+					break;
+				default:
+					printk ("scsi%d : phase = UNKNOWN\n",
+						hostno);
+					st0x_aborted = DID_ERROR;
+				}
+			}
+#endif
+			switch (status_read & REQ_MASK) {
+			case REQ_DATAOUT:
 /*
  * If we are in fast mode, then we simply splat the data out
  * in word-sized chunks as fast as we can.
  */
 
-          if (!len)
-          {
+				if (!len) {
 #if 0
-            printk ("scsi%d: underflow to target %d lun %d \n", hostno, target, lun);
-            st0x_aborted = DID_ERROR;
-            fast = 0;
-#endif
-            break;
-          }
-
-          if (fast && transfersize && !(len % transfersize)
-              && (len >= transfersize)
+					printk
+					    ("scsi%d: underflow to target %d lun %d \n",
+					     hostno, target, lun);
+					st0x_aborted = DID_ERROR;
+					fast = 0;
+#endif
+					break;
+				}
+
+				if (fast && transfersize
+				    && !(len % transfersize)
+				    && (len >= transfersize)
 #ifdef FAST32
-              && !(transfersize % 4)
+				    && !(transfersize % 4)
 #endif
-            )
-          {
-            DPRINTK (DEBUG_FAST,
-		     "scsi%d : FAST transfer, underflow = %d, transfersize = %d\n"
-                    "         len = %d, data = %08x\n",
-                  hostno, SCint->underflow, SCint->transfersize, len, data);
+				    ) {
+					DPRINTK (DEBUG_FAST,
+						 "scsi%d : FAST transfer, underflow = %d, transfersize = %d\n"
+						 "         len = %d, data = %08x\n",
+						 hostno, SCint->underflow,
+						 SCint->transfersize, len,
+						 data);
 
 /* SJT: Start. Fast Write */
 #ifdef SEAGATE_USE_ASM
-            __asm__(
-                "cld\n\t"
+					__asm__ ("cld\n\t"
 #ifdef FAST32
-                "shr $2, %%ecx\n\t"
-                "1:\t"
-                "lodsl\n\t"
-                "movl %%eax, (%%edi)\n\t"
+						 "shr $2, %%ecx\n\t"
+						 "1:\t"
+						 "lodsl\n\t"
+						 "movl %%eax, (%%edi)\n\t"
 #else
-                "1:\t"
-                "lodsb\n\t"
-                "movb %%al, (%%edi)\n\t"
-#endif
-                "loop 1b;"
-/* output */    :
-/* input */     : "D" (phys_to_virt(st0x_dr)), "S" (data), "c" (SCint->transfersize) 
-/* clobbered */ : "eax", "ecx", "esi" );
-#else /* SEAGATE_USE_ASM */
-            {
+						 "1:\t"
+						 "lodsb\n\t"
+						 "movb %%al, (%%edi)\n\t"
+#endif
+						 "loop 1b;"
+				      /* output */ :
+				      /* input */ :"D" (phys_to_virt (st0x_dr)),
+						 "S"
+						 (data),
+						 "c" (SCint->transfersize)
+/* clobbered */
+				      :	 "eax", "ecx",
+						 "esi");
+#else				/* SEAGATE_USE_ASM */
+					{
 #ifdef FAST32
-              unsigned int *iop = phys_to_virt (st0x_dr);
-              const unsigned int *dp = (unsigned int *) data;
-              int xferlen = transfersize >> 2;
+						unsigned int *iop =
+						    phys_to_virt (st0x_dr);
+						const unsigned int *dp =
+						    (unsigned int *) data;
+						int xferlen = transfersize >> 2;
 #else
-              unsigned char *iop = phys_to_virt (st0x_dr);
-              const unsigned char *dp = data;
-              int xferlen = transfersize;
-#endif
-              for (; xferlen; --xferlen)
-                *iop = *dp++;
-            }
-#endif /* SEAGATE_USE_ASM */
+						unsigned char *iop =
+						    phys_to_virt (st0x_dr);
+						const unsigned char *dp = data;
+						int xferlen = transfersize;
+#endif
+						for (; xferlen; --xferlen)
+							*iop = *dp++;
+					}
+#endif				/* SEAGATE_USE_ASM */
 /* SJT: End */
-            len -= transfersize;
-            data += transfersize;
-            DPRINTK (DEBUG_FAST,
-		     "scsi%d : FAST transfer complete len = %d data = %08x\n",
-                    hostno, len, data);
-          }
-          else
-          {
+					len -= transfersize;
+					data += transfersize;
+					DPRINTK (DEBUG_FAST,
+						 "scsi%d : FAST transfer complete len = %d data = %08x\n",
+						 hostno, len, data);
+				} else {
 /*
  *    We loop as long as we are in a data out phase, there is data to send,
  *      and BSY is still active.
@@ -1227,7 +1264,7 @@
 /* SJT: Start. Slow Write. */
 #ifdef SEAGATE_USE_ASM
 
-int __dummy_1,__dummy_2;
+					int __dummy_1, __dummy_2;
 
 /*
  *      We loop as long as we are in a data out phase, there is data to send, 
@@ -1236,159 +1273,173 @@
 /* Local variables : len = ecx , data = esi, 
                      st0x_cr_sr = ebx, st0x_dr =  edi
 */
-            __asm__ (
-            /* Test for any data here at all. */
-                    "orl %%ecx, %%ecx\n\t"
-                    "jz 2f\n\t"
-                    "cld\n\t"
+					__asm__ (
+							/* Test for any data here at all. */
+							"orl %%ecx, %%ecx\n\t"
+							"jz 2f\n\t" "cld\n\t"
 /*                    "movl " SYMBOL_NAME_STR(st0x_cr_sr) ", %%ebx\n\t"  */
 /*                    "movl " SYMBOL_NAME_STR(st0x_dr) ", %%edi\n\t"  */
-                "1:\t"
-                    "movb (%%ebx), %%al\n\t"
-            /* Test for BSY */
-                    "test $1, %%al\n\t"
-                    "jz 2f\n\t"
-            /* Test for data out phase - STATUS & REQ_MASK should be 
-               REQ_DATAOUT, which is 0. */
-                    "test $0xe, %%al\n\t"
-                    "jnz 2f\n\t"
-            /* Test for REQ */      
-                    "test $0x10, %%al\n\t"
-                    "jz 1b\n\t"
-                    "lodsb\n\t"
-                    "movb %%al, (%%edi)\n\t"
-                    "loop 1b\n\t"
-                "2:\n"
-/* output */    : "=S" (data), "=c" (len)  ,"=b" (__dummy_1) ,"=D" (__dummy_2)
-/* input */     : "0" (data), "1" (len), "2" (phys_to_virt(st0x_cr_sr)), "3" (phys_to_virt(st0x_dr)) 
-/* clobbered */ : "eax"); 
-#else /* SEAGATE_USE_ASM */
-            while (len)
-            {
-              unsigned char stat;
-
-              stat = STATUS;
-              if (!(stat & STAT_BSY) || ((stat & REQ_MASK) != REQ_DATAOUT))
-                break;
-              if (stat & STAT_REQ)
-              {
-                WRITE_DATA (*data++);
-                --len;
-              }
-            }
-#endif /* SEAGATE_USE_ASM */
+							"1:\t"
+							"movb (%%ebx), %%al\n\t"
+							/* Test for BSY */
+							"test $1, %%al\n\t"
+							"jz 2f\n\t"
+							/* Test for data out phase - STATUS & REQ_MASK should be 
+							   REQ_DATAOUT, which is 0. */
+							"test $0xe, %%al\n\t"
+							"jnz 2f\n\t"
+							/* Test for REQ */
+							"test $0x10, %%al\n\t"
+							"jz 1b\n\t"
+							"lodsb\n\t"
+							"movb %%al, (%%edi)\n\t"
+							"loop 1b\n\t" "2:\n"
+				      /* output */ :"=S" (data), "=c" (len),
+							"=b"
+							(__dummy_1),
+							"=D" (__dummy_2)
+/* input */
+				      :		"0" (data), "1" (len),
+							"2" (phys_to_virt
+							     (st0x_cr_sr)),
+							"3" (phys_to_virt
+							     (st0x_dr))
+/* clobbered */
+				      :		"eax");
+#else				/* SEAGATE_USE_ASM */
+					while (len) {
+						unsigned char stat;
+
+						stat = STATUS;
+						if (!(stat & STAT_BSY)
+						    || ((stat & REQ_MASK) !=
+							REQ_DATAOUT))
+							break;
+						if (stat & STAT_REQ) {
+							WRITE_DATA (*data++);
+							--len;
+						}
+					}
+#endif				/* SEAGATE_USE_ASM */
 /* SJT: End. */
-          }
+				}
 
-          if (!len && nobuffs)
-          {
-            --nobuffs;
-            ++buffer;
-            len = buffer->length;
-            data = (unsigned char *) buffer->address;
-            DPRINTK (DEBUG_SG,
-		    "scsi%d : next scatter-gather buffer len = %d address = %08x\n",
-                    hostno, len, data);
-          }
-          break;
+				if (!len && nobuffs) {
+					--nobuffs;
+					++buffer;
+					len = buffer->length;
+					data =
+					    (unsigned char *) buffer->address;
+					DPRINTK (DEBUG_SG,
+						 "scsi%d : next scatter-gather buffer len = %d address = %08x\n",
+						 hostno, len, data);
+				}
+				break;
 
-        case REQ_DATAIN:
+			case REQ_DATAIN:
 #ifdef SLOW_RATE
-          if (borken)
-          {
+				if (borken) {
 #if (DEBUG & (PHASE_DATAIN))
-            transfered += len;
+					transfered += len;
 #endif
-            for (;
-                 len && (STATUS & (REQ_MASK | STAT_REQ)) == (REQ_DATAIN |
-                                                             STAT_REQ)
-                 ; --len)
-            {
-              *data++ = DATA;
-              borken_wait ();
-            }
+					for (;
+					     len
+					     && (STATUS & (REQ_MASK | STAT_REQ))
+					     == (REQ_DATAIN | STAT_REQ);
+					     --len) {
+						*data++ = DATA;
+						borken_wait ();
+					}
 #if (DEBUG & (PHASE_DATAIN))
-            transfered -= len;
+					transfered -= len;
 #endif
-          }
-          else
+				} else
 #endif
 
-            if (fast && transfersize && !(len % transfersize) &&
-                (len >= transfersize)
+					if (fast && transfersize
+					    && !(len % transfersize)
+					    && (len >= transfersize)
 #ifdef FAST32
-                && !(transfersize % 4)
+					    && !(transfersize % 4)
 #endif
-            )
-          {
-            DPRINTK (DEBUG_FAST,
-		     "scsi%d : FAST transfer, underflow = %d, transfersize = %d\n"
-                    "         len = %d, data = %08x\n",
-                  hostno, SCint->underflow, SCint->transfersize, len, data);
+				    ) {
+					DPRINTK (DEBUG_FAST,
+						 "scsi%d : FAST transfer, underflow = %d, transfersize = %d\n"
+						 "         len = %d, data = %08x\n",
+						 hostno, SCint->underflow,
+						 SCint->transfersize, len,
+						 data);
 
 /* SJT: Start. Fast Read */
 #ifdef SEAGATE_USE_ASM
-            __asm__(
-                    "cld\n\t"
+					__asm__ ("cld\n\t"
 #ifdef FAST32
-                    "shr $2, %%ecx\n\t"
-                "1:\t"
-                    "movl (%%esi), %%eax\n\t"
-                    "stosl\n\t"
+						 "shr $2, %%ecx\n\t"
+						 "1:\t"
+						 "movl (%%esi), %%eax\n\t"
+						 "stosl\n\t"
 #else
-                "1:\t"
-                    "movb (%%esi), %%al\n\t"
-                    "stosb\n\t"
-#endif
-                    "loop 1b\n\t"
-/* output */        : 
-/* input */         : "S" (phys_to_virt(st0x_dr)), "D" (data), "c" (SCint->transfersize) 
-/* clobbered */     : "eax", "ecx", "edi");
-#else /* SEAGATE_USE_ASM */
-            {
+						 "1:\t"
+						 "movb (%%esi), %%al\n\t"
+						 "stosb\n\t"
+#endif
+						 "loop 1b\n\t"
+				      /* output */ :
+				      /* input */ :"S" (phys_to_virt (st0x_dr)),
+						 "D"
+						 (data),
+						 "c" (SCint->transfersize)
+/* clobbered */
+				      :	 "eax", "ecx",
+						 "edi");
+#else				/* SEAGATE_USE_ASM */
+					{
 #ifdef FAST32
-              const unsigned int *iop = phys_to_virt (st0x_dr);
-              unsigned int *dp = (unsigned int *) data;
-              int xferlen = len >> 2;
+						const unsigned int *iop =
+						    phys_to_virt (st0x_dr);
+						unsigned int *dp =
+						    (unsigned int *) data;
+						int xferlen = len >> 2;
 #else
-              const unsigned char *iop = phys_to_virt (st0x_dr);
-              unsigned char *dp = data;
-              int xferlen = len;
-#endif
-              for (; xferlen; --xferlen)
-                *dp++ = *iop;
-            }
-#endif /* SEAGATE_USE_ASM */
+						const unsigned char *iop =
+						    phys_to_virt (st0x_dr);
+						unsigned char *dp = data;
+						int xferlen = len;
+#endif
+						for (; xferlen; --xferlen)
+							*dp++ = *iop;
+					}
+#endif				/* SEAGATE_USE_ASM */
 /* SJT: End */
-            len -= transfersize;
-            data += transfersize;
+					len -= transfersize;
+					data += transfersize;
 #if (DEBUG & PHASE_DATAIN)
-            printk ("scsi%d: transfered += %d\n", hostno, transfersize);
-            transfered += transfersize;
+					printk ("scsi%d: transfered += %d\n",
+						hostno, transfersize);
+					transfered += transfersize;
 #endif
 
-            DPRINTK (DEBUG_FAST,
-		     "scsi%d : FAST transfer complete len = %d data = %08x\n",
-                    hostno, len, data);
-          }
-          else
-          {
+					DPRINTK (DEBUG_FAST,
+						 "scsi%d : FAST transfer complete len = %d data = %08x\n",
+						 hostno, len, data);
+				} else {
 
 #if (DEBUG & PHASE_DATAIN)
-            printk ("scsi%d: transfered += %d\n", hostno, len);
-            transfered += len;          /* Assume we'll transfer it all, then
-                                           subtract what we *didn't* transfer */
+					printk ("scsi%d: transfered += %d\n",
+						hostno, len);
+					transfered += len;	/* Assume we'll transfer it all, then
+								   subtract what we *didn't* transfer */
 #endif
 
 /*
- *    We loop as long as we are in a data in phase, there is room to read,
+ *	We loop as long as we are in a data in phase, there is room to read,
  *      and BSY is still active
  */
 
 /* SJT: Start. */
 #ifdef SEAGATE_USE_ASM
 
-int __dummy_3,__dummy_4;
+					int __dummy_3, __dummy_4;
 
 /* Dummy clobbering variables for the new gcc-2.95 */
 
@@ -1396,175 +1447,200 @@
  *      We loop as long as we are in a data in phase, there is room to read, 
  *      and BSY is still active
  */
-            /* Local variables : ecx = len, edi = data
-                                 esi = st0x_cr_sr, ebx = st0x_dr */
-            __asm__ (
-            /* Test for room to read */
-                "orl %%ecx, %%ecx\n\t"
-                "jz 2f\n\t"
-                "cld\n\t"
+					/* Local variables : ecx = len, edi = data
+					   esi = st0x_cr_sr, ebx = st0x_dr */
+					__asm__ (
+							/* Test for room to read */
+							"orl %%ecx, %%ecx\n\t"
+							"jz 2f\n\t" "cld\n\t"
 /*                "movl " SYMBOL_NAME_STR(st0x_cr_sr) ", %%esi\n\t"  */
 /*                "movl " SYMBOL_NAME_STR(st0x_dr) ", %%ebx\n\t"  */
-            "1:\t"
-                "movb (%%esi), %%al\n\t"
-            /* Test for BSY */
-                "test $1, %%al\n\t"
-                "jz 2f\n\t"
-            /* Test for data in phase - STATUS & REQ_MASK should be REQ_DATAIN, 
-               = STAT_IO, which is 4. */
-                "movb $0xe, %%ah\n\t"      
-                "andb %%al, %%ah\n\t"
-                "cmpb $0x04, %%ah\n\t"
-                "jne 2f\n\t"
-            /* Test for REQ */      
-                "test $0x10, %%al\n\t"
-                "jz 1b\n\t"
-                "movb (%%ebx), %%al\n\t"      
-                "stosb\n\t"   
-                "loop 1b\n\t"
-            "2:\n"
-/* output */    : "=D" (data), "=c" (len) ,"=S" (__dummy_3) ,"=b" (__dummy_4)
-/* input */     : "0" (data), "1" (len), "2" (phys_to_virt(st0x_cr_sr)), "3" (phys_to_virt(st0x_dr)) 
-/* clobbered */ : "eax" ); 
-#else /* SEAGATE_USE_ASM */
-            while (len)
-            {
-              unsigned char stat;
-
-              stat = STATUS;
-              if (!(stat & STAT_BSY) || ((stat & REQ_MASK) != REQ_DATAIN))
-                break;
-              if (stat & STAT_REQ)
-              {
-                *data++ = DATA;
-                --len;
-              }
-            }
-#endif /* SEAGATE_USE_ASM */
+							"1:\t"
+							"movb (%%esi), %%al\n\t"
+							/* Test for BSY */
+							"test $1, %%al\n\t"
+							"jz 2f\n\t"
+							/* Test for data in phase - STATUS & REQ_MASK should be REQ_DATAIN, 
+							   = STAT_IO, which is 4. */
+							"movb $0xe, %%ah\n\t"
+							"andb %%al, %%ah\n\t"
+							"cmpb $0x04, %%ah\n\t"
+							"jne 2f\n\t"
+							/* Test for REQ */
+							"test $0x10, %%al\n\t"
+							"jz 1b\n\t"
+							"movb (%%ebx), %%al\n\t"
+							"stosb\n\t"
+							"loop 1b\n\t" "2:\n"
+				      /* output */ :"=D" (data), "=c" (len),
+							"=S"
+							(__dummy_3),
+							"=b" (__dummy_4)
+/* input */
+				      :		"0" (data), "1" (len),
+							"2" (phys_to_virt
+							     (st0x_cr_sr)),
+							"3" (phys_to_virt
+							     (st0x_dr))
+/* clobbered */
+				      :		"eax");
+#else				/* SEAGATE_USE_ASM */
+					while (len) {
+						unsigned char stat;
+
+						stat = STATUS;
+						if (!(stat & STAT_BSY)
+						    || ((stat & REQ_MASK) !=
+							REQ_DATAIN))
+							break;
+						if (stat & STAT_REQ) {
+							*data++ = DATA;
+							--len;
+						}
+					}
+#endif				/* SEAGATE_USE_ASM */
 /* SJT: End. */
 #if (DEBUG & PHASE_DATAIN)
-            printk ("scsi%d: transfered -= %d\n", hostno, len);
-            transfered -= len;          /* Since we assumed all of Len got  *
-                                           transfered, correct our mistake */
-#endif
-          }
-
-          if (!len && nobuffs)
-          {
-            --nobuffs;
-            ++buffer;
-            len = buffer->length;
-            data = (unsigned char *) buffer->address;
-            DPRINTK (DEBUG_SG, 
-		     "scsi%d : next scatter-gather buffer len = %d address = %08x\n",
-                    hostno, len, data);
-          }
-
-          break;
-
-        case REQ_CMDOUT:
-          while (((status_read = STATUS) & STAT_BSY) &&
-                 ((status_read & REQ_MASK) == REQ_CMDOUT))
-            if (status_read & STAT_REQ)
-            {
-              WRITE_DATA (*(const unsigned char *) cmnd);
-              cmnd = 1 + (const unsigned char *) cmnd;
+					printk ("scsi%d: transfered -= %d\n",
+						hostno, len);
+					transfered -= len;	/* Since we assumed all of Len got  *
+								   transfered, correct our mistake */
+#endif
+				}
+
+				if (!len && nobuffs) {
+					--nobuffs;
+					++buffer;
+					len = buffer->length;
+					data =
+					    (unsigned char *) buffer->address;
+					DPRINTK (DEBUG_SG,
+						 "scsi%d : next scatter-gather buffer len = %d address = %08x\n",
+						 hostno, len, data);
+				}
+
+				break;
+
+			case REQ_CMDOUT:
+				while (((status_read = STATUS) & STAT_BSY) &&
+				       ((status_read & REQ_MASK) == REQ_CMDOUT))
+					if (status_read & STAT_REQ) {
+						WRITE_DATA (*
+							    (const unsigned char
+							     *) cmnd);
+						cmnd =
+						    1 +
+						    (const unsigned char *)
+						    cmnd;
 #ifdef SLOW_RATE
-              if (borken)
-                borken_wait ();
+						if (borken)
+							borken_wait ();
 #endif
-            }
-          break;
+					}
+				break;
 
-        case REQ_STATIN:
-          status = DATA;
-          break;
+			case REQ_STATIN:
+				status = DATA;
+				break;
 
-        case REQ_MSGOUT:
+			case REQ_MSGOUT:
 /*
- *    We can only have sent a MSG OUT if we requested to do this
+ *	We can only have sent a MSG OUT if we requested to do this
  *      by raising ATTN.  So, we must drop ATTN.
  */
 
-          WRITE_CONTROL (BASE_CMD | CMD_DRVR_ENABLE);
+				WRITE_CONTROL (BASE_CMD | CMD_DRVR_ENABLE);
 /*
- *    If we are reconnecting, then we must send an IDENTIFY message in
- *       response  to MSGOUT.
+ *	If we are reconnecting, then we must send an IDENTIFY message in
+ *      response  to MSGOUT.
  */
-          switch (reselect)
-          {
-            case CAN_RECONNECT:
-              WRITE_DATA (IDENTIFY (1, lun));
-
-              DPRINTK (PHASE_RESELECT | PHASE_MSGOUT, "scsi%d : sent IDENTIFY message.\n", hostno);
-              break;
+				switch (reselect) {
+				case CAN_RECONNECT:
+					WRITE_DATA (IDENTIFY (1, lun));
+
+					DPRINTK (PHASE_RESELECT | PHASE_MSGOUT,
+						 "scsi%d : sent IDENTIFY message.\n",
+						 hostno);
+					break;
 #ifdef LINKED
-            case LINKED_WRONG:
-              WRITE_DATA (ABORT);
-              linked_connected = 0;
-              reselect = CAN_RECONNECT;
-              goto connect_loop;
-              DPRINTK (PHASE_MSGOUT | DEBUG_LINKED, 
-		       "scsi%d : sent ABORT message to cancel incorrect I_T_L nexus.\n", hostno);
-#endif /* LINKED */
-              DPRINTK (DEBUG_LINKED, "correct\n");
-            default:
-              WRITE_DATA (NOP);
-              printk ("scsi%d : target %d requested MSGOUT, sent NOP message.\n", hostno, target);
-          }
-          break;
-
-        case REQ_MSGIN:
-          switch (message = DATA)
-          {
-            case DISCONNECT:
-	      DANY ("seagate: deciding to disconnect\n");
-              should_reconnect = 1;
-              current_data = data;      /* WDE add */
-              current_buffer = buffer;
-              current_bufflen = len;    /* WDE add */
-              current_nobuffs = nobuffs;
+				case LINKED_WRONG:
+					WRITE_DATA (ABORT);
+					linked_connected = 0;
+					reselect = CAN_RECONNECT;
+					goto connect_loop;
+					DPRINTK (PHASE_MSGOUT | DEBUG_LINKED,
+						 "scsi%d : sent ABORT message to cancel incorrect I_T_L nexus.\n",
+						 hostno);
+#endif				/* LINKED */
+					DPRINTK (DEBUG_LINKED, "correct\n");
+				default:
+					WRITE_DATA (NOP);
+					printk
+					    ("scsi%d : target %d requested MSGOUT, sent NOP message.\n",
+					     hostno, target);
+				}
+				break;
+
+			case REQ_MSGIN:
+				switch (message = DATA) {
+				case DISCONNECT:
+					DANY ("seagate: deciding to disconnect\n");
+					should_reconnect = 1;
+					current_data = data;	/* WDE add */
+					current_buffer = buffer;
+					current_bufflen = len;	/* WDE add */
+					current_nobuffs = nobuffs;
 #ifdef LINKED
-              linked_connected = 0;
+					linked_connected = 0;
 #endif
-              done = 1;
-              DPRINTK ((PHASE_RESELECT | PHASE_MSGIN), "scsi%d : disconnected.\n", hostno);
-              break;
+					done = 1;
+					DPRINTK ((PHASE_RESELECT | PHASE_MSGIN),
+						 "scsi%d : disconnected.\n",
+						 hostno);
+					break;
 
 #ifdef LINKED
-            case LINKED_CMD_COMPLETE:
-            case LINKED_FLG_CMD_COMPLETE:
+				case LINKED_CMD_COMPLETE:
+				case LINKED_FLG_CMD_COMPLETE:
 #endif
-            case COMMAND_COMPLETE:
+				case COMMAND_COMPLETE:
 /*
  * Note : we should check for underflow here.
  */
-              DPRINTK (PHASE_MSGIN, "scsi%d : command complete.\n", hostno);
-              done = 1;
-              break;
-            case ABORT:
-              DPRINTK (PHASE_MSGIN, "scsi%d : abort message.\n", hostno);
-              done = 1;
-              break;
-            case SAVE_POINTERS:
-              current_buffer = buffer;
-              current_bufflen = len;    /* WDE add */
-              current_data = data;      /* WDE mod */
-              current_nobuffs = nobuffs;
-              DPRINTK (PHASE_MSGIN, "scsi%d : pointers saved.\n", hostno);
-              break;
-            case RESTORE_POINTERS:
-              buffer = current_buffer;
-              cmnd = current_cmnd;
-              data = current_data;      /* WDE mod */
-              len = current_bufflen;
-              nobuffs = current_nobuffs;
-              DPRINTK (PHASE_MSGIN, "scsi%d : pointers restored.\n", hostno);
-              break;
-            default:
+					DPRINTK (PHASE_MSGIN,
+						 "scsi%d : command complete.\n",
+						 hostno);
+					done = 1;
+					break;
+				case ABORT:
+					DPRINTK (PHASE_MSGIN,
+						 "scsi%d : abort message.\n",
+						 hostno);
+					done = 1;
+					break;
+				case SAVE_POINTERS:
+					current_buffer = buffer;
+					current_bufflen = len;	/* WDE add */
+					current_data = data;	/* WDE mod */
+					current_nobuffs = nobuffs;
+					DPRINTK (PHASE_MSGIN,
+						 "scsi%d : pointers saved.\n",
+						 hostno);
+					break;
+				case RESTORE_POINTERS:
+					buffer = current_buffer;
+					cmnd = current_cmnd;
+					data = current_data;	/* WDE mod */
+					len = current_bufflen;
+					nobuffs = current_nobuffs;
+					DPRINTK (PHASE_MSGIN,
+						 "scsi%d : pointers restored.\n",
+						 hostno);
+					break;
+				default:
 
 /*
- *    IDENTIFY distinguishes itself from the other messages by setting the
+ *	IDENTIFY distinguishes itself from the other messages by setting the
  *      high byte. [FIXME: should not this read "the high bit"? - pavel@ucw.cz]
  *
  *      Note : we need to handle at least one outstanding command per LUN,
@@ -1572,13 +1648,12 @@
  *      known ID (at this point) and LUN.
  */
 
-              if (message & 0x80)
-              {
-                DPRINTK (PHASE_MSGIN, "scsi%d : IDENTIFY message received from id %d, lun %d.\n",
-                        hostno, target, message & 7);
-              }
-              else
-              {
+					if (message & 0x80) {
+						DPRINTK (PHASE_MSGIN,
+							 "scsi%d : IDENTIFY message received from id %d, lun %d.\n",
+							 hostno, target,
+							 message & 7);
+					} else {
 
 /*
  *      We should go into a MESSAGE OUT phase, and send  a MESSAGE_REJECT
@@ -1586,17 +1661,19 @@
  *      needs some serious restructuring first though.
  */
 
-                DPRINTK (PHASE_MSGIN, 
-			 "scsi%d : unknown message %d from target %d.\n", hostno, message, target);
-              }
-          }
-          break;
-
-        default:
-          printk ("scsi%d : unknown phase.\n", hostno);
-          st0x_aborted = DID_ERROR;
-      }                                 /* end of switch (status_read &
-                                           REQ_MASK) */
+						DPRINTK (PHASE_MSGIN,
+							 "scsi%d : unknown message %d from target %d.\n",
+							 hostno, message,
+							 target);
+					}
+				}
+				break;
+
+			default:
+				printk ("scsi%d : unknown phase.\n", hostno);
+				st0x_aborted = DID_ERROR;
+			}	/* end of switch (status_read &
+				   REQ_MASK) */
 
 #ifdef SLOW_RATE
 /*
@@ -1604,34 +1681,34 @@
  * byte transfer case (ie, message in, message out, status), so
  * I'll do the wait here if necessary.
  */
-      if (borken)
-        borken_wait ();
+			if (borken)
+				borken_wait ();
 #endif
 
-    }                                   /* if(status_read & STAT_REQ) ends */
-  }                                     /* while(((status_read = STATUS)...)
-                                           ends */
+		}		/* if(status_read & STAT_REQ) ends */
+	}			/* while(((status_read = STATUS)...)
+				   ends */
 
-  DPRINTK (PHASE_DATAIN | PHASE_DATAOUT | PHASE_EXIT, 
-	   "scsi%d : Transfered %d bytes\n", hostno, transfered);
+	DPRINTK (PHASE_DATAIN | PHASE_DATAOUT | PHASE_EXIT,
+		 "scsi%d : Transfered %d bytes\n", hostno, transfered);
 
 #if (DEBUG & PHASE_EXIT)
-#if 0                                   /* Doesn't work for scatter/gather */
-  printk ("Buffer : \n");
-  for (i = 0; i < 20; ++i)
-    printk ("%02x  ", ((unsigned char *) data)[i]);     /* WDE mod */
-  printk ("\n");
-#endif
-  printk ("scsi%d : status = ", hostno);
-  print_status (status);
-  printk ("message = %02x\n", message);
+#if 0				/* Doesn't work for scatter/gather */
+	printk ("Buffer : \n");
+	for (i = 0; i < 20; ++i)
+		printk ("%02x  ", ((unsigned char *) data)[i]);	/* WDE mod */
+	printk ("\n");
+#endif
+	printk ("scsi%d : status = ", hostno);
+	print_status (status);
+	printk ("message = %02x\n", message);
 #endif
 
 /* We shouldn't reach this until *after* BSY has been deasserted */
 
 #ifdef LINKED
-  else
-  {
+	else
+	{
 /*
  * Fix the message byte so that unsuspecting high level drivers don't
  * puke when they see a LINKED COMMAND message in place of the COMMAND
@@ -1642,52 +1719,53 @@
  * and we are now disconnected.
  */
 
-    switch (message)
-    {
-      case LINKED_CMD_COMPLETE:
-      case LINKED_FLG_CMD_COMPLETE:
-        message = COMMAND_COMPLETE;
-        linked_target = current_target;
-        linked_lun = current_lun;
-        linked_connected = 1;
-	DPRINTK (DEBUG_LINKED, "scsi%d : keeping I_T_L nexus established"
-		 "for linked command.\n", hostno);
-    /* We also will need to adjust status to accommodate intermediate
-       conditions. */
-        if ((status == INTERMEDIATE_GOOD) ||
-            (status == INTERMEDIATE_C_GOOD))
-          status = GOOD;
+		switch (message) {
+		case LINKED_CMD_COMPLETE:
+		case LINKED_FLG_CMD_COMPLETE:
+			message = COMMAND_COMPLETE;
+			linked_target = current_target;
+			linked_lun = current_lun;
+			linked_connected = 1;
+			DPRINTK (DEBUG_LINKED,
+				 "scsi%d : keeping I_T_L nexus established"
+				 "for linked command.\n", hostno);
+			/* We also will need to adjust status to accommodate intermediate
+			   conditions. */
+			if ((status == INTERMEDIATE_GOOD) ||
+			    (status == INTERMEDIATE_C_GOOD))
+				status = GOOD;
 
-        break;
+			break;
 /*
  * We should also handle what are "normal" termination messages
  * here (ABORT, BUS_DEVICE_RESET?, and COMMAND_COMPLETE individually,
  * and flake if things aren't right.
  */
-      default:
-        DPRINTK (DEBUG_LINKED, "scsi%d : closing I_T_L nexus.\n", hostno);
-        linked_connected = 0;
-    }
-  }
-#endif /* LINKED */
-
-  if (should_reconnect)
-  {
-    DPRINTK (PHASE_RESELECT, "scsi%d : exiting seagate_st0x_queue_command()"
-	     "with reconnect enabled.\n", hostno);
-    WRITE_CONTROL (BASE_CMD | CMD_INTR);
-  }
-  else
-    WRITE_CONTROL (BASE_CMD);
+		default:
+			DPRINTK (DEBUG_LINKED,
+				 "scsi%d : closing I_T_L nexus.\n", hostno);
+			linked_connected = 0;
+		}
+	}
+#endif				/* LINKED */
 
-  return retcode (st0x_aborted);
-}                                       /* end of internal_command */
+	if (should_reconnect) {
+		DPRINTK (PHASE_RESELECT,
+			 "scsi%d : exiting seagate_st0x_queue_command()"
+			 "with reconnect enabled.\n", hostno);
+		WRITE_CONTROL (BASE_CMD | CMD_INTR);
+	} else
+		WRITE_CONTROL (BASE_CMD);
 
-int seagate_st0x_abort (Scsi_Cmnd * SCpnt)
+	return retcode (st0x_aborted);
+}				/* end of internal_command */
+
+static int seagate_st0x_abort (Scsi_Cmnd * SCpnt)
 {
-  st0x_aborted = DID_ABORT;
-  return SCSI_ABORT_PENDING;
+	st0x_aborted = DID_ABORT;
+	return SCSI_ABORT_PENDING;
 }
+
 #undef ULOOP
 #undef TIMEOUT
 
@@ -1695,23 +1773,22 @@
  * the seagate_st0x_reset function resets the SCSI bus 
  */
 
-int seagate_st0x_reset (Scsi_Cmnd * SCpnt, unsigned int reset_flags)
+static int seagate_st0x_reset (Scsi_Cmnd * SCpnt, unsigned int reset_flags)
 {
 /* No timeouts - this command is going to fail because it was reset. */
-  DANY ("scsi%d: Reseting bus... ", hostno );
+	DANY ("scsi%d: Reseting bus... ", hostno);
 
 /* assert  RESET signal on SCSI bus.  */
-  WRITE_CONTROL (BASE_CMD | CMD_RST);
+	WRITE_CONTROL (BASE_CMD | CMD_RST);
 
-  udelay( 20*1000 );
+	udelay (20 * 1000);
 
-  WRITE_CONTROL (BASE_CMD);
-  st0x_aborted = DID_RESET;
+	WRITE_CONTROL (BASE_CMD);
+	st0x_aborted = DID_RESET;
 
-  DANY ("done.\n");
-  return SCSI_RESET_WAKEUP;
+	DANY ("done.\n");
+	return SCSI_RESET_WAKEUP;
 }
-
 
 /* Eventually this will go into an include file, but this will be later */
 static Scsi_Host_Template driver_template = SEAGATE_ST0X;
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/seagate.h linux/drivers/scsi/seagate.h
--- v2.4.9/linux/drivers/scsi/seagate.h	Sun Sep 17 09:51:57 2000
+++ linux/drivers/scsi/seagate.h	Fri Sep  7 09:28:37 2001
@@ -16,9 +16,9 @@
 int seagate_st0x_command(Scsi_Cmnd *);
 int seagate_st0x_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 
-int seagate_st0x_abort(Scsi_Cmnd *);
+static int seagate_st0x_abort(Scsi_Cmnd *);
 const char *seagate_st0x_info(struct Scsi_Host *);
-int seagate_st0x_reset(Scsi_Cmnd *, unsigned int); 
+static int seagate_st0x_reset(Scsi_Cmnd *, unsigned int); 
 
 #define SEAGATE_ST0X  {  detect:         seagate_st0x_detect,		\
 			 info:           seagate_st0x_info,		\
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/sg.c linux/drivers/scsi/sg.c
--- v2.4.9/linux/drivers/scsi/sg.c	Wed Jul 25 17:10:23 2001
+++ linux/drivers/scsi/sg.c	Fri Sep  7 09:28:37 2001
@@ -19,9 +19,9 @@
  */
 #include <linux/config.h>
 #ifdef CONFIG_PROC_FS
- static char sg_version_str[] = "Version: 3.1.19 (20010623)";
+ static char sg_version_str[] = "Version: 3.1.20 (20010814)";
 #endif
- static int sg_version_num = 30119; /* 2 digits for each component */
+ static int sg_version_num = 30120; /* 2 digits for each component */
 /*
  *  D. P. Gilbert (dgilbert@interlog.com, dougg@triode.net.au), notes:
  *      - scsi logging is available via SCSI_LOG_TIMEOUT macros. First
@@ -271,6 +271,7 @@
      /* Prevent the device driver from vanishing while we sleep */
      if (sdp->device->host->hostt->module)
         __MOD_INC_USE_COUNT(sdp->device->host->hostt->module);
+    sdp->device->access_count++;
 
     if (! ((flags & O_NONBLOCK) ||
 	   scsi_block_when_processing_errors(sdp->device))) {
@@ -323,6 +324,7 @@
     return 0;
 
 error_out:
+    sdp->device->access_count--;
     if ((! sdp->detached) && sdp->device->host->hostt->module)
         __MOD_DEC_USE_COUNT(sdp->device->host->hostt->module);
     return retval;
@@ -342,8 +344,11 @@
     SCSI_LOG_TIMEOUT(3, printk("sg_release: dev=%d\n", MINOR(sdp->i_rdev)));
     sg_fasync(-1, filp, 0);   /* remove filp from async notification list */
     if (0 == sg_remove_sfp(sdp, sfp)) { /* Returns 1 when sdp gone */
-	if ((! sdp->detached) && sdp->device->host->hostt->module)
-	    __MOD_DEC_USE_COUNT(sdp->device->host->hostt->module);
+        if (! sdp->detached) {
+            sdp->device->access_count--;
+            if (sdp->device->host->hostt->module)
+                __MOD_DEC_USE_COUNT(sdp->device->host->hostt->module);
+        }
 	sdp->exclude = 0;
 	wake_up_interruptible(&sdp->o_excl_wait);
     }
@@ -874,6 +879,9 @@
         return 0;
     case SG_GET_VERSION_NUM:
         return put_user(sg_version_num, (int *)arg);
+    case SG_GET_ACCESS_COUNT:
+    	val = (sdp->device ? sdp->device->access_count : 0);
+	return put_user(val, (int *)arg);
     case SG_GET_REQUEST_TABLE:
 	result = verify_area(VERIFY_WRITE, (void *) arg,
 			     SZ_SG_REQ_INFO * SG_MAX_QUEUE);
@@ -1116,6 +1124,7 @@
             sg_remove_sfp(sdp, sfp);
 	    sfp = NULL;
         }
+	sdp->device->access_count--;
 	if (sg_template.module)
 		__MOD_DEC_USE_COUNT(sg_template.module);
 	if (sdp->device->host->hostt->module)
@@ -1241,6 +1250,15 @@
 
     for(k = 0; k < sg_template.dev_max; k++)
         if(! sg_dev_arr[k]) break;
+    if (k > MINORMASK) {
+	scsidp->attached--;
+	write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
+	printk("Unable to attach sg device <%d, %d, %d, %d>"
+	       " type=%d, minor number exceed %d\n", scsidp->host->host_no, 
+	       scsidp->channel, scsidp->id, scsidp->lun, scsidp->type,
+	       MINORMASK);
+	return 1;
+    }
     if(k < sg_template.dev_max)
     	sdp = (Sg_device *)kmalloc(sizeof(Sg_device), GFP_ATOMIC);
     else
@@ -1264,7 +1282,7 @@
     sdp->de = devfs_register (scsidp->de, "generic", DEVFS_FL_DEFAULT,
                              SCSI_GENERIC_MAJOR, k,
                              S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP,
-                             &sg_fops, NULL);
+                             &sg_fops, sdp);
     sg_template.nr_dev++;
     sg_dev_arr[k] = sdp;
     write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
@@ -1314,6 +1332,7 @@
 			sg_finish_rem_req(srp);
 		}
 		if (sfp->closed) {
+		    sdp->device->access_count--;
 		    if (sg_template.module)
 			__MOD_DEC_USE_COUNT(sg_template.module);
 		    if (sdp->device->host->hostt->module)
@@ -2210,6 +2229,7 @@
     }
     else {
         sfp->closed = 1; /* flag dirty state on this fd */
+	sdp->device->access_count++;
 	/* MOD_INC's to inhibit unloading sg and associated adapter driver */
 	if (sg_template.module)
 	    __MOD_INC_USE_COUNT(sg_template.module);
@@ -2753,7 +2773,7 @@
 static int sg_proc_devhdr_info(char * buffer, int * len, off_t * begin,
 			       off_t offset, int size)
 {
-    PRINT_PROC("host\tchan\tid\tlun\ttype\tbopens\tqdepth\tbusy\tonline\n");
+    PRINT_PROC("host\tchan\tid\tlun\ttype\topens\tqdepth\tbusy\tonline\n");
     return 1;
 }
 
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/sgiwd93.c linux/drivers/scsi/sgiwd93.c
--- v2.4.9/linux/drivers/scsi/sgiwd93.c	Sat Nov 11 19:01:11 2000
+++ linux/drivers/scsi/sgiwd93.c	Sun Sep  9 10:52:35 2001
@@ -281,18 +281,30 @@
 	sgiwd93_host->irq = SGI_WD93_0_IRQ;
 
 	buf = (uchar *) get_free_page(GFP_KERNEL);
+	if (!buf) {
+		printk(KERN_WARNING "sgiwd93: Could not allocate memory for host0 buffer.\n");
+		scsi_unregister(sgiwd93_host);
+		return 0;
+	}
 	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,
+	wd33c93_init(sgiwd93_host, (wd33c93_regs *) KSEG1ADDR (0x1fbc0003),
 		     dma_setup, dma_stop, WD33C93_FS_16_20);
 
 	hdata = (struct WD33C93_hostdata *)sgiwd93_host->hostdata;
 	hdata->no_sync = 0;
 	hdata->dma_bounce_buffer = (uchar *) (KSEG1ADDR(buf));
-	dma_cache_wback_inv((unsigned long) buf, PAGE_SIZE);
 
-	request_irq(SGI_WD93_0_IRQ, sgiwd93_intr, 0, "SGI WD93", (void *) sgiwd93_host);
+	if (request_irq(SGI_WD93_0_IRQ, sgiwd93_intr, 0, "SGI WD93", (void *) sgiwd93_host)) {
+		printk(KERN_WARNING "sgiwd93: Could not register IRQ %d (for host 0).\n", SGI_WD93_0_IRQ);
+#ifdef MODULE
+		wd33c93_release();
+#endif
+		free_page((unsigned long)buf);
+		scsi_unregister(sgiwd93_host);
+		return 0;
+	}
         /* set up second controller on the Indigo2 */
 	if(!sgi_guiness) {
 		sgiwd93_host1 = scsi_register(SGIblows, sizeof(struct WD33C93_hostdata));
@@ -302,10 +314,16 @@
 			sgiwd93_host1->irq = SGI_WD93_1_IRQ;
 	
 			buf = (uchar *) get_free_page(GFP_KERNEL);
+			if (!buf) {
+				printk(KERN_WARNING "sgiwd93: Could not allocate memory for host1 buffer.\n");
+				scsi_unregister(sgiwd93_host1);
+				called = 1;
+				return 1; /* We registered host0 so return success*/
+			}
 			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,
+			wd33c93_init(sgiwd93_host1, (wd33c93_regs *) KSEG1ADDR (0x1fbc8003),
 				     dma_setup, dma_stop, WD33C93_FS_16_20);
 	
 			hdata1 = (struct WD33C93_hostdata *)sgiwd93_host1->hostdata;
@@ -313,7 +331,15 @@
 			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);
+			if (request_irq(SGI_WD93_1_IRQ, sgiwd93_intr, 0, "SGI WD93", (void *) sgiwd93_host1)) {
+				printk(KERN_WARNING "sgiwd93: Could not allocate irq %d (for host1).\n", SGI_WD93_1_IRQ);
+#ifdef MODULE
+				wd33c93_release();
+#endif
+				free_page((unsigned long)buf);
+				scsi_unregister(sgiwd93_host1);
+				/* Fall through since host0 registered OK */
+			}
 		}
 	}
 	
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/sr.c linux/drivers/scsi/sr.c
--- v2.4.9/linux/drivers/scsi/sr.c	Wed Jul 25 17:10:23 2001
+++ linux/drivers/scsi/sr.c	Mon Aug 27 14:20:21 2001
@@ -101,7 +101,6 @@
 {
 	if (scsi_CDs[MINOR(cdi->dev)].device->sector_size > 2048)
 		sr_set_blocklength(MINOR(cdi->dev), 2048);
-	sync_dev(cdi->dev);
 	scsi_CDs[MINOR(cdi->dev)].device->access_count--;
 	if (scsi_CDs[MINOR(cdi->dev)].device->host->hostt->module)
 		__MOD_DEC_USE_COUNT(scsi_CDs[MINOR(cdi->dev)].device->host->hostt->module);
diff -u --recursive --new-file v2.4.9/linux/drivers/sgi/char/ds1286.c linux/drivers/sgi/char/ds1286.c
--- v2.4.9/linux/drivers/sgi/char/ds1286.c	Mon Aug 27 12:41:45 2001
+++ linux/drivers/sgi/char/ds1286.c	Mon Aug 27 08:56:31 2001
@@ -1,32 +1,30 @@
-/* $Id: ds1286.c,v 1.6 1999/10/09 00:01:31 ralf Exp $
- *
- *	Real Time Clock interface for Linux	
+/*
+ * DS1286 Real Time Clock interface for Linux	
  *
- *	Copyright (C) 1998, 1999 Ralf Baechle
+ * Copyright (C) 1998, 1999, 2000 Ralf Baechle
  *	
- *	Based on code written by Paul Gortmaker.
+ * 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 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.
  *
- *	The ioctls can be used to set the interrupt behaviour and
- *	generation rate from the RTC via IRQ 8. Then the /dev/rtc
- *	interface can be used to make use of these timer interrupts,
- *	be they interval or alarm based.
+ * The ioctls can be used to set the interrupt behaviour and generation rate
+ * from the RTC via IRQ 8. Then the /dev/rtc interface can be used to make
+ * use of these timer interrupts, be they interval or alarm based.
  *
- *	The /dev/rtc interface will block on reads until an interrupt
- *	has been received. If a RTC interrupt has already happened,
- *	it will output an unsigned long and then block. The output value
- *	contains the interrupt status in the low byte and the number of
- *	interrupts since the last read in the remaining high bytes. The 
- *	/dev/rtc interface can also be used with the select(2) call.
+ * The /dev/rtc interface will block on reads until an interrupt has been
+ * received. If a RTC interrupt has already happened, it will output an
+ * unsigned long and then block. The output value contains the interrupt
+ * status in the low byte and the number of interrupts since the last read
+ * in the remaining high bytes. The /dev/rtc interface can also be used with
+ * the select(2) call.
  *
- *	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 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/types.h>
 #include <linux/errno.h>
@@ -38,7 +36,6 @@
 #include <linux/poll.h>
 #include <linux/rtc.h>
 #include <linux/spinlock.h>
-#include <linux/smp_lock.h>
 
 #include <asm/ds1286.h>
 #include <asm/io.h>
@@ -81,58 +78,20 @@
 #define RTC_IS_OPEN		0x01	/* means /dev/rtc is in use	*/
 #define RTC_TIMER_ON		0x02	/* missed irq timer active	*/
 
-unsigned char ds1286_status = 0;	/* bitmapped status byte.	*/
-unsigned long ds1286_freq = 0;		/* Current periodic IRQ rate	*/
-unsigned long ds1286_irq_data = 0;	/* our output to the world	*/
+unsigned char ds1286_status;		/* bitmapped status byte.	*/
+unsigned long ds1286_freq;		/* Current periodic IRQ rate	*/
 
 unsigned char days_in_mo[] = 
 {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
 
 /*
- *	A very tiny interrupt handler. It runs with SA_INTERRUPT set,
- *	so that there is no possibility of conflicting with the
- *	set_rtc_mmss() call that happens during some timer interrupts.
- *	(See ./arch/XXXX/kernel/time.c for the set_rtc_mmss() function.)
- */
-
-/*
  *	Now all the various file operations that we export.
  */
 
 static ssize_t ds1286_read(struct file *file, char *buf,
                            size_t count, loff_t *ppos)
 {
-	DECLARE_WAITQUEUE(wait, current);
-	unsigned long data;
-	ssize_t retval;
-	
-	if (count < sizeof(unsigned long))
-		return -EINVAL;
-
-	add_wait_queue(&ds1286_wait, &wait);
-
-	current->state = TASK_INTERRUPTIBLE;
-		
-	while ((data = xchg(&ds1286_irq_data, 0)) == 0) {
-		if (file->f_flags & O_NONBLOCK) {
-			retval = -EAGAIN;
-			goto out;
-		}
-		if (signal_pending(current)) {
-			retval = -ERESTARTSYS;
-			goto out;
-		}
-		schedule();
-	}
-
-	retval = put_user(data, (unsigned long *)buf); 
-	if (!retval)
-		retval = sizeof(unsigned long); 
- out:
-	current->state = TASK_RUNNING;
-	remove_wait_queue(&ds1286_wait, &wait);
-
-	return retval;
+	return -EIO;
 }
 
 static int ds1286_ioctl(struct inode *inode, struct file *file,
@@ -338,27 +297,32 @@
 
 static int ds1286_open(struct inode *inode, struct file *file)
 {
-	if(ds1286_status & RTC_IS_OPEN)
-		return -EBUSY;
+	spin_lock_irq(&ds1286_lock);
+
+	if (ds1286_status & RTC_IS_OPEN)
+		goto out_busy;
 
 	ds1286_status |= RTC_IS_OPEN;
-	ds1286_irq_data = 0;
+
+	spin_lock_irq(&ds1286_lock);
 	return 0;
+
+out_busy:
+	spin_lock_irq(&ds1286_lock);
+	return -EBUSY;
 }
 
 static int ds1286_release(struct inode *inode, struct file *file)
 {
-	lock_kernel();
 	ds1286_status &= ~RTC_IS_OPEN;
-	unlock_kernel();
+
 	return 0;
 }
 
 static unsigned int ds1286_poll(struct file *file, poll_table *wait)
 {
 	poll_wait(file, &ds1286_wait, wait);
-	if (ds1286_irq_data != 0)
-		return POLLIN | POLLRDNORM;
+
 	return 0;
 }
 
@@ -407,7 +371,7 @@
 
 	get_rtc_time(&tm);
 	hundredth = CMOS_READ(RTC_HUNDREDTH_SECOND);
-	hundredth = BCD_TO_BIN(hundredth);
+	BCD_TO_BIN(hundredth);
 
 	p += sprintf(p,
 	             "rtc_time\t: %02d:%02d:%02d.%02d\n"
diff -u --recursive --new-file v2.4.9/linux/drivers/sgi/char/graphics.c linux/drivers/sgi/char/graphics.c
--- v2.4.9/linux/drivers/sgi/char/graphics.c	Mon Mar 19 12:35:09 2001
+++ linux/drivers/sgi/char/graphics.c	Mon Aug 27 08:56:31 2001
@@ -1,5 +1,4 @@
-/* $Id: graphics.c,v 1.22 2000/02/18 00:24:43 ralf Exp $
- *
+/*
  * gfx.c: support for SGI's /dev/graphics, /dev/opengl
  *
  * Author: Miguel de Icaza (miguel@nuclecu.unam.mx)
@@ -214,8 +213,7 @@
 /* 
  * This is the core of the direct rendering engine.
  */
-
-unsigned long
+struct page *
 sgi_graphics_nopage (struct vm_area_struct *vma, unsigned long address, int
 		     no_share)
 {
@@ -250,7 +248,6 @@
 	pgd = pgd_offset(current->mm, address);
 	pmd = pmd_offset(pgd, address);
 	pte = pte_offset(pmd, address);
-	printk("page: %08lx\n", pte_page(*pte));
 	return pte_page(*pte);
 }
 
diff -u --recursive --new-file v2.4.9/linux/drivers/sgi/char/graphics_syms.c linux/drivers/sgi/char/graphics_syms.c
--- v2.4.9/linux/drivers/sgi/char/graphics_syms.c	Mon Feb 28 07:18:20 2000
+++ linux/drivers/sgi/char/graphics_syms.c	Wed Dec 31 16:00:00 1969
@@ -1,35 +0,0 @@
-/*
- * graphics_syms.c: interfaces for SGI Indy newport graphics
- *
- * Copyright (C) 1999 Alex deVries <puffin@redhat.com>
- *
- * We should not even be trying to compile this if we are not doing
- * a module.
- */
-
-#define __NO_VERSION__
-#include <linux/module.h>
-
-/* extern int rrm_command (unsigned int cmd, void *arg);
-extern int rrm_close (struct inode *inode, struct file *file);
-EXPORT_SYMBOL(rrm_command);
-EXPORT_SYMBOL(rrm_close);
-
-
-*/
-extern void shmiq_init (void);
-extern void usema_init(void);
-
-EXPORT_SYMBOL(shmiq_init);
-EXPORT_SYMBOL(usema_init);
-
-extern void disable_gconsole(void);
-extern void enable_gconsole(void);
-extern void remove_mapping (struct task_struct *task, unsigned long start,
-      unsigned long end);
-
-EXPORT_SYMBOL(disable_gconsole);
-EXPORT_SYMBOL(enable_gconsole);
-EXPORT_SYMBOL(remove_mapping);
-
-EXPORT_SYMBOL(npregs);
diff -u --recursive --new-file v2.4.9/linux/drivers/sgi/char/newport.c linux/drivers/sgi/char/newport.c
--- v2.4.9/linux/drivers/sgi/char/newport.c	Mon Feb 28 07:18:20 2000
+++ linux/drivers/sgi/char/newport.c	Mon Aug 27 08:56:31 2001
@@ -16,6 +16,8 @@
 
 struct newport_regs *npregs;
 
+EXPORT_SYMBOL(npregs);
+
 /* Kernel routines for supporting graphics context switching */
 
 void newport_save (void *y)
diff -u --recursive --new-file v2.4.9/linux/drivers/sgi/char/rrm.c linux/drivers/sgi/char/rrm.c
--- v2.4.9/linux/drivers/sgi/char/rrm.c	Tue Aug 29 14:09:15 2000
+++ linux/drivers/sgi/char/rrm.c	Mon Aug 27 08:56:31 2001
@@ -9,12 +9,11 @@
  *
  * Fixes:
  */
+#include <linux/module.h>
+
 #include <asm/uaccess.h>
 #include <asm/rrm.h>
 
-#ifdef MODULE
-#include <linux/module.h>
-#endif
 
 int
 rrm_open_rn (int rnid, void *arg)
@@ -71,3 +70,6 @@
 	/* This routine is invoked when the device is closed */
 	return 0;
 }
+
+EXPORT_SYMBOL(rrm_command);
+EXPORT_SYMBOL(rrm_close);
diff -u --recursive --new-file v2.4.9/linux/drivers/sgi/char/sgicons.c linux/drivers/sgi/char/sgicons.c
--- v2.4.9/linux/drivers/sgi/char/sgicons.c	Sun Jul  9 22:32:58 2000
+++ linux/drivers/sgi/char/sgicons.c	Mon Aug 27 08:56:31 2001
@@ -1,5 +1,4 @@
-/* $Id: sgicons.c,v 1.10 1998/08/25 09:18:58 ralf Exp $
- *
+/*
  * sgicons.c: Setting up and registering console I/O on the SGI.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
@@ -10,12 +9,10 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
+#include <linux/module.h>
 #include <asm/uaccess.h>
 #include "gconsole.h"
 
-/* To make psaux code cleaner */
-unsigned char aux_device_present = 0xaa;
-
 /* This is the system graphics console (the first adapter found) */
 struct console_ops *gconsole = 0;
 struct console_ops *real_gconsole = 0;
@@ -35,6 +32,9 @@
 		gconsole = 0;
 	}
 }
+
+EXPORT_SYMBOL(disable_gconsole);
+EXPORT_SYMBOL(enable_gconsole);
 
 void
 register_gconsole (struct console_ops *gc)
diff -u --recursive --new-file v2.4.9/linux/drivers/sgi/char/sgiserial.c linux/drivers/sgi/char/sgiserial.c
--- v2.4.9/linux/drivers/sgi/char/sgiserial.c	Thu Oct 12 14:20:47 2000
+++ linux/drivers/sgi/char/sgiserial.c	Mon Aug 27 08:56:31 2001
@@ -13,6 +13,9 @@
  * 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
+ *
+ * 20010616 - Klaus Naumann <spock@mgnet.de> : Make serial console work with
+ *                                             any speed - not only 9600
  */
 
 #include <linux/config.h> /* for CONFIG_REMOTE_DEBUG */
@@ -58,9 +61,9 @@
 static int zilog_irq = SGI_SERIAL_IRQ;
 
 /* Console hooks... */
-static int zs_cons_chanout = 0;
-static int zs_cons_chanin = 0;
-struct sgi_serial *zs_consinfo = 0;
+static int zs_cons_chanout;
+static int zs_cons_chanin;
+struct sgi_serial *zs_consinfo;
 
 static unsigned char kgdb_regs[16] = {
 	0, 0, 0,                     /* write 0, 1, 2 */
@@ -97,6 +100,7 @@
 DECLARE_TASK_QUEUE(tq_serial);
 
 struct tty_driver serial_driver, callout_driver;
+struct console *sgisercon;
 static int serial_refcount;
 
 /* serial subtype definitions */
@@ -144,10 +148,10 @@
 					dev_t device, const char *routine)
 {
 #ifdef SERIAL_PARANOIA_CHECK
-	static const char *badmagic =
+	static const char *badmagic = KERN_WARNING
 		"Warning: bad magic number for serial struct (%d, %d) in %s\n";
-	static const char *badinfo =
-		"Warning: null sun_serial for (%d, %d) in %s\n";
+	static const char *badinfo = KERN_WARNING
+		"Warning: null sgi_serial for (%d, %d) in %s\n";
 
 	if (!info) {
 		printk(badinfo, MAJOR(device), MINOR(device), routine);
@@ -178,7 +182,8 @@
  * interrupts are enabled. Therefore we have to check ioc_iocontrol before we
  * access it.
  */
-static inline unsigned char read_zsreg(struct sgi_zschannel *channel, unsigned char reg)
+static inline unsigned char read_zsreg(struct sgi_zschannel *channel,
+                                       unsigned char reg)
 {
 	unsigned char retval;
 	volatile unsigned char junk;
@@ -192,7 +197,8 @@
 	return retval;
 }
 
-static inline void write_zsreg(struct sgi_zschannel *channel, unsigned char reg, unsigned char value)
+static inline void write_zsreg(struct sgi_zschannel *channel,
+                               unsigned char reg, unsigned char value)
 {
 	volatile unsigned char junk;
 
@@ -323,7 +329,7 @@
  */
 static void batten_down_hatches(void)
 {
-	prom_imode();
+	ArcEnterInteractiveMode();
 #if 0
 	/* If we are doing kadb, we call the debugger
 	 * else we just drop into the boot monitor.
@@ -682,7 +688,7 @@
 	save_flags(flags); cli();
 
 #ifdef SERIAL_DEBUG_OPEN
-	printk("starting up ttys%d (irq %d)...", info->line, info->irq);
+	printk("starting up ttys%d (irq %d)...\n", info->line, info->irq);
 #endif
 
 	/*
@@ -1302,6 +1308,59 @@
 	junk = ioc_icontrol->istat0;
 	sti();
 	return put_user(status,value);
+} 
+
+static int get_modem_info(struct sgi_serial * info, unsigned int *value)
+{
+	unsigned char status;
+	unsigned int result;
+
+	cli();
+	status = info->zs_channel->control;
+	udelay(2);
+	sti();
+	result =  ((info->curregs[5] & RTS) ? TIOCM_RTS : 0)
+		| ((info->curregs[5] & DTR) ? TIOCM_DTR : 0)
+		| ((status  & DCD) ? TIOCM_CAR : 0)
+		| ((status  & SYNC) ? TIOCM_DSR : 0)
+		| ((status  & CTS) ? TIOCM_CTS : 0);
+	if (put_user(result, value))
+		return -EFAULT;
+	return 0;
+}
+
+static int set_modem_info(struct sgi_serial * info, unsigned int cmd,
+			  unsigned int *value)
+{
+	unsigned int arg;
+
+	if (get_user(arg, value))
+		return -EFAULT;
+	switch (cmd) {
+	case TIOCMBIS: 
+		if (arg & TIOCM_RTS)
+			info->curregs[5] |= RTS;
+		if (arg & TIOCM_DTR)
+			info->curregs[5] |= DTR;
+		break;
+	case TIOCMBIC:
+		if (arg & TIOCM_RTS)
+			info->curregs[5] &= ~RTS;
+		if (arg & TIOCM_DTR)
+			info->curregs[5] &= ~DTR;
+		break;
+	case TIOCMSET:
+		info->curregs[5] = ((info->curregs[5] & ~(RTS | DTR))
+			     | ((arg & TIOCM_RTS) ? RTS : 0)
+			     | ((arg & TIOCM_DTR) ? DTR : 0));
+		break;
+	default:
+		return -EINVAL;
+	}
+	cli();
+	write_zsreg(info->zs_channel, 5, info->curregs[5]);
+	sti();
+	return 0;
 }
 
 /*
@@ -1322,11 +1381,10 @@
 static int rs_ioctl(struct tty_struct *tty, struct file * file,
 		    unsigned int cmd, unsigned long arg)
 {
-	int error;
-	struct sgi_serial * info = (struct sgi_serial *)tty->driver_data;
+	struct sgi_serial * info = (struct sgi_serial *) tty->driver_data;
 	int retval;
 
-	if (serial_paranoia_check(info, tty->device, "rs_ioctl"))
+	if (serial_paranoia_check(info, tty->device, "zs_ioctl"))
 		return -ENODEV;
 
 	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
@@ -1353,45 +1411,36 @@
 			send_break(info, arg ? arg*(HZ/10) : HZ/4);
 			return 0;
 		case TIOCGSOFTCAR:
-			error = verify_area(VERIFY_WRITE, (void *) arg,sizeof(long));
-			if (error)
-				return error;
-			put_user(C_CLOCAL(tty) ? 1 : 0,
-			         (unsigned long *) arg);
+			if (put_user(C_CLOCAL(tty) ? 1 : 0,
+				     (unsigned long *) arg))
+				return -EFAULT;
 			return 0;
 		case TIOCSSOFTCAR:
-			error = get_user(arg, (unsigned long *)arg);
-			if (error)
-				return error;
+			if (get_user(arg, (unsigned long *) arg))
+				return -EFAULT;
 			tty->termios->c_cflag =
 				((tty->termios->c_cflag & ~CLOCAL) |
 				 (arg ? CLOCAL : 0));
 			return 0;
+		case TIOCMGET:
+			return get_modem_info(info, (unsigned int *) arg);
+		case TIOCMBIS:
+		case TIOCMBIC:
+		case TIOCMSET:
+			return set_modem_info(info, cmd, (unsigned int *) arg);
 		case TIOCGSERIAL:
-			error = verify_area(VERIFY_WRITE, (void *) arg,
-						sizeof(struct serial_struct));
-			if (error)
-				return error;
 			return get_serial_info(info,
 					       (struct serial_struct *) arg);
 		case TIOCSSERIAL:
 			return set_serial_info(info,
 					       (struct serial_struct *) arg);
 		case TIOCSERGETLSR: /* Get line status register */
-			error = verify_area(VERIFY_WRITE, (void *) arg,
-				sizeof(unsigned int));
-			if (error)
-				return error;
-			else
-			    return get_lsr_info(info, (unsigned int *) arg);
+			return get_lsr_info(info, (unsigned int *) arg);
 
 		case TIOCSERGSTRUCT:
-			error = verify_area(VERIFY_WRITE, (void *) arg,
-						sizeof(struct sgi_serial));
-			if (error)
-				return error;
-			copy_to_user((struct sun_serial *) arg,
-				    info, sizeof(struct sgi_serial));
+			if (copy_to_user((struct sgi_serial *) arg,
+				    info, sizeof(struct sgi_serial)))
+				return -EFAULT;
 			return 0;
 			
 		default:
@@ -1727,11 +1776,19 @@
 		change_speed(info);
 	}
 
+	/* If this is the serial console change the speed to 
+	 * the right value
+	 */
+	if (info->is_cons) {
+		info->tty->termios->c_cflag = sgisercon->cflag;
+		change_speed(info);		
+	}
+
 	info->session = current->session;
 	info->pgrp = current->pgrp;
 
 #ifdef SERIAL_DEBUG_OPEN
-	printk("rs_open ttys%d successful...", info->line);
+	printk("rs_open ttys%d successful...\n", info->line);
 #endif
 	return 0;
 }
@@ -1748,13 +1805,10 @@
 {
 	extern struct hpc3_miscregs *hpc3mregs;
 
-	if(chip > 0) {
-		prom_printf("Wheee, bogus zs chip number requested.\n");
-		prom_getchar();
-		romvec->imode();
-	}
-	return (struct sgi_zslayout *) (&hpc3mregs->ser1cmd);
+	if (chip > 0)
+		panic("Wheee, bogus zs chip number requested.");
 
+	return (struct sgi_zslayout *) (&hpc3mregs->ser1cmd);
 }
 
 
@@ -1784,13 +1838,6 @@
 	}
 	if(o && i)
 		io = 1;
-	if(ss->zs_baud != 9562) { /* Don't ask... */
-		prom_printf("BAD console baud rate %d\n", ss->zs_baud);
-		prom_getchar();
-		prom_imode();
-		panic("Console baud rate weirdness");
-	}
-
 
 	/* Set flag variable for this port so that it cannot be
 	 * opened for other uses by accident.
@@ -1798,7 +1845,7 @@
 	ss->is_cons = 1;
 
 	if(io) {
-		if(!msg_printed) {
+		if (!msg_printed) {
 			printk("zs%d: console I/O\n", ((channel>>1)&1));
 			msg_printed = 1;
 		}
@@ -1806,7 +1853,6 @@
 	} else {
 		printk("zs%d: console %s\n", ((channel>>1)&1),
 		       (i==1 ? "input" : (o==1 ? "output" : "WEIRD")));
-
 	}
 }
 
@@ -2002,7 +2048,6 @@
 rs_cons_hook(int chip, int out, int line)
 {
 	int channel;
-
 	
 	if(chip)
 		panic("rs_cons_hook called with chip not zero");
@@ -2087,11 +2132,11 @@
 static int __init zs_console_setup(struct console *con, char *options)
 {
 	struct sgi_serial *info;
-	int	baud = 9600;
+	int	baud;
 	int	bits = 8;
 	int	parity = 'n';
 	int	cflag = CREAD | HUPCL | CLOCAL;
-	char	*s;
+	char	*s, *dbaud;
 	int     i, brg;
     
 	if (options) {
@@ -2102,6 +2147,21 @@
 		if (*s) parity = *s++;
 		if (*s) bits   = *s - '0';
 	}
+	else {
+		/* If the user doesn't set console=... try to read the
+		 * PROM variable - if this fails use 9600 baud and
+		 * inform the user about the problem
+		 */
+		dbaud = ArcGetEnvironmentVariable("dbaud");
+		if(dbaud) baud = simple_strtoul(dbaud, NULL, 10);
+		else {
+			/* Use prom_printf() to make sure that the user
+			 * is getting anything ...
+			 */
+			prom_printf("No dbaud set in PROM ?!? Using 9600.\n");
+			baud = 9600;
+		}
+	}
 
 	/*
 	 *	Now construct a cflag setting.
@@ -2156,7 +2216,8 @@
 	info = zs_soft + con->index;
 	info->is_cons = 1;
     
-	printk("Console: ttyS%d (Zilog8530)\n", info->line);
+	printk("Console: ttyS%d (Zilog8530), %d baud\n", 
+						info->line, baud);
 
 	i = con->cflag & CBAUD;
 	if (con->cflag & CBAUDEX) {
@@ -2195,6 +2256,8 @@
 		zscons_regs[4] |= SB2;
 	else
 		zscons_regs[4] |= SB1;
+	
+	sgisercon = con;
 
 	brg = BPS_TO_BRG(baud, ZS_CLOCK / info->clk_divisor);
 	zscons_regs[12] = brg & 0xff;
diff -u --recursive --new-file v2.4.9/linux/drivers/sgi/char/sgiserial.h linux/drivers/sgi/char/sgiserial.h
--- v2.4.9/linux/drivers/sgi/char/sgiserial.h	Fri Jun 25 17:39:34 1999
+++ linux/drivers/sgi/char/sgiserial.h	Mon Aug 27 08:56:31 2001
@@ -359,7 +359,7 @@
 #define	ZCOUNT		0x2	/* Zero count */
 #define	Tx_BUF_EMP	0x4	/* Tx Buffer empty */
 #define	DCD		0x8	/* DCD */
-#define	SYNC_HUNT	0x10	/* Sync/hunt */
+#define	SYNC		0x10	/* Sync/hunt */
 #define	CTS		0x20	/* CTS */
 #define	TxEOM		0x40	/* Tx underrun */
 #define	BRK_ABRT	0x80	/* Break/Abort */
diff -u --recursive --new-file v2.4.9/linux/drivers/sgi/char/shmiq.c linux/drivers/sgi/char/shmiq.c
--- v2.4.9/linux/drivers/sgi/char/shmiq.c	Mon Mar 19 12:35:09 2001
+++ linux/drivers/sgi/char/shmiq.c	Mon Aug 27 08:56:31 2001
@@ -1,5 +1,4 @@
-/* $Id: shmiq.c,v 1.19 2000/02/23 00:41:21 ralf Exp $
- *
+/*
  * shmiq.c: shared memory input queue driver
  * written 1997 Miguel de Icaza (miguel@nuclecu.unam.mx)
  *
@@ -42,7 +41,6 @@
  * Until then, I just allow for 1 qcntl device.
  *
  */
-
 #include <linux/fs.h>
 #include <linux/miscdevice.h>
 #include <linux/sched.h>
@@ -52,6 +50,7 @@
 #include <linux/vmalloc.h>
 #include <linux/wait.h>
 #include <linux/major.h>
+#include <linux/module.h>
 #include <linux/smp_lock.h>
 #include <linux/devfs_fs_kernel.h>
 
@@ -470,3 +469,5 @@
 			       S_IFCHR | S_IRUSR | S_IWUSR,
 			       &shmiq_fops, NULL);
 }
+
+EXPORT_SYMBOL(shmiq_init);
diff -u --recursive --new-file v2.4.9/linux/drivers/sgi/char/usema.c linux/drivers/sgi/char/usema.c
--- v2.4.9/linux/drivers/sgi/char/usema.c	Wed Jul 12 21:58:43 2000
+++ linux/drivers/sgi/char/usema.c	Mon Aug 27 08:56:31 2001
@@ -20,8 +20,7 @@
  * usema(7m), usinit(3p), usnewsema(3p)
  * /usr/include/sys/usioctl.h 
  *
-*/
-
+ */
 #include <linux/fs.h>
 #include <linux/miscdevice.h>
 #include <linux/sched.h>
@@ -31,6 +30,7 @@
 #include <linux/string.h>
 #include <linux/dcache.h>
 #include <linux/mm.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include "usema.h"
@@ -180,3 +180,5 @@
 	       SGI_USEMACLONE);
 	misc_register(&dev_usemaclone);
 }
+
+EXPORT_SYMBOL(usema_init);
diff -u --recursive --new-file v2.4.9/linux/drivers/sound/Config.in linux/drivers/sound/Config.in
--- v2.4.9/linux/drivers/sound/Config.in	Mon Aug 27 12:41:45 2001
+++ linux/drivers/sound/Config.in	Fri Sep  7 09:28:37 2001
@@ -45,6 +45,9 @@
 if [ "$CONFIG_VISWS" = "y" ]; then
     dep_tristate '  SGI Visual Workstation Sound' CONFIG_SOUND_VWSND $CONFIG_SOUND
 fi
+if [ "$CONFIG_DDB5477" = "y" ]; then
+    dep_tristate '  NEC Vrc5477 AC97 sound' CONFIG_SOUND_VRC5477 $CONFIG_SOUND
+fi
 dep_tristate '  Trident 4DWave DX/NX, SiS 7018 or ALi 5451 PCI Audio Core' CONFIG_SOUND_TRIDENT $CONFIG_SOUND
 
 dep_tristate '  Support for Turtle Beach MultiSound Classic, Tahiti, Monterey' CONFIG_SOUND_MSNDCLAS $CONFIG_SOUND
diff -u --recursive --new-file v2.4.9/linux/drivers/sound/ac97.h linux/drivers/sound/ac97.h
--- v2.4.9/linux/drivers/sound/ac97.h	Mon Dec 11 13:02:32 2000
+++ linux/drivers/sound/ac97.h	Fri Sep  7 09:28:37 2001
@@ -39,7 +39,7 @@
 #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_LR_ADC_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 */
diff -u --recursive --new-file v2.4.9/linux/drivers/sound/ac97_codec.c linux/drivers/sound/ac97_codec.c
--- v2.4.9/linux/drivers/sound/ac97_codec.c	Mon Aug 27 12:41:45 2001
+++ linux/drivers/sound/ac97_codec.c	Fri Sep  7 09:28:37 2001
@@ -104,6 +104,7 @@
 	{0x41445303, "Analog Devices AD1819",	&null_ops},
 	{0x41445340, "Analog Devices AD1881",	&null_ops},
 	{0x41445348, "Analog Devices AD1881A",	&null_ops},
+	{0x41445360, "Analog Devices AD1885",	&default_ops},
 	{0x41445460, "Analog Devices AD1885",	&default_ops},
 	{0x414B4D00, "Asahi Kasei AK4540",	&null_ops},
 	{0x414B4D01, "Asahi Kasei AK4542",	&null_ops},
@@ -937,3 +938,85 @@
 
 EXPORT_SYMBOL(ac97_read_proc);
 EXPORT_SYMBOL(ac97_probe_codec);
+
+/*
+ *	AC97 library support routines
+ */	
+ 
+/**
+ *	ac97_set_dac_rate	-	set codec rate adaption
+ *	@codec: ac97 code
+ *	@rate: rate in hertz
+ *
+ *	Set the DAC rate. Assumes the codec supports VRA. The caller is
+ *	expected to have checked this little detail.
+ */
+ 
+unsigned int ac97_set_dac_rate(struct ac97_codec *codec, unsigned int rate)
+{
+	unsigned int new_rate = rate;
+	u32 dacp;
+	u32 mast_vol, phone_vol, mono_vol, pcm_vol;
+	u32 mute_vol = 0x8000;	/* The mute volume? */
+
+	if(rate != codec->codec_read(codec, AC97_PCM_FRONT_DAC_RATE))
+	{
+		/* Mute several registers */
+		mast_vol = codec->codec_read(codec, AC97_MASTER_VOL_STEREO);
+		mono_vol = codec->codec_read(codec, AC97_MASTER_VOL_MONO);
+		phone_vol = codec->codec_read(codec, AC97_HEADPHONE_VOL);
+		pcm_vol = codec->codec_read(codec, AC97_PCMOUT_VOL);
+		codec->codec_write(codec, AC97_MASTER_VOL_STEREO, mute_vol);
+		codec->codec_write(codec, AC97_MASTER_VOL_MONO, mute_vol);
+		codec->codec_write(codec, AC97_HEADPHONE_VOL, mute_vol);
+		codec->codec_write(codec, AC97_PCMOUT_VOL, mute_vol);
+		
+		/* Power down the DAC */
+		dacp=codec->codec_read(codec, AC97_POWER_CONTROL);
+		codec->codec_write(codec, AC97_POWER_CONTROL, dacp|0x0200);
+		/* Load the rate and read the effective rate */
+		codec->codec_write(codec, AC97_PCM_FRONT_DAC_RATE, rate);
+		new_rate=codec->codec_read(codec, AC97_PCM_FRONT_DAC_RATE);
+		/* Power it back up */
+		codec->codec_write(codec, AC97_POWER_CONTROL, dacp);
+
+		/* Restore volumes */
+		codec->codec_write(codec, AC97_MASTER_VOL_STEREO, mast_vol);
+		codec->codec_write(codec, AC97_MASTER_VOL_MONO, mono_vol);
+		codec->codec_write(codec, AC97_HEADPHONE_VOL, phone_vol);
+		codec->codec_write(codec, AC97_PCMOUT_VOL, pcm_vol);
+	}
+	return new_rate;
+}
+
+EXPORT_SYMBOL(ac97_set_dac_rate);
+
+/**
+ *	ac97_set_adc_rate	-	set codec rate adaption
+ *	@codec: ac97 code
+ *	@rate: rate in hertz
+ *
+ *	Set the ADC rate. Assumes the codec supports VRA. The caller is
+ *	expected to have checked this little detail.
+ */
+
+unsigned int ac97_set_adc_rate(struct ac97_codec *codec, unsigned int rate)
+{
+	unsigned int new_rate = rate;
+	u32 dacp;
+
+	if(rate != codec->codec_read(codec, AC97_PCM_LR_ADC_RATE))
+	{
+		/* Power down the ADC */
+		dacp=codec->codec_read(codec, AC97_POWER_CONTROL);
+		codec->codec_write(codec, AC97_POWER_CONTROL, dacp|0x0100);
+		/* Load the rate and read the effective rate */
+		codec->codec_write(codec, AC97_PCM_LR_ADC_RATE, rate);
+		new_rate=codec->codec_read(codec, AC97_PCM_LR_ADC_RATE);
+		/* Power it back up */
+		codec->codec_write(codec, AC97_POWER_CONTROL, dacp);
+	}
+	return new_rate;
+}
+
+EXPORT_SYMBOL(ac97_set_adc_rate);
diff -u --recursive --new-file v2.4.9/linux/drivers/sound/ad1848.c linux/drivers/sound/ad1848.c
--- v2.4.9/linux/drivers/sound/ad1848.c	Wed Jul 25 17:10:23 2001
+++ linux/drivers/sound/ad1848.c	Fri Sep  7 09:28:37 2001
@@ -29,6 +29,7 @@
  * Christoph Hellwig	: adapted to module_init/module_exit
  * Aki Laukkanen	: added power management support
  * Arnaldo C. de Melo	: added missing restore_flags in ad1848_resume
+ * Miguel Freitas       : added ISA PnP support
  *
  * Status:
  *		Tested. Believed fully functional.
@@ -39,6 +40,7 @@
 #include <linux/module.h>
 #include <linux/stddef.h>
 #include <linux/pm.h>
+#include <linux/isapnp.h>
 
 #define DEB(x)
 #define DEB1(x)
@@ -160,6 +162,18 @@
     ,{CAP_F_TIMER} /* MD_1845_SSCAPE */
 };
 
+#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+static int isapnp	= 1;
+static int isapnpjump	= 0;
+static int reverse	= 0;
+
+static int audio_activated = 0;
+#else
+static int isapnp	= 0;
+#endif
+
+
+
 static int      ad1848_open(int dev, int mode);
 static void     ad1848_close(int dev);
 static void     ad1848_output_block(int dev, unsigned long buf, int count, int intrflag);
@@ -2812,34 +2826,207 @@
 MODULE_PARM(dma, "i");                  /* First DMA channel */
 MODULE_PARM(dma2, "i");                 /* Second DMA channel */
 MODULE_PARM(type, "i");                 /* Card type */
-MODULE_PARM(deskpro_xl, "i");           /* Special magic for Deskpro XL boxen
-*/
+MODULE_PARM(deskpro_xl, "i");           /* Special magic for Deskpro XL boxen */
 MODULE_PARM(deskpro_m, "i");            /* Special magic for Deskpro M box */
-MODULE_PARM(soundpro, "i");             /* More special magic for SoundPro
-chips */
+MODULE_PARM(soundpro, "i");             /* More special magic for SoundPro chips */
+
+#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+MODULE_PARM(isapnp,	"i");
+MODULE_PARM(isapnpjump,	"i");
+MODULE_PARM(reverse,	"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(reverse,	"When set to 1, will reverse ISAPnP search order");
+
+struct pci_dev	*ad1848_dev  = NULL;
+
+/* Please add new entries at the end of the table */
+static struct {
+	char *name;
+	unsigned short	card_vendor, card_device,
+			vendor, function;
+	short mss_io, irq, dma, dma2;   /* index into isapnp table */
+        int type;
+} ad1848_isapnp_list[] __initdata = {
+	{"CMI 8330 SoundPRO",
+		ISAPNP_VENDOR('C','M','I'), ISAPNP_DEVICE(0x0001),
+		ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001),
+		0, 0, 0,-1, 0},
+        {"CS4232 based card",
+                ISAPNP_ANY_ID, ISAPNP_ANY_ID,
+		ISAPNP_VENDOR('C','S','C'), ISAPNP_FUNCTION(0x0000),
+		0, 0, 0, 1, 0},
+        {"CS4232 based card",
+                ISAPNP_ANY_ID, ISAPNP_ANY_ID,
+		ISAPNP_VENDOR('C','S','C'), ISAPNP_FUNCTION(0x0100),
+		0, 0, 0, 1, 0},
+        {"OPL3-SA2 WSS mode",
+        	ISAPNP_ANY_ID, ISAPNP_ANY_ID,
+		ISAPNP_VENDOR('Y','M','H'), ISAPNP_FUNCTION(0x0021),
+                1, 0, 0, 1, 1},
+	{0}
+};
+
+static struct isapnp_device_id id_table[] __devinitdata = {
+	{	ISAPNP_VENDOR('C','M','I'), ISAPNP_DEVICE(0x0001),
+		ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001), 0 },
+        {       ISAPNP_ANY_ID, ISAPNP_ANY_ID,
+		ISAPNP_VENDOR('C','S','C'), ISAPNP_FUNCTION(0x0000), 0 },
+        {       ISAPNP_ANY_ID, ISAPNP_ANY_ID,
+		ISAPNP_VENDOR('C','S','C'), ISAPNP_FUNCTION(0x0100), 0 },
+        {       ISAPNP_ANY_ID, ISAPNP_ANY_ID,
+		ISAPNP_VENDOR('Y','M','H'), ISAPNP_FUNCTION(0x0021), 0 },
+	{0}
+};
+
+MODULE_DEVICE_TABLE(isapnp, id_table);
+
+static struct pci_dev *activate_dev(char *devname, char *resname, struct pci_dev *dev)
+{
+	int err;
+
+	/* Device already active? Let's use it */
+	if(dev->active)
+		return(dev);
+
+	if((err = dev->activate(dev)) < 0) {
+		printk(KERN_ERR "ad1848: %s %s config failed (out of resources?)[%d]\n", devname, resname, err);
+
+		dev->deactivate(dev);
+
+		return(NULL);
+	}
+	return(dev);
+}
+
+static struct pci_dev *ad1848_init_generic(struct pci_bus *bus, struct address_info *hw_config, int slot)
+{
+
+	/* Configure Audio device */
+	if((ad1848_dev = isapnp_find_dev(bus, ad1848_isapnp_list[slot].vendor, ad1848_isapnp_list[slot].function, NULL)))
+	{
+		int ret;
+		ret = ad1848_dev->prepare(ad1848_dev);
+		/* If device is active, assume configured with /proc/isapnp
+		 * and use anyway. Some other way to check this? */
+		if(ret && ret != -EBUSY) {
+			printk(KERN_ERR "ad1848: ISAPnP found device that could not be autoconfigured.\n");
+			return(NULL);
+		}
+		if(ret == -EBUSY)
+			audio_activated = 1;
+
+		if((ad1848_dev = activate_dev(ad1848_isapnp_list[slot].name, "ad1848", ad1848_dev)))
+		{
+			hw_config->io_base 	= ad1848_dev->resource[ad1848_isapnp_list[slot].mss_io].start;
+			hw_config->irq 		= ad1848_dev->irq_resource[ad1848_isapnp_list[slot].irq].start;
+			hw_config->dma 		= ad1848_dev->dma_resource[ad1848_isapnp_list[slot].dma].start;
+			if(ad1848_isapnp_list[slot].dma2 != -1)
+				hw_config->dma2 = ad1848_dev->dma_resource[ad1848_isapnp_list[slot].dma2].start;
+			else
+				hw_config->dma2 = -1;
+                        hw_config->card_subtype = ad1848_isapnp_list[slot].type;
+		} else
+			return(NULL);
+	} else
+		return(NULL);
+
+	return(ad1848_dev);
+}
+
+static int __init ad1848_isapnp_init(struct address_info *hw_config, struct pci_bus *bus, int slot)
+{
+	char *busname = bus->name[0] ? bus->name : ad1848_isapnp_list[slot].name;
+
+	printk(KERN_INFO "ad1848: %s detected\n", busname);
+
+	/* Initialize this baby. */
+
+	if(ad1848_init_generic(bus, hw_config, slot)) {
+		/* We got it. */
+
+		printk(KERN_NOTICE "ad1848: ISAPnP reports '%s' at i/o %#x, irq %d, dma %d, %d\n",
+		       busname,
+		       hw_config->io_base, hw_config->irq, hw_config->dma,
+		       hw_config->dma2);
+		return 1;
+	}
+	else
+		printk(KERN_INFO "ad1848: Failed to initialize %s\n", busname);
+
+	return 0;
+}
+
+static int __init ad1848_isapnp_probe(struct address_info *hw_config)
+{
+	static int first = 1;
+	int i;
+
+	/* Count entries in sb_isapnp_list */
+	for (i = 0; ad1848_isapnp_list[i].card_vendor != 0; i++);
+	i--;
+
+	/* Check and adjust isapnpjump */
+	if( isapnpjump < 0 || isapnpjump > i) {
+		isapnpjump = reverse ? i : 0;
+		printk(KERN_ERR "ad1848: Valid range for isapnpjump is 0-%d. Adjusted to %d.\n", i, isapnpjump);
+	}
+
+	if(!first || !reverse)
+		i = isapnpjump;
+	first = 0;
+	while(ad1848_isapnp_list[i].card_vendor != 0) {
+		static struct pci_bus *bus = NULL;
+
+		while ((bus = isapnp_find_card(
+				ad1848_isapnp_list[i].card_vendor,
+				ad1848_isapnp_list[i].card_device,
+				bus))) {
+
+			if(ad1848_isapnp_init(hw_config, bus, i)) {
+				isapnpjump = i; /* start next search from here */
+				return 0;
+			}
+		}
+		i += reverse ? -1 : 1;
+	}
+
+	return -ENODEV;
+}
+#endif
+
 
 static int __init init_ad1848(void)
 {
 	printk(KERN_INFO "ad1848/cs4248 codec driver Copyright (C) by Hannu Savolainen 1993-1996\n");
 
+#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+	if(isapnp && (ad1848_isapnp_probe(&cfg) < 0) ) {
+		printk(KERN_NOTICE "ad1848: No ISAPnP cards found, trying standard ones...\n");
+		isapnp = 0;
+	}
+#endif
+
 	if(io != -1) {
-		if(irq == -1 || dma == -1) {
-			printk(KERN_WARNING "ad1848: must give I/O , IRQ and DMA.\n");
-			return -EINVAL;
-		}
+	        if( isapnp == 0 )
+	        {
+			if(irq == -1 || dma == -1) {
+				printk(KERN_WARNING "ad1848: must give I/O , IRQ and DMA.\n");
+				return -EINVAL;
+			}
 
-		cfg.irq = irq;
-		cfg.io_base = io;
-		cfg.dma = dma;
-		cfg.dma2 = dma2;
-		cfg.card_subtype = type;
+			cfg.irq = irq;
+			cfg.io_base = io;
+			cfg.dma = dma;
+			cfg.dma2 = dma2;
+			cfg.card_subtype = type;
+	        }
 
 		if(!probe_ms_sound(&cfg))
 			return -ENODEV;
 		attach_ms_sound(&cfg, THIS_MODULE);
 		loaded = 1;
 	}
-	
 	return 0;
 }
 
@@ -2847,6 +3034,12 @@
 {
 	if(loaded)
 		unload_ms_sound(&cfg);
+
+#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+	if(audio_activated)
+		if(ad1848_dev)
+			ad1848_dev->deactivate(ad1848_dev);
+#endif
 }
 
 module_init(init_ad1848);
diff -u --recursive --new-file v2.4.9/linux/drivers/sound/awe_wave.c linux/drivers/sound/awe_wave.c
--- v2.4.9/linux/drivers/sound/awe_wave.c	Fri Mar  2 11:12:11 2001
+++ linux/drivers/sound/awe_wave.c	Mon Aug 27 08:11:43 2001
@@ -4873,7 +4873,7 @@
 /* any three numbers you like */
 #define UNIQUE_ID1	0x1234
 #define UNIQUE_ID2	0x4321
-#define UNIQUE_ID3	0xFFFF
+#define UNIQUE_ID3	0xABCD
 
 static void __init
 awe_check_dram(void)
diff -u --recursive --new-file v2.4.9/linux/drivers/sound/cmpci.c linux/drivers/sound/cmpci.c
--- v2.4.9/linux/drivers/sound/cmpci.c	Mon Aug 27 12:41:45 2001
+++ linux/drivers/sound/cmpci.c	Fri Sep  7 09:28:37 2001
@@ -75,13 +75,14 @@
  *    		   was calling prog_dmabuf with s->lock held, call missing
  *    		   unlock_kernel in cm_midi_release
  *
- *    Fri May 25 2001 - Carlos Eduardo Gorges <carlos@techlinux.com.br>
- *    - some driver cleanups
- *    - spin[un]lock* revision ( fix SMP support )
- *    - cosmetic code changes
+ *	Carlos Eduardo Gorges <carlos@techlinux.com.br>
+ *	Fri May 25 2001 
+ *	- SMP support ( spin[un]lock* revision )
+ *	- speaker mixer support 
+ *	Mon Aug 13 2001
+ *	- optimizations and cleanups
  *
  */
-
 /*****************************************************************************/
       
 #include <linux/version.h>
@@ -104,119 +105,98 @@
 #include <linux/smp_lock.h>
 #include <asm/uaccess.h>
 #include <asm/hardirq.h>
+#include <linux/bitops.h>
 
 #include "dm.h"
 
 /* --------------------------------------------------------------------- */
-
 #undef OSS_DOCUMENTED_MIXER_SEMANTICS
-
+#undef DMABYTEIO
 /* --------------------------------------------------------------------- */
 
-#ifndef PCI_VENDOR_ID_CMEDIA
-#define PCI_VENDOR_ID_CMEDIA         0x13F6
-#endif
-#ifndef PCI_DEVICE_ID_CMEDIA_CM8338A
-#define PCI_DEVICE_ID_CMEDIA_CM8338A 0x0100
-#endif
-#ifndef PCI_DEVICE_ID_CMEDIA_CM8338B
-#define PCI_DEVICE_ID_CMEDIA_CM8338B 0x0101
-#endif
-#ifndef PCI_DEVICE_ID_CMEDIA_CM8738
-#define PCI_DEVICE_ID_CMEDIA_CM8738  0x0111
-#endif
-#ifndef PCI_DEVICE_ID_CMEDIA_CM8738B
-#define PCI_DEVICE_ID_CMEDIA_CM8738B 0x0112
-#endif
-
 #define CM_MAGIC  ((PCI_VENDOR_ID_CMEDIA<<16)|PCI_DEVICE_ID_CMEDIA_CM8338A)
 
-/*
- * CM8338 registers definition
- */
+/* CM8338 registers definition ****************/
 
-#define CODEC_CMI_FUNCTRL0      (0x00)
-#define CODEC_CMI_FUNCTRL1      (0x04)
-#define CODEC_CMI_CHFORMAT      (0x08)
-#define CODEC_CMI_INT_HLDCLR    (0x0C)
-#define CODEC_CMI_INT_STATUS    (0x10)
-#define CODEC_CMI_LEGACY_CTRL   (0x14)
-#define CODEC_CMI_MISC_CTRL     (0x18)
-#define CODEC_CMI_TDMA_POS      (0x1C)
-#define CODEC_CMI_MIXER         (0x20)
-#define CODEC_SB16_DATA         (0x22)
-#define CODEC_SB16_ADDR         (0x23)
-#define CODEC_CMI_MIXER1        (0x24)
-#define CODEC_CMI_MIXER2        (0x25)
-#define CODEC_CMI_AUX_VOL       (0x26)
-#define CODEC_CMI_MISC          (0x27)
-#define CODEC_CMI_AC97          (0x28)
-
-#define CODEC_CMI_CH0_FRAME1    (0x80)
-#define CODEC_CMI_CH0_FRAME2    (0x84)
-#define CODEC_CMI_CH1_FRAME1    (0x88)
-#define CODEC_CMI_CH1_FRAME2    (0x8C)
-
-#define CODEC_CMI_EXT_REG       (0xF0)
-#define UCHAR	unsigned char
-/*
-**  Mixer registers for SB16
-*/
-
-#define DSP_MIX_DATARESETIDX    ((UCHAR)(0x00))
-
-#define DSP_MIX_MASTERVOLIDX_L  ((UCHAR)(0x30))
-#define DSP_MIX_MASTERVOLIDX_R  ((UCHAR)(0x31))
-#define DSP_MIX_VOICEVOLIDX_L   ((UCHAR)(0x32))
-#define DSP_MIX_VOICEVOLIDX_R   ((UCHAR)(0x33))
-#define DSP_MIX_FMVOLIDX_L      ((UCHAR)(0x34))
-#define DSP_MIX_FMVOLIDX_R      ((UCHAR)(0x35))
-#define DSP_MIX_CDVOLIDX_L      ((UCHAR)(0x36))
-#define DSP_MIX_CDVOLIDX_R      ((UCHAR)(0x37))
-#define DSP_MIX_LINEVOLIDX_L    ((UCHAR)(0x38))
-#define DSP_MIX_LINEVOLIDX_R    ((UCHAR)(0x39))
-
-#define DSP_MIX_MICVOLIDX       ((UCHAR)(0x3A))
-#define DSP_MIX_SPKRVOLIDX      ((UCHAR)(0x3B))
-
-#define DSP_MIX_OUTMIXIDX       ((UCHAR)(0x3C))
-
-#define DSP_MIX_ADCMIXIDX_L     ((UCHAR)(0x3D))
-#define DSP_MIX_ADCMIXIDX_R     ((UCHAR)(0x3E))
-
-#define DSP_MIX_INGAINIDX_L     ((UCHAR)(0x3F))
-#define DSP_MIX_INGAINIDX_R     ((UCHAR)(0x40))
-#define DSP_MIX_OUTGAINIDX_L    ((UCHAR)(0x41))
-#define DSP_MIX_OUTGAINIDX_R    ((UCHAR)(0x42))
-
-#define DSP_MIX_AGCIDX          ((UCHAR)(0x43))
-
-#define DSP_MIX_TREBLEIDX_L     ((UCHAR)(0x44))
-#define DSP_MIX_TREBLEIDX_R     ((UCHAR)(0x45))
-#define DSP_MIX_BASSIDX_L       ((UCHAR)(0x46))
-#define DSP_MIX_BASSIDX_R       ((UCHAR)(0x47))
-#define CM_CH0_RESET	  0x04
-#define CM_CH1_RESET	  0x08
-#define CM_EXTENT_CODEC	  0x100
-#define CM_EXTENT_MIDI	  0x2
-#define CM_EXTENT_SYNTH	  0x4
-#define CM_INT_CH0	  1
-#define CM_INT_CH1	  2
-
-#define CM_CFMT_STEREO     0x01
-#define CM_CFMT_16BIT      0x02
-#define CM_CFMT_MASK       0x03
-#define CM_CFMT_DACSHIFT   2
-#define CM_CFMT_ADCSHIFT   0
+#define CODEC_CMI_FUNCTRL0		(0x00)
+#define CODEC_CMI_FUNCTRL1		(0x04)
+#define CODEC_CMI_CHFORMAT		(0x08)
+#define CODEC_CMI_INT_HLDCLR		(0x0C)
+#define CODEC_CMI_INT_STATUS		(0x10)
+#define CODEC_CMI_LEGACY_CTRL		(0x14)
+#define CODEC_CMI_MISC_CTRL		(0x18)
+#define CODEC_CMI_TDMA_POS		(0x1C)
+#define CODEC_CMI_MIXER			(0x20)
+#define CODEC_SB16_DATA			(0x22)
+#define CODEC_SB16_ADDR			(0x23)
+#define CODEC_CMI_MIXER1		(0x24)
+#define CODEC_CMI_MIXER2		(0x25)
+#define CODEC_CMI_AUX_VOL		(0x26)
+#define CODEC_CMI_MISC			(0x27)
+#define CODEC_CMI_AC97			(0x28)
+
+#define CODEC_CMI_CH0_FRAME1		(0x80)
+#define CODEC_CMI_CH0_FRAME2		(0x84)
+#define CODEC_CMI_CH1_FRAME1		(0x88)
+#define CODEC_CMI_CH1_FRAME2		(0x8C)
+
+#define CODEC_CMI_EXT_REG		(0xF0)
+
+/*  Mixer registers for SB16 ******************/
+
+#define DSP_MIX_DATARESETIDX		((unsigned char)(0x00))
+
+#define DSP_MIX_MASTERVOLIDX_L		((unsigned char)(0x30))
+#define DSP_MIX_MASTERVOLIDX_R		((unsigned char)(0x31))
+#define DSP_MIX_VOICEVOLIDX_L		((unsigned char)(0x32))
+#define DSP_MIX_VOICEVOLIDX_R		((unsigned char)(0x33))
+#define DSP_MIX_FMVOLIDX_L		((unsigned char)(0x34))
+#define DSP_MIX_FMVOLIDX_R		((unsigned char)(0x35))
+#define DSP_MIX_CDVOLIDX_L		((unsigned char)(0x36))
+#define DSP_MIX_CDVOLIDX_R		((unsigned char)(0x37))
+#define DSP_MIX_LINEVOLIDX_L		((unsigned char)(0x38))
+#define DSP_MIX_LINEVOLIDX_R		((unsigned char)(0x39))
+
+#define DSP_MIX_MICVOLIDX		((unsigned char)(0x3A))
+#define DSP_MIX_SPKRVOLIDX		((unsigned char)(0x3B))
+
+#define DSP_MIX_OUTMIXIDX		((unsigned char)(0x3C))
+
+#define DSP_MIX_ADCMIXIDX_L		((unsigned char)(0x3D))
+#define DSP_MIX_ADCMIXIDX_R		((unsigned char)(0x3E))
+
+#define DSP_MIX_INGAINIDX_L		((unsigned char)(0x3F))
+#define DSP_MIX_INGAINIDX_R		((unsigned char)(0x40))
+#define DSP_MIX_OUTGAINIDX_L		((unsigned char)(0x41))
+#define DSP_MIX_OUTGAINIDX_R		((unsigned char)(0x42))
+
+#define DSP_MIX_AGCIDX			((unsigned char)(0x43))
+
+#define DSP_MIX_TREBLEIDX_L		((unsigned char)(0x44))
+#define DSP_MIX_TREBLEIDX_R		((unsigned char)(0x45))
+#define DSP_MIX_BASSIDX_L		((unsigned char)(0x46))
+#define DSP_MIX_BASSIDX_R		((unsigned char)(0x47))
+
+#define CM_CH0_RESET			0x04
+#define CM_CH1_RESET			0x08
+#define CM_EXTENT_CODEC			0x100
+#define CM_EXTENT_MIDI			0x2
+#define CM_EXTENT_SYNTH			0x4
+#define CM_INT_CH0			1
+#define CM_INT_CH1			2
+
+#define CM_CFMT_STEREO			0x01
+#define CM_CFMT_16BIT			0x02
+#define CM_CFMT_MASK			0x03
+#define CM_CFMT_DACSHIFT		2
+#define CM_CFMT_ADCSHIFT		0
 
-static const unsigned sample_size[] = { 1, 2, 2, 4 };
-static const unsigned sample_shift[] = { 0, 1, 1, 2 };
+static const unsigned sample_shift[]	= { 0, 1, 1, 2 };
 
 #define CM_ENABLE_CH1      0x2
 #define CM_ENABLE_CH0      0x1
 
-
-/* MIDI buffer sizes */
+/* MIDI buffer sizes **************************/
 
 #define MIDIINBUF  256
 #define MIDIOUTBUF 256
@@ -229,35 +209,29 @@
 
 #define SND_DEV_DSP16   5 
 
-/* --------------------------------------------------------------------- */
+#define NR_DEVICE 3		/* maximum number of devices */
 
-struct cm_state {
-	/* magic */
-	unsigned int magic;
+/*********************************************/
 
-	/* we keep cm cards in a linked list */
-	struct cm_state *next;
+struct cm_state {
+	unsigned int magic;		/* magic */
+	struct cm_state *next;		/* we keep cm cards in a linked list */
 
-	/* soundcore stuff */
-	int dev_audio;
+	int dev_audio;			/* soundcore stuff */
 	int dev_mixer;
 	int dev_midi;
 	int dev_dmfm;
 
-	/* hardware resources */
-	unsigned int iosb, iobase, iosynth, iomidi, iogame, irq;
-	unsigned short deviceid;
+	unsigned int iosb, iobase, iosynth,
+			 iomidi, iogame, irq;	/* hardware resources */
+	unsigned short deviceid;		/* pci_id */
 
-        /* mixer stuff */
-        struct {
+        struct {				/* mixer stuff */
                 unsigned int modcnt;
-#ifndef OSS_DOCUMENTED_MIXER_SEMANTICS
 		unsigned short vol[13];
-#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
         } mix;
 
-	/* wave stuff */
-	unsigned int rateadc, ratedac;
+	unsigned int rateadc, ratedac;		/* wave stuff */
 	unsigned char fmt, enable;
 
 	spinlock_t lock;
@@ -274,15 +248,15 @@
 		unsigned hwptr, swptr;
 		unsigned total_bytes;
 		int count;
-		unsigned error; /* over/underrun */
+		unsigned error;		/* over/underrun */
 		wait_queue_head_t wait;
-		/* redundant, but makes calculations easier */
-		unsigned fragsize;
+		
+		unsigned fragsize;	/* redundant, but makes calculations easier */
 		unsigned dmasize;
 		unsigned fragsamples;
 		unsigned dmasamples;
-		/* OSS stuff */
-		unsigned mapped:1;
+		
+		unsigned mapped:1;	/* OSS stuff */
 		unsigned ready:1;
 		unsigned endcleared:1;
 		unsigned ossfragshift;
@@ -290,8 +264,7 @@
 		unsigned subdivision;
 	} dma_dac, dma_adc;
 
-	/* midi stuff */
-	struct {
+	struct {			/* midi stuff */
 		unsigned ird, iwr, icnt;
 		unsigned ord, owr, ocnt;
 		wait_queue_head_t iwait;
@@ -301,44 +274,41 @@
 		unsigned char obuf[MIDIOUTBUF];
 	} midi;
 	
-	/* misc stuff */
-	int	chip_version;
+	int	chip_version;		
 	int	max_channels;
-	int	curr_channels;
-	int	speakers;	// number of speakers
-	int	capability;	// HW capability, various for chip versions
-	int	status;		// HW or SW state
+	int	curr_channels;		
+	int	speakers;		/* number of speakers */
+	int	capability;		/* HW capability, various for chip versions */
+
+	int	status;			/* HW or SW state */
 	
-	/* spdif frame counter */
-	int	spdif_counter;
+	int	spdif_counter;		/* spdif frame counter */
 };
 
 /* flags used for capability */
-#define	CAN_AC3_HW	0x00000001	// 037 or later
-#define	CAN_AC3_SW	0x00000002	// 033 or later
-#define	CAN_AC3		(CAN_AC3_HW | CAN_AC3_SW)
-#define CAN_DUAL_DAC	0x00000004	// 033 or later
-#define	CAN_MULTI_CH_HW	0x00000008	// 039 or later
-#define	CAN_MULTI_CH	(CAN_MULTI_CH_HW | CAN_DUAL_DAC)
-#define	CAN_LINE_AS_REAR	0x00000010	// 033 or later
-#define	CAN_LINE_AS_BASS	0x00000020	// 039 or later
-#define	CAN_MIC_AS_BASS		0x00000040	// 039 or later
+#define	CAN_AC3_HW		0x00000001		/* 037 or later */
+#define	CAN_AC3_SW		0x00000002		/* 033 or later */
+#define	CAN_AC3			(CAN_AC3_HW | CAN_AC3_SW)
+#define CAN_DUAL_DAC		0x00000004		/* 033 or later */
+#define	CAN_MULTI_CH_HW		0x00000008		/* 039 or later */
+#define	CAN_MULTI_CH		(CAN_MULTI_CH_HW | CAN_DUAL_DAC)
+#define	CAN_LINE_AS_REAR	0x00000010		/* 033 or later */
+#define	CAN_LINE_AS_BASS	0x00000020		/* 039 or later */
+#define	CAN_MIC_AS_BASS		0x00000040		/* 039 or later */
 
 /* flags used for status */
-#define	DO_AC3_HW	0x00000001
-#define	DO_AC3_SW	0x00000002
-#define	DO_AC3		(DO_AC3_HW | DO_AC3_SW)
-#define	DO_DUAL_DAC	0x00000004
-#define	DO_MULTI_CH_HW	0x00000008
-#define	DO_MULTI_CH	(DO_MULTI_CH_HW | DO_DUAL_DAC)
-#define	DO_LINE_AS_REAR	0x00000010	// 033 or later
-#define	DO_LINE_AS_BASS	0x00000020	// 039 or later
-#define	DO_MIC_AS_BASS	0x00000040	// 039 or later
-#define	DO_SPDIF_OUT	0x00000100
-#define	DO_SPDIF_IN	0x00000200
-#define	DO_SPDIF_LOOP	0x00000400
-
-/* --------------------------------------------------------------------- */
+#define	DO_AC3_HW		0x00000001
+#define	DO_AC3_SW		0x00000002
+#define	DO_AC3			(DO_AC3_HW | DO_AC3_SW)
+#define	DO_DUAL_DAC		0x00000004
+#define	DO_MULTI_CH_HW		0x00000008
+#define	DO_MULTI_CH		(DO_MULTI_CH_HW | DO_DUAL_DAC)
+#define	DO_LINE_AS_REAR		0x00000010		/* 033 or later */
+#define	DO_LINE_AS_BASS		0x00000020		/* 039 or later */
+#define	DO_MIC_AS_BASS		0x00000040		/* 039 or later */
+#define	DO_SPDIF_OUT		0x00000100
+#define	DO_SPDIF_IN		0x00000200
+#define	DO_SPDIF_LOOP		0x00000400
 
 static struct cm_state *devs;
 static unsigned long wavetable_mem;
@@ -347,55 +317,25 @@
 
 static inline unsigned ld2(unsigned int x)
 {
-	unsigned r = 0;
+	unsigned exp=16,l=5,r=0;
+	static const unsigned num[]={0x2,0x4,0x10,0x100,0x10000};
+
+	/* num: 2, 4, 16, 256, 65536 */
+	/* exp: 1, 2,  4,   8,    16 */
 	
-	if (x >= 0x10000) {
-		x >>= 16;
-		r += 16;
-	}
-	if (x >= 0x100) {
-		x >>= 8;
-		r += 8;
-	}
-	if (x >= 0x10) {
-		x >>= 4;
-		r += 4;
-	}
-	if (x >= 4) {
-		x >>= 2;
-		r += 2;
+	while(l--) {
+		if( x >= num[l] ) {
+			if(num[l]>2) x >>= exp;
+			r+=exp;
+		}
+		exp>>=1;
 	}
-	if (x >= 2)
-		r++;
-	return r;
-}
-
-/*
- * hweightN: returns the hamming weight (i.e. the number
- * of bits set) of a N-bit word
- */
 
-#ifdef hweight32
-#undef hweight32
-#endif
-
-static inline unsigned int hweight32(unsigned int w)
-{
-        unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
-        res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
-        res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F);
-        res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF);
-        return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF);
+	return r;
 }
 
 /* --------------------------------------------------------------------- */
 
-/*
- * Why use byte IO? Nobody knows, but S3 does it also in their Windows driver.
- */
-
-#undef DMABYTEIO
-
 static void maskb(unsigned int addr, unsigned int mask, unsigned int value)
 {
 	outb((inb(addr) & mask) | value, addr);
@@ -451,15 +391,10 @@
 {
 	unsigned int curr_addr;
 
-#if 1
 	curr_addr = inw(s->iobase + CODEC_CMI_CH1_FRAME2) + 1;
 	curr_addr <<= sample_shift[(s->fmt >> CM_CFMT_DACSHIFT) & CM_CFMT_MASK];
 	curr_addr = s->dma_dac.dmasize - curr_addr;
-#else
-	curr_addr = inl(s->iobase + CODEC_CMI_CH1_FRAME1);
-	curr_addr &= ~(sample_size[(s->fmt >> CM_CFMT_DACSHIFT) & CM_CFMT_MASK]-1);
-	curr_addr -= s->dma_dac.rawphys;
-#endif
+
 	return curr_addr;
 }
 
@@ -467,39 +402,45 @@
 {
 	unsigned int curr_addr;
 
-#if 1
 	curr_addr = inw(s->iobase + CODEC_CMI_CH0_FRAME2) + 1;
 	curr_addr <<= sample_shift[(s->fmt >> CM_CFMT_ADCSHIFT) & CM_CFMT_MASK];
 	curr_addr = s->dma_adc.dmasize - curr_addr;
-#else
-	curr_addr = inl(s->iobase + CODEC_CMI_CH0_FRAME1);
-	curr_addr &= ~(sample_size[(s->fmt >> CM_CFMT_ADCSHIFT) & CM_CFMT_MASK]-1);
-	curr_addr -= s->dma_adc.rawphys;
-#endif
+
 	return curr_addr;
 }
 
 static void wrmixer(struct cm_state *s, unsigned char idx, unsigned char data)
 {
 	outb(idx, s->iobase + CODEC_SB16_ADDR);
+	udelay(10);
 	outb(data, s->iobase + CODEC_SB16_DATA);
+	udelay(10);
 }
 
 static unsigned char rdmixer(struct cm_state *s, unsigned char idx)
 {
 	unsigned char v;
-
+	unsigned long flags;
+	
+	spin_lock_irqsave(&s->lock, flags);
 	outb(idx, s->iobase + CODEC_SB16_ADDR);
+	udelay(10);
 	v = inb(s->iobase + CODEC_SB16_DATA);
+	udelay(10);
+	spin_unlock_irqrestore(&s->lock, flags);
 	return v;
 }
 
 static void set_fmt_unlocked(struct cm_state *s, unsigned char mask, unsigned char data)
 {
 	if (mask)
+	{
 		s->fmt = inb(s->iobase + CODEC_CMI_CHFORMAT);
+		udelay(10);
+	}
 	s->fmt = (s->fmt & mask) | data;
 	outb(s->fmt, s->iobase + CODEC_CMI_CHFORMAT);
+	udelay(10);
 }
 
 static void set_fmt(struct cm_state *s, unsigned char mask, unsigned char data)
@@ -514,7 +455,9 @@
 static void frobindir(struct cm_state *s, unsigned char idx, unsigned char mask, unsigned char data)
 {
 	outb(idx, s->iobase + CODEC_SB16_ADDR);
+	udelay(10);
 	outb((inb(s->iobase + CODEC_SB16_DATA) & mask) | data, s->iobase + CODEC_SB16_DATA);
+	udelay(10);
 }
 
 static struct {
@@ -746,6 +689,7 @@
 {
 	/* reset bus master */
 	outb(s->enable | CM_CH0_RESET, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
+	udelay(10);
 	outb(s->enable & ~CM_CH0_RESET, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
 }
 
@@ -887,15 +831,6 @@
 	}
 }
 
-//static void start_dac1(struct cm_state *s)
-//{
-//	unsigned long flags;
-//
-//	spin_lock_irqsave(&s->lock, flags);
-//	start_dac1_unlocked(s);
-//	spin_unlock_irqrestore(&s->lock, flags);
-//}	
-
 static void start_dac_unlocked(struct cm_state *s)
 {
 	if ((s->dma_dac.mapped || s->dma_dac.count > 0) && s->dma_dac.ready) {
@@ -964,7 +899,7 @@
 		set_adc_rate_unlocked(s, s->ratedac);
 
 	    }
-	    // N4SPK3D, disable 4 speaker mode (analog duplicate)
+
 	    if (s->speakers > 2)
 		maskb(s->iobase + CODEC_CMI_MISC_CTRL + 3, ~0x04, 0);
 	    s->curr_channels = channels;
@@ -1041,10 +976,10 @@
 		db->buforder = order;
 		db->rawphys = virt_to_bus(db->rawbuf);
 		if ((db->rawphys ^ (db->rawphys + (PAGE_SIZE << db->buforder) - 1)) & ~0xffff)
-			printk(KERN_DEBUG "cm: DMA buffer crosses 64k boundary: busaddr 0x%lx  size %ld\n", 
+			printk(KERN_DEBUG "cmpci: DMA buffer crosses 64k boundary: busaddr 0x%lx  size %ld\n", 
 			       (long) db->rawphys, PAGE_SIZE << db->buforder);
 		if ((db->rawphys + (PAGE_SIZE << db->buforder) - 1) & ~0xffffff)
-			printk(KERN_DEBUG "cm: DMA buffer beyond 16MB: busaddr 0x%lx  size %ld\n", 
+			printk(KERN_DEBUG "cmpci: DMA buffer beyond 16MB: busaddr 0x%lx  size %ld\n", 
 			       (long) db->rawphys, PAGE_SIZE << db->buforder);
 		/* now mark the pages as reserved; otherwise remap_page_range doesn't do what we want */
 		pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
@@ -1260,7 +1195,7 @@
 
 /* --------------------------------------------------------------------- */
 
-static const char invalid_magic[] = KERN_CRIT "cm: invalid magic value\n";
+static const char invalid_magic[] = KERN_CRIT "cmpci: invalid magic value\n";
 
 #ifdef CONFIG_SOUND_CMPCI	/* support multiple chips */
 #define VALIDATE_STATE(s)
@@ -1298,59 +1233,6 @@
 	[SOUND_MIXER_SPEAKER]= { DSP_MIX_SPKRVOLIDX,	 DSP_MIX_SPKRVOLIDX,	 MT_5MUTEMONO, 0x01, 0x01 }
 };
 
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-
-static int return_mixval(struct cm_state *s, unsigned i, int *arg)
-{
-	unsigned long flags;
-	unsigned char l, r, rl, rr;
-
-	spin_lock_irqsave(&s->lock, flags);
-	l = rdmixer(s, mixtable[i].left);
-	r = rdmixer(s, mixtable[i].right);
-	spin_unlock_irqrestore(&s->lock, flags);
-	switch (mixtable[i].type) {
-	case MT_4:
-		r &= 0xf;
-		l &= 0xf;
-		rl = 10 + 6 * (l & 15);
-		rr = 10 + 6 * (r & 15);
-		break;
-
-	case MT_4MUTEMONO:
-		rl = 55 - 3 * (l & 15);
-		if (r & 0x10)
-			rl += 45;
-		rr = rl;
-		r = l;
-		break;
-
-	case MT_5MUTEMONO:
-		r = l;
-		rl = 100 - 3 * ((l >> 3) & 31);
-		rr = rl;
-		break;
-				
-	case MT_5MUTE:
-	default:
-		rl = 100 - 3 * ((l >> 3) & 31);
-		rr = 100 - 3 * ((r >> 3) & 31);
-		break;
-				
-	case MT_6MUTE:
-		rl = 100 - 3 * (l & 63) / 2;
-		rr = 100 - 3 * (r & 63) / 2;
-		break;
-	}
-	if (l & 0x80)
-		rl = 0;
-	if (r & 0x80)
-		rr = 0;
-	return put_user((rr << 8) | rl, arg);
-}
-
-#else /* OSS_DOCUMENTED_MIXER_SEMANTICS */
-
 static const unsigned char volidx[SOUND_MIXER_NRDEVICES] = 
 {
 	[SOUND_MIXER_CD]     = 1,
@@ -1362,16 +1244,11 @@
 	[SOUND_MIXER_SPEAKER]= 7
 };
 
-#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
-
 static unsigned mixer_recmask(struct cm_state *s)
 {
-	unsigned long flags;
 	int i, j, k;
 
-	spin_lock_irqsave(&s->lock, flags);
 	j = rdmixer(s, DSP_MIX_ADCMIXIDX_L);
-	spin_unlock_irqrestore(&s->lock, flags);
 	j &= 0x7f;
 	for (k = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
 		if (j & mixtable[i].rec)
@@ -1446,13 +1323,9 @@
 			i = _IOC_NR(cmd);
                         if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].type)
                                 return -EINVAL;
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-			return return_mixval(s, i, (int *)arg);
-#else /* OSS_DOCUMENTED_MIXER_SEMANTICS */
 			if (!volidx[i])
 				return -EINVAL;
 			return put_user(s->mix.vol[volidx[i]-1], (int *)arg);
-#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
 		}
 	}
         if (_IOC_DIR(cmd) != (_IOC_READ|_IOC_WRITE)) 
@@ -1462,7 +1335,7 @@
 	case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
 		if (get_user(val, (int *)arg))
 			return -EFAULT;
-		i = hweight32(val);
+		i = generic_hweight32(val);
 		for (j = i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
 			if (!(val & (1 << i)))
 				continue;
@@ -1554,14 +1427,11 @@
 			break;
 		}
 		spin_unlock_irqrestore(&s->lock, flags);
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-                return return_mixval(s, i, (int *)arg);
-#else /* OSS_DOCUMENTED_MIXER_SEMANTICS */
+
 		if (!volidx[i])
 			return -EINVAL;
 		s->mix.vol[volidx[i]-1] = val;
 		return put_user(s->mix.vol[volidx[i]-1], (int *)arg);
-#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
 	}
 }
 
@@ -1631,7 +1501,7 @@
 		tmo = 3 * HZ * (count + s->dma_dac.fragsize) / 2 / s->ratedac;
 		tmo >>= sample_shift[(s->fmt >> CM_CFMT_DACSHIFT) & CM_CFMT_MASK];
 		if (!schedule_timeout(tmo + 1))
-			printk(KERN_DEBUG "cm: dma timed out??\n");
+			printk(KERN_DEBUG "cmpci: dma timed out??\n");
         }
         remove_wait_queue(&s->dma_dac.wait, &wait);
         current->state = TASK_RUNNING;
@@ -1660,11 +1530,7 @@
 	if (!access_ok(VERIFY_WRITE, buffer, count))
 		return -EFAULT;
 	ret = 0;
-#if 0
-   spin_lock_irqsave(&s->lock, flags);
-   cm_update_ptr(s);
-   spin_unlock_irqrestore(&s->lock, flags);
-#endif
+
 	while (count > 0) {
 		spin_lock_irqsave(&s->lock, flags);
 		swptr = s->dma_adc.swptr;
@@ -1679,7 +1545,7 @@
 			if (file->f_flags & O_NONBLOCK)
 				return ret ? ret : -EAGAIN;
 			if (!interruptible_sleep_on_timeout(&s->dma_adc.wait, HZ)) {
-				printk(KERN_DEBUG "cm: read: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
+				printk(KERN_DEBUG "cmpci: read: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
 				       s->dma_adc.dmasize, s->dma_adc.fragsize, s->dma_adc.count,
 				       s->dma_adc.hwptr, s->dma_adc.swptr);
 				spin_lock_irqsave(&s->lock, flags);
@@ -1735,11 +1601,7 @@
 			return -EFAULT;
 	}
 	ret = 0;
-#if 0
-   spin_lock_irqsave(&s->lock, flags);
-   cm_update_ptr(s);
-   spin_unlock_irqrestore(&s->lock, flags);
-#endif                                                        
+
 	while (count > 0) {
 		spin_lock_irqsave(&s->lock, flags);
 		if (s->dma_dac.count < 0) {
@@ -1770,7 +1632,7 @@
 			if (file->f_flags & O_NONBLOCK)
 				return ret ? ret : -EAGAIN;
 			if (!interruptible_sleep_on_timeout(&s->dma_dac.wait, HZ)) {
-				printk(KERN_DEBUG "cm: write: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
+				printk(KERN_DEBUG "cmpci: write: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
 				       s->dma_dac.dmasize, s->dma_dac.fragsize, s->dma_dac.count,
 				       s->dma_dac.hwptr, s->dma_dac.swptr);
 				spin_lock_irqsave(&s->lock, flags);
@@ -2387,11 +2249,11 @@
 	down(&s->open_sem);
 	if (file->f_mode & FMODE_WRITE) {
 		stop_dac(s);
-#ifndef FIXEDDMA
+
 		dealloc_dmabuf(&s->dma_dac);
 		if (s->status & DO_DUAL_DAC)
 			dealloc_dmabuf(&s->dma_adc);
-#endif
+
 		if (s->status & DO_MULTI_CH)
 			set_dac_channels(s, 0);
 		if (s->status & DO_AC3)
@@ -2401,9 +2263,7 @@
 	}
 	if (file->f_mode & FMODE_READ) {
 		stop_adc(s);
-#ifndef FIXEDDMA
 		dealloc_dmabuf(&s->dma_adc);
-#endif
 	}
 	s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
 	up(&s->open_sem);
@@ -2668,7 +2528,7 @@
 			}
 			tmo = (count * HZ) / 3100;
 			if (!schedule_timeout(tmo ? : 1) && tmo)
-				printk(KERN_DEBUG "cm: midi timed out??\n");
+				printk(KERN_DEBUG "cmpci: midi timed out??\n");
 		}
 		remove_wait_queue(&s->midi.owait, &wait);
 		set_current_state(TASK_RUNNING);
@@ -2867,18 +2727,7 @@
 };
 #endif /* CONFIG_SOUND_CMPCI_FM */
 
-/* --------------------------------------------------------------------- */
 
-/* maximum number of devices */
-#define NR_DEVICE 5
-
-#if 0
-static int reverb[NR_DEVICE] = { 0, };
-
-static int wavetable[NR_DEVICE] = { 0, };
-#endif
-
-/* --------------------------------------------------------------------- */
 
 static struct initvol {
 	int mixch;
@@ -2941,14 +2790,14 @@
 }
 
 #ifdef CONFIG_SOUND_CMPCI_MIDI
-static	int	mpu_io = CONFIG_SOUND_CMPCI_MPUIO;
+static	int	mpuio = CONFIG_SOUND_CMPCI_MPUIO;
 #else
-static	int	mpu_io;
+static	int	mpuio;
 #endif
 #ifdef CONFIG_SOUND_CMPCI_FM
-static	int	fm_io = CONFIG_SOUND_CMPCI_FMIO;
+static	int	fmio = CONFIG_SOUND_CMPCI_FMIO;
 #else
-static	int	fm_io;
+static	int	fmio;
 #endif
 #ifdef CONFIG_SOUND_CMPCI_SPDIFINVERSE
 static	int	spdif_inverse = 1;
@@ -2980,16 +2829,16 @@
 #else
 static	int	joystick;
 #endif
-MODULE_PARM(mpu_io, "i");
-MODULE_PARM(fm_io, "i");
+MODULE_PARM(mpuio, "i");
+MODULE_PARM(fmio, "i");
 MODULE_PARM(spdif_inverse, "i");
 MODULE_PARM(spdif_loop, "i");
 MODULE_PARM(speakers, "i");
 MODULE_PARM(use_line_as_rear, "i");
 MODULE_PARM(use_line_as_bass, "i");
 MODULE_PARM(joystick, "i");
-MODULE_PARM_DESC(mpu_io, "(0x330, 0x320, 0x310, 0x300) Base of MPU-401, 0 to disable");
-MODULE_PARM_DESC(fm_io, "(0x388, 0x3C8, 0x3E0) Base of OPL3, 0 to disable");
+MODULE_PARM_DESC(mpuio, "(0x330, 0x320, 0x310, 0x300) Base of MPU-401, 0 to disable");
+MODULE_PARM_DESC(fmio, "(0x388, 0x3C8, 0x3E0) Base of OPL3, 0 to disable");
 MODULE_PARM_DESC(spdif_inverse, "(1/0) Invert S/PDIF-in signal");
 MODULE_PARM_DESC(spdif_loop, "(1/0) Route S/PDIF-in to S/PDIF-out directly");
 MODULE_PARM_DESC(speakers, "(2-6) Number of speakers you connect");
@@ -3021,7 +2870,7 @@
 			return;
 		s = kmalloc(sizeof(*s), GFP_KERNEL);
 		if (!s) {
-			printk(KERN_WARNING "cm: out of memory\n");
+			printk(KERN_WARNING "cmpci: out of memory\n");
 			return;
 		}
 		/* search device name */
@@ -3042,8 +2891,8 @@
 		spin_lock_init(&s->lock);
 		s->magic = CM_MAGIC;
 		s->iobase = pci_resource_start(pcidev, 0);
-		s->iosynth = fm_io;
-		s->iomidi = mpu_io;
+		s->iosynth = fmio;
+		s->iomidi = mpuio;
 		s->status = 0;
 		/* range check */
 		if (speakers < 2)
@@ -3056,7 +2905,7 @@
 		s->irq = pcidev->irq;
 
 		if (!request_region(s->iobase, CM_EXTENT_CODEC, "cmpci")) {
-			printk(KERN_ERR "cm: io ports %#x-%#x in use\n", s->iobase, s->iobase+CM_EXTENT_CODEC-1);
+			printk(KERN_ERR "cmpci: io ports %#x-%#x in use\n", s->iobase, s->iobase+CM_EXTENT_CODEC-1);
 			goto err_region5;
 		}
 #ifdef CONFIG_SOUND_CMPCI_MIDI
@@ -3064,7 +2913,7 @@
 		maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0x04, 0);
 		if (s->iomidi) {
 		    if (!request_region(s->iomidi, CM_EXTENT_MIDI, "cmpci Midi")) {
-			printk(KERN_ERR "cm: io ports %#x-%#x in use\n", s->iomidi, s->iomidi+CM_EXTENT_MIDI-1);
+			printk(KERN_ERR "cmpci: io ports %#x-%#x in use\n", s->iomidi, s->iomidi+CM_EXTENT_MIDI-1);
 			s->iomidi = 0;
 		    } else {
 		        /* set IO based at 0x330 */
@@ -3098,7 +2947,7 @@
 		maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~8, 0);
 		if (s->iosynth) {
 		    if (!request_region(s->iosynth, CM_EXTENT_SYNTH, "cmpci FM")) {
-			printk(KERN_ERR "cm: io ports %#x-%#x in use\n", s->iosynth, s->iosynth+CM_EXTENT_SYNTH-1);
+			printk(KERN_ERR "cmpci: io ports %#x-%#x in use\n", s->iosynth, s->iosynth+CM_EXTENT_SYNTH-1);
 			s->iosynth = 0;
 		    } else {
 		        /* set IO based at 0x388 */
@@ -3140,10 +2989,10 @@
 
 		/* request irq */
 		if (request_irq(s->irq, cm_interrupt, SA_SHIRQ, "cmpci", s)) {
-			printk(KERN_ERR "cm: irq %u in use\n", s->irq);
+			printk(KERN_ERR "cmpci: irq %u in use\n", s->irq);
 			goto err_irq;
 		}
-		printk(KERN_INFO "cm: found %s adapter at io %#06x irq %u\n",
+		printk(KERN_INFO "cmpci: found %s adapter at io %#06x irq %u\n",
 		       devicename, s->iobase, s->irq);
 		/* register devices */
 		if ((s->dev_audio = register_sound_dsp(&cm_audio_fops, -1)) < 0)
@@ -3174,15 +3023,18 @@
 		/* use channel 0 for record, channel 1 for play */
 		maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~2, 1);
 		s->deviceid = pcidev->device;
+
 		if (pcidev->device == PCI_DEVICE_ID_CMEDIA_CM8738) {
+
 			/* chip version and hw capability check */
 			s->chip_version = query_chip(s);
-			printk(KERN_INFO "chip version = 0%d\n", s->chip_version);
+			printk(KERN_INFO "cmpci: chip version = 0%d\n", s->chip_version);
+
 			/* seet SPDIF-in inverse before enable SPDIF loop */
 			if (spdif_inverse) {
 				/* turn on spdif-in inverse */
 				maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~0, 1);
-				printk(KERN_INFO "cm: Inverse SPDIF-in\n");
+				printk(KERN_INFO "cmpci: Inverse SPDIF-in\n");
 			} else {
 				/* turn off spdif-ininverse */
 				maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~1, 0);
@@ -3193,7 +3045,7 @@
 				s->status |= DO_SPDIF_LOOP;
 				/* turn on spdif-in to spdif-out */
 				maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0, 0x80);
-				printk(KERN_INFO "cm: Enable SPDIF loop\n");
+				printk(KERN_INFO "cmpci: Enable SPDIF loop\n");
 			} else {
 				s->status &= ~DO_SPDIF_LOOP;
 				/* turn off spdif-in to spdif-out */
@@ -3234,7 +3086,7 @@
 	err_dev2:
 		unregister_sound_dsp(s->dev_audio);
 	err_dev1:
-		printk(KERN_ERR "cm: cannot register misc device\n");
+		printk(KERN_ERR "cmpci: cannot register misc device\n");
 		free_irq(s->irq, s);
 	err_irq:
 #ifdef CONFIG_SOUND_CMPCI_FM
@@ -3264,11 +3116,8 @@
 	if (!pci_present())   /* No PCI bus in this machine! */
 #endif
 		return -ENODEV;
-	printk(KERN_INFO "cm: version $Revision: 5.64 $ time " __TIME__ " " __DATE__ "\n");
-#if 0
-	if (!(wavetable_mem = __get_free_pages(GFP_KERNEL, 20-PAGE_SHIFT)))
-		printk(KERN_INFO "cm: cannot allocate 1MB of contiguous nonpageable memory for wavetable data\n");
-#endif
+	printk(KERN_INFO "cmpci: version $Revision: 5.64 $ time " __TIME__ " " __DATE__ "\n");
+
 	while (index < NR_DEVICE && (
 	       (pcidev = pci_find_device(PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738, pcidev)))) { 
 		initialize_chip(pcidev);
@@ -3302,10 +3151,6 @@
 		synchronize_irq();
 		outb(0, s->iobase + CODEC_CMI_FUNCTRL0 + 2); /* disable channels */
 		free_irq(s->irq, s);
-#ifdef FIXEDDMA
-    		dealloc_dmabuf(&s->dma_dac);
-    		dealloc_dmabuf(&s->dma_adc);
-#endif
 
 		/* reset mixer */
 		wrmixer(s, DSP_MIX_DATARESETIDX, 0);
@@ -3329,7 +3174,7 @@
 	}
 	if (wavetable_mem)
 		free_pages(wavetable_mem, 20-PAGE_SHIFT);
-	printk(KERN_INFO "cm: unloading\n");
+	printk(KERN_INFO "cmpci: unloading\n");
 }
 
 module_init(init_cmpci);
diff -u --recursive --new-file v2.4.9/linux/drivers/sound/cs46xx.c linux/drivers/sound/cs46xx.c
--- v2.4.9/linux/drivers/sound/cs46xx.c	Mon Aug 27 12:41:45 2001
+++ linux/drivers/sound/cs46xx.c	Fri Sep  7 09:28:37 2001
@@ -1887,7 +1887,7 @@
         spin_unlock_irqrestore(&card->midi.lock, flags);
         card->midi.open_mode |= (file->f_mode & (FMODE_READ | FMODE_WRITE));
         up(&card->midi.open_sem);
-        MOD_INC_USE_COUNT;
+        MOD_INC_USE_COUNT; /* for 2.2 */
         return 0;
 }
 
@@ -1926,7 +1926,7 @@
         card->midi.open_mode &= (~(file->f_mode & (FMODE_READ | FMODE_WRITE)));
         up(&card->midi.open_sem);
         wake_up(&card->midi.open_wait);
-        MOD_DEC_USE_COUNT;
+        MOD_DEC_USE_COUNT; /* for 2.2 */
         return 0;
 }
 
@@ -3294,7 +3294,6 @@
 
 		state->open_mode |= FMODE_READ;
 		up(&state->open_sem);
-		MOD_INC_USE_COUNT;
 	}
 	if(file->f_mode & FMODE_WRITE)
 	{
@@ -3366,10 +3365,10 @@
 
 		state->open_mode |= FMODE_WRITE;
 		up(&state->open_sem);
-		MOD_INC_USE_COUNT;
 		if((ret = prog_dmabuf(state)))
 			return ret;
 	}
+	MOD_INC_USE_COUNT;	/* for 2.2 */
 	CS_DBGOUT(CS_OPEN | CS_FUNCTION, 2, printk("cs46xx: cs_open()- 0\n") );
 	return 0;
 }
@@ -3421,7 +3420,6 @@
 
 			kfree(state);
 		}
-		MOD_DEC_USE_COUNT;
 	}
 
 	state = card->states[0];
@@ -3454,10 +3452,10 @@
 
 			kfree(state);
 		}
-		MOD_DEC_USE_COUNT;
 	}
 
 	CS_DBGOUT(CS_FUNCTION | CS_RELEASE, 2, printk("cs46xx: cs_release()- 0\n") );
+	MOD_DEC_USE_COUNT;	/* For 2.2 */
 	return 0;
 }
 
@@ -4088,7 +4086,7 @@
 	}
 	card->amplifier_ctrl(card, 1);
 	CS_INC_USE_COUNT(&card->mixer_use_cnt);
-	MOD_INC_USE_COUNT;
+	MOD_INC_USE_COUNT; /* for 2.2 */
 	CS_DBGOUT(CS_FUNCTION | CS_OPEN, 4,
 		  printk(KERN_INFO "cs46xx: cs_open_mixdev()- 0\n"));
 	return 0;
@@ -4119,7 +4117,7 @@
 		return -ENODEV;
 	}
 match:
-	MOD_DEC_USE_COUNT;
+	MOD_DEC_USE_COUNT; /* for 2.2 */
 	if(!CS_DEC_AND_TEST(&card->mixer_use_cnt))
 	{
 		CS_DBGOUT(CS_FUNCTION | CS_RELEASE, 4,
diff -u --recursive --new-file v2.4.9/linux/drivers/sound/esssolo1.c linux/drivers/sound/esssolo1.c
--- v2.4.9/linux/drivers/sound/esssolo1.c	Mon Aug 27 12:41:45 2001
+++ linux/drivers/sound/esssolo1.c	Fri Sep  7 09:28:37 2001
@@ -2262,7 +2262,7 @@
 solo1_suspend(struct pci_dev *pci_dev, u32 state) {
 	struct solo1_state *s = (struct solo1_state*)pci_get_drvdata(pci_dev);
 	if (!s)
-		return;
+		return 1;
 	outb(0, s->iobase+6);
 	/* DMA master clear */
 	outb(0, s->ddmabase+0xd); 
diff -u --recursive --new-file v2.4.9/linux/drivers/sound/i810_audio.c linux/drivers/sound/i810_audio.c
--- v2.4.9/linux/drivers/sound/i810_audio.c	Mon Aug 27 12:41:45 2001
+++ linux/drivers/sound/i810_audio.c	Sun Sep  9 10:52:35 2001
@@ -106,6 +106,7 @@
 static int ftsodell=0;
 static int strict_clocking=0;
 static unsigned int clocking=48000;
+static int spdif_locked=0;
 
 //#define DEBUG
 //#define DEBUG2
@@ -118,6 +119,11 @@
 #define I810_FMT_STEREO	2
 #define I810_FMT_MASK	3
 
+#define SPDIF_ON	0x0004
+#define SURR_ON		0x0010
+#define CENTER_LFE_ON	0x0020
+#define VOL_MUTED	0x8000
+
 /* the 810's array of pointers to data buffers */
 
 struct sg_item {
@@ -191,7 +197,7 @@
 #define INT_MASK (INT_SEC|INT_PRI|INT_MC|INT_PO|INT_PI|INT_MO|INT_NI|INT_GPI)
 
 
-#define DRIVER_VERSION "0.03"
+#define DRIVER_VERSION "0.04"
 
 /* magic numbers to protect our data structures */
 #define I810_CARD_MAGIC		0x5072696E /* "Prin" */
@@ -325,6 +331,8 @@
 	struct i810_state *states[NR_HW_CH];
 
 	u16 ac97_features;
+	u16 ac97_status;
+	u16 channels;
 	
 	/* hardware resources */
 	unsigned long iobase;
@@ -401,11 +409,164 @@
 	card->channel[channel].used=0;
 }
 
+static int i810_valid_spdif_rate ( struct ac97_codec *codec, int rate )
+{
+	unsigned long id = 0L;
+
+	id = (i810_ac97_get(codec, AC97_VENDOR_ID1) << 16);
+	id |= i810_ac97_get(codec, AC97_VENDOR_ID2) & 0xffff;
+#ifdef DEBUG
+	printk ( "i810_audio: codec = %s, codec_id = 0x%08lx\n", codec->name, id);
+#endif
+	switch ( id ) {
+		case 0x41445361: /* AD1886 */
+			if (rate == 48000) {
+				return 1;
+			}
+			break;
+		default: /* all other codecs, until we know otherwiae */
+			if (rate == 48000 || rate == 44100 || rate == 32000) {
+				return 1;
+			}
+			break;
+	}
+	return (0);
+}
+
+/* i810_set_spdif_output
+ * 
+ *  Configure the S/PDIF output transmitter. When we turn on
+ *  S/PDIF, we turn off the analog output. This may not be
+ *  the right thing to do.
+ *
+ *  Assumptions:
+ *     The DSP sample rate must already be set to a supported
+ *     S/PDIF rate (32kHz, 44.1kHz, or 48kHz) or we abort.
+ */
+static void i810_set_spdif_output(struct i810_state *state, int slots, int rate)
+{
+	int	vol;
+	int	aud_reg;
+	struct ac97_codec *codec = state->card->ac97_codec[0];
+
+	if(!(state->card->ac97_features & 4)) {
+#ifdef DEBUG
+		printk(KERN_WARNING "i810_audio: S/PDIF transmitter not avalible.\n");
+#endif
+		state->card->ac97_status &= ~SPDIF_ON;
+	} else {
+		if ( slots == -1 ) { /* Turn off S/PDIF */
+			aud_reg = i810_ac97_get(codec, AC97_EXTENDED_STATUS);
+			i810_ac97_set(codec, AC97_EXTENDED_STATUS, (aud_reg & ~AC97_EA_SPDIF));
+
+			/* If the volume wasn't muted before we turned on S/PDIF, unmute it */
+			if ( !(state->card->ac97_status & VOL_MUTED) ) {
+				aud_reg = i810_ac97_get(codec, AC97_MASTER_VOL_STEREO);
+				i810_ac97_set(codec, AC97_MASTER_VOL_STEREO, (aud_reg & ~VOL_MUTED));
+			}
+			state->card->ac97_status &= ~(VOL_MUTED | SPDIF_ON);
+			return;
+		}
+
+		vol = i810_ac97_get(codec, AC97_MASTER_VOL_STEREO);
+		state->card->ac97_status = vol & VOL_MUTED;
+
+		/* Set S/PDIF transmitter sample rate */
+		aud_reg = i810_ac97_get(codec, AC97_SPDIF_CONTROL);
+		switch ( rate ) {
+			case 32000:
+				aud_reg = (aud_reg & AC97_SC_SPSR_MASK) | AC97_SC_SPSR_32K; 
+				break;
+			 case 44100:
+			 	aud_reg = (aud_reg & AC97_SC_SPSR_MASK) | AC97_SC_SPSR_44K; 
+				break;
+			case 48000:
+			 	aud_reg = (aud_reg & AC97_SC_SPSR_MASK) | AC97_SC_SPSR_48K; 
+				break;
+			default:
+#ifdef DEBUG
+				printk(KERN_WARNING "i810_audio: %d sample rate not supported by S/PDIF.\n", rate);
+#endif
+				/* turn off S/PDIF */
+				aud_reg = i810_ac97_get(codec, AC97_EXTENDED_STATUS);
+				i810_ac97_set(codec, AC97_EXTENDED_STATUS, (aud_reg & ~AC97_EA_SPDIF));
+				state->card->ac97_status &= ~SPDIF_ON;
+				return;
+		}
+
+		i810_ac97_set(codec, AC97_SPDIF_CONTROL, aud_reg);
+		
+		aud_reg = i810_ac97_get(codec, AC97_EXTENDED_STATUS);
+		aud_reg = (aud_reg & AC97_EA_SLOT_MASK) | slots | AC97_EA_VRA | AC97_EA_SPDIF;
+		i810_ac97_set(codec, AC97_EXTENDED_STATUS, aud_reg);
+		state->card->ac97_status |= SPDIF_ON;
+
+		/* Check to make sure the configuration is valid */
+		aud_reg = i810_ac97_get(codec, AC97_EXTENDED_STATUS);
+		if ( ! (aud_reg & 0x0400) ) {
+#ifdef DEBUG
+			printk(KERN_WARNING "i810_audio: S/PDIF transmitter configuration not valid (0x%04x).\n", aud_reg);
+#endif
+
+			/* turn off S/PDIF */
+			i810_ac97_set(codec, AC97_EXTENDED_STATUS, (aud_reg & ~AC97_EA_SPDIF));
+			state->card->ac97_status &= ~SPDIF_ON;
+			return;
+		}
+		/* Mute the analog output */
+		/* Should this only mute the PCM volume??? */
+		i810_ac97_set(codec, AC97_MASTER_VOL_STEREO, (vol | VOL_MUTED));
+	}
+}
+
+/* i810_set_dac_channels
+ *
+ *  Configure the codec's multi-channel DACs
+ *
+ *  The logic is backwards. Setting the bit to 1 turns off the DAC. 
+ *
+ *  What about the ICH? We currently configure it using the
+ *  SNDCTL_DSP_CHANNELS ioctl.  If we're turnning on the DAC, 
+ *  does that imply that we want the ICH set to support
+ *  these channels?
+ *  
+ *  TODO:
+ *    vailidate that the codec really supports these DACs
+ *    before turning them on. 
+ */
+static void i810_set_dac_channels(struct i810_state *state, int channel)
+{
+	int	aud_reg;
+	struct ac97_codec *codec = state->card->ac97_codec[0];
+
+	aud_reg = i810_ac97_get(codec, AC97_EXTENDED_STATUS);
+	aud_reg |= AC97_EA_PRI | AC97_EA_PRJ | AC97_EA_PRK;
+	state->card->ac97_status &= ~(SURR_ON | CENTER_LFE_ON);
+
+	switch ( channel ) {
+		case 2: /* always enabled */
+			break;
+		case 4:
+			aud_reg &= ~AC97_EA_PRJ;
+			state->card->ac97_status |= SURR_ON;
+			break;
+		case 6:
+			aud_reg &= ~(AC97_EA_PRJ | AC97_EA_PRI | AC97_EA_PRK);
+			state->card->ac97_status |= SURR_ON | CENTER_LFE_ON;
+			break;
+		default:
+			break;
+	}
+	i810_ac97_set(codec, AC97_EXTENDED_STATUS, aud_reg);
+
+}
+
+
 /* set playback sample rate */
 static unsigned int i810_set_dac_rate(struct i810_state * state, unsigned int rate)
 {	
 	struct dmabuf *dmabuf = &state->dmabuf;
-	u32 dacp, new_rate;
+	u32 new_rate;
 	struct ac97_codec *codec=state->card->ac97_codec[0];
 	
 	if(!(state->card->ac97_features&0x0001))
@@ -429,20 +590,11 @@
 		dmabuf->rate = (rate * 48000)/clocking;
 	}
 	
-	if(rate != i810_ac97_get(codec, AC97_PCM_FRONT_DAC_RATE))
-	{
-		/* Power down the DAC */
-		dacp=i810_ac97_get(codec, AC97_POWER_CONTROL);
-		i810_ac97_set(codec, AC97_POWER_CONTROL, dacp|0x0200);
-		/* Load the rate and read the effective rate */
-		i810_ac97_set(codec, AC97_PCM_FRONT_DAC_RATE, rate);
-		new_rate=i810_ac97_get(codec, AC97_PCM_FRONT_DAC_RATE);
-		/* Power it back up */
-		i810_ac97_set(codec, AC97_POWER_CONTROL, dacp);
-		if(new_rate != rate) {
-			dmabuf->rate = (new_rate * 48000)/clocking;
-			rate = new_rate;
-		}
+	new_rate = ac97_set_dac_rate(codec, rate);
+
+	if(new_rate != rate) {
+		dmabuf->rate = (new_rate * 48000)/clocking;
+		rate = new_rate;
 	}
 #ifdef DEBUG
 	printk("i810_audio: called i810_set_dac_rate : rate = %d/%d\n", dmabuf->rate, rate);
@@ -454,7 +606,7 @@
 static unsigned int i810_set_adc_rate(struct i810_state * state, unsigned int rate)
 {
 	struct dmabuf *dmabuf = &state->dmabuf;
-	u32 dacp, new_rate;
+	u32 new_rate;
 	struct ac97_codec *codec=state->card->ac97_codec[0];
 	
 	if(!(state->card->ac97_features&0x0001))
@@ -478,21 +630,12 @@
 		rate = 8000;
 		dmabuf->rate = (rate * 48000)/clocking;
 	}
+
+	new_rate = ac97_set_adc_rate(codec, rate);
 	
-	if(rate != i810_ac97_get(codec, AC97_PCM_LR_DAC_RATE))
-	{
-		/* Power down the ADC */
-		dacp=i810_ac97_get(codec, AC97_POWER_CONTROL);
-		i810_ac97_set(codec, AC97_POWER_CONTROL, dacp|0x0100);
-		/* Load the rate and read the effective rate */
-		i810_ac97_set(codec, AC97_PCM_LR_DAC_RATE, rate);
-		new_rate=i810_ac97_get(codec, AC97_PCM_LR_DAC_RATE);
-		/* Power it back up */
-		i810_ac97_set(codec, AC97_POWER_CONTROL, dacp);
-		if(new_rate != rate) {
-			dmabuf->rate = (new_rate * 48000)/clocking;
-			rate = new_rate;
-		}
+	if(new_rate != rate) {
+		dmabuf->rate = (new_rate * 48000)/clocking;
+		rate = new_rate;
 	}
 #ifdef DEBUG
 	printk("i810_audio: called i810_set_adc_rate : rate = %d/%d\n", dmabuf->rate, rate);
@@ -985,8 +1128,10 @@
 		dmabuf = &state->dmabuf;
 		if(dmabuf->enable & DAC_RUNNING)
 			c=dmabuf->write_channel;
-		else
+		else if(dmabuf->enable & ADC_RUNNING)
 			c=dmabuf->read_channel;
+		else	/* This can occur going from R/W to close */
+			continue;
 		
 		port+=c->port;
 		
@@ -1375,7 +1520,9 @@
 	unsigned long flags;
 	audio_buf_info abinfo;
 	count_info cinfo;
-	int val, mapped, ret;
+	unsigned int i_glob_cnt;
+	int val = 0, mapped, ret;
+	struct ac97_codec *codec = state->card->ac97_codec[0];
 
 	mapped = ((file->f_mode & FMODE_WRITE) && dmabuf->mapped) ||
 		((file->f_mode & FMODE_READ) && dmabuf->mapped);
@@ -1428,11 +1575,31 @@
 			return -EFAULT;
 		if (val >= 0) {
 			if (file->f_mode & FMODE_WRITE) {
-				stop_dac(state);
-				dmabuf->ready = 0;
-				spin_lock_irqsave(&state->card->lock, flags);
-				i810_set_dac_rate(state, val);
-				spin_unlock_irqrestore(&state->card->lock, flags);
+				if ( (state->card->ac97_status & SPDIF_ON) ) {  /* S/PDIF Enabled */
+					/* AD1886 only supports 48000, need to check that */
+					if ( i810_valid_spdif_rate ( codec, val ) ) {
+						/* Set DAC rate */
+                                        	i810_set_spdif_output ( state, -1, 0 );
+						stop_dac(state);
+						dmabuf->ready = 0;
+						spin_lock_irqsave(&state->card->lock, flags);
+						i810_set_dac_rate(state, val);
+						spin_unlock_irqrestore(&state->card->lock, flags);
+						/* Set S/PDIF transmitter rate. */
+						i810_set_spdif_output ( state, AC97_EA_SPSA_3_4, val );
+	                                        if ( ! (state->card->ac97_status & SPDIF_ON) ) {
+							val = dmabuf->rate;
+						}
+					} else { /* Not a valid rate for S/PDIF, ignore it */
+						val = dmabuf->rate;
+					}
+				} else {
+					stop_dac(state);
+					dmabuf->ready = 0;
+					spin_lock_irqsave(&state->card->lock, flags);
+					i810_set_dac_rate(state, val);
+					spin_unlock_irqrestore(&state->card->lock, flags);
+				}
 			}
 			if (file->f_mode & FMODE_READ) {
 				stop_adc(state);
@@ -1450,18 +1617,14 @@
 #endif
 		if (get_user(val, (int *)arg))
 			return -EFAULT;
-		if(val==0) {
-			return -EINVAL;
-		} else {
-			ret = 1;
-		}
+
 		if (dmabuf->enable & DAC_RUNNING) {
 			stop_dac(state);
 		}
 		if (dmabuf->enable & ADC_RUNNING) {
 			stop_adc(state);
 		}
-		return put_user(ret, (int *)arg);
+		return put_user(1, (int *)arg);
 
 	case SNDCTL_DSP_GETBLKSIZE:
 		if (file->f_mode & FMODE_WRITE) {
@@ -1487,13 +1650,82 @@
 #ifdef DEBUG
 		printk("SNDCTL_DSP_SETFMT\n");
 #endif
-		return put_user(AFMT_S16_LE, (int *)arg);
+		if (get_user(val, (int *)arg))
+			return -EFAULT;
+
+		switch ( val ) {
+			case AFMT_S16_LE:
+				break;
+			case AFMT_QUERY:
+			default:
+				val = AFMT_S16_LE;
+				break;
+		}
+		return put_user(val, (int *)arg);
 
 	case SNDCTL_DSP_CHANNELS:
 #ifdef DEBUG
 		printk("SNDCTL_DSP_CHANNELS\n");
 #endif
-		return put_user(2, (int *)arg);
+		if (get_user(val, (int *)arg))
+			return -EFAULT;
+
+		if (val > 0) {
+			if (dmabuf->enable & DAC_RUNNING) {
+				stop_dac(state);
+			}
+			if (dmabuf->enable & ADC_RUNNING) {
+				stop_adc(state);
+			}
+		} else {
+			return put_user(state->card->channels, (int *)arg);
+		}
+
+		/* ICH and ICH0 only support 2 channels */
+		if ( state->card->pci_id == 0x2415 || state->card->pci_id == 0x2425 ) 
+			return put_user(2, (int *)arg);
+	
+		/* Multi-channel support was added with ICH2. Bits in */
+		/* Global Status and Global Control register are now  */
+		/* used to indicate this.                             */
+
+                i_glob_cnt = inl(state->card->iobase + GLOB_CNT);
+
+		/* Current # of channels enabled */
+		if ( i_glob_cnt & 0x0100000 )
+			ret = 4;
+		else if ( i_glob_cnt & 0x0200000 )
+			ret = 6;
+		else
+			ret = 2;
+
+		switch ( val ) {
+			case 2: /* 2 channels is always supported */
+				outl(state->card->iobase + GLOB_CNT, (i_glob_cnt & 0xcfffff));
+				/* Do we need to change mixer settings????  */
+				break;
+			case 4: /* Supported on some chipsets, better check first */
+				if ( state->card->channels >= 4 ) {
+					outl(state->card->iobase + GLOB_CNT, ((i_glob_cnt & 0xcfffff) | 0x0100000));
+					/* Do we need to change mixer settings??? */
+				} else {
+					val = ret;
+				}
+				break;
+			case 6: /* Supported on some chipsets, better check first */
+				if ( state->card->channels >= 6 ) {
+					outl(state->card->iobase + GLOB_CNT, ((i_glob_cnt & 0xcfffff) | 0x0200000));
+					/* Do we need to change mixer settings??? */
+				} else {
+					val = ret;
+				}
+				break;
+			default: /* nothing else is ever supported by the chipset */
+				val = ret;
+				break;
+		}
+
+		return put_user(val, (int *)arg);
 
 	case SNDCTL_DSP_POST: /* the user has sent all data and is notifying us */
 		/* we update the swptr to the end of the last sg segment then return */
@@ -1740,6 +1972,148 @@
 #endif
 		return put_user(AFMT_S16_LE, (int *)arg);
 
+	case SNDCTL_DSP_SETSPDIF: /* Set S/PDIF Control register */
+#ifdef DEBUG
+		printk("SNDCTL_DSP_SETSPDIF\n");
+#endif
+		if (get_user(val, (int *)arg))
+			return -EFAULT;
+
+		/* Check to make sure the codec supports S/PDIF transmitter */
+
+		if((state->card->ac97_features & 4)) {
+			/* mask out the transmitter speed bits so the user can't set them */
+			val &= ~0x3000;
+
+			/* Add the current transmitter speed bits to the passed value */
+			ret = i810_ac97_get(codec, AC97_SPDIF_CONTROL);
+			val |= (ret & 0x3000);
+
+			i810_ac97_set(codec, AC97_SPDIF_CONTROL, val);
+			if(i810_ac97_get(codec, AC97_SPDIF_CONTROL) != val ) {
+				printk(KERN_ERR "i810_audio: Unable to set S/PDIF configuration to 0x%04x.\n", val);
+				return -EFAULT;
+			}
+		}
+#ifdef DEBUG
+		else 
+			printk(KERN_WARNING "i810_audio: S/PDIF transmitter not avalible.\n");
+#endif
+		return put_user(val, (int *)arg);
+
+	case SNDCTL_DSP_GETSPDIF: /* Get S/PDIF Control register */
+#ifdef DEBUG
+		printk("SNDCTL_DSP_GETSPDIF\n");
+#endif
+		if (get_user(val, (int *)arg))
+			return -EFAULT;
+
+		/* Check to make sure the codec supports S/PDIF transmitter */
+
+		if(!(state->card->ac97_features & 4)) {
+#ifdef DEBUG
+			printk(KERN_WARNING "i810_audio: S/PDIF transmitter not avalible.\n");
+#endif
+			val = 0;
+		} else {
+			val = i810_ac97_get(codec, AC97_SPDIF_CONTROL);
+		}
+		//return put_user((val & 0xcfff), (int *)arg);
+		return put_user(val, (int *)arg);
+   			
+	case SNDCTL_DSP_GETCHANNELMASK:
+#ifdef DEBUG
+		printk("SNDCTL_DSP_GETCHANNELMASK\n");
+#endif
+		if (get_user(val, (int *)arg))
+			return -EFAULT;
+		
+		/* Based on AC'97 DAC support, not ICH hardware */
+		val = DSP_BIND_FRONT;
+		if ( state->card->ac97_features & 0x0004 )
+			val |= DSP_BIND_SPDIF;
+
+		if ( state->card->ac97_features & 0x0080 )
+			val |= DSP_BIND_SURR;
+		if ( state->card->ac97_features & 0x0140 )
+			val |= DSP_BIND_CENTER_LFE;
+
+		return put_user(val, (int *)arg);
+
+	case SNDCTL_DSP_BIND_CHANNEL:
+#ifdef DEBUG
+		printk("SNDCTL_DSP_BIND_CHANNEL\n");
+#endif
+		if (get_user(val, (int *)arg))
+			return -EFAULT;
+		if ( val == DSP_BIND_QUERY ) {
+			val = DSP_BIND_FRONT; /* Always report this as being enabled */
+			if ( state->card->ac97_status & SPDIF_ON ) 
+				val |= DSP_BIND_SPDIF;
+			else {
+				if ( state->card->ac97_status & SURR_ON )
+					val |= DSP_BIND_SURR;
+				if ( state->card->ac97_status & CENTER_LFE_ON )
+					val |= DSP_BIND_CENTER_LFE;
+			}
+		} else {  /* Not a query, set it */
+			if (!(file->f_mode & FMODE_WRITE))
+				return -EINVAL;
+			if ( dmabuf->enable == DAC_RUNNING ) {
+				stop_dac(state);
+			}
+			if ( val & DSP_BIND_SPDIF ) {  /* Turn on SPDIF */
+				/*  Ok, this should probably define what slots
+				 *  to use. For now, we'll only set it to the
+				 *  defaults:
+				 * 
+				 *   non multichannel codec maps to slots 3&4
+				 *   2 channel codec maps to slots 7&8
+				 *   4 channel codec maps to slots 6&9
+				 *   6 channel codec maps to slots 10&11
+				 *
+				 *  there should be some way for the app to
+				 *  select the slot assignment.
+				 */
+	
+				i810_set_spdif_output ( state, AC97_EA_SPSA_3_4, dmabuf->rate );
+				if ( !(state->card->ac97_status & SPDIF_ON) )
+					val &= ~DSP_BIND_SPDIF;
+			} else {
+				int mask;
+				int channels;
+
+				/* Turn off S/PDIF if it was on */
+				if ( state->card->ac97_status & SPDIF_ON ) 
+					i810_set_spdif_output ( state, -1, 0 );
+				
+				mask = val & (DSP_BIND_FRONT | DSP_BIND_SURR | DSP_BIND_CENTER_LFE);
+				switch (mask) {
+					case DSP_BIND_FRONT:
+						channels = 2;
+						break;
+					case DSP_BIND_FRONT|DSP_BIND_SURR:
+						channels = 4;
+						break;
+					case DSP_BIND_FRONT|DSP_BIND_SURR|DSP_BIND_CENTER_LFE:
+						channels = 6;
+						break;
+					default:
+						val = DSP_BIND_FRONT;
+						channels = 2;
+						break;
+				}
+				i810_set_dac_channels ( state, channels );
+
+				/* check that they really got turned on */
+				if ( !state->card->ac97_status & SURR_ON )
+					val &= ~DSP_BIND_SURR;
+				if ( !state->card->ac97_status & CENTER_LFE_ON )
+					val &= ~DSP_BIND_CENTER_LFE;
+			}
+		}
+		return put_user(val, (int *)arg);
+		
 	case SNDCTL_DSP_MAPINBUF:
 	case SNDCTL_DSP_MAPOUTBUF:
 	case SNDCTL_DSP_SETSYNCRO:
@@ -1805,7 +2179,15 @@
 			card->states[i] = NULL;;
 			return -EBUSY;
 		}
-		i810_set_dac_rate(state, 8000);
+		/* Initialize to 8kHz?  What if we don't support 8kHz? */
+		/*  Let's change this to check for S/PDIF stuff */
+	
+		if ( spdif_locked ) {
+			i810_set_dac_rate(state, spdif_locked);
+			i810_set_spdif_output(state, AC97_EA_SPSA_3_4, spdif_locked);
+		} else {
+			i810_set_dac_rate(state, 8000);
+		}
 		dmabuf->trigger |= PCM_ENABLE_OUTPUT;
 	}
 		
@@ -1875,20 +2257,23 @@
 {
 	struct i810_card *card = dev->private_data;
 	int count = 100;
+	u8 reg_set = ((dev->id)?((reg&0x7f)|0x80):(reg&0x7f));
 
 	while(count-- && (inb(card->iobase + CAS) & 1)) 
 		udelay(1);
-	return inw(card->ac97base + (reg&0x7f));
+	
+	return inw(card->ac97base + reg_set);
 }
 
 static void i810_ac97_set(struct ac97_codec *dev, u8 reg, u16 data)
 {
 	struct i810_card *card = dev->private_data;
 	int count = 100;
+	u8 reg_set = ((dev->id)?((reg&0x7f)|0x80):(reg&0x7f));
 
 	while(count-- && (inb(card->iobase + CAS) & 1)) 
 		udelay(1);
-	outw(data, card->ac97base + (reg&0x7f));
+	outw(data, card->ac97base + reg_set);
 }
 
 
@@ -1929,7 +2314,7 @@
 static int __init i810_ac97_init(struct i810_card *card)
 {
 	int num_ac97 = 0;
-	int ready_2nd = 0;
+	int total_channels = 0;
 	struct ac97_codec *codec;
 	u16 eid;
 	int i=0;
@@ -1961,10 +2346,38 @@
 
 	current->state = TASK_UNINTERRUPTIBLE;
 	schedule_timeout(HZ/5);
+
+	/* Number of channels supported */
+	/* What about the codec?  Just because the ICH supports */
+	/* multiple channels doesn't mean the codec does.       */
+	/* we'll have to modify this in the codec section below */
+	/* to reflect what the codec has.                       */
+	/* ICH and ICH0 only support 2 channels so don't bother */
+	/* to check....                                         */
+
+	card->channels = 2;
+	reg = inl(card->iobase + GLOB_STA);
+	if ( reg & 0x0200000 )
+		card->channels = 6;
+	else if ( reg & 0x0100000 )
+		card->channels = 4;
+	printk("i810_audio: Audio Controller supports %d channels.\n", card->channels);
 		
 	inw(card->ac97base);
 
 	for (num_ac97 = 0; num_ac97 < NR_AC97; num_ac97++) {
+
+		/* The ICH programmer's reference says you should   */
+		/* check the ready status before probing. So we chk */
+		/*   What do we do if it's not ready?  Wait and try */
+		/*   again, or abort?                               */
+		reg = inl(card->iobase + GLOB_STA);
+		if (!(reg & (0x100 << num_ac97))) {
+			if(num_ac97 == 0)
+				printk(KERN_ERR "i810_audio: Primary codec not ready.\n");
+			break; /* I think this works, if not ready stop */
+		}
+
 		if ((codec = kmalloc(sizeof(struct ac97_codec), GFP_KERNEL)) == NULL)
 			return -ENOMEM;
 		memset(codec, 0, sizeof(struct ac97_codec));
@@ -1992,6 +2405,9 @@
 			schedule_timeout(HZ/20);
 		}
 
+		/* Store state information about S/PDIF transmitter */
+		card->ac97_status = 0;
+
 		/* Don't attempt to get eid until powerup is complete */
 		eid = i810_ac97_get(codec, AC97_EXTENDED_ID);
 		
@@ -2023,6 +2439,63 @@
 			}
 		}
    		
+		/* Determine how many channels the codec(s) support   */
+		/*   - The primary codec always supports 2            */
+		/*   - If the codec supports AMAP, surround DACs will */
+		/*     automaticlly get assigned to slots.            */
+		/*     * Check for surround DACs and increment if     */
+		/*       found.                                       */
+		/*   - Else check if the codec is revision 2.2        */
+		/*     * If surround DACs exist, assign them to slots */
+		/*       and increment channel count.                 */
+
+		/* All of this only applies to ICH2 and above. ICH    */
+		/* and ICH0 only support 2 channels.  ICH2 will only  */
+		/* support multiple codecs in a "split audio" config. */
+		/* as described above.                                */
+
+		/* TODO: Remove all the debugging messages!           */
+
+		if((eid & 0xc000) == 0) /* primary codec */
+			total_channels += 2; 
+
+		if(eid & 0x200) { /* GOOD, AMAP support */
+			if (eid & 0x0080) /* L/R Surround channels */
+				total_channels += 2;
+			if (eid & 0x0140) /* LFE and Center channels */
+				total_channels += 2;
+			printk("i810_audio: AC'97 codec %d supports AMAP, total channels = %d\n", num_ac97, total_channels);
+		} else if (eid & 0x0400) {  /* this only works on 2.2 compliant codecs */
+			eid &= 0xffcf;
+			if((eid & 0xc000) != 0)	{
+				switch ( total_channels ) {
+					case 2:
+						/* Set dsa1, dsa0 to 01 */
+						eid |= 0x0010;
+						break;
+					case 4:
+						/* Set dsa1, dsa0 to 10 */
+						eid |= 0x0020;
+						break;
+					case 6:
+						/* Set dsa1, dsa0 to 11 */
+						eid |= 0x0030;
+						break;
+				}
+				total_channels += 2;
+			}
+			i810_ac97_set(codec, AC97_EXTENDED_ID, eid);
+			eid = i810_ac97_get(codec, AC97_EXTENDED_ID);
+			printk("i810_audio: AC'97 codec %d, new EID value = 0x%04x\n", num_ac97, eid);
+			if (eid & 0x0080) /* L/R Surround channels */
+				total_channels += 2;
+			if (eid & 0x0140) /* LFE and Center channels */
+				total_channels += 2;
+			printk("i810_audio: AC'97 codec %d, DAC map configured, total channels = %d\n", num_ac97, total_channels);
+		} else {
+			printk("i810_audio: AC'97 codec %d Unable to map surround DAC's (or DAC's not present), total channels = %d\n", num_ac97, total_channels);
+		}
+
 		if ((codec->dev_mixer = register_sound_mixer(&i810_mixer_fops, -1)) < 0) {
 			printk(KERN_ERR "i810_audio: couldn't register mixer!\n");
 			kfree(codec);
@@ -2030,14 +2503,83 @@
 		}
 
 		card->ac97_codec[num_ac97] = codec;
-
-		/* if there is no secondary codec at all, don't probe any more */
-		if (!ready_2nd)
-			return num_ac97+1;
 	}
+
+	/* pick the minimum of channels supported by ICHx or codec(s) */
+	card->channels = (card->channels > total_channels)?total_channels:card->channels;
+
 	return num_ac97;
 }
 
+static void __init i810_configure_clocking (void)
+{
+	struct i810_card *card;
+	struct i810_state *state;
+	struct dmabuf *dmabuf;
+	unsigned int i, offset, new_offset;
+	unsigned long flags;
+
+	card = devs;
+	/* We could try to set the clocking for multiple cards, but can you even have
+	 * more than one i810 in a machine?  Besides, clocking is global, so unless
+	 * someone actually thinks more than one i810 in a machine is possible and
+	 * decides to rewrite that little bit, setting the rate for more than one card
+	 * is a waste of time.
+	 */
+	if(card != NULL) {
+		state = card->states[0] = (struct i810_state *)
+					kmalloc(sizeof(struct i810_state), GFP_KERNEL);
+		if (state == NULL)
+			return;
+		memset(state, 0, sizeof(struct i810_state));
+		dmabuf = &state->dmabuf;
+
+		dmabuf->write_channel = card->alloc_pcm_channel(card);
+		state->virt = 0;
+		state->card = card;
+		state->magic = I810_STATE_MAGIC;
+		init_waitqueue_head(&dmabuf->wait);
+		init_MUTEX(&state->open_sem);
+		dmabuf->fmt = I810_FMT_STEREO | I810_FMT_16BIT;
+		dmabuf->trigger = PCM_ENABLE_OUTPUT;
+		i810_set_dac_rate(state, 48000);
+		if(prog_dmabuf(state, 0) != 0) {
+			goto config_out_nodmabuf;
+		}
+		if(dmabuf->dmasize < 16384) {
+			goto config_out;
+		}
+		dmabuf->count = dmabuf->dmasize;
+		outb(31,card->iobase+dmabuf->write_channel->port+OFF_LVI);
+		save_flags(flags);
+		cli();
+		start_dac(state);
+		offset = i810_get_dma_addr(state, 0);
+		mdelay(50);
+		new_offset = i810_get_dma_addr(state, 0);
+		stop_dac(state);
+		outb(2,card->iobase+dmabuf->write_channel->port+OFF_CR);
+		restore_flags(flags);
+		i = new_offset - offset;
+#ifdef DEBUG
+		printk("i810_audio: %d bytes in 50 milliseconds\n", i);
+#endif
+		if(i == 0)
+			goto config_out;
+		i = i / 4 * 20;
+		if (i > 48500 || i < 47500) {
+			clocking = clocking * clocking / i;
+			printk("i810_audio: setting clocking to %d\n", clocking);
+		}
+config_out:
+		dealloc_dmabuf(state);
+config_out_nodmabuf:
+		state->card->free_pcm_channel(state->card,state->dmabuf.write_channel->num);
+		kfree(state);
+		card->states[0] = NULL;
+	}
+}
+
 /* install the driver, we do not allocate hardware channel nor DMA buffer now, they are defered 
    until "ACCESS" time (in prog_dmabuf called by open/read/write/ioctl/mmap) */
    
@@ -2102,27 +2644,37 @@
 		kfree(card);
 		return -ENODEV;
 	}
-	/* register /dev/dsp */
-	if ((card->dev_audio = register_sound_dsp(&i810_audio_fops, -1)) < 0) {
-		printk(KERN_ERR "i810_audio: couldn't register DSP device!\n");
+
+	/* initialize AC97 codec and register /dev/mixer */
+	if (i810_ac97_init(card) <= 0) {
 		release_region(card->iobase, 64);
 		release_region(card->ac97base, 256);
 		free_irq(card->irq, card);
 		kfree(card);
 		return -ENODEV;
 	}
+	pci_dev->driver_data = card;
 
+	if(clocking == 48000) {
+		i810_configure_clocking();
+	}
 
-	/* initialize AC97 codec and register /dev/mixer */
-	if (i810_ac97_init(card) <= 0) {
-		unregister_sound_dsp(card->dev_audio);
+	/* register /dev/dsp */
+	if ((card->dev_audio = register_sound_dsp(&i810_audio_fops, -1)) < 0) {
+		int i;
+		printk(KERN_ERR "i810_audio: couldn't register DSP device!\n");
 		release_region(card->iobase, 64);
 		release_region(card->ac97base, 256);
 		free_irq(card->irq, card);
+		for (i = 0; i < NR_AC97; i++)
+		if (card->ac97_codec[i] != NULL) {
+			unregister_sound_mixer(card->ac97_codec[i]->dev_mixer);
+			kfree (card->ac97_codec[i]);
+		}
 		kfree(card);
 		return -ENODEV;
 	}
-	pci_dev->driver_data = card;
+
 	return 0;
 }
 
@@ -2137,7 +2689,7 @@
 
 	/* unregister audio devices */
 	for (i = 0; i < NR_AC97; i++)
-		if (devs->ac97_codec[i] != NULL) {
+		if (card->ac97_codec[i] != NULL) {
 			unregister_sound_mixer(card->ac97_codec[i]->dev_mixer);
 			kfree (card->ac97_codec[i]);
 		}
@@ -2151,6 +2703,7 @@
 MODULE_PARM(ftsodell, "i");
 MODULE_PARM(clocking, "i");
 MODULE_PARM(strict_clocking, "i");
+MODULE_PARM(spdif_locked, "i");
 
 #define I810_MODULE_NAME "intel810_audio"
 
@@ -2161,74 +2714,6 @@
 	remove:		i810_remove,
 };
 
-static void __init i810_configure_clocking (void)
-{
-	struct i810_card *card;
-	struct i810_state *state;
-	struct dmabuf *dmabuf;
-	unsigned int i, offset, new_offset;
-	unsigned long flags;
-
-	card = devs;
-	/* We could try to set the clocking for multiple cards, but can you even have
-	 * more than one i810 in a machine?  Besides, clocking is global, so unless
-	 * someone actually thinks more than one i810 in a machine is possible and
-	 * decides to rewrite that little bit, setting the rate for more than one card
-	 * is a waste of time.
-	 */
-	if(card != NULL) {
-		state = card->states[0] = (struct i810_state *)
-					kmalloc(sizeof(struct i810_state), GFP_KERNEL);
-		if (state == NULL)
-			return;
-		memset(state, 0, sizeof(struct i810_state));
-		dmabuf = &state->dmabuf;
-
-		dmabuf->write_channel = card->alloc_pcm_channel(card);
-		state->virt = 0;
-		state->card = card;
-		state->magic = I810_STATE_MAGIC;
-		init_waitqueue_head(&dmabuf->wait);
-		init_MUTEX(&state->open_sem);
-		dmabuf->fmt = I810_FMT_STEREO | I810_FMT_16BIT;
-		dmabuf->trigger = PCM_ENABLE_OUTPUT;
-		i810_set_dac_rate(state, 48000);
-		if(prog_dmabuf(state, 0) != 0) {
-			goto config_out_nodmabuf;
-		}
-		if(dmabuf->dmasize < 16384) {
-			goto config_out;
-		}
-		dmabuf->count = dmabuf->dmasize;
-		outb(31,card->iobase+dmabuf->write_channel->port+OFF_LVI);
-		save_flags(flags);
-		cli();
-		start_dac(state);
-		offset = i810_get_dma_addr(state, 0);
-		mdelay(50);
-		new_offset = i810_get_dma_addr(state, 0);
-		stop_dac(state);
-		outb(2,card->iobase+dmabuf->write_channel->port+OFF_CR);
-		restore_flags(flags);
-		i = new_offset - offset;
-#ifdef DEBUG
-		printk("i810_audio: %d bytes in 50 milliseconds\n", i);
-#endif
-		if(i == 0)
-			goto config_out;
-		i = i / 4 * 20;
-		if (i > 48500 || i < 47500) {
-			clocking = clocking * clocking / i;
-			printk("i810_audio: setting clocking to %d\n", clocking);
-		}
-config_out:
-		dealloc_dmabuf(state);
-config_out_nodmabuf:
-		state->card->free_pcm_channel(state->card,state->dmabuf.write_channel->num);
-		kfree(state);
-		card->states[0] = NULL;
-	}
-}
 
 static int __init i810_init_module (void)
 {
@@ -2248,6 +2733,15 @@
 	if(clocking == 48000) {
 		i810_configure_clocking();
 	}
+	if(spdif_locked > 0 ) {
+		if(spdif_locked == 32000 || spdif_locked == 44100 || spdif_locked == 48000) {
+			printk("i810_audio: Enabling S/PDIF at sample rate %dHz.\n", spdif_locked);
+		} else {
+			printk("i810_audio: S/PDIF can only be locked to 32000, 441000, or 48000Hz.\n");
+			spdif_locked = 0;
+		}
+	}
+	
 	return 0;
 }
 
diff -u --recursive --new-file v2.4.9/linux/drivers/sound/ite8172.c linux/drivers/sound/ite8172.c
--- v2.4.9/linux/drivers/sound/ite8172.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/sound/ite8172.c	Fri Sep  7 09:28:37 2001
@@ -0,0 +1,1957 @@
+/*
+ *      ite8172.c  --  ITE IT8172G Sound Driver.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	stevel@mvista.com or source@mvista.com
+ *
+ *  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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * Module command line parameters:
+ *
+ *  Supported devices:
+ *  /dev/dsp    standard OSS /dev/dsp device
+ *  /dev/mixer  standard OSS /dev/mixer device
+ *
+ * Notes:
+ *
+ *  1. Much of the OSS buffer allocation, ioctl's, and mmap'ing are
+ *     taken, slightly modified or not at all, from the ES1371 driver,
+ *     so refer to the credits in es1371.c for those. The rest of the
+ *     code (probe, open, read, write, the ISR, etc.) is new.
+ *  2. The following support is untested:
+ *      * Memory mapping the audio buffers, and the ioctl controls that go
+ *        with it.
+ *      * S/PDIF output.
+ *  3. The following is not supported:
+ *      * I2S input.
+ *      * legacy audio mode.
+ *  4. Support for volume button interrupts is implemented but doesn't
+ *     work yet.
+ *
+ *  Revision history
+ *    02.08.2001  0.1   Initial release
+ */
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/sound.h>
+#include <linux/malloc.h>
+#include <linux/soundcard.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <linux/bitops.h>
+#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
+#include <linux/ac97_codec.h>
+#include <linux/wrapper.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <asm/uaccess.h>
+#include <asm/hardirq.h>
+#include <asm/it8172/it8172.h>
+
+/* --------------------------------------------------------------------- */
+
+#undef OSS_DOCUMENTED_MIXER_SEMANTICS
+#define IT8172_DEBUG
+#undef IT8172_VERBOSE_DEBUG
+#define DBG(x) {}
+
+static const unsigned sample_shift[] = { 0, 1, 1, 2 };
+
+
+/*
+ * Audio Controller register bit definitions follow. See
+ * include/asm/it8172/it8172.h for register offsets.
+ */
+
+/* PCM Out Volume Reg */
+#define PCMOV_PCMOM	(1<<15)	/* PCM Out Mute default 1: mute */
+#define	PCMOV_PCMRCG_BIT 8	/* PCM Right channel Gain */
+#define	PCMOV_PCMRCG_MASK (0x1f<<PCMOV_PCMRCG_BIT)
+#define PCMOV_PCMLCG_BIT 0	/* PCM Left channel gain  */
+#define PCMOV_PCMLCG_MASK 0x1f
+
+/* FM Out Volume Reg */
+#define FMOV_FMOM       (1<<15)	/* FM Out Mute default 1: mute */
+#define	FMOV_FMRCG_BIT	8	/* FM Right channel Gain */
+#define	FMOV_FMRCG_MASK (0x1f<<FMOV_FMRCG_BIT)
+#define FMOV_FMLCG_BIT	0	/* FM Left channel gain  */
+#define FMOV_FMLCG_MASK 0x1f
+
+/* I2S Out Volume Reg */
+#define I2SV_I2SOM	 (1<<15) /* I2S Out Mute default 1: mute */
+#define	I2SV_I2SRCG_BIT	 8	 /* I2S Right channel Gain */
+#define	I2SV_I2SRCG_MASK (0x1f<<I2SV_I2SRCG_BIT)
+#define I2SV_I2SLCG_BIT	 0	 /* I2S Left channel gain  */
+#define I2SV_I2SLCG_MASK 0x1f
+
+/* Digital Recording Source Select Reg */
+#define	DRSS_BIT   0
+#define	DRSS_MASK  0x07
+#define   DRSS_AC97_PRIM 0
+#define   DRSS_FM        1
+#define   DRSS_I2S       2
+#define   DRSS_PCM       3
+#define   DRSS_AC97_SEC  4
+
+/* Playback/Capture Channel Control Registers */
+#define	CC_SM	        (1<<15)	/* Stereo, Mone 0: mono 1: stereo */
+#define	CC_DF	        (1<<14)	/* Data Format 0: 8 bit 1: 16 bit */
+#define CC_FMT_BIT      14
+#define CC_FMT_MASK     (0x03<<CC_FMT_BIT)
+#define CC_CF_BIT       12      /* Channel format (Playback only) */
+#define CC_CF_MASK      (0x03<<CC_CF_BIT)
+#define	  CC_CF_2	0
+#define   CC_CF_4	(1<<CC_CF_BIT)
+#define   CC_CF_6	(2<<CC_CF_BIT)
+#define CC_SR_BIT       8       /* sample Rate */
+#define CC_SR_MASK      (0x0f<<CC_SR_BIT)
+#define	  CC_SR_5500	0
+#define	  CC_SR_8000	(1<<CC_SR_BIT)
+#define	  CC_SR_9600	(2<<CC_SR_BIT)
+#define	  CC_SR_11025	(3<<CC_SR_BIT)
+#define	  CC_SR_16000	(4<<CC_SR_BIT)
+#define	  CC_SR_19200	(5<<CC_SR_BIT)
+#define	  CC_SR_22050	(6<<CC_SR_BIT)
+#define	  CC_SR_32000	(7<<CC_SR_BIT)
+#define	  CC_SR_38400	(8<<CC_SR_BIT)
+#define	  CC_SR_44100	(9<<CC_SR_BIT)
+#define	  CC_SR_48000	(10<<CC_SR_BIT)
+#define	CC_CSP	        (1<<7)	/* Channel stop 
+				 * 0: End of Current buffer
+				 * 1: Immediately stop when rec stop */
+#define CC_CP	        (1<<6)	/* Channel pause 0: normal, 1: pause */
+#define	CC_CA	        (1<<5)	/* Channel Action 0: Stop , 1: start */
+#define	CC_CB2L         (1<<2)	/* Cur. buf. 2 xfr is last 0: No, 1: Yes */
+#define CC_CB1L         (1<<1)	/* Cur. buf. 1 xfr is last 0: No, 1: Yes */
+#define CC_DE	        1	/* DFC/DFIFO Data Empty 1: empty, 0: not empty
+				 * (Playback only)
+				 */
+
+/* Codec Control Reg */
+#define CODECC_GME	(1<<9)	/* AC97 GPIO Mode enable */
+#define	CODECC_ATM	(1<<8)	/* AC97 ATE test mode 0: test 1: normal */
+#define	CODECC_WR	(1<<6)	/* AC97 Warn reset 1: warm reset , 0: Normal */
+#define	CODECC_CR	(1<<5)	/* AC97 Cold reset 1: Cold reset , 0: Normal */
+
+
+/* I2S Control Reg	*/
+#define	I2SMC_SR_BIT	 6	/* I2S Sampling rate 
+				 * 00: 48KHz, 01: 44.1 KHz, 10: 32 32 KHz */
+#define	I2SMC_SR_MASK    (0x03<<I2SMC_SR_BIT)
+#define	  I2SMC_SR_48000 0
+#define	  I2SMC_SR_44100 (1<<I2SMC_SR_BIT)
+#define	  I2SMC_SR_32000 (2<<I2SMC_SR_BIT)
+#define	I2SMC_SRSS	 (1<<5)	/* Sample Rate Source Select 1:S/W, 0: H/W */
+#define I2SMC_I2SF_BIT	 0	/* I2S Format */
+#define I2SMC_I2SF_MASK  0x03
+#define   I2SMC_I2SF_DAC 0
+#define   I2SMC_I2SF_ADC 2
+#define   I2SMC_I2SF_I2S 3
+
+
+/* Volume up, Down, Mute */
+#define	VS_VMP	(1<<2)	/* Volume mute 1: pushed, 0: not */
+#define	VS_VDP	(1<<1)	/* Volume Down 1: pushed, 0: not */
+#define VS_VUP	1	/* Volime Up 1: pushed, 0: not */
+
+/* SRC, Mixer test control/DFC status reg */
+#define SRCS_DPUSC      (1<<5)	/* DFC Playback underrun Status/clear */
+#define	SRCS_DCOSC	(1<<4)	/* DFC Capture Overrun Status/clear */
+#define SRCS_SIS	(1<<3)	/* SRC input select 1: Mixer, 0: Codec I/F */
+#define SRCS_CDIS_BIT	0	/* Codec Data Input Select */
+#define SRCS_CDIS_MASK  0x07
+#define   SRCS_CDIS_MIXER 0
+#define   SRCS_CDIS_PCM   1
+#define   SRCS_CDIS_I2S   2
+#define   SRCS_CDIS_FM    3
+#define   SRCS_CDIS_DFC   4
+
+
+/* Codec Index Reg command Port */
+#define CIRCP_CID_BIT   10
+#define CIRCP_CID_MASK  (0x03<<CIRCP_CID_BIT)
+#define CIRCP_CPS	(1<<9)	/* Command Port Status 0: ready, 1: busy */
+#define	CIRCP_DPVF	(1<<8)	/* Data Port Valid Flag 0: invalis, 1: valid */
+#define CIRCP_RWC	(1<<7)	/* Read/write command */
+#define CIRCP_CIA_BIT   0
+#define CIRCP_CIA_MASK  0x007F	/* Codec Index Address */
+
+/* Test Mode Control/Test group Select Control */
+
+/* General Control Reg */
+#define GC_VDC_BIT	6	/* Volume Division Control */
+#define GC_VDC_MASK     (0x03<<GC_VDC_BIT)
+#define   GC_VDC_NONE   0
+#define   GC_VDC_DIV2   (1<<GC_VDC_BIT)
+#define   GC_VDC_DIV4   (2<<GC_VDC_BIT)
+#define	GC_SOE	        (1<<2)	/* S/PDIF Output enable */
+#define	GC_SWR	        1	/* Software warn reset */
+
+/* Interrupt mask Control Reg */
+#define	IMC_VCIM	(1<<6)	/* Volume CNTL interrupt mask */
+#define	IMC_CCIM	(1<<1)	/* Capture Chan. iterrupt mask */
+#define	IMC_PCIM	1	/* Playback Chan. interrupt mask */
+
+/* Interrupt status/clear reg */
+#define	ISC_VCI	        (1<<6)	/* Volume CNTL interrupt 1: clears */
+#define	ISC_CCI	        (1<<1)	/* Capture Chan. interrupt 1: clears  */
+#define	ISC_PCI	        1	/* Playback Chan. interrupt 1: clears */
+
+/* misc stuff */
+#define POLL_COUNT   0x5000
+
+
+#define IT8172_MODULE_NAME "IT8172 audio"
+#define PFX IT8172_MODULE_NAME ": "
+
+
+/* --------------------------------------------------------------------- */
+
+struct it8172_state {
+    /* list of it8172 devices */
+    struct list_head devs;
+
+    /* the corresponding pci_dev structure */
+    struct pci_dev *dev;
+
+    /* soundcore stuff */
+    int dev_audio;
+
+    /* hardware resources */
+    unsigned long io;
+    unsigned int irq;
+
+    /* PCI ID's */
+    u16 vendor;
+    u16 device;
+    u8 rev; /* the chip revision */
+
+    /* options */
+    int spdif_volume; /* S/PDIF output is enabled if != -1 */
+
+#ifdef IT8172_DEBUG
+    /* debug /proc entry */
+    struct proc_dir_entry *ps;
+    struct proc_dir_entry *ac97_ps;
+#endif /* IT8172_DEBUG */
+
+    struct ac97_codec codec;
+
+    unsigned short pcc, capcc;
+    unsigned dacrate, adcrate;
+
+    spinlock_t lock;
+    struct semaphore open_sem;
+    mode_t open_mode;
+    wait_queue_head_t open_wait;
+
+    struct dmabuf {
+	void *rawbuf;
+	dma_addr_t dmaaddr;
+	unsigned buforder;
+	unsigned numfrag;
+	unsigned fragshift;
+	void* nextIn;
+	void* nextOut;
+	int count;
+	int curBufPtr;
+	unsigned total_bytes;
+	unsigned error; /* over/underrun */
+	wait_queue_head_t wait;
+	/* redundant, but makes calculations easier */
+	unsigned fragsize;
+	unsigned dmasize;
+	unsigned fragsamples;
+	/* OSS stuff */
+	unsigned mapped:1;
+	unsigned ready:1;
+	unsigned stopped:1;
+	unsigned ossfragshift;
+	int ossmaxfrags;
+	unsigned subdivision;
+    } dma_dac, dma_adc;
+};
+
+/* --------------------------------------------------------------------- */
+
+static LIST_HEAD(devs);
+
+/* --------------------------------------------------------------------- */
+
+extern inline unsigned ld2(unsigned int x)
+{
+    unsigned r = 0;
+	
+    if (x >= 0x10000) {
+	x >>= 16;
+	r += 16;
+    }
+    if (x >= 0x100) {
+	x >>= 8;
+	r += 8;
+    }
+    if (x >= 0x10) {
+	x >>= 4;
+	r += 4;
+    }
+    if (x >= 4) {
+	x >>= 2;
+	r += 2;
+    }
+    if (x >= 2)
+	r++;
+    return r;
+}
+
+/* --------------------------------------------------------------------- */
+
+static void it8172_delay(int msec)
+{
+    unsigned long tmo;
+    signed long tmo2;
+
+    if (in_interrupt())
+	return;
+    
+    tmo = jiffies + (msec*HZ)/1000;
+    for (;;) {
+	tmo2 = tmo - jiffies;
+	if (tmo2 <= 0)
+	    break;
+	schedule_timeout(tmo2);
+    }
+}
+
+
+static unsigned short
+get_compat_rate(unsigned* rate)
+{
+    unsigned rate_out = *rate;
+    unsigned short sr;
+    
+    if (rate_out >= 46050) {
+	sr = CC_SR_48000; rate_out = 48000;
+    } else if (rate_out >= 41250) {
+	sr = CC_SR_44100; rate_out = 44100;
+    } else if (rate_out >= 35200) {
+	sr = CC_SR_38400; rate_out = 38400;
+    } else if (rate_out >= 27025) {
+	sr = CC_SR_32000; rate_out = 32000;
+    } else if (rate_out >= 20625) {
+	sr = CC_SR_22050; rate_out = 22050;
+    } else if (rate_out >= 17600) {
+	sr = CC_SR_19200; rate_out = 19200;
+    } else if (rate_out >= 13513) {
+	sr = CC_SR_16000; rate_out = 16000;
+    } else if (rate_out >= 10313) {
+	sr = CC_SR_11025; rate_out = 11025;
+    } else if (rate_out >= 8800) {
+	sr = CC_SR_9600; rate_out = 9600;
+    } else if (rate_out >= 6750) {
+	sr = CC_SR_8000; rate_out = 8000;
+    } else {
+	sr = CC_SR_5500; rate_out = 5500;
+    }
+
+    *rate = rate_out;
+    return sr;
+}
+
+static void set_adc_rate(struct it8172_state *s, unsigned rate)
+{
+    unsigned long flags;
+    unsigned short sr;
+    
+    sr = get_compat_rate(&rate);
+
+    spin_lock_irqsave(&s->lock, flags);
+    s->capcc &= ~CC_SR_MASK;
+    s->capcc |= sr;
+    outw(s->capcc, s->io+IT_AC_CAPCC);
+    spin_unlock_irqrestore(&s->lock, flags);
+
+    s->adcrate = rate;
+}
+
+
+static void set_dac_rate(struct it8172_state *s, unsigned rate)
+{
+    unsigned long flags;
+    unsigned short sr;
+    
+    sr = get_compat_rate(&rate);
+
+    spin_lock_irqsave(&s->lock, flags);
+    s->pcc &= ~CC_SR_MASK;
+    s->pcc |= sr;
+    outw(s->pcc, s->io+IT_AC_PCC);
+    spin_unlock_irqrestore(&s->lock, flags);
+
+    s->dacrate = rate;
+}
+
+
+/* --------------------------------------------------------------------- */
+
+static u16 rdcodec(struct ac97_codec *codec, u8 addr)
+{
+    struct it8172_state *s = (struct it8172_state *)codec->private_data;
+    unsigned long flags;
+    unsigned short circp, data;
+    int i;
+    
+    spin_lock_irqsave(&s->lock, flags);
+
+    for (i = 0; i < POLL_COUNT; i++)
+	if (!(inw(s->io+IT_AC_CIRCP) & CIRCP_CPS))
+	    break;
+    if (i == POLL_COUNT)
+	printk(KERN_INFO PFX "rdcodec: codec ready poll expired!\n");
+
+    circp = addr & CIRCP_CIA_MASK;
+    circp |= (codec->id << CIRCP_CID_BIT);
+    circp |= CIRCP_RWC; // read command
+    outw(circp, s->io+IT_AC_CIRCP);
+
+    /* now wait for the data */
+    for (i = 0; i < POLL_COUNT; i++)
+	if (inw(s->io+IT_AC_CIRCP) & CIRCP_DPVF)
+	    break;
+    if (i == POLL_COUNT)
+	printk(KERN_INFO PFX "rdcodec: read poll expired!\n");
+
+    data = inw(s->io+IT_AC_CIRDP);
+    spin_unlock_irqrestore(&s->lock, flags);
+
+    return data;
+}
+
+
+static void wrcodec(struct ac97_codec *codec, u8 addr, u16 data)
+{
+    struct it8172_state *s = (struct it8172_state *)codec->private_data;
+    unsigned long flags;
+    unsigned short circp;
+    int i;
+    
+    spin_lock_irqsave(&s->lock, flags);
+
+    for (i = 0; i < POLL_COUNT; i++)
+	if (!(inw(s->io+IT_AC_CIRCP) & CIRCP_CPS))
+	    break;
+    if (i == POLL_COUNT)
+	printk(KERN_INFO PFX "wrcodec: codec ready poll expired!\n");
+
+    circp = addr & CIRCP_CIA_MASK;
+    circp |= (codec->id << CIRCP_CID_BIT);
+    circp &= ~CIRCP_RWC; // write command
+
+    outw(data,  s->io+IT_AC_CIRDP);  // send data first
+    outw(circp, s->io+IT_AC_CIRCP);
+
+    spin_unlock_irqrestore(&s->lock, flags);
+}
+
+
+static void waitcodec(struct ac97_codec *codec)
+{
+    unsigned short temp;
+
+    /* codec_wait is used to wait for a ready state after
+       an AC97_RESET. */
+    it8172_delay(10);
+
+    temp = rdcodec(codec, 0x26);
+
+    // If power down, power up
+    if (temp & 0x3f00) {
+	// Power on
+	wrcodec(codec, 0x26, 0);
+	it8172_delay(100);
+	// Reread
+	temp = rdcodec(codec, 0x26);
+    }
+    
+    // Check if Codec REF,ANL,DAC,ADC ready***/
+    if ((temp & 0x3f0f) != 0x000f) {
+	printk(KERN_INFO PFX "codec reg 26 status (0x%x) not ready!!\n",
+	       temp);
+	return;
+    }
+}
+
+
+/* --------------------------------------------------------------------- */
+
+extern inline void stop_adc(struct it8172_state *s)
+{
+    struct dmabuf* db = &s->dma_adc;
+    unsigned long flags;
+    unsigned char imc;
+    
+    if (db->stopped)
+	return;
+
+    spin_lock_irqsave(&s->lock, flags);
+
+    s->capcc &= ~(CC_CA | CC_CP | CC_CB2L | CC_CB1L);
+    s->capcc |= CC_CSP;
+    outw(s->capcc, s->io+IT_AC_CAPCC);
+    
+    // disable capture interrupt
+    imc = inb(s->io+IT_AC_IMC);
+    outb(imc | IMC_CCIM, s->io+IT_AC_IMC);
+
+    db->stopped = 1;
+
+    spin_unlock_irqrestore(&s->lock, flags);
+}	
+
+extern inline void stop_dac(struct it8172_state *s)
+{
+    struct dmabuf* db = &s->dma_dac;
+    unsigned long flags;
+    unsigned char imc;
+    
+    if (db->stopped)
+	return;
+
+    spin_lock_irqsave(&s->lock, flags);
+
+    s->pcc &= ~(CC_CA | CC_CP | CC_CB2L | CC_CB1L);
+    s->pcc |= CC_CSP;
+    outw(s->pcc, s->io+IT_AC_PCC);
+    
+    // disable playback interrupt
+    imc = inb(s->io+IT_AC_IMC);
+    outb(imc | IMC_PCIM, s->io+IT_AC_IMC);
+
+    db->stopped = 1;
+    
+    spin_unlock_irqrestore(&s->lock, flags);
+}	
+
+static void start_dac(struct it8172_state *s)
+{
+    struct dmabuf* db = &s->dma_dac;
+    unsigned long flags;
+    unsigned char imc;
+    unsigned long buf1, buf2;
+    
+    if (!db->stopped)
+	return;
+    
+    spin_lock_irqsave(&s->lock, flags);
+
+    // reset Buffer 1 and 2 pointers to nextOut and nextOut+fragsize
+    buf1 = virt_to_bus(db->nextOut);
+    buf2 = buf1 + db->fragsize;
+    if (buf2 >= db->dmaaddr + db->dmasize)
+	buf2 -= db->dmasize;
+    
+    outl(buf1, s->io+IT_AC_PCB1STA);
+    outl(buf2, s->io+IT_AC_PCB2STA);
+    db->curBufPtr = IT_AC_PCB1STA;
+    
+    // enable playback interrupt
+    imc = inb(s->io+IT_AC_IMC);
+    outb(imc & ~IMC_PCIM, s->io+IT_AC_IMC);
+
+    s->pcc &= ~(CC_CSP | CC_CP | CC_CB2L | CC_CB1L);
+    s->pcc |= CC_CA;
+    outw(s->pcc, s->io+IT_AC_PCC);
+    
+    db->stopped = 0;
+
+    spin_unlock_irqrestore(&s->lock, flags);
+}	
+
+static void start_adc(struct it8172_state *s)
+{
+    struct dmabuf* db = &s->dma_adc;
+    unsigned long flags;
+    unsigned char imc;
+    unsigned long buf1, buf2;
+    
+    if (!db->stopped)
+	return;
+
+    spin_lock_irqsave(&s->lock, flags);
+
+    // reset Buffer 1 and 2 pointers to nextIn and nextIn+fragsize
+    buf1 = virt_to_bus(db->nextIn);
+    buf2 = buf1 + db->fragsize;
+    if (buf2 >= db->dmaaddr + db->dmasize)
+	buf2 -= db->dmasize;
+    
+    outl(buf1, s->io+IT_AC_CAPB1STA);
+    outl(buf2, s->io+IT_AC_CAPB2STA);
+    db->curBufPtr = IT_AC_CAPB1STA;
+
+    // enable capture interrupt
+    imc = inb(s->io+IT_AC_IMC);
+    outb(imc & ~IMC_CCIM, s->io+IT_AC_IMC);
+
+    s->capcc &= ~(CC_CSP | CC_CP | CC_CB2L | CC_CB1L);
+    s->capcc |= CC_CA;
+    outw(s->capcc, s->io+IT_AC_CAPCC);
+    
+    db->stopped = 0;
+
+    spin_unlock_irqrestore(&s->lock, flags);
+}	
+
+/* --------------------------------------------------------------------- */
+
+#define DMABUF_DEFAULTORDER (17-PAGE_SHIFT)
+#define DMABUF_MINORDER 1
+
+extern inline void dealloc_dmabuf(struct it8172_state *s, struct dmabuf *db)
+{
+    struct page *page, *pend;
+
+    if (db->rawbuf) {
+	/* undo marking the pages as reserved */
+	pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
+	for (page = virt_to_page(db->rawbuf); page <= pend; page++)
+	    mem_map_unreserve(page);
+	pci_free_consistent(s->dev, PAGE_SIZE << db->buforder,
+			    db->rawbuf, db->dmaaddr);
+    }
+    db->rawbuf = db->nextIn = db->nextOut = NULL;
+    db->mapped = db->ready = 0;
+}
+
+static int prog_dmabuf(struct it8172_state *s, struct dmabuf *db,
+		       unsigned rate, unsigned fmt, unsigned reg)
+{
+    int order;
+    unsigned bytepersec;
+    unsigned bufs;
+    struct page *page, *pend;
+
+    if (!db->rawbuf) {
+	db->ready = db->mapped = 0;
+	for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--)
+	    if ((db->rawbuf = pci_alloc_consistent(s->dev,
+						   PAGE_SIZE << order,
+						   &db->dmaaddr)))
+		break;
+	if (!db->rawbuf)
+	    return -ENOMEM;
+	db->buforder = order;
+	/* now mark the pages as reserved;
+	   otherwise remap_page_range doesn't do what we want */
+	pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
+	for (page = virt_to_page(db->rawbuf); page <= pend; page++)
+	    mem_map_reserve(page);
+    }
+
+    db->count = 0;
+    db->nextIn = db->nextOut = db->rawbuf;
+    
+    bytepersec = rate << sample_shift[fmt];
+    bufs = PAGE_SIZE << db->buforder;
+    if (db->ossfragshift) {
+	if ((1000 << db->ossfragshift) < bytepersec)
+	    db->fragshift = ld2(bytepersec/1000);
+	else
+	    db->fragshift = db->ossfragshift;
+    } else {
+	db->fragshift = ld2(bytepersec/100/(db->subdivision ?
+					    db->subdivision : 1));
+	if (db->fragshift < 3)
+	    db->fragshift = 3;
+    }
+    db->numfrag = bufs >> db->fragshift;
+    while (db->numfrag < 4 && db->fragshift > 3) {
+	db->fragshift--;
+	db->numfrag = bufs >> db->fragshift;
+    }
+    db->fragsize = 1 << db->fragshift;
+    if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
+	db->numfrag = db->ossmaxfrags;
+    db->fragsamples = db->fragsize >> sample_shift[fmt];
+    db->dmasize = db->numfrag << db->fragshift;
+    memset(db->rawbuf, (fmt & (CC_DF>>CC_FMT_BIT)) ? 0 : 0x80, db->dmasize);
+    
+    // set data length register
+    outw(db->fragsize, s->io+reg+2);
+    db->ready = 1;
+
+    return 0;
+}
+
+extern inline int prog_dmabuf_adc(struct it8172_state *s)
+{
+    stop_adc(s);
+    return prog_dmabuf(s, &s->dma_adc, s->adcrate,
+		       (s->capcc & CC_FMT_MASK) >> CC_FMT_BIT,
+		       IT_AC_CAPCC);
+}
+
+extern inline int prog_dmabuf_dac(struct it8172_state *s)
+{
+    stop_dac(s);
+    return prog_dmabuf(s, &s->dma_dac, s->dacrate,
+		       (s->pcc & CC_FMT_MASK) >> CC_FMT_BIT,
+		       IT_AC_PCC);
+}
+
+
+/* hold spinlock for the following! */
+
+static void it8172_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+    struct it8172_state *s = (struct it8172_state *)dev_id;
+    struct dmabuf* dac = &s->dma_dac;
+    struct dmabuf* adc = &s->dma_adc;
+    unsigned char isc, vs;
+    unsigned short vol, mute;
+    unsigned long newptr;
+    
+    spin_lock(&s->lock);
+
+    isc = inb(s->io+IT_AC_ISC);
+
+    /* fastpath out, to ease interrupt sharing */
+    if (!(isc & (ISC_VCI | ISC_CCI | ISC_PCI)))
+	return;
+
+    /* clear audio interrupts first */
+    outb(isc | ISC_VCI | ISC_CCI | ISC_PCI, s->io+IT_AC_ISC);
+    
+    /* handle volume button events */
+    if (isc & ISC_VCI) {
+	vs = inb(s->io+IT_AC_VS);
+	outb(0, s->io+IT_AC_VS);
+	vol = inw(s->io+IT_AC_PCMOV);
+	mute = vol & PCMOV_PCMOM;
+	vol &= PCMOV_PCMLCG_MASK;
+	if ((vs & VS_VUP) && vol > 0)
+	    vol--;
+	if ((vs & VS_VDP) && vol < 0x1f)
+	    vol++;
+	vol |= (vol << PCMOV_PCMRCG_BIT);
+	if (vs & VS_VMP)
+	    vol |= (mute ^ PCMOV_PCMOM);
+	outw(vol, s->io+IT_AC_PCMOV);
+    }
+    
+    /* update capture pointers */
+    if (isc & ISC_CCI) {
+	if (adc->count > adc->dmasize - adc->fragsize) {
+	    // Overrun. Stop ADC and log the error
+	    stop_adc(s);
+	    adc->error++;
+	    printk(KERN_INFO PFX "adc overrun\n");
+	} else {
+	    newptr = virt_to_bus(adc->nextIn) + 2*adc->fragsize;
+	    if (newptr >= adc->dmaaddr + adc->dmasize)
+		newptr -= adc->dmasize;
+	    
+	    outl(newptr, s->io+adc->curBufPtr);
+	    adc->curBufPtr = (adc->curBufPtr == IT_AC_CAPB1STA) ?
+		IT_AC_CAPB2STA : IT_AC_CAPB1STA;
+	    
+	    adc->nextIn += adc->fragsize;
+	    if (adc->nextIn >= adc->rawbuf + adc->dmasize)
+		adc->nextIn -= adc->dmasize;
+	    
+	    adc->count += adc->fragsize;
+	    adc->total_bytes += adc->fragsize;
+
+	    /* wake up anybody listening */
+	    if (waitqueue_active(&adc->wait))
+		wake_up_interruptible(&adc->wait);
+	}
+    }
+    
+    /* update playback pointers */
+    if (isc & ISC_PCI) {
+	newptr = virt_to_bus(dac->nextOut) + 2*dac->fragsize;
+	if (newptr >= dac->dmaaddr + dac->dmasize)
+	    newptr -= dac->dmasize;
+	
+	outl(newptr, s->io+dac->curBufPtr);
+	dac->curBufPtr = (dac->curBufPtr == IT_AC_PCB1STA) ?
+	    IT_AC_PCB2STA : IT_AC_PCB1STA;
+	
+	dac->nextOut += dac->fragsize;
+	if (dac->nextOut >= dac->rawbuf + dac->dmasize)
+	    dac->nextOut -= dac->dmasize;
+	
+	dac->count -= dac->fragsize;
+	dac->total_bytes += dac->fragsize;
+
+	/* wake up anybody listening */
+	if (waitqueue_active(&dac->wait))
+	    wake_up_interruptible(&dac->wait);
+	
+	if (dac->count <= 0)
+	    stop_dac(s);
+    }
+    
+    spin_unlock(&s->lock);
+}
+
+/* --------------------------------------------------------------------- */
+
+static loff_t it8172_llseek(struct file *file, loff_t offset, int origin)
+{
+    return -ESPIPE;
+}
+
+
+static int it8172_open_mixdev(struct inode *inode, struct file *file)
+{
+    int minor = MINOR(inode->i_rdev);
+    struct list_head *list;
+    struct it8172_state *s;
+
+    for (list = devs.next; ; list = list->next) {
+	if (list == &devs)
+	    return -ENODEV;
+	s = list_entry(list, struct it8172_state, devs);
+	if (s->codec.dev_mixer == minor)
+	    break;
+    }
+    file->private_data = s;
+    return 0;
+}
+
+static int it8172_release_mixdev(struct inode *inode, struct file *file)
+{
+    return 0;
+}
+
+
+static int mixdev_ioctl(struct ac97_codec *codec, unsigned int cmd,
+			unsigned long arg)
+{
+    return codec->mixer_ioctl(codec, cmd, arg);
+}
+
+static int it8172_ioctl_mixdev(struct inode *inode, struct file *file,
+			       unsigned int cmd, unsigned long arg)
+{
+    struct it8172_state *s = (struct it8172_state *)file->private_data;
+    struct ac97_codec *codec = &s->codec;
+
+    return mixdev_ioctl(codec, cmd, arg);
+}
+
+static /*const*/ struct file_operations it8172_mixer_fops = {
+    owner:	THIS_MODULE,
+    llseek:	it8172_llseek,
+    ioctl:	it8172_ioctl_mixdev,
+    open:	it8172_open_mixdev,
+    release:	it8172_release_mixdev,
+};
+
+/* --------------------------------------------------------------------- */
+
+static int drain_dac(struct it8172_state *s, int nonblock)
+{
+    unsigned long flags;
+    int count, tmo;
+	
+    if (s->dma_dac.mapped || !s->dma_dac.ready)
+	return 0;
+
+    for (;;) {
+	spin_lock_irqsave(&s->lock, flags);
+	count = s->dma_dac.count;
+	spin_unlock_irqrestore(&s->lock, flags);
+	if (count <= 0)
+	    break;
+	if (signal_pending(current))
+	    break;
+	if (nonblock)
+	    return -EBUSY;
+	tmo = 1000 * count / s->dacrate;
+	tmo >>= sample_shift[(s->pcc & CC_FMT_MASK) >> CC_FMT_BIT];
+	it8172_delay(tmo);
+    }
+    if (signal_pending(current))
+	return -ERESTARTSYS;
+    return 0;
+}
+
+/* --------------------------------------------------------------------- */
+
+static ssize_t it8172_read(struct file *file, char *buffer,
+			   size_t count, loff_t *ppos)
+{
+    struct it8172_state *s = (struct it8172_state *)file->private_data;
+    struct dmabuf *db = &s->dma_adc;
+    ssize_t ret;
+    unsigned long flags;
+    int cnt, bufcnt, avail;
+
+    if (ppos != &file->f_pos)
+	return -ESPIPE;
+    if (db->mapped)
+	return -ENXIO;
+    if (!access_ok(VERIFY_WRITE, buffer, count))
+	return -EFAULT;
+    ret = 0;
+
+    while (count > 0) {
+	// wait for samples in capture buffer
+	do {
+	    spin_lock_irqsave(&s->lock, flags);
+	    if (db->stopped)
+		start_adc(s);
+	    avail = db->count;
+	    spin_unlock_irqrestore(&s->lock, flags);
+	    if (avail <= 0) {
+		if (file->f_flags & O_NONBLOCK) {
+		    if (!ret)
+			ret = -EAGAIN;
+		    return ret;
+		}
+		interruptible_sleep_on(&db->wait);
+		if (signal_pending(current)) {
+		    if (!ret)
+			ret = -ERESTARTSYS;
+		    return ret;
+		}
+	    }
+	} while (avail <= 0);
+
+	cnt = count > avail ? avail : count;
+	bufcnt = cnt;
+	if (cnt % db->fragsize) {
+	    // round count up to nearest fragment
+	    int newcnt = db->fragsize * ((cnt + db->fragsize) / db->fragsize);
+	    cnt = newcnt;
+	}
+
+	// copy from nextOut to user
+	if (copy_to_user(buffer, db->nextOut, bufcnt)) {
+	    if (!ret)
+		ret = -EFAULT;
+	    return ret;
+	}
+
+	spin_lock_irqsave(&s->lock, flags);
+	db->count -= cnt;
+	spin_unlock_irqrestore(&s->lock, flags);
+
+	db->nextOut += cnt;
+	if (db->nextOut >= db->rawbuf + db->dmasize)
+	    db->nextOut -= db->dmasize;	
+
+	count -= bufcnt;
+	buffer += bufcnt;
+	ret += bufcnt;
+    } // while (count > 0)
+
+    return ret;
+}
+
+static ssize_t it8172_write(struct file *file, const char *buffer,
+			    size_t count, loff_t *ppos)
+{
+    struct it8172_state *s = (struct it8172_state *)file->private_data;
+    struct dmabuf *db = &s->dma_dac;
+    ssize_t ret;
+    unsigned long flags;
+    int cnt, bufcnt, avail;
+
+    if (ppos != &file->f_pos)
+	return -ESPIPE;
+    if (db->mapped)
+	return -ENXIO;
+    if (!access_ok(VERIFY_READ, buffer, count))
+	return -EFAULT;
+    ret = 0;
+    
+    while (count > 0) {
+	// wait for space in playback buffer
+	do {
+	    spin_lock_irqsave(&s->lock, flags);
+	    avail = db->dmasize - db->count;
+	    spin_unlock_irqrestore(&s->lock, flags);
+	    if (avail <= 0) {
+		if (file->f_flags & O_NONBLOCK) {
+		    if (!ret)
+			ret = -EAGAIN;
+		    return ret;
+		}
+		interruptible_sleep_on(&db->wait);
+		if (signal_pending(current)) {
+		    if (!ret)
+			ret = -ERESTARTSYS;
+		    return ret;
+		}
+	    }
+	} while (avail <= 0);
+	
+	cnt = count > avail ? avail : count;
+	// copy to nextIn
+	if (copy_from_user(db->nextIn, buffer, cnt)) {
+	    if (!ret)
+		ret = -EFAULT;
+	    return ret;
+	}
+
+	bufcnt = cnt;
+	if (cnt % db->fragsize) {
+	    // round count up to nearest fragment, and fill remainder of
+	    // fragment with silence
+	    int newcnt = db->fragsize * ((cnt + db->fragsize) / db->fragsize);
+	    memset(db->nextIn + cnt, (s->pcc & CC_DF) ? 0 : 0x80, newcnt - cnt);
+	    cnt = newcnt;
+	}
+
+	spin_lock_irqsave(&s->lock, flags);
+	db->count += cnt;
+	if (db->stopped)
+	    start_dac(s);
+	spin_unlock_irqrestore(&s->lock, flags);
+	
+	db->nextIn += cnt;
+	if (db->nextIn >= db->rawbuf + db->dmasize)
+	    db->nextIn -= db->dmasize;
+	
+	count -= bufcnt;
+	buffer += bufcnt;
+	ret += bufcnt;
+    } // while (count > 0)
+	
+    return ret;
+}
+
+/* No kernel lock - we have our own spinlock */
+static unsigned int it8172_poll(struct file *file,
+				struct poll_table_struct *wait)
+{
+    struct it8172_state *s = (struct it8172_state *)file->private_data;
+    unsigned long flags;
+    unsigned int mask = 0;
+
+    if (file->f_mode & FMODE_WRITE)
+	poll_wait(file, &s->dma_dac.wait, wait);
+    if (file->f_mode & FMODE_READ)
+	poll_wait(file, &s->dma_adc.wait, wait);
+    spin_lock_irqsave(&s->lock, flags);
+    if (file->f_mode & FMODE_READ) {
+	if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
+	    mask |= POLLIN | POLLRDNORM;
+    }
+    if (file->f_mode & FMODE_WRITE) {
+	if (s->dma_dac.mapped) {
+	    if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) 
+		mask |= POLLOUT | POLLWRNORM;
+	} else {
+	    if ((signed)s->dma_dac.dmasize >=
+		s->dma_dac.count + (signed)s->dma_dac.fragsize)
+		mask |= POLLOUT | POLLWRNORM;
+	}
+    }
+    spin_unlock_irqrestore(&s->lock, flags);
+    return mask;
+}
+
+static int it8172_mmap(struct file *file, struct vm_area_struct *vma)
+{
+    struct it8172_state *s = (struct it8172_state *)file->private_data;
+    struct dmabuf *db;
+    unsigned long size;
+
+    lock_kernel();
+    if (vma->vm_flags & VM_WRITE)
+	db = &s->dma_dac;
+    else if (vma->vm_flags & VM_READ)
+	db = &s->dma_adc;
+    else {
+	unlock_kernel();
+	return -EINVAL;
+    }
+    if (vma->vm_pgoff != 0) {
+	unlock_kernel();
+	return -EINVAL;
+    }
+    size = vma->vm_end - vma->vm_start;
+    if (size > (PAGE_SIZE << db->buforder)) {
+	unlock_kernel();
+	return -EINVAL;
+    }
+    if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf),
+			 size, vma->vm_page_prot)) {
+	unlock_kernel();
+	return -EAGAIN;
+    }
+    db->mapped = 1;
+    unlock_kernel();
+    return 0;
+}
+
+
+#ifdef IT8172_VERBOSE_DEBUG
+static struct ioctl_str_t {
+    unsigned int cmd;
+    const char* str;
+} ioctl_str[] = {
+    {SNDCTL_DSP_RESET, "SNDCTL_DSP_RESET"},
+    {SNDCTL_DSP_SYNC, "SNDCTL_DSP_SYNC"},
+    {SNDCTL_DSP_SPEED, "SNDCTL_DSP_SPEED"},
+    {SNDCTL_DSP_STEREO, "SNDCTL_DSP_STEREO"},
+    {SNDCTL_DSP_GETBLKSIZE, "SNDCTL_DSP_GETBLKSIZE"},
+    {SNDCTL_DSP_SAMPLESIZE, "SNDCTL_DSP_SAMPLESIZE"},
+    {SNDCTL_DSP_CHANNELS, "SNDCTL_DSP_CHANNELS"},
+    {SOUND_PCM_WRITE_CHANNELS, "SOUND_PCM_WRITE_CHANNELS"},
+    {SOUND_PCM_WRITE_FILTER, "SOUND_PCM_WRITE_FILTER"},
+    {SNDCTL_DSP_POST, "SNDCTL_DSP_POST"},
+    {SNDCTL_DSP_SUBDIVIDE, "SNDCTL_DSP_SUBDIVIDE"},
+    {SNDCTL_DSP_SETFRAGMENT, "SNDCTL_DSP_SETFRAGMENT"},
+    {SNDCTL_DSP_GETFMTS, "SNDCTL_DSP_GETFMTS"},
+    {SNDCTL_DSP_SETFMT, "SNDCTL_DSP_SETFMT"},
+    {SNDCTL_DSP_GETOSPACE, "SNDCTL_DSP_GETOSPACE"},
+    {SNDCTL_DSP_GETISPACE, "SNDCTL_DSP_GETISPACE"},
+    {SNDCTL_DSP_NONBLOCK, "SNDCTL_DSP_NONBLOCK"},
+    {SNDCTL_DSP_GETCAPS, "SNDCTL_DSP_GETCAPS"},
+    {SNDCTL_DSP_GETTRIGGER, "SNDCTL_DSP_GETTRIGGER"},
+    {SNDCTL_DSP_SETTRIGGER, "SNDCTL_DSP_SETTRIGGER"},
+    {SNDCTL_DSP_GETIPTR, "SNDCTL_DSP_GETIPTR"},
+    {SNDCTL_DSP_GETOPTR, "SNDCTL_DSP_GETOPTR"},
+    {SNDCTL_DSP_MAPINBUF, "SNDCTL_DSP_MAPINBUF"},
+    {SNDCTL_DSP_MAPOUTBUF, "SNDCTL_DSP_MAPOUTBUF"},
+    {SNDCTL_DSP_SETSYNCRO, "SNDCTL_DSP_SETSYNCRO"},
+    {SNDCTL_DSP_SETDUPLEX, "SNDCTL_DSP_SETDUPLEX"},
+    {SNDCTL_DSP_GETODELAY, "SNDCTL_DSP_GETODELAY"},
+    {SNDCTL_DSP_GETCHANNELMASK, "SNDCTL_DSP_GETCHANNELMASK"},
+    {SNDCTL_DSP_BIND_CHANNEL, "SNDCTL_DSP_BIND_CHANNEL"},
+    {OSS_GETVERSION, "OSS_GETVERSION"},
+    {SOUND_PCM_READ_RATE, "SOUND_PCM_READ_RATE"},
+    {SOUND_PCM_READ_CHANNELS, "SOUND_PCM_READ_CHANNELS"},
+    {SOUND_PCM_READ_BITS, "SOUND_PCM_READ_BITS"},
+    {SOUND_PCM_READ_FILTER, "SOUND_PCM_READ_FILTER"}
+};
+#endif    
+
+static int it8172_ioctl(struct inode *inode, struct file *file,
+			unsigned int cmd, unsigned long arg)
+{
+    struct it8172_state *s = (struct it8172_state *)file->private_data;
+    unsigned long flags;
+    audio_buf_info abinfo;
+    count_info cinfo;
+    int count;
+    int val, mapped, ret, diff;
+
+    mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
+	((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
+
+#ifdef IT8172_VERBOSE_DEBUG
+    for (count=0; count<sizeof(ioctl_str)/sizeof(ioctl_str[0]); count++) {
+	if (ioctl_str[count].cmd == cmd)
+	    break;
+    }
+    if (count < sizeof(ioctl_str)/sizeof(ioctl_str[0]))
+	printk(KERN_INFO PFX "ioctl %s\n", ioctl_str[count].str);
+    else
+	printk(KERN_INFO PFX "ioctl unknown, 0x%x\n", cmd);
+#endif
+    
+    switch (cmd) {
+    case OSS_GETVERSION:
+	return put_user(SOUND_VERSION, (int *)arg);
+
+    case SNDCTL_DSP_SYNC:
+	if (file->f_mode & FMODE_WRITE)
+	    return drain_dac(s, file->f_flags & O_NONBLOCK);
+	return 0;
+		
+    case SNDCTL_DSP_SETDUPLEX:
+	return 0;
+
+    case SNDCTL_DSP_GETCAPS:
+	return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME |
+			DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
+		
+    case SNDCTL_DSP_RESET:
+	if (file->f_mode & FMODE_WRITE) {
+	    stop_dac(s);
+	    synchronize_irq();
+	    s->dma_dac.count = s->dma_dac.total_bytes = 0;
+	    s->dma_dac.nextIn = s->dma_dac.nextOut = s->dma_dac.rawbuf;
+	}
+	if (file->f_mode & FMODE_READ) {
+	    stop_adc(s);
+	    synchronize_irq();
+	    s->dma_adc.count = s->dma_adc.total_bytes = 0;
+	    s->dma_adc.nextIn = s->dma_adc.nextOut = s->dma_adc.rawbuf;
+	}
+	return 0;
+
+    case SNDCTL_DSP_SPEED:
+	if (get_user(val, (int *)arg))
+	    return -EFAULT;
+	if (val >= 0) {
+	    if (file->f_mode & FMODE_READ) {
+		stop_adc(s);
+		set_adc_rate(s, val);
+		if ((ret = prog_dmabuf_adc(s)))
+		    return ret;
+	    }
+	    if (file->f_mode & FMODE_WRITE) {
+		stop_dac(s);
+		set_dac_rate(s, val);
+		if ((ret = prog_dmabuf_dac(s)))
+		    return ret;
+	    }
+	}
+	return put_user((file->f_mode & FMODE_READ) ?
+			s->adcrate : s->dacrate, (int *)arg);
+
+    case SNDCTL_DSP_STEREO:
+	if (get_user(val, (int *)arg))
+	    return -EFAULT;
+	if (file->f_mode & FMODE_READ) {
+	    stop_adc(s);
+	    if (val)
+		s->capcc |= CC_SM;
+	    else
+		s->capcc &= ~CC_SM;
+	    outw(s->capcc, s->io+IT_AC_CAPCC);
+	    if ((ret = prog_dmabuf_adc(s)))
+		return ret;
+	}
+	if (file->f_mode & FMODE_WRITE) {
+	    stop_dac(s);
+	    if (val)
+		s->pcc |= CC_SM;
+	    else
+		s->pcc &= ~CC_SM;
+	    outw(s->pcc, s->io+IT_AC_PCC);
+	    if ((ret = prog_dmabuf_dac(s)))
+		return ret;
+	}
+	return 0;
+
+    case SNDCTL_DSP_CHANNELS:
+	if (get_user(val, (int *)arg))
+	    return -EFAULT;
+	if (val != 0) {
+	    if (file->f_mode & FMODE_READ) {
+		stop_adc(s);
+		if (val >= 2) {
+		    val = 2;
+		    s->capcc |= CC_SM;
+		}
+		else
+		    s->capcc &= ~CC_SM;
+		outw(s->capcc, s->io+IT_AC_CAPCC);
+		if ((ret = prog_dmabuf_adc(s)))
+		    return ret;
+	    }
+	    if (file->f_mode & FMODE_WRITE) {
+		stop_dac(s);
+		switch (val) {
+		case 1:
+		    s->pcc &= ~CC_SM;
+		    break;
+		case 2:
+		    s->pcc |= CC_SM;
+		    break;
+		default:
+		    // FIX! support multichannel???
+		    val = 2;
+		    s->pcc |= CC_SM;
+		    break;
+		}
+		outw(s->pcc, s->io+IT_AC_PCC);
+		if ((ret = prog_dmabuf_dac(s)))
+		    return ret;
+	    }
+	}
+	return put_user(val, (int *)arg);
+		
+    case SNDCTL_DSP_GETFMTS: /* Returns a mask */
+	return put_user(AFMT_S16_LE|AFMT_U8, (int *)arg);
+		
+    case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
+	if (get_user(val, (int *)arg))
+	    return -EFAULT;
+	if (val != AFMT_QUERY) {
+	    if (file->f_mode & FMODE_READ) {
+		stop_adc(s);
+		if (val == AFMT_S16_LE)
+		    s->capcc |= CC_DF;
+		else {
+		    val = AFMT_U8;
+		    s->capcc &= ~CC_DF;
+		}
+		outw(s->capcc, s->io+IT_AC_CAPCC);
+		if ((ret = prog_dmabuf_adc(s)))
+		    return ret;
+	    }
+	    if (file->f_mode & FMODE_WRITE) {
+		stop_dac(s);
+		if (val == AFMT_S16_LE)
+		    s->pcc |= CC_DF;
+		else {
+		    val = AFMT_U8;
+		    s->pcc &= ~CC_DF;
+		}
+		outw(s->pcc, s->io+IT_AC_PCC);
+		if ((ret = prog_dmabuf_dac(s)))
+		    return ret;
+	    }
+	} else {
+	    if (file->f_mode & FMODE_READ)
+		val = (s->capcc & CC_DF) ? AFMT_S16_LE : AFMT_U8;
+	    else
+		val = (s->pcc & CC_DF) ? AFMT_S16_LE : AFMT_U8;
+	}
+	return put_user(val, (int *)arg);
+		
+    case SNDCTL_DSP_POST:
+	return 0;
+
+    case SNDCTL_DSP_GETTRIGGER:
+	val = 0;
+	spin_lock_irqsave(&s->lock, flags);
+	if (file->f_mode & FMODE_READ && !s->dma_adc.stopped)
+	    val |= PCM_ENABLE_INPUT;
+	if (file->f_mode & FMODE_WRITE && !s->dma_dac.stopped)
+	    val |= PCM_ENABLE_OUTPUT;
+	spin_unlock_irqrestore(&s->lock, flags);
+	return put_user(val, (int *)arg);
+		
+    case SNDCTL_DSP_SETTRIGGER:
+	if (get_user(val, (int *)arg))
+	    return -EFAULT;
+	if (file->f_mode & FMODE_READ) {
+	    if (val & PCM_ENABLE_INPUT)
+		start_adc(s);
+	    else
+		stop_adc(s);
+	}
+	if (file->f_mode & FMODE_WRITE) {
+	    if (val & PCM_ENABLE_OUTPUT)
+		start_dac(s);
+	    else
+		stop_dac(s);
+	}
+	return 0;
+
+    case SNDCTL_DSP_GETOSPACE:
+	if (!(file->f_mode & FMODE_WRITE))
+	    return -EINVAL;
+	abinfo.fragsize = s->dma_dac.fragsize;
+	spin_lock_irqsave(&s->lock, flags);
+	count = s->dma_dac.count;
+	if (!s->dma_dac.stopped)
+	    count -= (s->dma_dac.fragsize - inw(s->io+IT_AC_PCDL));
+	spin_unlock_irqrestore(&s->lock, flags);
+	if (count < 0)
+	    count = 0;
+	abinfo.bytes = s->dma_dac.dmasize - count;
+	abinfo.fragstotal = s->dma_dac.numfrag;
+	abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;      
+	return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+
+    case SNDCTL_DSP_GETISPACE:
+	if (!(file->f_mode & FMODE_READ))
+	    return -EINVAL;
+	abinfo.fragsize = s->dma_adc.fragsize;
+	spin_lock_irqsave(&s->lock, flags);
+	count = s->dma_adc.count;
+	if (!s->dma_adc.stopped)
+	    count += (s->dma_adc.fragsize - inw(s->io+IT_AC_CAPCDL));
+	spin_unlock_irqrestore(&s->lock, flags);
+	if (count < 0)
+	    count = 0;
+	abinfo.bytes = count;
+	abinfo.fragstotal = s->dma_adc.numfrag;
+	abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;      
+	return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+		
+    case SNDCTL_DSP_NONBLOCK:
+	file->f_flags |= O_NONBLOCK;
+	return 0;
+
+    case SNDCTL_DSP_GETODELAY:
+	if (!(file->f_mode & FMODE_WRITE))
+	    return -EINVAL;
+	spin_lock_irqsave(&s->lock, flags);
+	count = s->dma_dac.count;
+	if (!s->dma_dac.stopped)
+	    count -= (s->dma_dac.fragsize - inw(s->io+IT_AC_PCDL));
+	spin_unlock_irqrestore(&s->lock, flags);
+	if (count < 0)
+	    count = 0;
+	return put_user(count, (int *)arg);
+
+    case SNDCTL_DSP_GETIPTR:
+	if (!(file->f_mode & FMODE_READ))
+	    return -EINVAL;
+	spin_lock_irqsave(&s->lock, flags);
+	cinfo.bytes = s->dma_adc.total_bytes;
+	count = s->dma_adc.count;
+	if (!s->dma_adc.stopped) {
+	    diff = s->dma_adc.fragsize - inw(s->io+IT_AC_CAPCDL);
+	    count += diff;
+	    cinfo.bytes += diff;
+	    cinfo.ptr = inl(s->io+s->dma_adc.curBufPtr) - s->dma_adc.dmaaddr;
+	} else
+	    cinfo.ptr = virt_to_bus(s->dma_adc.nextIn) - s->dma_adc.dmaaddr;
+	if (s->dma_adc.mapped)
+	    s->dma_adc.count &= s->dma_adc.fragsize-1;
+	spin_unlock_irqrestore(&s->lock, flags);
+	if (count < 0)
+	    count = 0;
+	cinfo.blocks = count >> s->dma_adc.fragshift;
+	return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+
+    case SNDCTL_DSP_GETOPTR:
+	if (!(file->f_mode & FMODE_READ))
+	    return -EINVAL;
+	spin_lock_irqsave(&s->lock, flags);
+	cinfo.bytes = s->dma_dac.total_bytes;
+	count = s->dma_dac.count;
+	if (!s->dma_dac.stopped) {
+	    diff = s->dma_dac.fragsize - inw(s->io+IT_AC_CAPCDL);
+	    count -= diff;
+	    cinfo.bytes += diff;
+	    cinfo.ptr = inl(s->io+s->dma_dac.curBufPtr) - s->dma_dac.dmaaddr;
+	} else
+	    cinfo.ptr = virt_to_bus(s->dma_dac.nextOut) - s->dma_dac.dmaaddr;
+	if (s->dma_dac.mapped)
+	    s->dma_dac.count &= s->dma_dac.fragsize-1;
+	spin_unlock_irqrestore(&s->lock, flags);
+	if (count < 0)
+	    count = 0;
+	cinfo.blocks = count >> s->dma_dac.fragshift;
+	return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+
+    case SNDCTL_DSP_GETBLKSIZE:
+	if (file->f_mode & FMODE_WRITE)
+	    return put_user(s->dma_dac.fragsize, (int *)arg);
+	else
+	    return put_user(s->dma_adc.fragsize, (int *)arg);
+
+    case SNDCTL_DSP_SETFRAGMENT:
+	if (get_user(val, (int *)arg))
+	    return -EFAULT;
+	if (file->f_mode & FMODE_READ) {
+	    stop_adc(s);
+	    s->dma_adc.ossfragshift = val & 0xffff;
+	    s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
+	    if (s->dma_adc.ossfragshift < 4)
+		s->dma_adc.ossfragshift = 4;
+	    if (s->dma_adc.ossfragshift > 15)
+		s->dma_adc.ossfragshift = 15;
+	    if (s->dma_adc.ossmaxfrags < 4)
+		s->dma_adc.ossmaxfrags = 4;
+	    if ((ret = prog_dmabuf_adc(s)))
+		return ret;
+	}
+	if (file->f_mode & FMODE_WRITE) {
+	    stop_dac(s);
+	    s->dma_dac.ossfragshift = val & 0xffff;
+	    s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff;
+	    if (s->dma_dac.ossfragshift < 4)
+		s->dma_dac.ossfragshift = 4;
+	    if (s->dma_dac.ossfragshift > 15)
+		s->dma_dac.ossfragshift = 15;
+	    if (s->dma_dac.ossmaxfrags < 4)
+		s->dma_dac.ossmaxfrags = 4;
+	    if ((ret = prog_dmabuf_dac(s)))
+		return ret;
+	}
+	return 0;
+
+    case SNDCTL_DSP_SUBDIVIDE:
+	if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
+	    (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
+	    return -EINVAL;
+	if (get_user(val, (int *)arg))
+	    return -EFAULT;
+	if (val != 1 && val != 2 && val != 4)
+	    return -EINVAL;
+	if (file->f_mode & FMODE_READ) {
+	    stop_adc(s);
+	    s->dma_adc.subdivision = val;
+	    if ((ret = prog_dmabuf_adc(s)))
+		return ret;
+	}
+	if (file->f_mode & FMODE_WRITE) {
+	    stop_dac(s);
+	    s->dma_dac.subdivision = val;
+	    if ((ret = prog_dmabuf_dac(s)))
+		return ret;
+	}
+	return 0;
+
+    case SOUND_PCM_READ_RATE:
+	return put_user((file->f_mode & FMODE_READ) ?
+			s->adcrate : s->dacrate, (int *)arg);
+
+    case SOUND_PCM_READ_CHANNELS:
+	if (file->f_mode & FMODE_READ)
+	    return put_user((s->capcc & CC_SM) ? 2 : 1, (int *)arg);
+	else
+	    return put_user((s->pcc & CC_SM) ? 2 : 1, (int *)arg);
+	    
+    case SOUND_PCM_READ_BITS:
+	if (file->f_mode & FMODE_READ)
+	    return put_user((s->capcc & CC_DF) ? 16 : 8, (int *)arg);
+	else
+	    return put_user((s->pcc & CC_DF) ? 16 : 8, (int *)arg);
+
+    case SOUND_PCM_WRITE_FILTER:
+    case SNDCTL_DSP_SETSYNCRO:
+    case SOUND_PCM_READ_FILTER:
+	return -EINVAL;
+    }
+
+    return mixdev_ioctl(&s->codec, cmd, arg);
+}
+
+
+static int it8172_open(struct inode *inode, struct file *file)
+{
+    int minor = MINOR(inode->i_rdev);
+    DECLARE_WAITQUEUE(wait, current);
+    unsigned long flags;
+    struct list_head *list;
+    struct it8172_state *s;
+    int ret;
+    
+    for (list = devs.next; ; list = list->next) {
+	if (list == &devs)
+	    return -ENODEV;
+	s = list_entry(list, struct it8172_state, devs);
+	if (!((s->dev_audio ^ minor) & ~0xf))
+	    break;
+    }
+    file->private_data = s;
+    /* wait for device to become free */
+    down(&s->open_sem);
+    while (s->open_mode & file->f_mode) {
+	if (file->f_flags & O_NONBLOCK) {
+	    up(&s->open_sem);
+	    return -EBUSY;
+	}
+	add_wait_queue(&s->open_wait, &wait);
+	__set_current_state(TASK_INTERRUPTIBLE);
+	up(&s->open_sem);
+	schedule();
+	remove_wait_queue(&s->open_wait, &wait);
+	set_current_state(TASK_RUNNING);
+	if (signal_pending(current))
+	    return -ERESTARTSYS;
+	down(&s->open_sem);
+    }
+
+    spin_lock_irqsave(&s->lock, flags);
+
+    if (file->f_mode & FMODE_READ) {
+	s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags =
+	    s->dma_adc.subdivision = s->dma_adc.total_bytes = 0;
+	s->capcc &= ~(CC_SM | CC_DF);
+	set_adc_rate(s, 8000);
+	if ((minor & 0xf) == SND_DEV_DSP16)
+	    s->capcc |= CC_DF;
+	outw(s->capcc, s->io+IT_AC_CAPCC);
+	if ((ret = prog_dmabuf_adc(s)))
+	    return ret;
+    }
+    if (file->f_mode & FMODE_WRITE) {
+	s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags =
+	    s->dma_dac.subdivision = s->dma_dac.total_bytes = 0;
+	s->pcc &= ~(CC_SM | CC_DF);
+	set_dac_rate(s, 8000);
+	if ((minor & 0xf) == SND_DEV_DSP16)
+	    s->pcc |= CC_DF;
+	outw(s->pcc, s->io+IT_AC_PCC);
+	if ((ret = prog_dmabuf_dac(s)))
+	    return ret;
+    }
+
+    spin_unlock_irqrestore(&s->lock, flags);
+
+    s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
+    up(&s->open_sem);
+    return 0;
+}
+
+static int it8172_release(struct inode *inode, struct file *file)
+{
+    struct it8172_state *s = (struct it8172_state *)file->private_data;
+
+    lock_kernel();
+    if (file->f_mode & FMODE_WRITE)
+	drain_dac(s, file->f_flags & O_NONBLOCK);
+    down(&s->open_sem);
+    if (file->f_mode & FMODE_WRITE) {
+	stop_dac(s);
+	dealloc_dmabuf(s, &s->dma_dac);
+    }
+    if (file->f_mode & FMODE_READ) {
+	stop_adc(s);
+	dealloc_dmabuf(s, &s->dma_adc);
+    }
+    s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
+    up(&s->open_sem);
+    wake_up(&s->open_wait);
+    unlock_kernel();
+    return 0;
+}
+
+static /*const*/ struct file_operations it8172_audio_fops = {
+    owner:	THIS_MODULE,
+    llseek:	it8172_llseek,
+    read:	it8172_read,
+    write:	it8172_write,
+    poll:	it8172_poll,
+    ioctl:	it8172_ioctl,
+    mmap:	it8172_mmap,
+    open:	it8172_open,
+    release:	it8172_release,
+};
+
+
+/* --------------------------------------------------------------------- */
+
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * for debugging purposes, we'll create a proc device that dumps the
+ * CODEC chipstate
+ */
+
+#ifdef IT8172_DEBUG
+static int proc_it8172_dump (char *buf, char **start, off_t fpos,
+			     int length, int *eof, void *data)
+{
+    struct it8172_state *s;
+    int cnt, len = 0;
+
+    if (list_empty(&devs))
+	return 0;
+    s = list_entry(devs.next, struct it8172_state, devs);
+
+    /* print out header */
+    len += sprintf(buf + len, "\n\t\tIT8172 Audio Debug\n\n");
+
+    // print out digital controller state
+    len += sprintf (buf + len, "IT8172 Audio Controller registers\n");
+    len += sprintf (buf + len, "---------------------------------\n");
+    cnt=0;
+    while (cnt < 0x72) {
+	if (cnt == IT_AC_PCB1STA || cnt == IT_AC_PCB2STA ||
+	    cnt == IT_AC_CAPB1STA || cnt == IT_AC_CAPB2STA ||
+	    cnt == IT_AC_PFDP) {
+	    len+= sprintf (buf + len, "reg %02x = %08x\n",
+			   cnt, inl(s->io+cnt));
+	    cnt += 4;
+	} else {
+	    len+= sprintf (buf + len, "reg %02x = %04x\n",
+			   cnt, inw(s->io+cnt));
+	    cnt += 2;
+	}
+    }
+    
+    /* print out CODEC state */
+    len += sprintf (buf + len, "\nAC97 CODEC registers\n");
+    len += sprintf (buf + len, "----------------------\n");
+    for (cnt=0; cnt <= 0x7e; cnt = cnt +2)
+	len+= sprintf (buf + len, "reg %02x = %04x\n",
+		       cnt, rdcodec(&s->codec, cnt));
+
+    if (fpos >=len){
+	*start = buf;
+	*eof =1;
+	return 0;
+    }
+    *start = buf + fpos;
+    if ((len -= fpos) > length)
+	return length;
+    *eof =1;
+    return len;
+
+}
+#endif /* IT8172_DEBUG */
+
+/* --------------------------------------------------------------------- */
+
+/* maximum number of devices; only used for command line params */
+#define NR_DEVICE 5
+
+static int spdif[NR_DEVICE] = { 0, };
+
+static unsigned int devindex = 0;
+
+MODULE_PARM(spdif, "1-" __MODULE_STRING(NR_DEVICE) "i");
+MODULE_PARM_DESC(spdif, "if 1 the S/PDIF digital output is enabled");
+
+MODULE_AUTHOR("Monta Vista Software, stevel@mvista.com");
+MODULE_DESCRIPTION("IT8172 AudioPCI97 Driver");
+
+/* --------------------------------------------------------------------- */
+
+static int __devinit it8172_probe(struct pci_dev *pcidev,
+				  const struct pci_device_id *pciid)
+{
+    struct it8172_state *s;
+    int i, val;
+    unsigned short pcisr, vol;
+    unsigned char legacy, imc;
+    char proc_str[80];
+    
+    if (pcidev->irq == 0) 
+	return -1;
+
+    if (!(s = kmalloc(sizeof(struct it8172_state), GFP_KERNEL))) {
+	printk(KERN_ERR PFX "alloc of device struct failed\n");
+	return -1;
+    }
+	
+    memset(s, 0, sizeof(struct it8172_state));
+    init_waitqueue_head(&s->dma_adc.wait);
+    init_waitqueue_head(&s->dma_dac.wait);
+    init_waitqueue_head(&s->open_wait);
+    init_MUTEX(&s->open_sem);
+    spin_lock_init(&s->lock);
+    s->dev = pcidev;
+    s->io = pci_resource_start(pcidev, 0);
+    s->irq = pcidev->irq;
+    s->vendor = pcidev->vendor;
+    s->device = pcidev->device;
+    pci_read_config_byte(pcidev, PCI_REVISION_ID, &s->rev);
+    s->codec.private_data = s;
+    s->codec.id = 0;
+    s->codec.codec_read = rdcodec;
+    s->codec.codec_write = wrcodec;
+    s->codec.codec_wait = waitcodec;
+
+    if (!request_region(s->io, pci_resource_len(pcidev,0),
+			IT8172_MODULE_NAME)) {
+	printk(KERN_ERR PFX "io ports %#lx->%#lx in use\n",
+		s->io, s->io + pci_resource_len(pcidev,0)-1);
+	goto err_region;
+    }
+    if (request_irq(s->irq, it8172_interrupt, SA_INTERRUPT,
+		    IT8172_MODULE_NAME, s)) {
+	printk(KERN_ERR PFX "irq %u in use\n", s->irq);
+	goto err_irq;
+    }
+
+    printk(KERN_INFO PFX "IO at %#lx, IRQ %d\n", s->io, s->irq);
+
+    /* register devices */
+    if ((s->dev_audio = register_sound_dsp(&it8172_audio_fops, -1)) < 0)
+	goto err_dev1;
+    if ((s->codec.dev_mixer =
+	 register_sound_mixer(&it8172_mixer_fops, -1)) < 0)
+	goto err_dev2;
+
+#ifdef IT8172_DEBUG
+    /* intialize the debug proc device */
+    s->ps = create_proc_read_entry(IT8172_MODULE_NAME, 0, NULL,
+				   proc_it8172_dump, NULL);
+#endif /* IT8172_DEBUG */
+	
+    /*
+     * Reset the Audio device using the IT8172 PCI Reset register. This
+     * creates an audible double click on a speaker connected to Line-out.
+     */
+    IT_IO_READ16(IT_PM_PCISR, pcisr);
+    pcisr |= IT_PM_PCISR_ACSR;
+    IT_IO_WRITE16(IT_PM_PCISR, pcisr);
+    /* wait up to 100msec for reset to complete */
+    for (i=0; pcisr & IT_PM_PCISR_ACSR; i++) {
+	it8172_delay(10);
+	if (i == 10)
+	    break;
+	IT_IO_READ16(IT_PM_PCISR, pcisr);
+    }
+    if (i == 10) {
+	printk(KERN_ERR PFX "chip reset timeout!\n");
+	goto err_dev3;
+    }
+    
+    /* enable pci io and bus mastering */
+    if (pci_enable_device(pcidev))
+	goto err_dev3;
+    pci_set_master(pcidev);
+
+    /* get out of legacy mode */
+    pci_read_config_byte (pcidev, 0x40, &legacy);
+    pci_write_config_byte (pcidev, 0x40, legacy & ~1);
+    
+    s->spdif_volume = -1;
+    /* check to see if s/pdif mode is being requested */
+    if (spdif[devindex]) {
+	printk(KERN_INFO PFX "enabling S/PDIF output\n");
+	s->spdif_volume = 0;
+	outb(GC_SOE, s->io+IT_AC_GC);
+    } else {
+	printk(KERN_INFO PFX "disabling S/PDIF output\n");
+	outb(0, s->io+IT_AC_GC);
+    }
+    
+    /* cold reset the AC97 */
+    outw(CODECC_CR, s->io+IT_AC_CODECC);
+    udelay(1000);
+    outw(0, s->io+IT_AC_CODECC);
+    /* need to delay around 500msec(bleech) to give
+       some CODECs enough time to wakeup */
+    it8172_delay(500);
+    
+    /* AC97 warm reset to start the bitclk */
+    outw(CODECC_WR, s->io+IT_AC_CODECC);
+    udelay(1000);
+    outw(0, s->io+IT_AC_CODECC);
+    
+    /* codec init */
+    if (!ac97_probe_codec(&s->codec))
+	goto err_dev3;
+
+    /* Enable Volume button interrupts */
+    imc = inb(s->io+IT_AC_IMC);
+    outb(imc & ~IMC_VCIM, s->io+IT_AC_IMC);
+
+    /* Un-mute PCM and FM out on the controller */
+    vol = inw(s->io+IT_AC_PCMOV);
+    outw(vol & ~PCMOV_PCMOM, s->io+IT_AC_PCMOV);
+    vol = inw(s->io+IT_AC_FMOV);
+    outw(vol & ~FMOV_FMOM, s->io+IT_AC_FMOV);
+
+    /* set channel defaults to 8-bit, mono, 8 Khz */
+    s->pcc = 0;
+    s->capcc = 0;
+    set_dac_rate(s, 8000);
+    set_adc_rate(s, 8000);
+
+    /* set mic to be the recording source */
+    val = SOUND_MASK_MIC;
+    mixdev_ioctl(&s->codec, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val);
+
+    /* mute master and PCM when in S/PDIF mode */
+    if (s->spdif_volume != -1) {
+	val = 0x0000;
+	mixdev_ioctl(&s->codec, SOUND_MIXER_WRITE_VOLUME,
+		     (unsigned long)&val);
+	mixdev_ioctl(&s->codec, SOUND_MIXER_WRITE_PCM,
+		     (unsigned long)&val);
+    }
+    
+#ifdef IT8172_DEBUG
+    sprintf(proc_str, "driver/%s/%d/ac97", IT8172_MODULE_NAME, s->codec.id);
+    s->ac97_ps = create_proc_read_entry (proc_str, 0, NULL,
+					 ac97_read_proc, &s->codec);
+#endif
+    
+    /* store it in the driver field */
+    pci_set_drvdata(pcidev, s);
+    pcidev->dma_mask = 0xffffffff;
+    /* put it into driver list */
+    list_add_tail(&s->devs, &devs);
+    /* increment devindex */
+    if (devindex < NR_DEVICE-1)
+	devindex++;
+    return 0;
+
+ err_dev3:
+    unregister_sound_mixer(s->codec.dev_mixer);
+ err_dev2:
+    unregister_sound_dsp(s->dev_audio);
+ err_dev1:
+    printk(KERN_ERR PFX "cannot register misc device\n");
+    free_irq(s->irq, s);
+ err_irq:
+    release_region(s->io, pci_resource_len(pcidev,0));
+ err_region:
+    kfree(s);
+    return -1;
+}
+
+static void __devinit it8172_remove(struct pci_dev *dev)
+{
+    struct it8172_state *s = pci_get_drvdata(dev);
+
+    if (!s)
+	return;
+    list_del(&s->devs);
+#ifdef IT8172_DEBUG
+    if (s->ps)
+	remove_proc_entry(IT8172_MODULE_NAME, NULL);
+#endif /* IT8172_DEBUG */
+    synchronize_irq();
+    free_irq(s->irq, s);
+    release_region(s->io, pci_resource_len(dev,0));
+    unregister_sound_dsp(s->dev_audio);
+    unregister_sound_mixer(s->codec.dev_mixer);
+    kfree(s);
+    pci_set_drvdata(dev, NULL);
+}
+
+
+
+static struct pci_device_id id_table[] __devinitdata = {
+    { PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_IT8172G_AUDIO, PCI_ANY_ID,
+      PCI_ANY_ID, 0, 0 },
+    { 0, }
+};
+
+MODULE_DEVICE_TABLE(pci, id_table);
+
+static struct pci_driver it8172_driver = {
+    name: IT8172_MODULE_NAME,
+    id_table: id_table,
+    probe: it8172_probe,
+    remove: it8172_remove
+};
+
+static int __init init_it8172(void)
+{
+    if (!pci_present())   /* No PCI bus in this machine! */
+	return -ENODEV;
+    printk("version v0.26 time " __TIME__ " " __DATE__ "\n");
+    return pci_module_init(&it8172_driver);
+}
+
+static void __exit cleanup_it8172(void)
+{
+    printk(KERN_INFO PFX "unloading\n");
+    pci_unregister_driver(&it8172_driver);
+}
+
+module_init(init_it8172);
+module_exit(cleanup_it8172);
+
diff -u --recursive --new-file v2.4.9/linux/drivers/sound/msnd_pinnacle.c linux/drivers/sound/msnd_pinnacle.c
--- v2.4.9/linux/drivers/sound/msnd_pinnacle.c	Wed Jul 25 17:10:23 2001
+++ linux/drivers/sound/msnd_pinnacle.c	Fri Sep  7 09:28:37 2001
@@ -29,7 +29,12 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * $Id: msnd_pinnacle.c,v 1.75 1999/03/21 16:50:09 andrewtv Exp $
+ * $Id: msnd_pinnacle.c,v 1.8 2000/12/30 00:33:21 sycamore Exp $
+ *
+ * 12-3-2000  Modified IO port validation  Steve Sycamore
+ *
+ *
+ * $$$: msnd_pinnacle.c,v 1.75 1999/03/21 16:50:09 andrewtv $$$ $
  *
  ********************************************************************/
 
@@ -1703,6 +1708,7 @@
 	if (io == -1 || irq == -1 || mem == -1)
 		printk(KERN_WARNING LOGNAME ": io, irq and mem must be set\n");
 
+#ifdef MSND_CLASSIC
 	if (io == -1 ||
 	    !(io == 0x290 ||
 	      io == 0x260 ||
@@ -1715,6 +1721,15 @@
 		printk(KERN_ERR LOGNAME ": \"io\" - DSP I/O base must be set to 0x210, 0x220, 0x230, 0x240, 0x250, 0x260, 0x290, or 0x3E0\n");
 		return -EINVAL;
 	}
+#else
+	if (io == -1 ||
+		io < 0x100 ||
+		io > 0x3e0 ||
+		(io % 0x10) != 0) {
+			printk(KERN_ERR LOGNAME ": \"io\" - DSP I/O base must within the range 0x100 to 0x3E0 and must be evenly divisible by 0x10\n");
+			return -EINVAL;
+	}
+#endif /* MSND_CLASSIC */
 
 	if (irq == -1 ||
 	    !(irq == 5 ||
diff -u --recursive --new-file v2.4.9/linux/drivers/sound/nec_vrc5477.c linux/drivers/sound/nec_vrc5477.c
--- v2.4.9/linux/drivers/sound/nec_vrc5477.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/sound/nec_vrc5477.c	Fri Sep  7 09:28:37 2001
@@ -0,0 +1,2044 @@
+/***********************************************************************
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * drivers/sound/nec_vrc5477.c
+ *     AC97 sound dirver for NEC Vrc5477 chip (an integrated, 
+ *     multi-function controller chip for MIPS CPUs)
+ *
+ * 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 code is derived from ite8172.c, which is written by Steve Longerbeam.
+ *
+ * Features:
+ *   Currently we only support the following capabilities:
+ *	. mono output to PCM L/R (line out).
+ *	. stereo output to PCM L/R (line out).
+ *	. mono input from PCM L (line in).
+ *	. stereo output from PCM (line in).
+ *	. sampling rate at 48k or variable sampling rate 
+ *	. support /dev/dsp, /dev/mixer devices, standard OSS devices.
+ *	. only support 16-bit PCM format (hardware limit, no software
+ *	  translation) 
+ *	. support duplex, but no trigger or realtime.
+ *	
+ *   Specifically the following are not supported:
+ *	. app-set frag size.
+ *	. mmap'ed buffer access
+ */
+
+/* 
+ * Original comments from ite8172.c file.
+ */
+
+/*
+ *
+ * Notes:
+ *
+ *  1. Much of the OSS buffer allocation, ioctl's, and mmap'ing are
+ *     taken, slightly modified or not at all, from the ES1371 driver,
+ *     so refer to the credits in es1371.c for those. The rest of the
+ *     code (probe, open, read, write, the ISR, etc.) is new.
+ *  2. The following support is untested:
+ *      * Memory mapping the audio buffers, and the ioctl controls that go
+ *        with it.
+ *      * S/PDIF output.
+ *  3. The following is not supported:
+ *      * I2S input.
+ *      * legacy audio mode.
+ *  4. Support for volume button interrupts is implemented but doesn't
+ *     work yet.
+ *
+ *  Revision history
+ *    02.08.2001  0.1   Initial release
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/sound.h>
+#include <linux/malloc.h>
+#include <linux/soundcard.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <linux/bitops.h>
+#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
+#include <linux/ac97_codec.h>
+#include <linux/wrapper.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <asm/uaccess.h>
+#include <asm/hardirq.h>
+
+#include <asm/ddb5xxx/debug.h>
+
+#undef VRC5477_AC97_VERBOSE_DEBUG
+
+/* one must turn on CONFIG_LL_DEBUG before VERBOSE_DEBUG is turned */
+#if defined(VRC5477_AC97_VERBOSE_DEBUG)
+#if !defined(CONFIG_LL_DEBUG)
+#error "You must turn CONFIG_LL_DEBUG"
+#endif
+#endif
+
+#if defined(VRC5477_AC97_VERBOSE_DEBUG)
+static u16 inTicket=0; 		/* check sync between intr & write */
+static u16 outTicket=0;
+#endif
+
+/* --------------------------------------------------------------------- */
+
+#undef OSS_DOCUMENTED_MIXER_SEMANTICS
+
+static const unsigned sample_shift[] = { 0, 1, 1, 2 };
+
+#define         VRC5477_INT_CLR         0x0
+#define         VRC5477_INT_STATUS	0x0
+#define         VRC5477_CODEC_WR        0x4
+#define         VRC5477_CODEC_RD        0x8
+#define         VRC5477_CTRL            0x18
+#define         VRC5477_ACLINK_CTRL     0x1c
+#define         VRC5477_INT_MASK        0x24
+
+#define		VRC5477_DAC1_CTRL	0x30
+#define		VRC5477_DAC1L		0x34
+#define		VRC5477_DAC1_BADDR	0x38
+#define		VRC5477_DAC2_CTRL	0x3c
+#define		VRC5477_DAC2L		0x40
+#define		VRC5477_DAC2_BADDR	0x44
+#define		VRC5477_DAC3_CTRL	0x48
+#define		VRC5477_DAC3L		0x4c
+#define		VRC5477_DAC3_BADDR	0x50
+
+#define		VRC5477_ADC1_CTRL	0x54
+#define		VRC5477_ADC1L		0x58
+#define		VRC5477_ADC1_BADDR	0x5c
+#define		VRC5477_ADC2_CTRL	0x60
+#define		VRC5477_ADC2L		0x64
+#define		VRC5477_ADC2_BADDR	0x68
+#define		VRC5477_ADC3_CTRL	0x6c
+#define		VRC5477_ADC3L		0x70
+#define		VRC5477_ADC3_BADDR	0x74
+
+#define		VRC5477_CODEC_WR_RWC	(1 << 23)
+
+#define		VRC5477_CODEC_RD_RRDYA	(1 << 31)
+#define		VRC5477_CODEC_RD_RRDYD	(1 << 30)
+
+#define		VRC5477_ACLINK_CTRL_RST_ON	(1 << 15)
+#define		VRC5477_ACLINK_CTRL_RST_TIME	0x7f
+#define		VRC5477_ACLINK_CTRL_SYNC_ON	(1 << 30)
+#define		VRC5477_ACLINK_CTRL_CK_STOP_ON	(1 << 31)
+
+#define		VRC5477_CTRL_DAC2ENB		(1 << 15) 
+#define		VRC5477_CTRL_ADC2ENB		(1 << 14) 
+#define		VRC5477_CTRL_DAC1ENB		(1 << 13) 
+#define		VRC5477_CTRL_ADC1ENB		(1 << 12) 
+
+#define		VRC5477_INT_MASK_NMASK		(1 << 31) 
+#define		VRC5477_INT_MASK_DAC1END	(1 << 5) 
+#define		VRC5477_INT_MASK_DAC2END	(1 << 4) 
+#define		VRC5477_INT_MASK_DAC3END	(1 << 3) 
+#define		VRC5477_INT_MASK_ADC1END	(1 << 2) 
+#define		VRC5477_INT_MASK_ADC2END	(1 << 1) 
+#define		VRC5477_INT_MASK_ADC3END	(1 << 0) 
+
+#define		VRC5477_DMA_ACTIVATION		(1 << 31)
+#define		VRC5477_DMA_WIP			(1 << 30)
+
+
+#define VRC5477_AC97_MODULE_NAME "NEC_Vrc5477_audio"
+#define PFX VRC5477_AC97_MODULE_NAME ": "
+
+/* --------------------------------------------------------------------- */
+
+struct vrc5477_ac97_state {
+	/* list of vrc5477_ac97 devices */
+	struct list_head devs;
+
+	/* the corresponding pci_dev structure */
+	struct pci_dev *dev;
+
+	/* soundcore stuff */
+	int dev_audio;
+
+	/* hardware resources */
+	unsigned long io;
+	unsigned int irq;
+
+#ifdef CONFIG_LL_DEBUG
+	/* debug /proc entry */
+	struct proc_dir_entry *ps;
+	struct proc_dir_entry *ac97_ps;
+#endif /* CONFIG_LL_DEBUG */
+
+	struct ac97_codec codec;
+
+	unsigned dacChannels, adcChannels;
+	unsigned short dacRate, adcRate;
+
+	spinlock_t lock;
+	struct semaphore open_sem;
+	mode_t open_mode;
+	wait_queue_head_t open_wait;
+
+	struct dmabuf {
+		void *lbuf, *rbuf;
+		dma_addr_t lbufDma, rbufDma;
+		unsigned bufOrder;
+		unsigned numFrag;
+		unsigned fragShift;
+		unsigned fragSize;	/* redundant */
+		unsigned fragTotalSize;	/* = numFrag * fragSize(real)  */
+		unsigned nextIn;
+		unsigned nextOut;
+		int count;
+		unsigned error; /* over/underrun */
+		wait_queue_head_t wait;
+		/* OSS stuff */
+		unsigned stopped:1;
+		unsigned ready:1;
+	} dma_dac, dma_adc;
+
+	#define	WORK_BUF_SIZE	2048
+	struct {
+		u16 lchannel;
+		u16 rchannel;
+	} workBuf[WORK_BUF_SIZE/4];
+};
+
+/* --------------------------------------------------------------------- */
+
+static LIST_HEAD(devs);
+
+/* --------------------------------------------------------------------- */
+
+extern inline unsigned ld2(unsigned int x)
+{
+    unsigned r = 0;
+	
+    if (x >= 0x10000) {
+	x >>= 16;
+	r += 16;
+    }
+    if (x >= 0x100) {
+	x >>= 8;
+	r += 8;
+    }
+    if (x >= 0x10) {
+	x >>= 4;
+	r += 4;
+    }
+    if (x >= 4) {
+	x >>= 2;
+	r += 2;
+    }
+    if (x >= 2)
+	r++;
+    return r;
+}
+
+/* --------------------------------------------------------------------- */
+
+static u16 rdcodec(struct ac97_codec *codec, u8 addr)
+{
+	struct vrc5477_ac97_state *s = 
+		(struct vrc5477_ac97_state *)codec->private_data;
+	unsigned long flags;
+	u32 result;
+
+	spin_lock_irqsave(&s->lock, flags);
+
+	/* wait until we can access codec registers */
+	while (inl(s->io + VRC5477_CODEC_WR) & 0x80000000);
+
+	/* write the address and "read" command to codec */
+	addr = addr & 0x7f;
+	outl((addr << 16) | VRC5477_CODEC_WR_RWC, s->io + VRC5477_CODEC_WR);
+
+	/* get the return result */
+	udelay(100); /* workaround hardware bug */
+	while ( (result = inl(s->io + VRC5477_CODEC_RD)) & 
+                (VRC5477_CODEC_RD_RRDYA | VRC5477_CODEC_RD_RRDYD) ) {
+		/* we get either addr or data, or both */
+		if (result & VRC5477_CODEC_RD_RRDYA) {
+			MIPS_ASSERT(addr == ((result >> 16) & 0x7f) );
+		}
+		if (result & VRC5477_CODEC_RD_RRDYD) {
+			break;
+		}
+	}
+
+	spin_unlock_irqrestore(&s->lock, flags);
+
+	return result & 0xffff;;
+}
+
+
+static void wrcodec(struct ac97_codec *codec, u8 addr, u16 data)
+{
+	struct vrc5477_ac97_state *s = 
+		(struct vrc5477_ac97_state *)codec->private_data;
+	unsigned long flags;
+
+	spin_lock_irqsave(&s->lock, flags);
+
+	/* wait until we can access codec registers */
+	while (inl(s->io + VRC5477_CODEC_WR) & 0x80000000);
+
+	/* write the address and value to codec */
+	outl((addr << 16) | data, s->io + VRC5477_CODEC_WR);
+
+	spin_unlock_irqrestore(&s->lock, flags);
+}
+
+
+static void waitcodec(struct ac97_codec *codec)
+{
+	struct vrc5477_ac97_state *s = 
+		(struct vrc5477_ac97_state *)codec->private_data;
+
+	/* wait until we can access codec registers */
+	while (inl(s->io + VRC5477_CODEC_WR) & 0x80000000);
+}
+
+
+/* --------------------------------------------------------------------- */
+
+static void vrc5477_ac97_delay(int msec)
+{
+	unsigned long tmo;
+	signed long tmo2;
+
+	if (in_interrupt())
+		return;
+    
+	tmo = jiffies + (msec*HZ)/1000;
+	for (;;) {
+		tmo2 = tmo - jiffies;
+		if (tmo2 <= 0)
+			break;
+		schedule_timeout(tmo2);
+	}
+}
+
+
+static void set_adc_rate(struct vrc5477_ac97_state *s, unsigned rate)
+{
+	wrcodec(&s->codec, AC97_PCM_LR_ADC_RATE, rate);
+	s->adcRate = rate;
+}
+
+
+static void set_dac_rate(struct vrc5477_ac97_state *s, unsigned rate)
+{
+	wrcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE, rate);
+	s->dacRate = rate;
+}
+
+
+/* --------------------------------------------------------------------- */
+
+extern inline void 
+stop_dac(struct vrc5477_ac97_state *s)
+{
+	struct dmabuf* db = &s->dma_dac;
+	unsigned long flags;
+	u32 temp;
+    
+	spin_lock_irqsave(&s->lock, flags);
+
+	if (db->stopped) {
+		spin_unlock_irqrestore(&s->lock, flags);
+		return;
+	}
+
+	/* deactivate the dma */
+	outl(0, s->io + VRC5477_DAC1_CTRL);
+	outl(0, s->io + VRC5477_DAC2_CTRL);
+
+	/* wait for DAM completely stop */
+	while (inl(s->io + VRC5477_DAC1_CTRL) & VRC5477_DMA_WIP);
+	while (inl(s->io + VRC5477_DAC2_CTRL) & VRC5477_DMA_WIP);
+
+	/* disable dac slots in aclink */
+	temp = inl(s->io + VRC5477_CTRL);
+	temp &= ~ (VRC5477_CTRL_DAC1ENB | VRC5477_CTRL_DAC2ENB);
+	outl (temp, s->io + VRC5477_CTRL);
+
+	/* disable interrupts */
+	temp = inl(s->io + VRC5477_INT_MASK);
+	temp &= ~ (VRC5477_INT_MASK_DAC1END | VRC5477_INT_MASK_DAC2END); 
+	outl (temp, s->io + VRC5477_INT_MASK);
+
+	/* clear pending ones */
+	outl(VRC5477_INT_MASK_DAC1END | VRC5477_INT_MASK_DAC2END, 
+	     s->io +  VRC5477_INT_CLR);
+    
+	db->stopped = 1;
+    
+	spin_unlock_irqrestore(&s->lock, flags);
+}	
+
+static void start_dac(struct vrc5477_ac97_state *s)
+{
+	struct dmabuf* db = &s->dma_dac;
+	unsigned long flags;
+	u32 dmaLength;
+	u32 temp;
+
+	spin_lock_irqsave(&s->lock, flags);
+
+	if (!db->stopped) {
+		spin_unlock_irqrestore(&s->lock, flags);
+		return;
+	}
+
+	/* we should have some data to do the DMA trasnfer */
+	MIPS_ASSERT(db->count >= db->fragSize);
+
+	/* clear pending fales interrupts */
+	outl(VRC5477_INT_MASK_DAC1END | VRC5477_INT_MASK_DAC2END, 
+	     s->io +  VRC5477_INT_CLR);
+
+	/* enable interrupts */
+	temp = inl(s->io + VRC5477_INT_MASK);
+	temp |= VRC5477_INT_MASK_DAC1END | VRC5477_INT_MASK_DAC2END;
+	outl(temp, s->io +  VRC5477_INT_MASK);
+
+	/* setup dma base addr */
+	outl(db->lbufDma + db->nextOut, s->io + VRC5477_DAC1_BADDR);
+	if (s->dacChannels == 1) {
+		outl(db->lbufDma + db->nextOut, s->io + VRC5477_DAC2_BADDR);
+	} else {
+		outl(db->rbufDma + db->nextOut, s->io + VRC5477_DAC2_BADDR);
+	}
+
+	/* set dma length, in the unit of 0x10 bytes */
+	dmaLength = db->fragSize >> 4;
+	outl(dmaLength, s->io + VRC5477_DAC1L);
+	outl(dmaLength, s->io + VRC5477_DAC2L);
+
+	/* activate dma */
+	outl(VRC5477_DMA_ACTIVATION, s->io + VRC5477_DAC1_CTRL);
+	outl(VRC5477_DMA_ACTIVATION, s->io + VRC5477_DAC2_CTRL);
+
+	/* enable dac slots - we should hear the music now! */
+	temp = inl(s->io + VRC5477_CTRL);
+	temp |= (VRC5477_CTRL_DAC1ENB | VRC5477_CTRL_DAC2ENB);
+	outl (temp, s->io + VRC5477_CTRL);
+
+	/* it is time to setup next dma transfer */
+	MIPS_ASSERT(inl(s->io + VRC5477_DAC1_CTRL) & VRC5477_DMA_WIP);
+	MIPS_ASSERT(inl(s->io + VRC5477_DAC2_CTRL) & VRC5477_DMA_WIP);
+
+	temp = db->nextOut + db->fragSize;
+	if (temp >= db->fragTotalSize) {
+		MIPS_ASSERT(temp == db->fragTotalSize);
+		temp = 0;
+	}
+
+	outl(db->lbufDma + temp, s->io + VRC5477_DAC1_BADDR);
+	if (s->dacChannels == 1) {
+		outl(db->lbufDma + temp, s->io + VRC5477_DAC2_BADDR);
+	} else {
+		outl(db->rbufDma + temp, s->io + VRC5477_DAC2_BADDR);
+	}
+
+	db->stopped = 0;
+
+#if defined(VRC5477_AC97_VERBOSE_DEBUG)
+	outTicket = *(u16*)(db->lbuf+db->nextOut);
+	if (db->count > db->fragSize) {
+		MIPS_ASSERT((u16)(outTicket+1) == *(u16*)(db->lbuf+temp));
+	}
+#endif
+
+	spin_unlock_irqrestore(&s->lock, flags);
+}	
+
+extern inline void stop_adc(struct vrc5477_ac97_state *s)
+{
+	struct dmabuf* db = &s->dma_adc;
+	unsigned long flags;
+	u32 temp;
+    
+	spin_lock_irqsave(&s->lock, flags);
+
+	if (db->stopped) {
+		spin_unlock_irqrestore(&s->lock, flags);
+		return;
+	}
+
+	/* deactivate the dma */
+	outl(0, s->io + VRC5477_ADC1_CTRL);
+	outl(0, s->io + VRC5477_ADC2_CTRL);
+
+	/* disable adc slots in aclink */
+	temp = inl(s->io + VRC5477_CTRL);
+	temp &= ~ (VRC5477_CTRL_ADC1ENB | VRC5477_CTRL_ADC2ENB);
+	outl (temp, s->io + VRC5477_CTRL);
+
+	/* disable interrupts */
+        temp = inl(s->io + VRC5477_INT_MASK);
+        temp &= ~ (VRC5477_INT_MASK_ADC1END | VRC5477_INT_MASK_ADC2END); 
+        outl (temp, s->io + VRC5477_INT_MASK);
+
+	/* clear pending ones */
+	outl(VRC5477_INT_MASK_ADC1END | VRC5477_INT_MASK_ADC2END, 
+	     s->io +  VRC5477_INT_CLR);
+    
+	db->stopped = 1;
+
+	spin_unlock_irqrestore(&s->lock, flags);
+}	
+
+static void start_adc(struct vrc5477_ac97_state *s)
+{
+	struct dmabuf* db = &s->dma_adc;
+	unsigned long flags;
+	u32 dmaLength;
+	u32 temp;
+
+	spin_lock_irqsave(&s->lock, flags);
+
+	if (!db->stopped) {
+		spin_unlock_irqrestore(&s->lock, flags);
+		return;
+	}
+
+	/* we should at least have some free space in the buffer */
+	MIPS_ASSERT(db->count < db->fragTotalSize - db->fragSize * 2);
+
+	/* clear pending ones */
+	outl(VRC5477_INT_MASK_ADC1END | VRC5477_INT_MASK_ADC2END, 
+	     s->io +  VRC5477_INT_CLR);
+
+        /* enable interrupts */
+        temp = inl(s->io + VRC5477_INT_MASK);
+        temp |= VRC5477_INT_MASK_ADC1END | VRC5477_INT_MASK_ADC2END;
+        outl(temp, s->io +  VRC5477_INT_MASK);
+
+	/* setup dma base addr */
+	outl(db->lbufDma + db->nextIn, s->io + VRC5477_ADC1_BADDR);
+	outl(db->rbufDma + db->nextIn, s->io + VRC5477_ADC2_BADDR);
+
+	/* setup dma length */
+	dmaLength = db->fragSize >> 4;
+	outl(dmaLength, s->io + VRC5477_ADC1L);
+	outl(dmaLength, s->io + VRC5477_ADC2L);
+
+	/* activate dma */
+	outl(VRC5477_DMA_ACTIVATION, s->io + VRC5477_ADC1_CTRL);
+	outl(VRC5477_DMA_ACTIVATION, s->io + VRC5477_ADC2_CTRL);
+
+	/* enable adc slots */
+	temp = inl(s->io + VRC5477_CTRL);
+	temp |= (VRC5477_CTRL_ADC1ENB | VRC5477_CTRL_ADC2ENB);
+	outl (temp, s->io + VRC5477_CTRL);
+
+	/* it is time to setup next dma transfer */
+	temp = db->nextIn + db->fragSize;
+	if (temp >= db->fragTotalSize) {
+		MIPS_ASSERT(temp == db->fragTotalSize);
+		temp = 0;
+	}
+	outl(db->lbufDma + temp, s->io + VRC5477_ADC1_BADDR);
+	outl(db->rbufDma + temp, s->io + VRC5477_ADC2_BADDR);
+
+	db->stopped = 0;
+
+	spin_unlock_irqrestore(&s->lock, flags);
+}	
+
+/* --------------------------------------------------------------------- */
+
+#define DMABUF_DEFAULTORDER (16-PAGE_SHIFT)
+#define DMABUF_MINORDER 1
+
+extern inline void dealloc_dmabuf(struct vrc5477_ac97_state *s, 
+				  struct dmabuf *db)
+{
+	if (db->lbuf) {
+		MIPS_ASSERT(db->rbuf);
+		pci_free_consistent(s->dev, PAGE_SIZE << db->bufOrder,
+				    db->lbuf, db->lbufDma);
+		pci_free_consistent(s->dev, PAGE_SIZE << db->bufOrder,
+				    db->rbuf, db->rbufDma);
+		db->lbuf = db->rbuf = NULL;
+	}
+	db->nextIn = db->nextOut = 0;
+	db->ready = 0;
+}
+
+static int prog_dmabuf(struct vrc5477_ac97_state *s, 
+		       struct dmabuf *db,
+		       unsigned rate)
+{
+	int order;
+	unsigned bufsize;
+
+	if (!db->lbuf) {
+		MIPS_ASSERT(!db->rbuf);
+
+		db->ready = 0;
+		for (order = DMABUF_DEFAULTORDER; 
+		     order >= DMABUF_MINORDER; 
+		     order--) {
+			db->lbuf = pci_alloc_consistent(s->dev,
+							PAGE_SIZE << order,
+							&db->lbufDma);
+			db->rbuf = pci_alloc_consistent(s->dev,
+							PAGE_SIZE << order,
+							&db->rbufDma);
+			if (db->lbuf && db->rbuf) break;
+			if (db->lbuf) {
+			    MIPS_ASSERT(!db->rbuf);
+			    pci_free_consistent(s->dev, 
+						PAGE_SIZE << order,
+						db->lbuf,
+						db->lbufDma);
+			}
+		}
+		if (!db->lbuf) {
+			MIPS_ASSERT(!db->rbuf);
+			return -ENOMEM;
+		}
+
+		db->bufOrder = order;
+	}
+
+	db->count = 0;
+	db->nextIn = db->nextOut = 0;
+    
+	bufsize = PAGE_SIZE << db->bufOrder;
+	db->fragShift = ld2(rate * 2 / 100);
+	if (db->fragShift < 4) db->fragShift = 4;
+
+	db->numFrag = bufsize >> db->fragShift;
+	while (db->numFrag < 4 && db->fragShift > 4) {
+		db->fragShift--;
+		db->numFrag = bufsize >> db->fragShift;
+	}
+	db->fragSize = 1 << db->fragShift;
+	db->fragTotalSize = db->numFrag << db->fragShift;
+	memset(db->lbuf, 0, db->fragTotalSize);
+	memset(db->rbuf, 0, db->fragTotalSize);
+    
+	db->ready = 1;
+
+	return 0;
+}
+
+extern inline int prog_dmabuf_adc(struct vrc5477_ac97_state *s)
+{
+    stop_adc(s);
+    return prog_dmabuf(s, &s->dma_adc, s->adcRate);
+}
+
+extern inline int prog_dmabuf_dac(struct vrc5477_ac97_state *s)
+{
+    stop_dac(s);
+    return prog_dmabuf(s, &s->dma_dac, s->dacRate);
+}
+
+
+/* --------------------------------------------------------------------- */
+/* hold spinlock for the following! */
+
+static inline void vrc5477_ac97_adc_interrupt(struct vrc5477_ac97_state *s)
+{
+	struct dmabuf* adc = &s->dma_adc;
+	unsigned temp;
+
+	/* we need two frags avaiable because one is already being used
+	 * and the other will be used when next interrupt happens.
+	 */
+	if (adc->count >= adc->fragTotalSize - adc->fragSize) {
+		stop_adc(s);
+		adc->error++;
+		printk(KERN_INFO PFX "adc overrun\n");
+		return;
+	}
+
+	/* set the base addr for next DMA transfer */
+	temp = adc->nextIn + 2*adc->fragSize;
+	if (temp >= adc->fragTotalSize) {
+		MIPS_ASSERT( (temp == adc->fragTotalSize) ||
+                             (temp == adc->fragTotalSize + adc->fragSize) );
+		temp -= adc->fragTotalSize;
+	}
+	outl(adc->lbufDma + temp, s->io + VRC5477_ADC1_BADDR);
+	outl(adc->rbufDma + temp, s->io + VRC5477_ADC2_BADDR);
+
+	/* adjust nextIn */
+	adc->nextIn += adc->fragSize;
+	if (adc->nextIn >= adc->fragTotalSize) {
+		MIPS_ASSERT(adc->nextIn == adc->fragTotalSize);
+		adc->nextIn = 0;
+	}
+
+	/* adjust count */
+	adc->count += adc->fragSize;
+
+	/* wake up anybody listening */
+	if (waitqueue_active(&adc->wait)) {
+		wake_up_interruptible(&adc->wait);
+	}	
+}
+
+static inline void vrc5477_ac97_dac_interrupt(struct vrc5477_ac97_state *s)
+{
+	struct dmabuf* dac = &s->dma_dac;
+	unsigned temp;
+
+	/* next DMA transfer should already started */
+	MIPS_ASSERT(inl(s->io + VRC5477_DAC1_CTRL) & VRC5477_DMA_WIP);
+	MIPS_ASSERT(inl(s->io + VRC5477_DAC2_CTRL) & VRC5477_DMA_WIP);
+
+	/* let us set for next next DMA transfer */
+	temp = dac->nextOut + dac->fragSize*2;
+	if (temp >= dac->fragTotalSize) {
+		MIPS_ASSERT( (temp == dac->fragTotalSize) || 
+                             (temp == dac->fragTotalSize + dac->fragSize) );
+		temp -= dac->fragTotalSize;
+	}
+	outl(dac->lbufDma + temp, s->io + VRC5477_DAC1_BADDR);
+	if (s->dacChannels == 1) {
+		outl(dac->lbufDma + temp, s->io + VRC5477_DAC2_BADDR);
+	} else {
+		outl(dac->rbufDma + temp, s->io + VRC5477_DAC2_BADDR);
+	}
+
+#if defined(VRC5477_AC97_VERBOSE_DEBUG)
+	if (*(u16*)(dac->lbuf +  dac->nextOut) != outTicket) {
+		printk("assert fail: - %d vs %d\n", 
+		        *(u16*)(dac->lbuf +  dac->nextOut),
+                        outTicket);
+                MIPS_ASSERT(1 == 0);
+	}
+#endif
+
+	/* adjust nextOut pointer */
+	dac->nextOut += dac->fragSize;
+	if (dac->nextOut >= dac->fragTotalSize) {
+		MIPS_ASSERT(dac->nextOut == dac->fragTotalSize);
+		dac->nextOut = 0;
+	}
+
+	/* adjust count */
+	dac->count -= dac->fragSize;
+	if (dac->count <=0 ) {
+		MIPS_ASSERT(dac->count == 0);
+		MIPS_ASSERT(dac->nextIn == dac->nextOut);
+		/* buffer under run */
+		stop_dac(s);
+	}
+
+#if defined(VRC5477_AC97_VERBOSE_DEBUG)
+	if (dac->count) {
+		outTicket ++;
+		MIPS_ASSERT(*(u16*)(dac->lbuf +  dac->nextOut) == outTicket);
+	}
+#endif
+	
+	/* we cannot have both under run and someone is waiting on us */
+	MIPS_ASSERT(! (waitqueue_active(&dac->wait) && (dac->count <= 0)) );
+
+	/* wake up anybody listening */
+	if (waitqueue_active(&dac->wait))
+		wake_up_interruptible(&dac->wait);
+}
+
+static void vrc5477_ac97_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct vrc5477_ac97_state *s = (struct vrc5477_ac97_state *)dev_id;
+	u32 irqStatus;
+	u32 adcInterrupts, dacInterrupts;
+
+	spin_lock(&s->lock);
+
+	/* get irqStatus and clear the detected ones */
+	irqStatus = inl(s->io + VRC5477_INT_STATUS);
+	outl(irqStatus, s->io + VRC5477_INT_CLR);
+
+	/* let us see what we get */
+	dacInterrupts = VRC5477_INT_MASK_DAC1END | VRC5477_INT_MASK_DAC2END;
+	adcInterrupts = VRC5477_INT_MASK_ADC1END | VRC5477_INT_MASK_ADC2END;
+	if (irqStatus & dacInterrupts) {
+		/* we should get both interrupts, but just in case ...  */
+		if (irqStatus & VRC5477_INT_MASK_DAC1END) {
+			vrc5477_ac97_dac_interrupt(s);
+		}
+		if ( (irqStatus & dacInterrupts) != dacInterrupts ) {
+			printk(KERN_WARNING "vrc5477_ac97 : dac interrupts not in sync!!!\n");
+			stop_dac(s);
+			start_dac(s);
+		}
+	} else if (irqStatus & adcInterrupts) {
+		/* we should get both interrupts, but just in case ...  */
+		if(irqStatus & VRC5477_INT_MASK_ADC1END) {
+			vrc5477_ac97_adc_interrupt(s);
+		} 
+		if ( (irqStatus & adcInterrupts) != adcInterrupts ) {
+			printk(KERN_WARNING "vrc5477_ac97 : adc interrupts not in sync!!!\n");
+			stop_adc(s);
+			start_adc(s);
+		}
+	}
+
+	spin_unlock(&s->lock);
+}
+
+/* --------------------------------------------------------------------- */
+
+static loff_t vrc5477_ac97_llseek(struct file *file, loff_t offset, int origin)
+{
+	return -ESPIPE;
+}
+
+
+static int vrc5477_ac97_open_mixdev(struct inode *inode, struct file *file)
+{
+	int minor = MINOR(inode->i_rdev);
+	struct list_head *list;
+	struct vrc5477_ac97_state *s;
+
+	for (list = devs.next; ; list = list->next) {
+		if (list == &devs)
+			return -ENODEV;
+		s = list_entry(list, struct vrc5477_ac97_state, devs);
+		if (s->codec.dev_mixer == minor)
+			break;
+	}
+	file->private_data = s;
+	return 0;
+}
+
+static int vrc5477_ac97_release_mixdev(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+
+
+static int mixdev_ioctl(struct ac97_codec *codec, unsigned int cmd,
+			unsigned long arg)
+{
+	return codec->mixer_ioctl(codec, cmd, arg);
+}
+
+static int vrc5477_ac97_ioctl_mixdev(struct inode *inode, struct file *file,
+				     unsigned int cmd, unsigned long arg)
+{
+    struct vrc5477_ac97_state *s = 
+	    (struct vrc5477_ac97_state *)file->private_data;
+    struct ac97_codec *codec = &s->codec;
+
+    return mixdev_ioctl(codec, cmd, arg);
+}
+
+static /*const*/ struct file_operations vrc5477_ac97_mixer_fops = {
+	owner:		THIS_MODULE,
+	llseek:		vrc5477_ac97_llseek,
+	ioctl:		vrc5477_ac97_ioctl_mixdev,
+	open:		vrc5477_ac97_open_mixdev,
+	release:	vrc5477_ac97_release_mixdev,
+};
+
+/* --------------------------------------------------------------------- */
+
+static int drain_dac(struct vrc5477_ac97_state *s, int nonblock)
+{
+	unsigned long flags;
+	int count, tmo;
+	
+	if (!s->dma_dac.ready)
+		return 0;
+
+	for (;;) {
+		spin_lock_irqsave(&s->lock, flags);
+		count = s->dma_dac.count;
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (count <= 0)
+			break;
+		if (signal_pending(current))
+			break;
+		if (nonblock)
+			return -EBUSY;
+		tmo = 1000 * count / s->dacRate / 2;
+		vrc5477_ac97_delay(tmo);
+	}
+	if (signal_pending(current))
+		return -ERESTARTSYS;
+	return 0;
+}
+
+/* --------------------------------------------------------------------- */
+
+static int inline 
+copy_two_channel_adc_to_user(struct vrc5477_ac97_state *s, 
+		             char *buffer, 
+			     int copyCount)
+{
+	struct dmabuf *db = &s->dma_adc;
+	int bufStart = db->nextOut;
+	for (; copyCount > 0; ) {
+		int i;
+		int count = copyCount;
+		if (count > WORK_BUF_SIZE/2) count = WORK_BUF_SIZE/2;
+		for (i=0; i< count/2; i++) {
+			s->workBuf[i].lchannel = 
+				*(u16*)(db->lbuf + bufStart + i*2);
+			s->workBuf[i].rchannel = 
+				*(u16*)(db->rbuf + bufStart + i*2);
+		}
+		if (copy_to_user(buffer, s->workBuf, count*2)) {
+			return -1;
+		}
+
+		copyCount -= count;
+		bufStart += count;
+		MIPS_ASSERT(bufStart <= db->fragTotalSize);
+		buffer += count *2;
+	}
+	return 0;
+}
+
+/* return the total bytes that is copied */
+static int inline 
+copy_adc_to_user(struct vrc5477_ac97_state *s,
+		 char * buffer,
+		 size_t count,
+		 int avail)
+{
+	struct dmabuf *db = &s->dma_adc;
+	int copyCount=0;
+	int copyFragCount=0;
+	int totalCopyCount = 0;
+	int totalCopyFragCount = 0;
+	unsigned long flags;
+
+	/* adjust count to signel channel byte count */
+	count >>= s->adcChannels - 1;
+
+	/* we may have to "copy" twice as ring buffer wraps around */
+	for (; (avail > 0) && (count > 0); ) {
+		/* determine max possible copy count for single channel */
+		copyCount = count;
+		if (copyCount > avail) {
+			copyCount = avail;
+		}
+		if (copyCount + db->nextOut > db->fragTotalSize) {
+			copyCount = db->fragTotalSize - db->nextOut;
+			MIPS_ASSERT((copyCount % db->fragSize) == 0);
+		}
+
+		copyFragCount = (copyCount-1) >> db->fragShift;
+		copyFragCount = (copyFragCount+1) << db->fragShift;
+		MIPS_ASSERT(copyFragCount >= copyCount);
+
+		/* we copy differently based on adc channels */
+		if (s->adcChannels == 1) {
+			if (copy_to_user(buffer, 
+					 db->lbuf + db->nextOut, 
+					 copyCount)) 
+				return -1;
+		} else {
+			/* *sigh* we have to mix two streams into one  */
+			if (copy_two_channel_adc_to_user(s, buffer, copyCount))
+				return -1;
+		}	
+
+		count -= copyCount;
+		totalCopyCount += copyCount;
+		avail -= copyFragCount;
+		totalCopyFragCount += copyFragCount;
+
+		buffer += copyCount << (s->adcChannels-1);
+
+		db->nextOut += copyFragCount;
+		if (db->nextOut >= db->fragTotalSize) {
+			MIPS_ASSERT(db->nextOut == db->fragTotalSize);
+			db->nextOut = 0;
+		}
+
+		MIPS_ASSERT((copyFragCount % db->fragSize) == 0);
+		MIPS_ASSERT( (count == 0) || (copyCount == copyFragCount));
+	}
+
+	spin_lock_irqsave(&s->lock, flags);
+        db->count -= totalCopyFragCount;
+        spin_unlock_irqrestore(&s->lock, flags);
+
+	return totalCopyCount << (s->adcChannels-1);
+}
+
+static ssize_t 
+vrc5477_ac97_read(struct file *file, 
+		  char *buffer,
+		  size_t count, 
+		  loff_t *ppos)
+{
+	struct vrc5477_ac97_state *s = 
+		(struct vrc5477_ac97_state *)file->private_data;
+	struct dmabuf *db = &s->dma_adc;
+	ssize_t ret = 0;
+	unsigned long flags;
+	int copyCount;
+	size_t avail;
+
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+	if (!access_ok(VERIFY_WRITE, buffer, count))
+		return -EFAULT;
+
+	MIPS_ASSERT(db->ready);
+
+	while (count > 0) {
+		// wait for samples in capture buffer
+		do {
+			spin_lock_irqsave(&s->lock, flags);
+			if (db->stopped)
+				start_adc(s);
+			avail = db->count;
+			spin_unlock_irqrestore(&s->lock, flags);
+			if (avail <= 0) {
+				if (file->f_flags & O_NONBLOCK) {
+					if (!ret)
+						ret = -EAGAIN;
+					return ret;
+				}
+				interruptible_sleep_on(&db->wait);
+				if (signal_pending(current)) {
+					if (!ret)
+						ret = -ERESTARTSYS;
+					return ret;
+				}
+			}
+		} while (avail <= 0);
+
+		MIPS_ASSERT( (avail % db->fragSize) == 0);
+		copyCount = copy_adc_to_user(s, buffer, count, avail);
+		if (copyCount <=0 ) {
+			if (!ret) ret = -EFAULT;
+			return ret;
+		}
+
+		count -= copyCount;
+		buffer += copyCount;
+		ret += copyCount;
+	} // while (count > 0)
+
+	return ret;
+}
+
+static int inline 
+copy_two_channel_dac_from_user(struct vrc5477_ac97_state *s, 
+			       const char *buffer, 
+			       int copyCount)
+{
+	struct dmabuf *db = &s->dma_dac;
+	int bufStart = db->nextIn;
+
+	MIPS_ASSERT(db->ready);
+
+        for (; copyCount > 0; ) {
+                int i;
+                int count = copyCount;
+                if (count > WORK_BUF_SIZE/2) count = WORK_BUF_SIZE/2;
+                if (copy_from_user(s->workBuf, buffer, count*2)) {
+                        return -1;
+                }
+                for (i=0; i< count/2; i++) {
+			*(u16*)(db->lbuf + bufStart + i*2) = 
+				s->workBuf[i].lchannel;
+			*(u16*)(db->rbuf + bufStart + i*2) = 
+				s->workBuf[i].rchannel;
+                }
+
+                copyCount -= count;
+		bufStart += count;
+		MIPS_ASSERT(bufStart <= db->fragTotalSize);
+                buffer += count *2;
+        }
+        return 0;
+
+}
+
+/* return the total bytes that is copied */
+static int inline 
+copy_dac_from_user(struct vrc5477_ac97_state *s, 
+		   const char *buffer, 
+		   size_t count, 
+		   int avail)
+{	
+        struct dmabuf *db = &s->dma_dac;
+        int copyCount=0;
+        int copyFragCount=0;
+        int totalCopyCount = 0;
+        int totalCopyFragCount = 0;
+        unsigned long flags;
+#if defined(VRC5477_AC97_VERBOSE_DEBUG)
+	int i;
+#endif
+
+        /* adjust count to signel channel byte count */
+        count >>= s->dacChannels - 1;
+
+        /* we may have to "copy" twice as ring buffer wraps around */
+        for (; (avail > 0) && (count > 0); ) {
+                /* determine max possible copy count for single channel */
+                copyCount = count;
+                if (copyCount > avail) {
+                        copyCount = avail;
+		}
+                if (copyCount + db->nextIn > db->fragTotalSize) {
+                        copyCount = db->fragTotalSize - db->nextIn;
+                        MIPS_ASSERT((copyCount % db->fragSize) == 0);
+                        MIPS_ASSERT(copyCount > 0);
+                }
+
+		copyFragCount = (copyCount-1) >> db->fragShift;
+		copyFragCount = (copyFragCount+1) << db->fragShift;
+		MIPS_ASSERT(copyFragCount >= copyCount);
+
+		/* we copy differently based on the number channels */
+		if (s->dacChannels == 1) {
+			if (copy_from_user(db->lbuf + db->nextIn,
+					   buffer,
+					   copyCount)) 
+				return -1;
+			/* fill gaps with 0 */
+			memset(db->lbuf + db->nextIn + copyCount,
+			       0,
+			       copyFragCount - copyCount);
+		} else {
+			/* we have demux the stream into two separate ones */
+			if (copy_two_channel_dac_from_user(s, buffer, copyCount))
+				return -1;
+			/* fill gaps with 0 */
+			memset(db->lbuf + db->nextIn + copyCount,
+			       0,
+			       copyFragCount - copyCount);
+			memset(db->rbuf + db->nextIn + copyCount,
+			       0,
+			       copyFragCount - copyCount);
+		}
+
+#if defined(VRC5477_AC97_VERBOSE_DEBUG)
+		for (i=0; i< copyFragCount; i+= db->fragSize) {
+			*(u16*)(db->lbuf + db->nextIn + i) = inTicket ++;
+		}
+#endif
+
+		count -= copyCount;
+		totalCopyCount =+ copyCount;
+		avail -= copyFragCount;
+		totalCopyFragCount += copyFragCount;
+
+		buffer += copyCount << (s->dacChannels - 1);
+
+		db->nextIn += copyFragCount;
+		if (db->nextIn >= db->fragTotalSize) {
+			MIPS_ASSERT(db->nextIn == db->fragTotalSize);
+			db->nextIn = 0;
+		}
+
+		MIPS_ASSERT((copyFragCount % db->fragSize) == 0);
+		MIPS_ASSERT( (count == 0) || (copyCount == copyFragCount));
+	}
+
+	spin_lock_irqsave(&s->lock, flags);
+        db->count += totalCopyFragCount;
+	if (db->stopped) {
+		start_dac(s);
+	}
+
+	/* nextIn should not be equal to nextOut unless we are full */
+	MIPS_ASSERT( ( (db->count == db->fragTotalSize) && 
+                       (db->nextIn == db->nextOut) ) ||
+                     ( (db->count < db->fragTotalSize) &&
+                       (db->nextIn != db->nextOut) ) );
+
+        spin_unlock_irqrestore(&s->lock, flags);
+
+        return totalCopyCount << (s->dacChannels-1);
+
+}
+
+static ssize_t vrc5477_ac97_write(struct file *file, const char *buffer,
+				  size_t count, loff_t *ppos)
+{
+	struct vrc5477_ac97_state *s = 
+		(struct vrc5477_ac97_state *)file->private_data;
+	struct dmabuf *db = &s->dma_dac;
+	ssize_t ret;
+	unsigned long flags;
+	int copyCount, avail;
+
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+	if (!access_ok(VERIFY_READ, buffer, count))
+		return -EFAULT;
+	ret = 0;
+    
+	while (count > 0) {
+		// wait for space in playback buffer
+		do {
+			spin_lock_irqsave(&s->lock, flags);
+			avail = db->fragTotalSize - db->count;
+			spin_unlock_irqrestore(&s->lock, flags);
+			if (avail <= 0) {
+				if (file->f_flags & O_NONBLOCK) {
+					if (!ret)
+						ret = -EAGAIN;
+					return ret;
+				}
+				interruptible_sleep_on(&db->wait);
+				if (signal_pending(current)) {
+					if (!ret)
+						ret = -ERESTARTSYS;
+					return ret;
+				}
+			}
+		} while (avail <= 0);
+	
+		MIPS_ASSERT( (avail % db->fragSize) == 0);
+		copyCount = copy_dac_from_user(s, buffer, count, avail);
+		if (copyCount < 0) {
+			if (!ret) ret = -EFAULT;
+			return ret;
+		}
+
+		count -= copyCount;
+		buffer += copyCount;
+		ret += copyCount;
+	} // while (count > 0)
+	
+	return ret;
+}
+
+/* No kernel lock - we have our own spinlock */
+static unsigned int vrc5477_ac97_poll(struct file *file,
+				      struct poll_table_struct *wait)
+{
+	struct vrc5477_ac97_state *s = (struct vrc5477_ac97_state *)file->private_data;
+	unsigned long flags;
+	unsigned int mask = 0;
+
+	if (file->f_mode & FMODE_WRITE)
+		poll_wait(file, &s->dma_dac.wait, wait);
+	if (file->f_mode & FMODE_READ)
+		poll_wait(file, &s->dma_adc.wait, wait);
+	spin_lock_irqsave(&s->lock, flags);
+	if (file->f_mode & FMODE_READ) {
+		if (s->dma_adc.count >= (signed)s->dma_adc.fragSize)
+			mask |= POLLIN | POLLRDNORM;
+	}
+	if (file->f_mode & FMODE_WRITE) {
+		if ((signed)s->dma_dac.fragTotalSize >=
+		    s->dma_dac.count + (signed)s->dma_dac.fragSize)
+			mask |= POLLOUT | POLLWRNORM;
+	}
+	spin_unlock_irqrestore(&s->lock, flags);
+	return mask;
+}
+
+#ifdef CONFIG_LL_DEBUG
+static struct ioctl_str_t {
+    unsigned int cmd;
+    const char* str;
+} ioctl_str[] = {
+    {SNDCTL_DSP_RESET, "SNDCTL_DSP_RESET"},
+    {SNDCTL_DSP_SYNC, "SNDCTL_DSP_SYNC"},
+    {SNDCTL_DSP_SPEED, "SNDCTL_DSP_SPEED"},
+    {SNDCTL_DSP_STEREO, "SNDCTL_DSP_STEREO"},
+    {SNDCTL_DSP_GETBLKSIZE, "SNDCTL_DSP_GETBLKSIZE"},
+    {SNDCTL_DSP_SETFMT, "SNDCTL_DSP_SETFMT"},
+    {SNDCTL_DSP_SAMPLESIZE, "SNDCTL_DSP_SAMPLESIZE"},
+    {SNDCTL_DSP_CHANNELS, "SNDCTL_DSP_CHANNELS"},
+    {SOUND_PCM_WRITE_CHANNELS, "SOUND_PCM_WRITE_CHANNELS"},
+    {SOUND_PCM_WRITE_FILTER, "SOUND_PCM_WRITE_FILTER"},
+    {SNDCTL_DSP_POST, "SNDCTL_DSP_POST"},
+    {SNDCTL_DSP_SUBDIVIDE, "SNDCTL_DSP_SUBDIVIDE"},
+    {SNDCTL_DSP_SETFRAGMENT, "SNDCTL_DSP_SETFRAGMENT"},
+    {SNDCTL_DSP_GETFMTS, "SNDCTL_DSP_GETFMTS"},
+    {SNDCTL_DSP_GETOSPACE, "SNDCTL_DSP_GETOSPACE"},
+    {SNDCTL_DSP_GETISPACE, "SNDCTL_DSP_GETISPACE"},
+    {SNDCTL_DSP_NONBLOCK, "SNDCTL_DSP_NONBLOCK"},
+    {SNDCTL_DSP_GETCAPS, "SNDCTL_DSP_GETCAPS"},
+    {SNDCTL_DSP_GETTRIGGER, "SNDCTL_DSP_GETTRIGGER"},
+    {SNDCTL_DSP_SETTRIGGER, "SNDCTL_DSP_SETTRIGGER"},
+    {SNDCTL_DSP_GETIPTR, "SNDCTL_DSP_GETIPTR"},
+    {SNDCTL_DSP_GETOPTR, "SNDCTL_DSP_GETOPTR"},
+    {SNDCTL_DSP_MAPINBUF, "SNDCTL_DSP_MAPINBUF"},
+    {SNDCTL_DSP_MAPOUTBUF, "SNDCTL_DSP_MAPOUTBUF"},
+    {SNDCTL_DSP_SETSYNCRO, "SNDCTL_DSP_SETSYNCRO"},
+    {SNDCTL_DSP_SETDUPLEX, "SNDCTL_DSP_SETDUPLEX"},
+    {SNDCTL_DSP_GETODELAY, "SNDCTL_DSP_GETODELAY"},
+    {SNDCTL_DSP_GETCHANNELMASK, "SNDCTL_DSP_GETCHANNELMASK"},
+    {SNDCTL_DSP_BIND_CHANNEL, "SNDCTL_DSP_BIND_CHANNEL"},
+    {OSS_GETVERSION, "OSS_GETVERSION"},
+    {SOUND_PCM_READ_RATE, "SOUND_PCM_READ_RATE"},
+    {SOUND_PCM_READ_CHANNELS, "SOUND_PCM_READ_CHANNELS"},
+    {SOUND_PCM_READ_BITS, "SOUND_PCM_READ_BITS"},
+    {SOUND_PCM_READ_FILTER, "SOUND_PCM_READ_FILTER"}
+};
+#endif    
+
+static int vrc5477_ac97_ioctl(struct inode *inode, struct file *file,
+			unsigned int cmd, unsigned long arg)
+{
+	struct vrc5477_ac97_state *s = (struct vrc5477_ac97_state *)file->private_data;
+	unsigned long flags;
+	audio_buf_info abinfo;
+	int count;
+	int val, ret;
+
+#ifdef CONFIG_LL_DEBUG
+	for (count=0; count<sizeof(ioctl_str)/sizeof(ioctl_str[0]); count++) {
+		if (ioctl_str[count].cmd == cmd)
+			break;
+	}
+	if (count < sizeof(ioctl_str)/sizeof(ioctl_str[0]))
+		printk(KERN_INFO PFX "ioctl %s\n", ioctl_str[count].str);
+	else
+		printk(KERN_INFO PFX "ioctl unknown, 0x%x\n", cmd);
+#endif
+    
+	switch (cmd) {
+	case OSS_GETVERSION:
+		return put_user(SOUND_VERSION, (int *)arg);
+
+	case SNDCTL_DSP_SYNC:
+		if (file->f_mode & FMODE_WRITE)
+			return drain_dac(s, file->f_flags & O_NONBLOCK);
+		return 0;
+		
+	case SNDCTL_DSP_SETDUPLEX:
+		return 0;
+
+	case SNDCTL_DSP_GETCAPS:
+		return put_user(DSP_CAP_DUPLEX, (int *)arg);
+		
+	case SNDCTL_DSP_RESET:
+		if (file->f_mode & FMODE_WRITE) {
+			stop_dac(s);
+			synchronize_irq();
+			s->dma_dac.count = 0;
+			s->dma_dac.nextIn = s->dma_dac.nextOut = 0;
+		}
+		if (file->f_mode & FMODE_READ) {
+			stop_adc(s);
+			synchronize_irq();
+			s->dma_adc.count = 0;
+			s->dma_adc.nextIn = s->dma_adc.nextOut = 0;
+		}
+		return 0;
+
+	case SNDCTL_DSP_SPEED:
+		if (get_user(val, (int *)arg))
+			return -EFAULT;
+		if (val >= 0) {
+			if (file->f_mode & FMODE_READ) {
+				stop_adc(s);
+				set_adc_rate(s, val);
+				if ((ret = prog_dmabuf_adc(s)))
+					return ret;
+			}
+			if (file->f_mode & FMODE_WRITE) {
+				stop_dac(s);
+				set_dac_rate(s, val);
+				if ((ret = prog_dmabuf_dac(s)))
+					return ret;
+			}
+		}
+		return put_user((file->f_mode & FMODE_READ) ?
+				s->adcRate : s->dacRate, (int *)arg);
+
+	case SNDCTL_DSP_STEREO:
+		if (get_user(val, (int *)arg))
+			return -EFAULT;
+		if (file->f_mode & FMODE_READ) {
+			stop_adc(s);
+			if (val)
+				s->adcChannels = 2;
+			else
+				s->adcChannels = 1;
+			if ((ret = prog_dmabuf_adc(s)))
+				return ret;
+		}
+		if (file->f_mode & FMODE_WRITE) {
+			stop_dac(s);
+			if (val)
+				s->dacChannels = 2;
+			else
+				s->dacChannels = 1;
+			if ((ret = prog_dmabuf_dac(s)))
+				return ret;
+		}
+		return 0;
+
+	case SNDCTL_DSP_CHANNELS:
+		if (get_user(val, (int *)arg))
+			return -EFAULT;
+		if (val != 0) {
+			if ( (val != 1) && (val != 2)) val = 2;
+
+			if (file->f_mode & FMODE_READ) {
+				stop_adc(s);
+				s->dacChannels = val;
+				if ((ret = prog_dmabuf_adc(s)))
+					return ret;
+			}
+			if (file->f_mode & FMODE_WRITE) {
+				stop_dac(s);
+				s->dacChannels = val;
+				if ((ret = prog_dmabuf_dac(s)))
+					return ret;
+			}
+		}
+		return put_user(val, (int *)arg);
+		
+	case SNDCTL_DSP_GETFMTS: /* Returns a mask */
+		return put_user(AFMT_S16_LE, (int *)arg);
+		
+	case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
+		if (get_user(val, (int *)arg))
+			return -EFAULT;
+		if (val != AFMT_QUERY) {
+			if (val != AFMT_S16_LE) return -EINVAL;
+			if (file->f_mode & FMODE_READ) {
+				stop_adc(s);
+				if ((ret = prog_dmabuf_adc(s)))
+					return ret;
+			}
+			if (file->f_mode & FMODE_WRITE) {
+				stop_dac(s);
+				if ((ret = prog_dmabuf_dac(s)))
+					return ret;
+			}
+		} else {
+			val = AFMT_S16_LE;
+		}
+		return put_user(val, (int *)arg);
+		
+	case SNDCTL_DSP_POST:
+		return 0;
+
+	case SNDCTL_DSP_GETTRIGGER:
+	case SNDCTL_DSP_SETTRIGGER:
+		/* NO trigger */
+		return -EINVAL;
+
+	case SNDCTL_DSP_GETOSPACE:
+		if (!(file->f_mode & FMODE_WRITE))
+			return -EINVAL;
+		abinfo.fragsize = s->dma_dac.fragSize << (s->dacChannels-1);
+		spin_lock_irqsave(&s->lock, flags);
+		count = s->dma_dac.count;
+		spin_unlock_irqrestore(&s->lock, flags);
+		abinfo.bytes = (s->dma_dac.fragTotalSize - count) << 
+			(s->dacChannels-1);
+		abinfo.fragstotal = s->dma_dac.numFrag;
+		abinfo.fragments = abinfo.bytes >> s->dma_dac.fragShift >> 
+			(s->dacChannels-1);      
+		return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+
+	case SNDCTL_DSP_GETISPACE:
+		if (!(file->f_mode & FMODE_READ))
+			return -EINVAL;
+		abinfo.fragsize = s->dma_adc.fragSize << (s->adcChannels-1);
+		spin_lock_irqsave(&s->lock, flags);
+		count = s->dma_adc.count;
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (count < 0)
+			count = 0;
+		abinfo.bytes = count << (s->adcChannels-1);
+		abinfo.fragstotal = s->dma_adc.numFrag;
+		abinfo.fragments = (abinfo.bytes >> s->dma_adc.fragShift) >>
+			(s->adcChannels-1);      
+		return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+		
+	case SNDCTL_DSP_NONBLOCK:
+		file->f_flags |= O_NONBLOCK;
+		return 0;
+
+	case SNDCTL_DSP_GETODELAY:
+		if (!(file->f_mode & FMODE_WRITE))
+			return -EINVAL;
+		spin_lock_irqsave(&s->lock, flags);
+		count = s->dma_dac.count;
+		spin_unlock_irqrestore(&s->lock, flags);
+		return put_user(count, (int *)arg);
+
+	case SNDCTL_DSP_GETIPTR:
+	case SNDCTL_DSP_GETOPTR:
+		/* we cannot get DMA ptr */
+		return -EINVAL;
+
+	case SNDCTL_DSP_GETBLKSIZE:
+		if (file->f_mode & FMODE_WRITE)
+			return put_user(s->dma_dac.fragSize << (s->dacChannels-1), (int *)arg);
+		else
+			return put_user(s->dma_adc.fragSize << (s->adcChannels-1), (int *)arg);
+
+	case SNDCTL_DSP_SETFRAGMENT:
+		/* we ignore fragment size request */
+		return 0;
+
+	case SNDCTL_DSP_SUBDIVIDE:
+		/* what is this for? [jsun] */
+		return 0;
+
+	case SOUND_PCM_READ_RATE:
+		return put_user((file->f_mode & FMODE_READ) ?
+				s->adcRate : s->dacRate, (int *)arg);
+
+	case SOUND_PCM_READ_CHANNELS:
+		if (file->f_mode & FMODE_READ)
+			return put_user(s->adcChannels, (int *)arg);
+		else
+			return put_user(s->dacChannels ? 2 : 1, (int *)arg);
+	    
+	case SOUND_PCM_READ_BITS:
+		return put_user(16, (int *)arg);
+
+	case SOUND_PCM_WRITE_FILTER:
+	case SNDCTL_DSP_SETSYNCRO:
+	case SOUND_PCM_READ_FILTER:
+		return -EINVAL;
+	}
+
+	return mixdev_ioctl(&s->codec, cmd, arg);
+}
+
+
+static int vrc5477_ac97_open(struct inode *inode, struct file *file)
+{
+	int minor = MINOR(inode->i_rdev);
+	DECLARE_WAITQUEUE(wait, current);
+	unsigned long flags;
+	struct list_head *list;
+	struct vrc5477_ac97_state *s;
+	int ret=0;
+    
+	for (list = devs.next; ; list = list->next) {
+		if (list == &devs)
+			return -ENODEV;
+		s = list_entry(list, struct vrc5477_ac97_state, devs);
+		if (!((s->dev_audio ^ minor) & ~0xf))
+			break;
+	}
+	file->private_data = s;
+
+	/* wait for device to become free */
+	down(&s->open_sem);
+	while (s->open_mode & file->f_mode) {
+
+		if (file->f_flags & O_NONBLOCK) {
+			up(&s->open_sem);
+			return -EBUSY;
+		}
+		add_wait_queue(&s->open_wait, &wait);
+		__set_current_state(TASK_INTERRUPTIBLE);
+		up(&s->open_sem);
+		schedule();
+		remove_wait_queue(&s->open_wait, &wait);
+		set_current_state(TASK_RUNNING);
+		if (signal_pending(current))
+			return -ERESTARTSYS;
+		down(&s->open_sem);
+	}
+
+	spin_lock_irqsave(&s->lock, flags);
+
+	if (file->f_mode & FMODE_READ) {
+		/* set default settings */
+		set_adc_rate(s, 48000);
+		s->adcChannels = 2;
+
+		ret = prog_dmabuf_adc(s);
+		if (ret) goto bailout;
+	}
+	if (file->f_mode & FMODE_WRITE) {
+		/* set default settings */
+		set_dac_rate(s, 48000);
+		s->dacChannels = 2;
+
+		ret = prog_dmabuf_dac(s);
+		if (ret) goto bailout;
+	}
+
+	s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
+
+ bailout:
+	spin_unlock_irqrestore(&s->lock, flags);
+
+	up(&s->open_sem);
+	return ret;
+}
+
+static int vrc5477_ac97_release(struct inode *inode, struct file *file)
+{
+	struct vrc5477_ac97_state *s = 
+		(struct vrc5477_ac97_state *)file->private_data;
+
+	lock_kernel();
+	if (file->f_mode & FMODE_WRITE)
+		drain_dac(s, file->f_flags & O_NONBLOCK);
+	down(&s->open_sem);
+	if (file->f_mode & FMODE_WRITE) {
+		stop_dac(s);
+		dealloc_dmabuf(s, &s->dma_dac);
+	}
+	if (file->f_mode & FMODE_READ) {
+		stop_adc(s);
+		dealloc_dmabuf(s, &s->dma_adc);
+	}
+	s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
+	up(&s->open_sem);
+	wake_up(&s->open_wait);
+	unlock_kernel();
+	return 0;
+}
+
+static /*const*/ struct file_operations vrc5477_ac97_audio_fops = {
+	owner:	THIS_MODULE,
+	llseek:		vrc5477_ac97_llseek,
+	read:		vrc5477_ac97_read,
+	write:		vrc5477_ac97_write,
+	poll:		vrc5477_ac97_poll,
+	ioctl:		vrc5477_ac97_ioctl,
+	// mmap:	vrc5477_ac97_mmap,
+	open:		vrc5477_ac97_open,
+	release:	vrc5477_ac97_release,
+};
+
+
+/* --------------------------------------------------------------------- */
+
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * for debugging purposes, we'll create a proc device that dumps the
+ * CODEC chipstate
+ */
+
+#ifdef CONFIG_LL_DEBUG
+
+struct {
+       const char *regname;
+       unsigned regaddr;
+} vrc5477_ac97_regs[] = {
+	{"VRC5477_INT_STATUS", VRC5477_INT_STATUS},
+	{"VRC5477_CODEC_WR", VRC5477_CODEC_WR},
+	{"VRC5477_CODEC_RD", VRC5477_CODEC_RD},
+	{"VRC5477_CTRL", VRC5477_CTRL},
+	{"VRC5477_ACLINK_CTRL", VRC5477_ACLINK_CTRL},
+	{"VRC5477_INT_MASK", VRC5477_INT_MASK},
+	{"VRC5477_DAC1_CTRL", VRC5477_DAC1_CTRL},
+	{"VRC5477_DAC1L", VRC5477_DAC1L},
+	{"VRC5477_DAC1_BADDR", VRC5477_DAC1_BADDR},
+	{"VRC5477_DAC2_CTRL", VRC5477_DAC2_CTRL},
+	{"VRC5477_DAC2L", VRC5477_DAC2L},
+	{"VRC5477_DAC2_BADDR", VRC5477_DAC2_BADDR},
+	{"VRC5477_DAC3_CTRL", VRC5477_DAC3_CTRL},
+	{"VRC5477_DAC3L", VRC5477_DAC3L},
+	{"VRC5477_DAC3_BADDR", VRC5477_DAC3_BADDR},
+	{"VRC5477_ADC1_CTRL", VRC5477_ADC1_CTRL},
+	{"VRC5477_ADC1L", VRC5477_ADC1L},
+	{"VRC5477_ADC1_BADDR", VRC5477_ADC1_BADDR},
+	{"VRC5477_ADC2_CTRL", VRC5477_ADC2_CTRL},
+	{"VRC5477_ADC2L", VRC5477_ADC2L},
+	{"VRC5477_ADC2_BADDR", VRC5477_ADC2_BADDR},
+	{"VRC5477_ADC3_CTRL", VRC5477_ADC3_CTRL},
+	{"VRC5477_ADC3L", VRC5477_ADC3L},
+	{"VRC5477_ADC3_BADDR", VRC5477_ADC3_BADDR},
+	{NULL, 0x0}
+};
+
+static int proc_vrc5477_ac97_dump (char *buf, char **start, off_t fpos,
+				   int length, int *eof, void *data)
+{
+	struct vrc5477_ac97_state *s;
+	int cnt, len = 0;
+
+	if (list_empty(&devs))
+		return 0;
+	s = list_entry(devs.next, struct vrc5477_ac97_state, devs);
+
+	/* print out header */
+	len += sprintf(buf + len, "\n\t\tVrc5477 Audio Debug\n\n");
+
+	// print out digital controller state
+	len += sprintf (buf + len, "NEC Vrc5477 Audio Controller registers\n");
+	len += sprintf (buf + len, "---------------------------------\n");
+	for (cnt=0; vrc5477_ac97_regs[cnt].regname != NULL; cnt++) {
+		len+= sprintf (buf + len, "%-20s = %08x\n",
+			       vrc5477_ac97_regs[cnt].regname,
+			       inl(s->io + vrc5477_ac97_regs[cnt].regaddr));
+	}
+   
+	/* print out driver state */
+	len += sprintf (buf + len, "NEC Vrc5477 Audio driver states\n");
+	len += sprintf (buf + len, "---------------------------------\n");
+	len += sprintf (buf + len, "dacChannels  = %d\n", s->dacChannels);
+	len += sprintf (buf + len, "adcChannels  = %d\n", s->adcChannels);
+	len += sprintf (buf + len, "dacRate  = %d\n", s->dacRate);
+	len += sprintf (buf + len, "adcRate  = %d\n", s->adcRate);
+
+	len += sprintf (buf + len, "dma_dac is %s ready\n",  
+	                s->dma_dac.ready? "" : "not");
+        if (s->dma_dac.ready) {
+		len += sprintf (buf + len, "dma_dac is %s stopped.\n",  
+	                        s->dma_dac.stopped? "" : "not");
+		len += sprintf (buf + len, "dma_dac.fragSize = %x\n", 
+                                s->dma_dac.fragSize);
+		len += sprintf (buf + len, "dma_dac.fragShift = %x\n", 
+                                s->dma_dac.fragShift);
+		len += sprintf (buf + len, "dma_dac.numFrag = %x\n", 
+                                s->dma_dac.numFrag);
+		len += sprintf (buf + len, "dma_dac.fragTotalSize = %x\n", 
+                                s->dma_dac.fragTotalSize);
+		len += sprintf (buf + len, "dma_dac.nextIn = %x\n", 
+                                s->dma_dac.nextIn);
+		len += sprintf (buf + len, "dma_dac.nextOut = %x\n", 
+                                s->dma_dac.nextOut);
+		len += sprintf (buf + len, "dma_dac.count = %x\n", 
+                                s->dma_dac.count);
+	}
+
+	len += sprintf (buf + len, "dma_adc is %s ready\n",  
+	                s->dma_adc.ready? "" : "not");
+        if (s->dma_adc.ready) {
+		len += sprintf (buf + len, "dma_adc is %s stopped.\n",  
+	                        s->dma_adc.stopped? "" : "not");
+		len += sprintf (buf + len, "dma_adc.fragSize = %x\n", 
+                                s->dma_adc.fragSize);
+		len += sprintf (buf + len, "dma_adc.fragShift = %x\n", 
+                                s->dma_adc.fragShift);
+		len += sprintf (buf + len, "dma_adc.numFrag = %x\n", 
+                                s->dma_adc.numFrag);
+		len += sprintf (buf + len, "dma_adc.fragTotalSize = %x\n", 
+                                s->dma_adc.fragTotalSize);
+		len += sprintf (buf + len, "dma_adc.nextIn = %x\n", 
+                                s->dma_adc.nextIn);
+		len += sprintf (buf + len, "dma_adc.nextOut = %x\n", 
+                                s->dma_adc.nextOut);
+		len += sprintf (buf + len, "dma_adc.count = %x\n", 
+                                s->dma_adc.count);
+	}
+	 
+	/* print out CODEC state */
+	len += sprintf (buf + len, "\nAC97 CODEC registers\n");
+	len += sprintf (buf + len, "----------------------\n");
+	for (cnt=0; cnt <= 0x7e; cnt = cnt +2)
+		len+= sprintf (buf + len, "reg %02x = %04x\n",
+			       cnt, rdcodec(&s->codec, cnt));
+
+	if (fpos >=len){
+		*start = buf;
+		*eof =1;
+		return 0;
+	}
+	*start = buf + fpos;
+	if ((len -= fpos) > length)
+		return length;
+	*eof =1;
+	return len;
+
+}
+#endif /* CONFIG_LL_DEBUG */
+
+/* --------------------------------------------------------------------- */
+
+/* maximum number of devices; only used for command line params */
+#define NR_DEVICE 5
+
+static unsigned int devindex = 0;
+
+MODULE_AUTHOR("Monta Vista Software, jsun@mvista.com or jsun@junsun.net");
+MODULE_DESCRIPTION("NEC Vrc5477 audio (AC97) Driver");
+
+/* --------------------------------------------------------------------- */
+extern void jsun_scan_pci_bus(void);
+extern void vrc5477_show_pci_regs(void);
+extern void vrc5477_show_pdar_regs(void);
+
+/* -------------------------------------------------------- */
+#define         AC97_BASE               0xbb000000
+#define         myinl(x)                  *(volatile u32*)(AC97_BASE + (x))
+#define         myoutl(x,y)               *(volatile u32*)(AC97_BASE + (y)) = (x)
+
+u16 myrdcodec(u8 addr)
+{
+        u32 result;
+
+        /* wait until we can access codec registers */
+        // while (inl(VRC5477_CODEC_WR) & 0x80000000);
+
+        /* write the address and "read" command to codec */
+        addr = addr & 0x7f;
+        myoutl((addr << 16) | VRC5477_CODEC_WR_RWC, VRC5477_CODEC_WR);
+
+        /* get the return result */
+        udelay(100); /* workaround hardware bug */
+        // dump_memory(0xbb000000, 48);
+        while ( ((result=myinl(VRC5477_CODEC_RD)) & 0xc0000000) != 0xc0000000);
+        MIPS_ASSERT(addr == ((result >> 16) & 0x7f) );
+        return result & 0xffff;
+}
+
+void mywrcodec(u8 addr, u16 data)
+{
+        /* wait until we can access codec registers */
+        while (myinl(VRC5477_CODEC_WR) & 0x80000000);
+
+        /* write the address and value to codec */
+        myoutl((addr << 16) | data, VRC5477_CODEC_WR);
+
+}
+
+
+void jsun_ac97_test(struct vrc5477_ac97_state *s)
+{
+        int i;
+
+        /* reset codec */
+	/*
+        wrcodec(&s->codec, 0, 0);
+        while (inl(s->io + VRC5477_CODEC_WR) & 0x80000000);
+	*/
+        mywrcodec(0, 0);
+        while (myinl(VRC5477_CODEC_WR) & 0x80000000);
+
+	for (i=0; i< 0x40; i+=4) {	
+	MIPS_ASSERT(inl(s->io+i) == myinl(i));
+	}
+
+        printk("codec registers : ");
+        for (i=0; i<= 0x3a; i+=2) {
+                if ( (i%0x10) == 0) {
+                        printk("\n%02x\t", i);
+                }
+                // printk("%04x\t", rdcodec(&s->codec, i));
+                printk("%04x\t", myrdcodec(i));
+        }
+        printk("\n\n");
+        printk("codec registers : ");
+        for (i=0; i<= 0x3a; i+=2) {
+                if ( (i%0x10) == 0) {
+                        printk("\n%02x\t", i);
+                }
+                printk("%04x\t", rdcodec(&s->codec, i));
+        }
+        printk("\n\n");
+}
+
+static int __devinit vrc5477_ac97_probe(struct pci_dev *pcidev,
+					const struct pci_device_id *pciid)
+{
+	struct vrc5477_ac97_state *s;
+	char proc_str[80];
+
+	MIPS_DEBUG(printk("vrc5477_ac97_probe() invoked\n"));
+
+	if (pcidev->irq == 0) 
+		return -1;
+
+	if (!(s = kmalloc(sizeof(struct vrc5477_ac97_state), GFP_KERNEL))) {
+		printk(KERN_ERR PFX "alloc of device struct failed\n");
+		return -1;
+	}
+	memset(s, 0, sizeof(struct vrc5477_ac97_state));
+
+	init_waitqueue_head(&s->dma_adc.wait);
+	init_waitqueue_head(&s->dma_dac.wait);
+	init_waitqueue_head(&s->open_wait);
+	init_MUTEX(&s->open_sem);
+	spin_lock_init(&s->lock);
+
+	s->dev = pcidev;
+	s->io = pci_resource_start(pcidev, 0);
+	s->irq = pcidev->irq;
+
+	s->codec.private_data = s;
+	s->codec.id = 0;
+	s->codec.codec_read = rdcodec;
+	s->codec.codec_write = wrcodec;
+	s->codec.codec_wait = waitcodec;
+
+	/* setting some other default values such as
+	 * adcChannels, adcRate is done in open() so that
+         * no persistent state across file opens.
+	 */
+
+	if (!request_region(s->io, pci_resource_len(pcidev,0),
+			    VRC5477_AC97_MODULE_NAME)) {
+		printk(KERN_ERR PFX "io ports %#lx->%#lx in use\n",
+		       s->io, s->io + pci_resource_len(pcidev,0)-1);
+		goto err_region;
+	}
+	if (request_irq(s->irq, vrc5477_ac97_interrupt, SA_INTERRUPT,
+			VRC5477_AC97_MODULE_NAME, s)) {
+		printk(KERN_ERR PFX "irq %u in use\n", s->irq);
+		goto err_irq;
+	}
+
+	printk(KERN_INFO PFX "IO at %#lx, IRQ %d\n", s->io, s->irq);
+
+	/* register devices */
+	if ((s->dev_audio = register_sound_dsp(&vrc5477_ac97_audio_fops, -1)) < 0)
+		goto err_dev1;
+	if ((s->codec.dev_mixer =
+	     register_sound_mixer(&vrc5477_ac97_mixer_fops, -1)) < 0)
+		goto err_dev2;
+
+#ifdef CONFIG_LL_DEBUG
+	/* intialize the debug proc device */
+	s->ps = create_proc_read_entry(VRC5477_AC97_MODULE_NAME, 0, NULL,
+				       proc_vrc5477_ac97_dump, NULL);
+#endif /* CONFIG_LL_DEBUG */
+	
+	/* enable pci io and bus mastering */
+	if (pci_enable_device(pcidev))
+		goto err_dev3;
+	pci_set_master(pcidev);
+
+/*
+jsun_scan_pci_bus();
+vrc5477_show_pci_regs();
+vrc5477_show_pdar_regs();
+*/
+
+	/* cold reset the AC97 */
+	outl(VRC5477_ACLINK_CTRL_RST_ON | VRC5477_ACLINK_CTRL_RST_TIME,
+	     s->io + VRC5477_ACLINK_CTRL);
+	while (inl(s->io + VRC5477_ACLINK_CTRL) & VRC5477_ACLINK_CTRL_RST_ON);
+
+/*
+jsun_ac97_test(s);
+*/
+
+	/* codec init */
+	if (!ac97_probe_codec(&s->codec))
+		goto err_dev3;
+
+#ifdef CONFIG_LL_DEBUG
+	sprintf(proc_str, "driver/%s/%d/ac97", 
+		VRC5477_AC97_MODULE_NAME, s->codec.id);
+	s->ac97_ps = create_proc_read_entry (proc_str, 0, NULL,
+					     ac97_read_proc, &s->codec);
+	/* TODO : why this proc file does not show up? */
+#endif
+
+        /* let us get the default volumne louder */
+        wrcodec(&s->codec, 0x2, 0);
+        wrcodec(&s->codec, 0x18, 0x0707);
+	/* mute line in loopback to line out */
+	wrcodec(&s->codec, 0x10, 0x8000);
+
+	/* by default we select line in the input */
+	wrcodec(&s->codec, 0x1a, 0x0404);
+	/* pick middle value for record gain */
+	// wrcodec(&s->codec, 0x1c, 0x0707);
+	wrcodec(&s->codec, 0x1c, 0x0f0f);
+	wrcodec(&s->codec, 0x1e, 0x07);
+
+	/* enable the master interrupt but disable all others */
+	outl(VRC5477_INT_MASK_NMASK, s->io + VRC5477_INT_MASK);
+
+	/* store it in the driver field */
+	pci_set_drvdata(pcidev, s);
+	pcidev->dma_mask = 0xffffffff;
+	/* put it into driver list */
+	list_add_tail(&s->devs, &devs);
+	/* increment devindex */
+	if (devindex < NR_DEVICE-1)
+		devindex++;
+	return 0;
+
+ err_dev3:
+	unregister_sound_mixer(s->codec.dev_mixer);
+ err_dev2:
+	unregister_sound_dsp(s->dev_audio);
+ err_dev1:
+	printk(KERN_ERR PFX "cannot register misc device\n");
+	free_irq(s->irq, s);
+ err_irq:
+	release_region(s->io, pci_resource_len(pcidev,0));
+ err_region:
+	kfree(s);
+	return -1;
+}
+
+static void __devinit vrc5477_ac97_remove(struct pci_dev *dev)
+{
+	struct vrc5477_ac97_state *s = pci_get_drvdata(dev);
+
+	if (!s)
+		return;
+	list_del(&s->devs);
+#ifdef CONFIG_LL_DEBUG
+	if (s->ps)
+		remove_proc_entry(VRC5477_AC97_MODULE_NAME, NULL);
+#endif /* CONFIG_LL_DEBUG */
+	synchronize_irq();
+	free_irq(s->irq, s);
+	release_region(s->io, pci_resource_len(dev,0));
+	unregister_sound_dsp(s->dev_audio);
+	unregister_sound_mixer(s->codec.dev_mixer);
+	kfree(s);
+	pci_set_drvdata(dev, NULL);
+}
+
+
+#define		PCI_VENDOR_ID_NEC		0x1033
+#define		PCI_DEVICE_ID_NEC_VRC5477_AC97	0x00A6
+static struct pci_device_id id_table[] __devinitdata = {
+    { PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_VRC5477_AC97, 
+      PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
+    { 0, }
+};
+
+MODULE_DEVICE_TABLE(pci, id_table);
+
+static struct pci_driver vrc5477_ac97_driver = {
+	name: VRC5477_AC97_MODULE_NAME,
+	id_table: id_table,
+	probe: vrc5477_ac97_probe,
+	remove: vrc5477_ac97_remove
+};
+
+static int __init init_vrc5477_ac97(void)
+{
+	if (!pci_present())   /* No PCI bus in this machine! */
+		return -ENODEV;
+	printk("Vrc5477 AC97 driver: version v0.1 time " __TIME__ " " __DATE__ " by Jun Sun\n");
+	return pci_module_init(&vrc5477_ac97_driver);
+}
+
+static void __exit cleanup_vrc5477_ac97(void)
+{
+	printk(KERN_INFO PFX "unloading\n");
+	pci_unregister_driver(&vrc5477_ac97_driver);
+}
+
+module_init(init_vrc5477_ac97);
+module_exit(cleanup_vrc5477_ac97);
+
diff -u --recursive --new-file v2.4.9/linux/drivers/sound/opl3sa2.c linux/drivers/sound/opl3sa2.c
--- v2.4.9/linux/drivers/sound/opl3sa2.c	Fri Mar  2 18:38:39 2001
+++ linux/drivers/sound/opl3sa2.c	Sun Sep  9 10:52:35 2001
@@ -810,7 +810,7 @@
 struct isapnp_device_id isapnp_opl3sa2_list[] __initdata = {
 	{	ISAPNP_ANY_ID, ISAPNP_ANY_ID,
 		ISAPNP_VENDOR('Y','M','H'), ISAPNP_FUNCTION(0x0021),
-		NULL },
+		0 },
 	{0}
 };
 
diff -u --recursive --new-file v2.4.9/linux/drivers/sound/sonicvibes.c linux/drivers/sound/sonicvibes.c
--- v2.4.9/linux/drivers/sound/sonicvibes.c	Mon Aug 27 12:41:45 2001
+++ linux/drivers/sound/sonicvibes.c	Fri Sep  7 09:28:37 2001
@@ -2496,7 +2496,7 @@
 
 static int __devinit sv_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
 {
-	static const char __initdata sv_ddma_name[] = "S3 Inc. SonicVibes DDMA Controller";
+	static char __initdata sv_ddma_name[] = "S3 Inc. SonicVibes DDMA Controller";
        	struct sv_state *s;
 	mm_segment_t fs;
 	int i, val, ret;
diff -u --recursive --new-file v2.4.9/linux/drivers/sound/sound_core.c linux/drivers/sound/sound_core.c
--- v2.4.9/linux/drivers/sound/sound_core.c	Fri Apr  6 10:51:19 2001
+++ linux/drivers/sound/sound_core.c	Sun Sep  9 10:52:35 2001
@@ -145,7 +145,7 @@
  *	This lock guards the sound loader list.
  */
 
-spinlock_t sound_loader_lock = SPIN_LOCK_UNLOCKED;
+static spinlock_t sound_loader_lock = SPIN_LOCK_UNLOCKED;
 
 /*
  *	Allocate the controlling structure and add it to the sound driver
diff -u --recursive --new-file v2.4.9/linux/drivers/sound/trident.c linux/drivers/sound/trident.c
--- v2.4.9/linux/drivers/sound/trident.c	Mon Aug 27 12:41:45 2001
+++ linux/drivers/sound/trident.c	Fri Sep  7 09:28:37 2001
@@ -1,6 +1,10 @@
 /*
+ *	OSS driver for Linux 2.4.x for
  *
- *	Trident 4D-Wave/SiS 7018/ALi 5451 OSS driver for Linux 2.2.x
+ *	Trident 4D-Wave
+ *	SiS 7018
+ *	ALi 5451
+ *	Tvia/IGST CyberPro 5050
  *
  *	Driver: Alan Cox <alan@redhat.com>
  *
@@ -14,6 +18,7 @@
  *	Ollie Lho <ollie@sis.com.tw> SiS 7018 Audio Core Support
  *	Ching-Ling Lee <cling-li@ali.com.tw> ALi 5451 Audio Core Support 
  *	Matt Wu <mattwu@acersoftech.com.cn> ALi 5451 Audio Core Support
+ *	Peter Wächtler <pwaechtler@loewe-komp.de> CyberPro5050 support
  *
  *
  *	This program is free software; you can redistribute it and/or modify
@@ -31,6 +36,10 @@
  *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  *  History
+ *  v0.14.9c
+ *	August 10 2001 Peter Wächtler <pwaechtler@loewe-komp.de>
+ *	added support for Tvia (formerly Integraphics/IGST) CyberPro5050
+ *	this chip is often found in settop boxes (combined video+audio)
  *  v0.14.9b
  *	Switch to static inline not extern inline (gcc 3)
  *  v0.14.9a
@@ -61,7 +70,7 @@
  *	Implement multi-channels and S/PDIF in support for ALi 1535+
  *  v0.14.6 
  *	Nov 1 2000 Ching-Ling Lee
- *	Fix the bug of memory leak when swithing 5.1-channels to 2 channels.
+ *	Fix the bug of memory leak when switching 5.1-channels to 2 channels.
  *	Add lock protection into dynamic changing format of data.
  *	Oct 18 2000 Ching-Ling Lee
  *	5.1-channels support for ALi
@@ -167,7 +176,7 @@
 
 #include <linux/pm.h>
 
-#define DRIVER_VERSION "0.14.9b"
+#define DRIVER_VERSION "0.14.9c"
 
 /* magic numbers to protect our data structures */
 #define TRIDENT_CARD_MAGIC	0x5072696E /* "Prin" */
@@ -195,14 +204,16 @@
 	TRIDENT_4D_DX = 0,
 	TRIDENT_4D_NX,
 	SIS_7018,
-	ALI_5451
+	ALI_5451,
+	CYBER5050
 };
 
 static char * card_names[] = {
 	"Trident 4DWave DX",
 	"Trident 4DWave NX",
 	"SiS 7018 PCI Audio",
-	"ALi Audio Accelerator"
+	"ALi Audio Accelerator",
+	"Tvia/IGST CyberPro 5050"
 };
 
 static struct pci_device_id trident_pci_tbl [] __devinitdata = {
@@ -214,6 +225,8 @@
 	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_7018},
 	{PCI_VENDOR_ID_ALI, PCI_DEVICE_ID_ALI_5451,
 	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, ALI_5451},
+	{ PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_5050, 
+	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, CYBER5050},
 	{0,}
 };
 
@@ -456,6 +469,7 @@
 	case PCI_DEVICE_ID_ALI_5451:
 	case PCI_DEVICE_ID_TRIDENT_4DWAVE_DX:
 	case PCI_DEVICE_ID_TRIDENT_4DWAVE_NX:
+	case PCI_DEVICE_ID_INTERG_5050:
 		global_control |= (ENDLP_IE | MIDLP_IE);
 		break;
 	default:
@@ -466,7 +480,7 @@
 
 #ifdef DEBUG
 	printk("trident: Enable Loop Interrupts, globctl = 0x%08X\n",
-	       global_control);
+			inl(TRID_REG(card, T4D_LFO_GC_CIR)));
 #endif
 	return (TRUE);
 }
@@ -497,9 +511,9 @@
 	outl(reg, TRID_REG(card, addr));
 
 #ifdef DEBUG
-	reg = inl(TRID_REG(card, T4D_AINTEN_B));
-	printk("trident: enabled IRQ on channel %d, AINTEN_B = 0x%08x\n",
-	       channel, reg);
+	reg = inl(TRID_REG(card, addr));
+	printk("trident: enabled IRQ on channel %d, %s = 0x%08x(addr:%X)\n",
+		channel, addr==T4D_AINTEN_B? "AINTEN_B":"AINTEN_A",reg,addr);
 #endif
 }
 
@@ -517,9 +531,9 @@
 	outl(mask, TRID_REG(card, bank->addresses->aint));
 
 #ifdef DEBUG
-	reg = inl(TRID_REG(card, T4D_AINTEN_B));
-	printk("trident: disabled IRQ on channel %d, AINTEN_B = 0x%08x\n",
-	       channel, reg);
+	reg = inl(TRID_REG(card, addr));
+	printk("trident: disabled IRQ on channel %d, %s = 0x%08x(addr:%X)\n",
+		channel, addr==T4D_AINTEN_B? "AINTEN_B":"AINTEN_A",reg,addr);
 #endif
 }
 
@@ -536,9 +550,9 @@
 	outl(mask, TRID_REG(card, addr));
 
 #ifdef DEBUG
-	reg = inl(TRID_REG(card, T4D_START_B));
-	printk("trident: start voice on channel %d, START_B  = 0x%08x\n",
-	       channel, reg);
+	reg = inl(TRID_REG(card, addr));
+	printk("trident: start voice on channel %d, %s = 0x%08x(addr:%X)\n",
+		channel, addr==T4D_START_B? "START_B":"START_A",reg,addr);
 #endif
 }
 
@@ -555,9 +569,9 @@
 	outl(mask, TRID_REG(card, addr));
 
 #ifdef DEBUG
-	reg = inl(TRID_REG(card, T4D_STOP_B));
-	printk("trident: stop voice on channel %d,  STOP_B  = 0x%08x\n",
-	       channel, reg);
+	reg = inl(TRID_REG(card, addr));
+	printk("trident: stop voice on channel %d, %s = 0x%08x(addr:%X)\n",
+		channel, addr==T4D_STOP_B? "STOP_B":"STOP_A",reg,addr);
 #endif
 }
 
@@ -575,8 +589,8 @@
 
 #ifdef DEBUG
 	if (reg & mask)
-		printk("trident: channel %d has interrupt, AINT_B = 0x%08x\n",
-		       channel, reg);
+		printk("trident: channel %d has interrupt, %s = 0x%08x\n",
+			channel,reg==T4D_AINT_B? "AINT_B":"AINT_A", reg);
 #endif
 	return (reg & mask) ? TRUE : FALSE;
 }
@@ -614,7 +628,7 @@
 		}
 	}
 
-	/* no more free channels avaliable */
+	/* no more free channels available */
 	printk(KERN_ERR "trident: no more channels available on Bank B.\n");
 	return NULL;
 }
@@ -632,7 +646,94 @@
 	card->banks[bank].bitmap &= ~(1 << (channel));
 }
 
-/* called with spin lock held */
+static struct trident_channel * cyber_alloc_pcm_channel(struct trident_card *card)
+{
+	struct trident_pcm_bank *bank;
+	int idx;
+
+	/* The cyberpro 5050 has only 32 voices and one bank */
+	/* .. at least they are not documented (if you want to call that 
+	 * crap documentation), perhaps broken ? */
+
+	bank = &card->banks[BANK_A];
+
+	for (idx = 31; idx >= 0; idx--) {
+		if (!(bank->bitmap & (1 << idx))) {
+			struct trident_channel *channel = &bank->channels[idx];
+			bank->bitmap |= 1 << idx;
+			channel->num = idx;
+			return channel;
+		}
+	}
+
+	/* no more free channels available */
+	printk(KERN_ERR "cyberpro5050: no more channels available on Bank A.\n");
+	return NULL;
+}
+
+static void cyber_free_pcm_channel(struct trident_card *card, unsigned int channel)
+{
+	if (channel > 31)
+		return;
+	card->banks[BANK_A].bitmap &= ~(1 << (channel));
+}
+
+static inline void cyber_outidx(int port,int idx,int data)
+{
+	outb(idx,port);
+	outb(data,port+1);
+}
+
+static inline int cyber_inidx(int port,int idx)
+{
+	outb(idx,port);
+	return inb(port+1);
+}
+
+static int cyber_init_ritual(struct trident_card *card)
+{
+	/* some black magic, taken from SDK samples */
+	/* remove this and nothing will work */
+	int portDat;
+	int ret = 0;
+	unsigned long flags;
+
+	/*
+ 	 *	Keep interrupts off for the configure - we don't want to
+ 	 *	clash with another cyberpro config event
+ 	 */
+ 
+	save_flags(flags);
+	cli();
+	portDat = cyber_inidx(CYBER_PORT_AUDIO, CYBER_IDX_AUDIO_ENABLE);
+	/* enable, if it was disabled */
+	if( (portDat & CYBER_BMSK_AUENZ) != CYBER_BMSK_AUENZ_ENABLE ) {
+		printk(KERN_INFO "cyberpro5050: enabling audio controller\n" );
+		cyber_outidx( CYBER_PORT_AUDIO, CYBER_IDX_AUDIO_ENABLE,
+			portDat | CYBER_BMSK_AUENZ_ENABLE );
+		/* check again if hardware is enabled now */
+		portDat = cyber_inidx(CYBER_PORT_AUDIO, CYBER_IDX_AUDIO_ENABLE);
+	}
+	if( (portDat & CYBER_BMSK_AUENZ) != CYBER_BMSK_AUENZ_ENABLE )
+	{
+		printk(KERN_ERR "cyberpro5050: initAudioAccess: no success\n" );
+		ret = -1;
+	}
+	else
+	{
+		cyber_outidx( CYBER_PORT_AUDIO, CYBER_IDX_IRQ_ENABLE, CYBER_BMSK_AUDIO_INT_ENABLE );
+		cyber_outidx( CYBER_PORT_AUDIO, 0xbf, 0x01 );
+		cyber_outidx( CYBER_PORT_AUDIO, 0xba, 0x20 );
+		cyber_outidx( CYBER_PORT_AUDIO, 0xbb, 0x08 );
+		cyber_outidx( CYBER_PORT_AUDIO, 0xbf, 0x02 );
+		cyber_outidx( CYBER_PORT_AUDIO, 0xb3, 0x06 );
+		cyber_outidx( CYBER_PORT_AUDIO, 0xbf, 0x00 );
+	}
+	restore_flags(flags);
+	return ret;
+}
+
+/*  called with spin lock held */
 
 static int trident_load_channel_registers(struct trident_card *card, u32 *data, unsigned int channel)
 {
@@ -651,7 +752,8 @@
 			continue;
 		outl(data[i], TRID_REG(card, CHANNEL_START + 4*i));
 	}
-	if (card->pci_id == PCI_DEVICE_ID_ALI_5451) {
+	if (card->pci_id == PCI_DEVICE_ID_ALI_5451 ||
+		card->pci_id == PCI_DEVICE_ID_INTERG_5050) {
 		outl(ALI_EMOD_Still, TRID_REG(card, ALI_EBUF1));
 		outl(ALI_EMOD_Still, TRID_REG(card, ALI_EBUF2));
 	}
@@ -677,6 +779,7 @@
 		data[3] = 0;
 		break;	
 	case PCI_DEVICE_ID_SI_7018:
+	case PCI_DEVICE_ID_INTERG_5050:
 		data[0] = 0; /* Current Sample Offset */
 		data[2] = (channel->eso << 16) | (channel->delta & 0xffff);
 		data[3] = (channel->attribute << 16) | (channel->fm_vol & 0xffff);
@@ -814,7 +917,7 @@
 		channel->control |= CHANNEL_STEREO;
 #ifdef DEBUG
 	printk("trident: trident_play_setup, LBA = 0x%08x, "
-	       "Delat = 0x%08x, ESO = 0x%08x, Control = 0x%08x\n",
+	       "Delta = 0x%08x, ESO = 0x%08x, Control = 0x%08x\n",
 	       channel->lba, channel->delta, channel->eso, channel->control);
 #endif
 	trident_write_voice_regs(state);
@@ -852,6 +955,9 @@
 		/* enable and set record channel */
 		outb(0x80 | channel->num, TRID_REG(card, T4D_REC_CH));
 		break;
+	case PCI_DEVICE_ID_INTERG_5050:
+		/* don't know yet, using special channel 22 in GC1(0xd4)? */
+		break;
 	default:
 		return;
 	}
@@ -920,6 +1026,7 @@
 	case PCI_DEVICE_ID_ALI_5451:
 	case PCI_DEVICE_ID_SI_7018:
 	case PCI_DEVICE_ID_TRIDENT_4DWAVE_DX:
+	case PCI_DEVICE_ID_INTERG_5050:
 		/* 16 bits ESO, CSO for 7018 and DX */
 		cso = inw(TRID_REG(state->card, CH_DX_CSO_ALPHA_FMS + 2));
 		break;
@@ -1271,7 +1378,8 @@
 
 		/* No matter how much data is left in the buffer, we have to wait until
 		   CSO == ESO/2 or CSO == ESO when address engine interrupts */
-	 	if (state->card->pci_id == PCI_DEVICE_ID_ALI_5451)
+	 	if (state->card->pci_id == PCI_DEVICE_ID_ALI_5451 ||
+		    state->card->pci_id == PCI_DEVICE_ID_INTERG_5050)
 		{	
 			diff = dmabuf->swptr - trident_get_dma_addr(state) + dmabuf->dmasize ;
 			diff = diff % (dmabuf->dmasize);
@@ -1528,6 +1636,38 @@
 	ali_set_timer(card);
 }
 
+static void cyber_address_interrupt(struct trident_card *card)
+{
+	int i,irq_status;
+	struct trident_state *state;
+
+	/* Update the pointers for all channels we are running. */
+	/* FIXED: read interrupt status only once */
+	irq_status=inl(TRID_REG(card, T4D_AINT_A) );
+#ifdef DEBUG	
+	printk("cyber_address_interrupt: irq_status 0x%X\n",irq_status);
+#endif
+	for (i = 0; i < NR_HW_CH; i++) {
+		if (irq_status & ( 1 << (31 - i)) ) {
+
+			/* clear bit by writing a 1, zeroes are ignored */ 		
+			outl( (1 <<(31-i)), TRID_REG(card, T4D_AINT_A));
+		
+#ifdef DEBUG	
+	printk("cyber_interrupt: channel %d\n", 31-i);
+#endif
+			if ((state = card->states[i]) != NULL) {
+				trident_update_ptr(state);
+			} else {
+				printk("cyber5050: spurious channel irq %d.\n",
+				       31 - i);
+				trident_stop_voice(card, 31 - i);
+				trident_disable_voice_irq(card, 31 - i);
+			}
+		}
+	}
+}
+
 static void trident_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct trident_card *card = (struct trident_card *)dev_id;
@@ -2537,6 +2677,11 @@
 		drain_dac(state, file->f_flags & O_NONBLOCK);
 	}
 
+#ifdef DEBUG
+	printk(KERN_ERR "trident: closing virtual channel %d, hard channel %d\n", 
+		state->virt, dmabuf->channel->num);
+#endif
+
 	/* stop DMA state machine and free DMA buffers/channels */
 	down(&card->open_sem);
 
@@ -2626,6 +2771,12 @@
 			mask |= NX_AC97_WRITE_SECONDARY;
 		busy = NX_AC97_BUSY_WRITE;
 		break;
+	case PCI_DEVICE_ID_INTERG_5050:
+		address = SI_AC97_WRITE;
+		mask = busy = SI_AC97_BUSY_WRITE;
+		if (codec->id)
+			mask |= SI_AC97_SECONDARY;
+		break;
 	}
 
 	spin_lock_irqsave(&card->lock, flags);
@@ -2678,6 +2829,12 @@
 		mask = NX_AC97_BUSY_READ;
 		busy = NX_AC97_BUSY_READ | NX_AC97_BUSY_DATA;
 		break;
+	case PCI_DEVICE_ID_INTERG_5050:
+		address = SI_AC97_READ;
+		mask = busy = SI_AC97_BUSY_READ;
+		if (codec->id)
+			mask |= SI_AC97_SECONDARY;
+		break;
 	}
 
 	data = (mask | (reg & AC97_REG_ADDR));
@@ -3707,6 +3864,18 @@
 		ready_2nd = inl(TRID_REG(card, NX_ACR0_AC97_COM_STAT));
 		ready_2nd &= NX_AC97_SECONDARY_READY;
 		break;
+	case PCI_DEVICE_ID_INTERG_5050:
+		/* disable AC97 GPIO interrupt */
+		outl(0x00, TRID_REG(card, SI_AC97_GPIO));
+		/* when power up, the AC link is in cold reset mode, so stop it */
+		outl(PCMOUT|SURROUT|CENTEROUT|LFEOUT,
+		     TRID_REG(card, SI_SERIAL_INTF_CTRL));
+		/* it take a long time to recover from a cold reset (especially when you have
+		   more than one codec) */
+		udelay(2000);
+		ready_2nd = inl(TRID_REG(card, SI_SERIAL_INTF_CTRL));
+		ready_2nd &= SI_AC97_SECONDARY_READY;
+		break;
 	}
 
 	for (num_ac97 = 0; num_ac97 < NR_AC97; num_ac97++) {
@@ -3769,7 +3938,7 @@
 	struct pci_dev *pci_dev_m1533 = NULL;
 
 	if (pci_enable_device(pci_dev))
-	    return -ENODEV;
+		return -ENODEV;
 
 	if (pci_set_dma_mask(pci_dev, TRIDENT_DMA_MASK)) {
 		printk(KERN_ERR "trident: architecture does not support"
@@ -3778,7 +3947,11 @@
 	}
 	pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &revision);
 
-	iobase = pci_resource_start(pci_dev, 0);
+	if (pci_id->device == PCI_DEVICE_ID_INTERG_5050)
+		iobase = pci_resource_start(pci_dev, 1);
+	else
+		iobase = pci_resource_start(pci_dev, 0);
+
 	if (check_region(iobase, 256)) {
 		printk(KERN_ERR "trident: can't allocate I/O space at 0x%4.4lx\n",
 		       iobase);
@@ -3855,7 +4028,16 @@
 			pci_write_config_byte(pci_dev_m1533, 0x7b, bits);
 		}
 	}
-	else {
+	else if(card->pci_id == PCI_DEVICE_ID_INTERG_5050)
+	{
+		card->alloc_pcm_channel = cyber_alloc_pcm_channel;
+		card->alloc_rec_pcm_channel = cyber_alloc_pcm_channel;
+		card->free_pcm_channel = cyber_free_pcm_channel;
+		card->address_interrupt = cyber_address_interrupt;
+		cyber_init_ritual(card);
+	}
+	else
+	{
 		card->alloc_pcm_channel = trident_alloc_pcm_channel;
 		card->alloc_rec_pcm_channel = trident_alloc_pcm_channel;
 		card->free_pcm_channel = trident_free_pcm_channel;
@@ -3982,7 +4164,7 @@
 }
 
 MODULE_AUTHOR("Alan Cox, Aaron Holtzman, Ollie Lho, Ching Ling Lee");
-MODULE_DESCRIPTION("Trident 4DWave/SiS 7018/ALi 5451 PCI Audio Driver");
+MODULE_DESCRIPTION("Trident 4DWave/SiS 7018/ALi 5451 and Tvia/IGST CyberPro5050 PCI Audio Driver");
 
 #define TRIDENT_MODULE_NAME "trident"
 
@@ -4000,7 +4182,7 @@
 	if (!pci_present())   /* No PCI bus in this machine! */
 		return -ENODEV;
 
-	printk(KERN_INFO "Trident 4DWave/SiS 7018/ALi 5451 PCI Audio, version "
+	printk(KERN_INFO "Trident 4DWave/SiS 7018/ALi 5451,Tvia CyberPro 5050 PCI Audio, version "
 	       DRIVER_VERSION ", " __TIME__ " " __DATE__ "\n");
 
 	if (!pci_register_driver(&trident_pci_driver)) {
diff -u --recursive --new-file v2.4.9/linux/drivers/sound/trident.h linux/drivers/sound/trident.h
--- v2.4.9/linux/drivers/sound/trident.h	Mon Aug 27 12:41:45 2001
+++ linux/drivers/sound/trident.h	Fri Sep  7 09:28:37 2001
@@ -315,12 +315,19 @@
 
 #define TRID_REG( trident, x ) ( (trident) -> iobase + (x) )
 
+#define		CYBER_PORT_AUDIO		0x3CE
+#define		CYBER_IDX_AUDIO_ENABLE          0x7B
+#define		CYBER_BMSK_AUDIO_INT_ENABLE	0x09
+#define		CYBER_BMSK_AUENZ		0x01
+#define		CYBER_BMSK_AUENZ_ENABLE		0x00
+#define		CYBER_IDX_IRQ_ENABLE		0x12
+      
 #define VALIDATE_MAGIC(FOO,MAG)				\
-({						  \
-	if (!(FOO) || (FOO)->magic != MAG) { \
-		printk(invalid_magic,__FUNCTION__);	       \
-		return -ENXIO;			  \
-	}					  \
+({						  	\
+	if (!(FOO) || (FOO)->magic != MAG) { 		\
+		printk(invalid_magic,__FUNCTION__);	\
+		return -ENXIO;			  	\
+	}					  	\
 })
 
 #define VALIDATE_STATE(a) VALIDATE_MAGIC(a,TRIDENT_STATE_MAGIC)
diff -u --recursive --new-file v2.4.9/linux/drivers/sound/via82cxxx_audio.c linux/drivers/sound/via82cxxx_audio.c
--- v2.4.9/linux/drivers/sound/via82cxxx_audio.c	Mon Aug 27 12:41:45 2001
+++ linux/drivers/sound/via82cxxx_audio.c	Sun Sep  9 10:52:35 2001
@@ -90,10 +90,6 @@
 
 #define VIA_MIN_FRAG_NUMBER		2	
 
-#ifndef AC97_PCM_LR_ADC_RATE
-#  define AC97_PCM_LR_ADC_RATE AC97_PCM_LR_DAC_RATE
-#endif
-
 /* 82C686 function 5 (audio codec) PCI configuration registers */
 #define VIA_ACLINK_CTRL		0x41
 #define VIA_FUNC_ENABLE		0x42
@@ -862,6 +858,7 @@
 
 /**
  *	via_chan_clear - Stop DMA channel operation, and reset pointers
+ *	@card: the chip to accessed
  *	@chan: Channel to be cleared
  *
  *	Call via_chan_stop to halt DMA operations, and then resets
diff -u --recursive --new-file v2.4.9/linux/drivers/tc/lk201-map.map linux/drivers/tc/lk201-map.map
--- v2.4.9/linux/drivers/tc/lk201-map.map	Wed Dec 31 16:00:00 1969
+++ linux/drivers/tc/lk201-map.map	Mon Aug 27 08:56:31 2001
@@ -0,0 +1,356 @@
+# Default kernel keymap. This uses 7 modifier combinations.
+keymaps 0-2,4-5,8,12
+# Change the above line into
+#	keymaps 0-2,4-6,8,12
+# in case you want the entries
+#	altgr   control keycode  83 = Boot            
+#	altgr   control keycode 111 = Boot            
+# below.
+#
+# In fact AltGr is used very little, and one more keymap can
+# be saved by mapping AltGr to Alt (and adapting a few entries):
+# keycode 100 = Alt
+#
+keycode   0x15 = grave		tilde
+	alt     keycode   0x15 = Escape
+	control keycode   0x15 = Meta_Escape
+keycode   0x16 = one              exclam
+	alt     keycode   0x16 = Meta_one
+keycode   0x17 = two              at               at
+	control	keycode   0x17 = nul
+	shift	control	keycode   0x17 = nul
+	alt	keycode   0x17 = Meta_two
+keycode   0x18 = three            numbersign
+	control keycode   0x18 = Escape
+	alt     keycode   0x18 = Meta_three
+keycode   0x19 = four             dollar           dollar
+	control keycode   0x19 = Control_backslash
+	alt     keycode   0x19 = Meta_four
+keycode   0x1a = five             percent
+	control keycode   0x1a = Control_bracketright
+	alt     keycode   0x1a = Meta_five
+keycode   0x1b = six              asciicircum
+	control keycode   0x1b = Control_asciicircum
+	alt     keycode   0x1b = Meta_six
+keycode   0x1c = seven            ampersand        braceleft
+	control keycode   0x1c = Control_underscore
+	alt     keycode   0x1c = Meta_seven
+keycode   0x1d = eight            asterisk         bracketleft
+	control keycode   0x1d = Delete
+	alt     keycode   0x1d = Meta_eight
+keycode  0x1e = nine             parenleft        bracketright
+	alt     keycode  0x1e = Meta_nine
+keycode  0x1f = zero             parenright       braceright
+	alt     keycode  0x1f = Meta_zero
+keycode  0x20 = minus            underscore       backslash
+	control	keycode  0x20 = Control_underscore
+	shift	control	keycode  0x20 = Control_underscore
+	alt	keycode  0x20 = Meta_minus
+keycode  0x21 = equal            plus
+	alt     keycode  0x21 = Meta_equal
+keycode  0x22 = Delete           Delete
+	control keycode  0x22 = BackSpace
+	alt     keycode  0x22 = Meta_Delete
+keycode  0x2a = Tab              Tab
+	alt     keycode  0x2a = Meta_Tab
+keycode  0x2b = q
+keycode  0x2c = w
+keycode  0x2d = e
+	altgr   keycode  0x2d = Hex_E
+keycode  0x2e = r
+keycode  0x2f = t
+keycode  0x30 = y
+keycode  0x31 = u
+keycode  0x32 = i
+keycode  0x33 = o
+keycode  0x34 = p
+keycode  0x35 = bracketleft      braceleft
+	control keycode  0x35 = Escape
+	alt     keycode  0x35 = Meta_bracketleft
+keycode  0x36 = bracketright     braceright       asciitilde
+	control keycode  0x36 = Control_bracketright
+	alt     keycode  0x36 = Meta_bracketright
+keycode  0x37 = Return
+	alt     keycode  0x37 = Meta_Control_m
+keycode  0x3f = Control
+keycode  0x41 = a
+	altgr   keycode  0x41 = Hex_A
+keycode  0x42 = s
+keycode  0x43 = d
+	altgr   keycode  0x43 = Hex_D
+keycode  0x44 = f
+	altgr   keycode  0x44 = Hex_F
+keycode  0x45 = g
+keycode  0x46 = h
+keycode  0x47 = j
+keycode  0x48 = k
+keycode  0x49 = l
+keycode  0x4a = semicolon        colon
+	alt     keycode  0x4a = Meta_semicolon
+keycode  0x4b = apostrophe       quotedbl
+	control keycode  0x4b = Control_g
+	alt     keycode  0x4b = Meta_apostrophe
+# keycode  41 = grave            asciitilde
+#	control keycode  41 = nul
+#	alt     keycode  41 = Meta_grave
+keycode  0x52 = Shift
+keycode  0x4c = backslash        bar
+	control keycode  0x4c = Control_backslash
+	alt     keycode  0x4c = Meta_backslash
+keycode  0x53 = greater	less
+keycode  0x54 = z
+keycode  0x55 = x
+keycode  0x56 = c
+	altgr   keycode  0x56 = Hex_C
+keycode  0x57 = v
+keycode  0x58 = b
+	altgr   keycode  0x58 = Hex_B
+keycode  0x59 = n
+keycode  0x5a = m
+keycode  0x5b = comma            less
+	alt     keycode  0x5b = Meta_comma
+keycode  0x5c = period           greater
+	control keycode  0x5c = Compose
+	alt     keycode  0x5c = Meta_period
+keycode  0x5d = slash            question
+	control keycode  0x5d = Delete
+	alt     keycode  0x5d = Meta_slash
+
+keycode  0x67 = Alt
+keycode  0x68 = space            space
+	control keycode  0x68 = nul
+	alt     keycode  0x68 = Meta_space
+keycode  0x40 = Caps_Lock
+keycode  0x01 = F1
+	control keycode  0x01 = F1
+	alt     keycode  0x01 = Console_1
+	control alt     keycode  0x01 = Console_1
+keycode  0x02 = F2
+	control keycode  0x02 = F2
+	alt     keycode  0x02 = Console_2
+	control alt     keycode  0x02 = Console_2
+keycode  0x03 = F3
+	control keycode  0x03 = F3
+	alt     keycode  0x03 = Console_3
+	control alt     keycode  0x03 = Console_3
+keycode  0x04 = F4
+	control keycode  0x04 = F4
+	alt     keycode  0x04 = Console_4
+	control alt     keycode  0x04 = Console_4
+keycode  0x05 = F5
+	control keycode  0x05 = F5
+	alt     keycode  0x05 = Console_5
+	control alt     keycode  0x05 = Console_5
+keycode  0x06 = F6
+	control keycode  0x06 = F6
+	alt     keycode  0x06 = Console_6
+	control alt     keycode  0x06 = Console_6
+keycode  0x07 = F7
+	control keycode  0x07 = F7
+	alt     keycode  0x07 = Console_7
+	control alt     keycode  0x07 = Console_7
+keycode  0x08 = F8
+	control keycode  0x08 = F8
+	alt     keycode  0x08 = Console_8
+	control alt     keycode  0x08 = Console_8
+keycode  0x09 = F9
+	control keycode  0x09 = F9
+	alt     keycode  0x09 = Console_9
+	control alt     keycode  0x09 = Console_9
+keycode  0x0a = F10
+	control keycode  0x0a = F10
+	alt     keycode  0x0a = Console_10
+	control alt     keycode  0x0a = Console_10
+keycode  0x0b = F11
+	control keycode  0x0b = F11
+	alt     keycode  0x0b = Console_11
+	control alt     keycode  0x0b = Console_11
+keycode  0x0c = F12
+	control keycode  0x0c = F12
+	alt     keycode  0x0c = Console_12
+	control alt     keycode  0x0c = Console_12
+keycode  0x0d = F13
+	control keycode  0x0d = F13
+	alt     keycode  0x0d = Console_13
+	control alt     keycode  0x0d = Console_13
+keycode  0x0e = F14
+	control keycode  0x0e = F14
+	alt     keycode  0x0e = Console_14
+	control alt     keycode  0x0e = Console_14
+
+keycode  0x11 = F17
+	control keycode  0x11 = F17
+	alt     keycode  0x11 = Console_17
+	control alt     keycode  0x11 = Console_17
+keycode  0x12 = F18
+	control keycode  0x12 = F18
+	alt     keycode  0x12 = Console_18
+	control alt     keycode  0x12 = Console_18
+keycode  0x13 = F19
+	control keycode  0x13 = F19
+	alt     keycode  0x13 = Console_19
+	control alt     keycode  0x13 = Console_19
+keycode  0x14 = F20
+	control keycode  0x14 = F20
+	alt     keycode  0x14 = Console_20
+	control alt     keycode  0x14 = Console_20
+
+
+keycode  0x3b = KP_7
+	alt     keycode  0x3b = Ascii_7
+	altgr   keycode  0x3b = Hex_7
+keycode  0x3c = KP_8
+	alt     keycode  0x3c = Ascii_8
+	altgr   keycode  0x3c = Hex_8
+keycode  0x3d = KP_9
+	alt     keycode  0x3d = Ascii_9
+	altgr   keycode  0x3d = Hex_9
+keycode  0x3e = KP_Subtract
+keycode  0x4e = KP_4
+	alt     keycode  0x4e = Ascii_4
+	altgr   keycode  0x4e = Hex_4
+keycode  0x4f = KP_5
+	alt     keycode  0x4f = Ascii_5
+	altgr   keycode  0x4f = Hex_5
+keycode  0x50 = KP_6
+	alt     keycode  0x50 = Ascii_6
+	altgr   keycode  0x50 = Hex_6
+keycode  0x62 = KP_1
+	alt     keycode  0x62 = Ascii_1
+	altgr   keycode  0x62 = Hex_1
+keycode  0x63 = KP_2
+	alt     keycode  0x63 = Ascii_2
+	altgr   keycode  0x63 = Hex_2
+keycode  0x64 = KP_3
+	alt     keycode  0x64 = Ascii_3
+	altgr   keycode  0x64 = Hex_3
+keycode  0x6b = KP_0
+	alt     keycode  0x6b = Ascii_0
+	altgr   keycode  0x6b = Hex_0
+keycode  0x6c = KP_Period
+#	altgr   control keycode  0x6c = Boot
+	control alt     keycode  0x6c = Boot
+keycode  0x65 = KP_Enter
+
+keycode  0x3f = Control
+
+# keycode 100 = AltGr
+
+keycode 0x23 = Find
+keycode 0x4d = Up
+keycode 0x39 = Prior
+	shift   keycode 0x39 = Scroll_Backward
+keycode 0x5f = Left
+	alt     keycode 0x5f = Decr_Console
+keycode 0x61 = Right
+	alt     keycode 0x61 = Incr_Console
+keycode 0x38 = Select
+keycode 0x60 = Down
+keycode 0x3a = Next
+	shift   keycode 0x3a = Scroll_Forward
+keycode 0x24 = Insert
+keycode 0x25 = Remove
+#	altgr   control keycode 0x25 = Boot
+	control alt     keycode 0x25 = Boot
+
+keycode 0x0f = Help      Show_Memory      Show_Registers
+	control keycode  0x0f = Show_State
+
+keycode 0x10 = Do
+
+string F1 = "\033[[A"
+string F2 = "\033[[B"
+string F3 = "\033[[C"
+string F4 = "\033[[D"
+string F5 = "\033[[E"
+string F6 = "\033[17~"
+string F7 = "\033[18~"
+string F8 = "\033[19~"
+string F9 = "\033[20~"
+string F10 = "\033[21~"
+string F11 = "\033[23~"
+string F12 = "\033[24~"
+string F13 = "\033[25~"
+string F14 = "\033[26~"
+string F15 = "\033[28~"
+string F16 = "\033[29~"
+string F17 = "\033[31~"
+string F18 = "\033[32~"
+string F19 = "\033[33~"
+string F20 = "\033[34~"
+string Find = "\033[1~"
+string Insert = "\033[2~"
+string Remove = "\033[3~"
+string Select = "\033[4~"
+string Prior = "\033[5~"
+string Next = "\033[6~"
+string Macro = "\033[M"
+string Pause = "\033[P"
+compose '`' 'A' to 'À'
+compose '`' 'a' to 'à'
+compose '\'' 'A' to 'Á'
+compose '\'' 'a' to 'á'
+compose '^' 'A' to 'Â'
+compose '^' 'a' to 'â'
+compose '~' 'A' to 'Ã'
+compose '~' 'a' to 'ã'
+compose '"' 'A' to 'Ä'
+compose '"' 'a' to 'ä'
+compose 'O' 'A' to 'Å'
+compose 'o' 'a' to 'å'
+compose '0' 'A' to 'Å'
+compose '0' 'a' to 'å'
+compose 'A' 'A' to 'Å'
+compose 'a' 'a' to 'å'
+compose 'A' 'E' to 'Æ'
+compose 'a' 'e' to 'æ'
+compose ',' 'C' to 'Ç'
+compose ',' 'c' to 'ç'
+compose '`' 'E' to 'È'
+compose '`' 'e' to 'è'
+compose '\'' 'E' to 'É'
+compose '\'' 'e' to 'é'
+compose '^' 'E' to 'Ê'
+compose '^' 'e' to 'ê'
+compose '"' 'E' to 'Ë'
+compose '"' 'e' to 'ë'
+compose '`' 'I' to 'Ì'
+compose '`' 'i' to 'ì'
+compose '\'' 'I' to 'Í'
+compose '\'' 'i' to 'í'
+compose '^' 'I' to 'Î'
+compose '^' 'i' to 'î'
+compose '"' 'I' to 'Ï'
+compose '"' 'i' to 'ï'
+compose '-' 'D' to 'Ð'
+compose '-' 'd' to 'ð'
+compose '~' 'N' to 'Ñ'
+compose '~' 'n' to 'ñ'
+compose '`' 'O' to 'Ò'
+compose '`' 'o' to 'ò'
+compose '\'' 'O' to 'Ó'
+compose '\'' 'o' to 'ó'
+compose '^' 'O' to 'Ô'
+compose '^' 'o' to 'ô'
+compose '~' 'O' to 'Õ'
+compose '~' 'o' to 'õ'
+compose '"' 'O' to 'Ö'
+compose '"' 'o' to 'ö'
+compose '/' 'O' to 'Ø'
+compose '/' 'o' to 'ø'
+compose '`' 'U' to 'Ù'
+compose '`' 'u' to 'ù'
+compose '\'' 'U' to 'Ú'
+compose '\'' 'u' to 'ú'
+compose '^' 'U' to 'Û'
+compose '^' 'u' to 'û'
+compose '"' 'U' to 'Ü'
+compose '"' 'u' to 'ü'
+compose '\'' 'Y' to 'Ý'
+compose '\'' 'y' to 'ý'
+compose 'T' 'H' to 'Þ'
+compose 't' 'h' to 'þ'
+compose 's' 's' to 'ß'
+compose '"' 'y' to 'ÿ'
+compose 's' 'z' to 'ß'
+compose 'i' 'j' to 'ÿ'
diff -u --recursive --new-file v2.4.9/linux/drivers/tc/lk201-remap.c linux/drivers/tc/lk201-remap.c
--- v2.4.9/linux/drivers/tc/lk201-remap.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/tc/lk201-remap.c	Mon Aug 27 08:56:31 2001
@@ -0,0 +1,172 @@
+/*
+ * Keyboard mappings for DEC LK201/401/501 keyboards
+ * 
+ * 17.05.99 Michael Engel (engel@unix-ag.org)
+ *
+ * DEC US keyboards generate keycodes in the range 0x55 - 0xfb
+ *
+ * This conflicts with Linux scancode conventions which define 
+ * 0x00-0x7f as "normal" and 0x80-0xff as "shifted" scancodes, so we
+ * have to remap the keycodes to 0x00-0x7f with the scancodeRemap
+ * array. The generated scancode is simply the number of the key counted
+ * from the left upper to the right lower corner of the keyboard ...
+ *
+ * These scancodes are then being remapped (I hope ;-)) with the 
+ * lk501*map[] arrays which define scancode -> Linux code mapping
+ *
+ * Oh man is this horrible ;-)
+ *
+ * Scancodes with dual labels exist for keyboards as follows:
+ *
+ * code:  left label          / right label
+ *
+ * 0x73:  LKx01, LK421        / LK443, LK444
+ * 0x74:  LKx01, LK421        / LK443, LK444
+ * 0x7c:  LKx01, LK421        / LK443, LK444
+ * 0x8a:  LKx01, LK421        / LK443, LK444
+ * 0x8b:  LKx01, LK421        / LK443, LK444
+ * 0x8c:  LKx01, LK421        / LK443, LK444
+ * 0x8d:  LKx01, LK421        / LK443, LK444
+ * 0x8e:  LKx01, LK421        / LK443, LK444
+ * 0x8f:  LKx01, LK421        / LK443, LK444
+ * 0x9c:  LKx01, LK421        / LK443, LK444
+ * 0xa1:  LKx01, LK421        / LK443, LK444
+ * 0xa2:  LKx01, LK421        / LK443, LK444
+ * 0xa3:  LKx01, LK421        / LK443, LK444
+ * 0xa4:  LKx01, LK421        / LK443, LK444
+ * 0xad:         LK421        / LK443, LK444
+ * 0xc9:  LKx01, LK421, LK443 /        LK444
+ * 0xf7:  LKx01,        LK443 /        LK444
+ */
+
+unsigned char scancodeRemap[256] = {
+/* ----- 								*/
+/*  0 */ 0,		0,		0,		0,
+/* ----- 								*/
+/*  4 */ 0,		0,		0,		0,
+/* ----- 								*/
+/*  8 */ 0,		0,		0,		0,
+/* ----- 								*/
+/*  c */ 0,		0,		0,		0,
+/* ----- 								*/
+/* 10 */ 0,		0,		0,		0,
+/* ----- 								*/
+/* 14 */ 0,		0,		0,		0,
+/* ----- 								*/
+/* 18 */ 0,		0,		0,		0,
+/* ----- 								*/
+/* 1c */ 0,		0,		0,		0,
+/* ----- 								*/
+/* 20 */ 0,		0,		0,		0,
+/* ----- 								*/
+/* 24 */ 0,		0,		0,		0,
+/* ----- 								*/
+/* 28 */ 0,		0,		0,		0,
+/* ----- 								*/
+/* 2c */ 0,		0,		0,		0,
+/* ----- 								*/
+/* 30 */ 0,		0,		0,		0,
+/* ----- 								*/
+/* 34 */ 0,		0,		0,		0,
+/* ----- 								*/
+/* 38 */ 0,		0,		0,		0,
+/* ----- 								*/
+/* 3c */ 0,		0,		0,		0,
+/* ----- 								*/
+/* 40 */ 0,		0,		0,		0,
+/* ----- 								*/
+/* 44 */ 0,		0,		0,		0,
+/* ----- 								*/
+/* 48 */ 0,		0,		0,		0,
+/* ----- 								*/
+/* 4c */ 0,		0,		0,		0,
+/* ----- 								*/
+/* 50 */ 0,		0,		0,		0,
+/* ----- 	 	ESC		F1		F2 		*/
+/* 54 */ 0,		0,		0x01,  		0x02,
+/* ----- F3		F4		F5				*/
+/* 58 */ 0x03,  	0x04,		0x05,		0,
+/* ----- 								*/
+/* 5c */ 0,		0,		0,		0,
+/* ----- 								*/
+/* 60 */ 0,		0,		0,		0,
+/* ----- F6		F7		F8		F9		*/
+/* 64 */ 0x06,		0x07,		0x08,		0x09, 
+/* ----- F10								*/
+/* 68 */ 0x0a,		0,		0,		0,
+/* ----- 								*/
+/* 6c */ 0,		0,		0,		0,
+/* ----- 		F11   		F12		F13/PRNT SCRN	*/
+/* 70 */ 0,		0x0b,  		0x0c,		0x0d,
+/* ----- F14/SCRL LCK							*/
+/* 74 */ 0x0e,		0,		0,		0,
+/* ----- 								*/
+/* 78 */ 0,		0,		0,		0,
+/* ----- HELP/PAUSE	DO						*/
+/* 7c */ 0x0f,		0x10,		0,		0,
+/* ----- F17		F18		F19		F20		*/
+/* 80 */ 0x11,		0x12,		0x13,		0x14,
+/* ----- 								*/
+/* 84 */ 0,		0,		0,		0,
+/* ----- 				FIND/INSERT	INSERT/HOME	*/
+/* 88 */ 0,		0,		0x23,		0x24,
+/* ----- REMOVE/PG UP	SELECT/DELETE	PREVIOUS/END	NEXT/PG DN	*/
+/* 8c */ 0x25,		0x38,		0x39,		0x3a,
+/* ----- 				KP 0				*/
+/* 90 */ 0,		0,		0x6b,		0,
+/* ----- KP .		KP ENTER	KP 1		KP 2		*/
+/* 94 */ 0x6c,		0x65,		0x62,		0x63,
+/* ----- KP 3		KP 4		KP 5		KP 6		*/
+/* 98 */ 0x64,		0x4e,		0x4f,		0x50,
+/* ----- KP ,/KP +	KP 7		KP 8		KP 9		*/
+/* 9c */ 0x51,		0x3b,		0x3c,		0x3d,
+/* ----- KP -		KP F1/NUM LCK	KP F2/KP /	KP F3/KP *	*/
+/* a0 */ 0x3e,		0x26,		0x27,		0x28,
+/* ----- KP F4/KP -					LEFT		*/
+/* a4 */ 0x29,		0,		0,		0x5f,
+/* ----- RIGHT		DOWN		UP		SHIFT Rt	*/
+/* a8 */ 0x61,		0x60, 		0x4d,		0x5e,
+/* ----- ALT		COMP Rt/CTRL Rt	SHIFT		CONTROL		*/
+/* ac */ 0,		0,		0x52,		0x3f,
+/* ----- CAPS		COMPOSE		ALT Rt				*/
+/* b0 */ 0x40,		0x67,		0,		0,
+/* ----- 								*/
+/* b4 */ 0,		0,		0,		0,
+/* ----- 								*/
+/* b8 */ 0,		0,		0,		0,
+/* ----- BKSP		RET		TAB		`		*/
+/* bc */ 0x22,		0x37,		0x2a,		0x15,
+/* ----- 1		q		a		z		*/
+/* c0 */ 0x16,		0x2b,		0x41,		0x54,
+/* ----- 		2		w		s		*/
+/* c4 */ 0,		0x17,		0x2c,		0x42,
+/* ----- x		</\\				3		*/
+/* c8 */ 0x55,		0x53,		0,		0x18,
+/* ----- e		d		c				*/
+/* cc */ 0x2d,		0x43,		0x56,		0,
+/* ----- 4		r		f		v		*/
+/* d0 */ 0x19,		0x2e,		0x44,		0x57,
+/* ----- SPACE				5		t		*/
+/* d4 */ 0x68,		0,		0x1a,		0x2f,
+/* ----- g		b				6		*/
+/* d8 */ 0x45,		0x58,		0,		0x1b,
+/* ----- y		h		n				*/
+/* dc */ 0x30,		0x46,		0x59,		0,
+/* ----- 7		u		j		m		*/
+/* e0 */ 0x1c,		0x31,		0x47,		0x5a,
+/* ----- 		8		i		k		*/
+/* e4 */ 0,		0x1d,		0x32,		0x48,
+/* ----- ,				9		o		*/
+/* e8 */ 0x5b,		0,		0x1e,		0x33,
+/* ----- l		.				0		*/
+/* ec */ 0x49,		0x5c,		0,		0x1f,
+/* ----- p				;		/		*/
+/* f0 */ 0x34,		0,		0x4a,		0x5d,
+/* ----- 		=		]		\\/\'		*/
+/* f4 */ 0,		0x21,		0x36,		0x4c,
+/* ----- 		-		[		\'		*/
+/* f8 */ 0,		0x20,		0x35,		0x4b,
+/* ----- 								*/
+/* fc */ 0,		0,		0,		0,
+};
+
diff -u --recursive --new-file v2.4.9/linux/drivers/tc/lk201.c linux/drivers/tc/lk201.c
--- v2.4.9/linux/drivers/tc/lk201.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/tc/lk201.c	Mon Aug 27 08:56:31 2001
@@ -0,0 +1,237 @@
+/*
+ *
+ * This file 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.
+ *
+ */
+#include <linux/errno.h>
+#include <linux/tty.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/kbd_ll.h>
+#include <asm/wbflush.h>
+#include <asm/dec/tc.h>
+#include <asm/dec/machtype.h>
+
+#include "zs.h"
+#include "lk201.h"
+
+/* Simple translation table for the SysRq keys */
+
+#ifdef CONFIG_MAGIC_SYSRQ
+/*
+ * Actually no translation at all, at least until we figure out
+ * how to define SysRq for LK201 and friends. --macro
+ */
+unsigned char lk201_sysrq_xlate[128];
+unsigned char *kbd_sysrq_xlate = lk201_sysrq_xlate;
+#endif
+
+#define KEYB_LINE	3
+
+static int __init lk201_init(struct dec_serial *);
+static void __init lk201_info(struct dec_serial *);
+static void lk201_kbd_rx_char(unsigned char, unsigned char);
+
+struct zs_hook lk201_kbdhook = {
+	init_channel:   lk201_init,
+	init_info:      lk201_info,
+	rx_char:        NULL,
+	poll_rx_char:   NULL,
+	poll_tx_char:   NULL,
+	cflags:         B4800 | CS8 | CSTOPB | CLOCAL
+};
+
+/*
+ * This is used during keyboard initialisation
+ */
+static unsigned char lk201_reset_string[] = {
+	LK_CMD_LEDS_ON, LK_PARAM_LED_MASK(0xf),	/* show we are resetting */
+	LK_CMD_SET_DEFAULTS,
+	LK_CMD_MODE(LK_MODE_RPT_DOWN, 1),
+	LK_CMD_MODE(LK_MODE_RPT_DOWN, 2),
+	LK_CMD_MODE(LK_MODE_RPT_DOWN, 3),
+	LK_CMD_MODE(LK_MODE_RPT_DOWN, 4),
+	LK_CMD_MODE(LK_MODE_DOWN_UP, 5),
+	LK_CMD_MODE(LK_MODE_DOWN_UP, 6),
+	LK_CMD_MODE(LK_MODE_RPT_DOWN, 7),
+	LK_CMD_MODE(LK_MODE_RPT_DOWN, 8),
+	LK_CMD_MODE(LK_MODE_RPT_DOWN, 9),
+	LK_CMD_MODE(LK_MODE_RPT_DOWN, 10),
+	LK_CMD_MODE(LK_MODE_RPT_DOWN, 11),
+	LK_CMD_MODE(LK_MODE_RPT_DOWN, 12),
+	LK_CMD_MODE(LK_MODE_DOWN, 13),
+	LK_CMD_MODE(LK_MODE_RPT_DOWN, 14),
+	LK_CMD_ENB_RPT,
+	LK_CMD_DIS_KEYCLK,
+	LK_CMD_RESUME,
+	LK_CMD_ENB_BELL, LK_PARAM_VOLUME(4),
+	LK_CMD_LEDS_OFF, LK_PARAM_LED_MASK(0xf)
+};
+
+static int __init lk201_reset(struct dec_serial *info)
+{
+	int i;
+
+	for (i = 0; i < sizeof(lk201_reset_string); i++)
+		if (info->hook->poll_tx_char(info, lk201_reset_string[i])) {
+			printk(__FUNCTION__" transmit timeout\n");
+			return -EIO;
+		}
+	return 0;
+}
+
+void kbd_leds(unsigned char leds)
+{
+	return;
+}
+
+int kbd_setkeycode(unsigned int scancode, unsigned int keycode)
+{
+	return -EINVAL;
+}
+
+int kbd_getkeycode(unsigned int scancode)
+{
+	return -EINVAL;
+}
+
+int kbd_translate(unsigned char scancode, unsigned char *keycode,
+		  char raw_mode)
+{
+	*keycode = scancode;
+	return 1;
+}
+
+char kbd_unexpected_up(unsigned char keycode)
+{
+	return 0x80;
+}
+
+static void lk201_kbd_rx_char(unsigned char ch, unsigned char stat)
+{
+	static int shift_state = 0;
+	static int prev_scancode;
+	unsigned char c = scancodeRemap[ch];
+
+	if (!stat || stat == 4) {
+		switch (ch) {
+		case LK_KEY_ACK:
+			break;
+		case LK_KEY_LOCK:
+			shift_state ^= LK_LOCK;
+			handle_scancode(c, shift_state && LK_LOCK ? 1 : 0);
+			break;
+		case LK_KEY_SHIFT:
+			shift_state ^= LK_SHIFT;
+			handle_scancode(c, shift_state && LK_SHIFT ? 1 : 0);
+			break;
+		case LK_KEY_CTRL:
+			shift_state ^= LK_CTRL;
+			handle_scancode(c, shift_state && LK_CTRL ? 1 : 0);
+			break;
+		case LK_KEY_COMP:
+			shift_state ^= LK_COMP;
+			handle_scancode(c, shift_state && LK_COMP ? 1 : 0);
+			break;
+		case LK_KEY_RELEASE:
+			if (shift_state & LK_SHIFT)
+				handle_scancode(scancodeRemap[LK_KEY_SHIFT], 0);
+			if (shift_state & LK_CTRL)
+				handle_scancode(scancodeRemap[LK_KEY_CTRL], 0);
+			if (shift_state & LK_COMP)
+				handle_scancode(scancodeRemap[LK_KEY_COMP], 0);
+			if (shift_state & LK_LOCK)
+				handle_scancode(scancodeRemap[LK_KEY_LOCK], 0);
+			shift_state = 0;
+			break;
+		case LK_KEY_REPEAT:
+			handle_scancode(prev_scancode, 1);
+			break;
+		default:
+			prev_scancode = c;
+			handle_scancode(c, 1);
+			break;
+		}
+	} else
+		printk("Error reading LKx01 keyboard: 0x%02x\n", stat);
+}
+
+static void __init lk201_info(struct dec_serial *info)
+{
+}
+
+static int __init lk201_init(struct dec_serial *info)
+{
+	unsigned int ch, id = 0;
+	int result;
+
+	printk("DECstation LK keyboard driver v0.04... ");
+
+	result = lk201_reset(info);
+	if (result)
+		return result;
+	mdelay(10);
+
+	/*
+	 * Detect whether there is an LK201 or an LK401
+	 * The LK401 has ALT keys...
+	 */
+	info->hook->poll_tx_char(info, LK_CMD_REQ_ID);
+	while ((ch = info->hook->poll_rx_char(info)) > 0)
+		id = ch;
+
+	switch (id) {
+	case 1:
+		printk("LK201 detected\n");
+		break;
+	case 2:
+		printk("LK401 detected\n");
+		break;
+	default:
+		printk("unknown keyboard, ID %d,\n", id);
+		printk("... please report to <linux-mips@oss.sgi.com>\n");
+	}
+
+	/*
+	 * now we're ready
+	 */
+	info->hook->rx_char = lk201_kbd_rx_char;
+
+	return 0;
+}
+
+void __init kbd_init_hw(void)
+{
+	extern int register_zs_hook(unsigned int, struct zs_hook *);
+	extern int unregister_zs_hook(unsigned int);
+
+	if (TURBOCHANNEL) {
+		if (mips_machtype != MACH_DS5000_XX) {
+			/*
+			 * This is not a MAXINE, so:
+			 *
+			 * kbd_init_hw() is being called before
+			 * rs_init() so just register the kbd hook
+			 * and let zs_init do the rest :-)
+			 */
+			if (mips_machtype == MACH_DS5000_200)
+				printk("LK201 Support for DS5000/200 not yet ready ...\n");
+			else
+				if(!register_zs_hook(KEYB_LINE, &lk201_kbdhook))
+					unregister_zs_hook(KEYB_LINE);
+		}
+	} else {
+		/*
+		 * TODO: modify dz.c to allow similar hooks
+		 * for LK201 handling on DS2100, DS3100, and DS5000/200
+		 */
+		printk("LK201 Support for DS3100 not yet ready ...\n");
+	}
+}
+
+
+
+
diff -u --recursive --new-file v2.4.9/linux/drivers/tc/lk201.h linux/drivers/tc/lk201.h
--- v2.4.9/linux/drivers/tc/lk201.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/tc/lk201.h	Mon Aug 27 08:56:31 2001
@@ -0,0 +1,53 @@
+/*
+ *	Commands to the keyboard processor
+ */
+
+#define	LK_PARAM		0x80	/* start/end parameter list */
+
+#define	LK_CMD_RESUME		0x8b
+#define	LK_CMD_INHIBIT		0xb9
+#define	LK_CMD_LEDS_ON		0x13	/* 1 param: led bitmask */
+#define	LK_CMD_LEDS_OFF		0x11	/* 1 param: led bitmask */
+#define	LK_CMD_DIS_KEYCLK	0x99
+#define	LK_CMD_ENB_KEYCLK	0x1b	/* 1 param: volume */
+#define	LK_CMD_DIS_CTLCLK	0xb9
+#define	LK_CMD_ENB_CTLCLK	0xbb
+#define	LK_CMD_SOUND_CLK	0x9f
+#define	LK_CMD_DIS_BELL		0xa1
+#define	LK_CMD_ENB_BELL		0x23	/* 1 param: volume */
+#define	LK_CMD_BELL		0xa7
+#define	LK_CMD_TMP_NORPT	0xc1
+#define	LK_CMD_ENB_RPT		0xe3
+#define	LK_CMD_DIS_RPT		0xe1
+#define	LK_CMD_RPT_TO_DOWN	0xd9
+#define	LK_CMD_REQ_ID		0xab
+#define	LK_CMD_POWER_UP		0xfd
+#define	LK_CMD_TEST_MODE	0xcb
+#define	LK_CMD_SET_DEFAULTS	0xd3
+
+/* there are 4 leds, represent them in the low 4 bits of a byte */
+#define	LK_PARAM_LED_MASK(ledbmap)	(LK_PARAM|(ledbmap))
+
+/* max volume is 0, lowest is 0x7 */
+#define	LK_PARAM_VOLUME(v)		(LK_PARAM|((v)&0x7))
+
+/* mode set command(s) details */
+#define	LK_MODE_DOWN		0x0
+#define	LK_MODE_RPT_DOWN	0x2
+#define	LK_MODE_DOWN_UP		0x6
+#define	LK_CMD_MODE(m,div)	(LK_PARAM|(div<<3)|m)
+
+#define LK_SHIFT 1<<0
+#define LK_CTRL 1<<1
+#define LK_LOCK 1<<2
+#define LK_COMP 1<<3
+
+#define LK_KEY_SHIFT 174
+#define LK_KEY_CTRL 175
+#define LK_KEY_LOCK 176
+#define LK_KEY_COMP 177
+#define LK_KEY_RELEASE 179
+#define LK_KEY_REPEAT 180
+#define LK_KEY_ACK 186
+
+extern unsigned char scancodeRemap[256];
\ No newline at end of file
diff -u --recursive --new-file v2.4.9/linux/drivers/tc/tc.c linux/drivers/tc/tc.c
--- v2.4.9/linux/drivers/tc/tc.c	Sat May 13 08:31:25 2000
+++ linux/drivers/tc/tc.c	Mon Aug 27 08:56:31 2001
@@ -1,4 +1,4 @@
-/* $Id: tc.c,v 1.3 1999/10/09 00:01:32 ralf Exp $
+/*
  * tc-init: We assume the TURBOchannel to be up and running so
  * just probe for Modules and fill in the global data structure
  * tc_bus.
@@ -8,9 +8,7 @@
  * for more details.
  *
  * Copyright (c) Harald Koerfgen, 1998
- *
  */
-
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
@@ -23,14 +21,15 @@
 
 #include <asm/ptrace.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 
 #define TC_DEBUG
 
 slot_info tc_bus[MAX_SLOT];
-static int max_tcslot = 0;
-static tcinfo *info = (tcinfo *)0;
+static int max_tcslot;
+static tcinfo *info;
 
-unsigned long system_base = 0;
+unsigned long system_base;
 
 extern void (*dbe_board_handler)(struct pt_regs *regs);
 extern unsigned long *(*rex_slot_address)(int);
@@ -112,19 +111,19 @@
 	for (slot = 0; slot <= max_slot; slot++) {
 		module = (char *)(startaddr + slot * size);
 		offset = -1;
-		if (module[OLDCARD + PATTERN0] == 0x55 && module[OLDCARD + PATTERN1] == 0x00
-		  && module[OLDCARD + PATTERN2] == 0xaa && module[OLDCARD + PATTERN3] == 0xff)
+		if (module[OLDCARD + TC_PATTERN0] == 0x55 && module[OLDCARD + TC_PATTERN1] == 0x00
+		  && module[OLDCARD + TC_PATTERN2] == 0xaa && module[OLDCARD + TC_PATTERN3] == 0xff)
 			offset = OLDCARD;
-		if (module[PATTERN0] == 0x55 && module[PATTERN1] == 0x00
-		  && module[PATTERN2] == 0xaa && module[PATTERN3] == 0xff)
+		if (module[TC_PATTERN0] == 0x55 && module[TC_PATTERN1] == 0x00
+		  && module[TC_PATTERN2] == 0xaa && module[TC_PATTERN3] == 0xff)
 			offset = 0;
 
 		if (offset != -1) {
 			tc_bus[slot].base_addr = (unsigned long)module;
 			for(i = 0; i < 8; i++) {
-				tc_bus[slot].firmware[i] = module[FIRM_VER + offset + 4 * i];
-				tc_bus[slot].vendor[i] = module[VENDOR + offset + 4 * i];
-				tc_bus[slot].name[i] = module[MODULE + offset + 4 * i];
+				tc_bus[slot].firmware[i] = module[TC_FIRM_VER + offset + 4 * i];
+				tc_bus[slot].vendor[i] = module[TC_VENDOR + offset + 4 * i];
+				tc_bus[slot].name[i] = module[TC_MODULE + offset + 4 * i];
 			}
 			tc_bus[slot].firmware[8] = 0;
 			tc_bus[slot].vendor[8] = 0;
@@ -206,7 +205,7 @@
 	if (TURBOCHANNEL && info->slot_size && slot0addr) {
 		printk("TURBOchannel rev. %1d at %2d.%1d MHz ", info->revision,
 			tc_clock / 10, tc_clock % 10);
-		printk("(%sparity)\n", info->parity ? "" : "no ");
+		printk("(with%s parity)\n", info->parity ? "" : "out");
 
 		slot_size = info->slot_size << 20;
 
@@ -235,3 +234,11 @@
 		ioport_resource.end = KSEG2 - 1;
 	}
 }
+
+EXPORT_SYMBOL(search_tc_card);
+EXPORT_SYMBOL(claim_tc_card);
+EXPORT_SYMBOL(release_tc_card);
+EXPORT_SYMBOL(get_tc_base_addr);
+EXPORT_SYMBOL(get_tc_irq_nr);
+EXPORT_SYMBOL(get_tc_speed);
+
diff -u --recursive --new-file v2.4.9/linux/drivers/tc/tcsyms.c linux/drivers/tc/tcsyms.c
--- v2.4.9/linux/drivers/tc/tcsyms.c	Sat May 13 08:31:25 2000
+++ linux/drivers/tc/tcsyms.c	Wed Dec 31 16:00:00 1969
@@ -1,14 +0,0 @@
-/*
- *	TURBOchannel Services -- Exported Symbols
- *
- */
-
-#include <linux/module.h>
-#include <asm/dec/tc.h>
-
-EXPORT_SYMBOL(search_tc_card);
-EXPORT_SYMBOL(claim_tc_card);
-EXPORT_SYMBOL(release_tc_card);
-EXPORT_SYMBOL(get_tc_base_addr);
-EXPORT_SYMBOL(get_tc_irq_nr);
-EXPORT_SYMBOL(get_tc_speed);
diff -u --recursive --new-file v2.4.9/linux/drivers/tc/zs.c linux/drivers/tc/zs.c
--- v2.4.9/linux/drivers/tc/zs.c	Thu Oct 12 14:20:47 2000
+++ linux/drivers/tc/zs.c	Mon Aug 27 08:56:31 2001
@@ -1,22 +1,46 @@
 /*
- * decserial.c: Serial port driver for IOASIC DECsatations.
+ * decserial.c: Serial port driver for IOASIC DECstations.
  *
- * Derived from drivers/macintosh/macserial.c by Harald Koerfgen.
  * Derived from drivers/sbus/char/sunserial.c by Paul Mackerras.
+ * Derived from drivers/macintosh/macserial.c by Harald Koerfgen.
  *
  * DECstation changes
- * Copyright (C) 1998 Harald Koerfgen (Harald.Koerfgen@home.ivm.de)
+ * Copyright (C) 1998-2000 Harald Koerfgen
+ * Copyright (C) 2000,2001 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
  *
  * For the rest of the code the original Copyright applies:
  * Copyright (C) 1996 Paul Mackerras (Paul.Mackerras@cs.anu.edu.au)
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
  *
- * Keyboard and mouse are not supported right now. If you want to change this,
- * you might want to have a look at drivers/sbus/char/sunserial.c to see
- * how this might be done. HK
+ *
+ * Note: for IOASIC systems the wiring is as follows:
+ *
+ * mouse/keyboard:
+ * DIN-7 MJ-4  signal        SCC
+ * 2     1     TxD       <-  A.TxD
+ * 3     4     RxD       ->  A.RxD
+ *
+ * EIA-232/EIA-423:
+ * DB-25 MMJ-6 signal        SCC
+ * 2     2     TxD       <-  B.TxD
+ * 3     5     RxD       ->  B.RxD
+ * 4           RTS       <- ~A.RTS
+ * 5           CTS       -> ~B.CTS
+ * 6     6     DSR       -> ~A.SYNC
+ * 8           CD        -> ~B.DCD
+ * 12          DSRS(DCE) -> ~A.CTS  (*)
+ * 15          TxC       ->  B.TxC
+ * 17          RxC       ->  B.RxC
+ * 20    1     DTR       <- ~A.DTR
+ * 22          RI        -> ~A.DCD
+ * 23          DSRS(DTE) <- ~B.RTS
+ *
+ * (*) EIA-232 defines the signal at this pin to be SCD, while DSRS(DCE)
+ *     is shared with DSRS(DTE) at pin 23.
  */
 
 #include <linux/config.h>
+#include <linux/version.h>
 #include <linux/errno.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
@@ -31,6 +55,7 @@
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/ioport.h>
 #ifdef CONFIG_SERIAL_CONSOLE
 #include <linux/console.h>
 #endif
@@ -43,17 +68,26 @@
 #include <asm/bitops.h>
 #include <asm/uaccess.h>
 #include <asm/wbflush.h>
+#include <asm/bootinfo.h>
+#ifdef CONFIG_DECSTATION
 #include <asm/dec/interrupts.h>
 #include <asm/dec/machtype.h>
 #include <asm/dec/tc.h>
 #include <asm/dec/ioasic_addrs.h>
+#endif
+#ifdef CONFIG_BAGET_MIPS
+#include <asm/baget/baget.h>
+unsigned long system_base;
+#endif
 #ifdef CONFIG_KGDB
 #include <asm/kgdb.h>
 #endif
+#ifdef CONFIG_MAGIC_SYSRQ
+#include <linux/sysrq.h>
+#endif
 
 #include "zs.h"
 
-
 /*
  * It would be nice to dynamically allocate everything that
  * depends on NUM_SERIAL, so we could support any number of
@@ -61,11 +95,60 @@
  */
 #define NUM_SERIAL	2		/* Max number of ZS chips supported */
 #define NUM_CHANNELS	(NUM_SERIAL * 2)	/* 2 channels per chip */
+#define CHANNEL_A_NR  (zs_parms->channel_a_offset > zs_parms->channel_b_offset)
+                                        /* Number of channel A in the chip */ 
+#define ZS_CHAN_IO_SIZE 8
+#define ZS_CLOCK        7372800 	/* Z8530 RTxC input clock rate */
 
 #define RECOVERY_DELAY  udelay(2)
 
-struct dec_zschannel zs_channels[NUM_CHANNELS];
+struct zs_parms {
+	unsigned long scc0;
+	unsigned long scc1;
+	int channel_a_offset;
+	int channel_b_offset;
+	int irq;
+	int clock;
+};
 
+static struct zs_parms *zs_parms;
+
+#ifdef CONFIG_DECSTATION
+static struct zs_parms ds_parms = {
+	scc0 : SCC0,
+	scc1 : SCC1,
+	channel_a_offset : 1,
+	channel_b_offset : 9,
+	irq : SERIAL,
+	clock : ZS_CLOCK
+};
+#endif
+#ifdef CONFIG_BAGET_MIPS
+static struct zs_parms baget_parms = {
+	scc0 : UNI_SCC0,
+	scc1 : UNI_SCC1,
+	channel_a_offset : 9,
+	channel_b_offset : 1,
+	irq : BAGET_SCC_IRQ,
+	clock : 14745000
+};
+#endif
+
+#ifdef CONFIG_DECSTATION
+#define DS_BUS_PRESENT (IOASIC)
+#else
+#define DS_BUS_PRESENT 0
+#endif
+
+#ifdef CONFIG_BAGET_MIPS
+#define BAGET_BUS_PRESENT (mips_machtype == MACH_BAGET202)
+#else
+#define BAGET_BUS_PRESENT 0
+#endif
+
+#define BUS_PRESENT (DS_BUS_PRESENT || BAGET_BUS_PRESENT)
+
+struct dec_zschannel zs_channels[NUM_CHANNELS];
 struct dec_serial zs_soft[NUM_CHANNELS];
 int zs_channels_found;
 struct dec_serial *zs_chain;	/* list of all channels */
@@ -75,19 +158,9 @@
 #ifdef CONFIG_SERIAL_CONSOLE
 static struct console sercons;
 #endif
-
-#ifdef CONFIG_KGDB
-struct dec_zschannel *zs_kgdbchan;
-static unsigned char scc_inittab[] = {
-	9,  0x80,	/* reset A side (CHRA) */
-	13, 0,		/* set baud rate divisor */
-	12, 1,
-	14, 1,		/* baud rate gen enable, src=rtxc (BRENABL) */
-	11, 0x50,	/* clocks = br gen (RCBR | TCBR) */
-	5,  0x6a,	/* tx 8 bits, assert RTS (Tx8 | TxENAB | RTS) */
-	4,  0x44,	/* x16 clock, 1 stop (SB1 | X16CLK)*/
-	3,  0xc1,	/* rx enable, 8 bits (RxENABLE | Rx8)*/
-};
+#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) \
+    && !defined(MODULE)
+static unsigned long break_pressed; /* break, really ... */
 #endif
 
 static unsigned char zs_init_regs[16] __initdata = {
@@ -106,8 +179,6 @@
 	0 			     /* write 15 */
 };
 
-#define ZS_CLOCK         7372800 	/* Z8530 RTxC input clock rate */
-
 DECLARE_TASK_QUEUE(tq_zs_serial);
 
 struct tty_driver serial_driver, callout_driver;
@@ -129,6 +200,12 @@
 #undef SERIAL_DEBUG_THROTTLE
 #undef SERIAL_PARANOIA_CHECK
 
+#undef ZS_DEBUG_REGS
+
+#ifdef SERIAL_DEBUG_THROTTLE
+#define _tty_name(tty,buf) tty_name(tty,buf)
+#endif
+
 #define RS_STROBE_TIME 10
 #define RS_ISR_PASS_LIMIT 256
 
@@ -184,7 +261,7 @@
  */
 static int baud_table[] = {
 	0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
-	9600, 19200, 38400, 57600, 0, 0 };
+	9600, 19200, 38400, 57600, 115200, 0 };
 
 /* 
  * Reading and writing Z8530 registers.
@@ -256,16 +333,21 @@
 }
 
 /* Sets or clears DTR/RTS on the requested line */
-static inline void zs_rtsdtr(struct dec_serial *ss, int set)
+static inline void zs_rtsdtr(struct dec_serial *info, int which, int set)
 {
-	if (ss->zs_channel != ss->zs_chan_a) {
-		if (set)
-			ss->zs_chan_a->curregs[5] |= (RTS | DTR);
-		else
-			ss->zs_chan_a->curregs[5] &= ~(RTS | DTR);
-		write_zsreg(ss->zs_chan_a, 5, ss->zs_chan_a->curregs[5]);
+        unsigned long flags;
+
+
+	save_flags(flags); cli();
+	if (info->zs_channel != info->zs_chan_a) {
+		if (set) {
+			info->zs_chan_a->curregs[5] |= (which & (RTS | DTR));
+		} else {
+			info->zs_chan_a->curregs[5] &= ~(which & (RTS | DTR));
+		}
+		write_zsreg(info->zs_chan_a, 5, info->zs_chan_a->curregs[5]);
 	}
-	return;
+	restore_flags(flags);
 }
 
 /* Utility routines for the Zilog */
@@ -281,7 +363,7 @@
 	 */
 	brg = (read_zsreg(channel, 13) << 8);
 	brg |= read_zsreg(channel, 12);
-	return BRG_TO_BPS(brg, (ZS_CLOCK/(ss->clk_divisor)));
+	return BRG_TO_BPS(brg, (zs_parms->clock/(ss->clk_divisor)));
 }
 
 /* On receive, this clears errors and the receiver interrupts */
@@ -302,6 +384,8 @@
  * -----------------------------------------------------------------------
  */
 
+static int tty_break;	/* Set whenever BREAK condition is detected.  */
+
 /*
  * This routine is used by the interrupt handler to schedule
  * processing in the software interrupt portion of the driver.
@@ -320,23 +404,59 @@
 	struct tty_struct *tty = info->tty;
 	unsigned char ch, stat, flag;
 
-	while ((read_zsreg(info->zs_channel, 0) & Rx_CH_AV) != 0) {
+	while ((read_zsreg(info->zs_channel, R0) & Rx_CH_AV) != 0) {
 
 		stat = read_zsreg(info->zs_channel, R1);
 		ch = read_zsdata(info->zs_channel);
 
-#ifdef CONFIG_KGDB
-		if (info->kgdb_channel) {
-			if (ch == 0x03 || ch == '$')
-				breakpoint();
-			if (stat & (Rx_OVR|FRM_ERR|PAR_ERR))
-				write_zsreg(info->zs_channel, 0, ERR_RES);
-			return;
+		if (!tty && !info->hook && !info->hook->rx_char)
+			continue;
+
+		if (tty_break) {
+			tty_break = 0;
+#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) && !defined(MODULE)
+			if (info->line == sercons.index) {
+				if (!break_pressed) {
+					break_pressed = jiffies;
+					goto ignore_char;
+				}
+				break_pressed = 0;
+			}
+#endif
+			flag = TTY_BREAK;
+			if (info->flags & ZILOG_SAK)
+				do_SAK(tty);
+		} else {
+			if (stat & Rx_OVR) {
+				flag = TTY_OVERRUN;
+			} else if (stat & FRM_ERR) {
+				flag = TTY_FRAME;
+			} else if (stat & PAR_ERR) {
+				flag = TTY_PARITY;
+			} else
+				flag = 0;
+			if (flag)
+				/* reset the error indication */
+				write_zsreg(info->zs_channel, R0, ERR_RES);
+		}
+
+#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) && !defined(MODULE)
+		if (break_pressed && info->line == sercons.index) {
+			if (ch != 0 &&
+			    time_before(jiffies, break_pressed + HZ*5)) {
+				handle_sysrq(ch, regs, NULL, NULL);
+				break_pressed = 0;
+				goto ignore_char;
+			}
+			break_pressed = 0;
 		}
 #endif
-		if (!tty)
-			continue;
 
+		if (info->hook && info->hook->rx_char) {
+			(*info->hook->rx_char)(ch, flag);
+			return;
+  		}
+		
 		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
 			static int flip_buf_ovf;
 			++flip_buf_ovf;
@@ -348,26 +468,18 @@
 			if (flip_max_cnt < tty->flip.count)
 				flip_max_cnt = tty->flip.count;
 		}
-		if (stat & Rx_OVR) {
-			flag = TTY_OVERRUN;
-		} else if (stat & FRM_ERR) {
-			flag = TTY_FRAME;
-		} else if (stat & PAR_ERR) {
-			flag = TTY_PARITY;
-		} else
-			flag = 0;
-		if (flag)
-			/* reset the error indication */
-			write_zsreg(info->zs_channel, 0, ERR_RES);
+
 		*tty->flip.flag_buf_ptr++ = flag;
 		*tty->flip.char_buf_ptr++ = ch;
+	ignore_char:
 	}
-	tty_flip_buffer_push(tty);
+	if (tty)
+		tty_flip_buffer_push(tty);
 }
 
 static void transmit_chars(struct dec_serial *info)
 {
-	if ((read_zsreg(info->zs_channel, 0) & Tx_BUF_EMP) == 0)
+	if ((read_zsreg(info->zs_channel, R0) & Tx_BUF_EMP) == 0)
 		return;
 	info->tx_active = 0;
 
@@ -379,8 +491,9 @@
 		return;
 	}
 
-	if ((info->xmit_cnt <= 0) || info->tty->stopped || info->tx_stopped) {
-		write_zsreg(info->zs_channel, 0, RES_Tx_P);
+	if ((info->xmit_cnt <= 0) || (info->tty && info->tty->stopped)
+	    || info->tx_stopped) {
+		write_zsreg(info->zs_channel, R0, RES_Tx_P);
 		return;
 	}
 	/* Send char */
@@ -395,45 +508,48 @@
 
 static _INLINE_ void status_handle(struct dec_serial *info)
 {
-	unsigned char status;
+	unsigned char stat;
 
 	/* Get status from Read Register 0 */
-	status = read_zsreg(info->zs_channel, 0);
+	stat = read_zsreg(info->zs_channel, R0);
+
+	if (stat & BRK_ABRT) {
+#ifdef SERIAL_DEBUG_INTR
+		printk("handling break....");
+#endif
+		tty_break = 1;
+	}
 
-	/* FIXEM: Check for DCD transitions */
-	if (((status ^ info->read_reg_zero) & DCD) != 0
-	    && info->tty && !C_CLOCAL(info->tty)) {
-		if (status & DCD) {
-			wake_up_interruptible(&info->open_wait);
-		} else if (!(info->flags & ZILOG_CALLOUT_ACTIVE)) {
-			if (info->tty)
+	if (info->zs_channel != info->zs_chan_a) {
+
+		/* FIXEM: Check for DCD transitions */
+		if (((stat ^ info->read_reg_zero) & DCD) != 0
+		    && info->tty && !C_CLOCAL(info->tty)) {
+			if (stat & DCD) {
+				wake_up_interruptible(&info->open_wait);
+			} else if (!(info->flags & ZILOG_CALLOUT_ACTIVE)) {
 				tty_hangup(info->tty);
+			}
 		}
-	}
 
-	/* Check for CTS transitions */
-	if (info->tty && C_CRTSCTS(info->tty)) {
-		/*
-		 * For some reason, on the Power Macintosh,
-		 * it seems that the CTS bit is 1 when CTS is
-		 * *negated* and 0 when it is asserted.
-		 * The DCD bit doesn't seem to be inverted
-		 * like this.
-		 */
-		if ((status & CTS) != 0) {
-			if (info->tx_stopped) {
-				info->tx_stopped = 0;
-				if (!info->tx_active)
-					transmit_chars(info);
+		/* Check for CTS transitions */
+		if (info->tty && C_CRTSCTS(info->tty)) {
+			if ((stat & CTS) != 0) {
+				if (info->tx_stopped) {
+					info->tx_stopped = 0;
+					if (!info->tx_active)
+						transmit_chars(info);
+				}
+			} else {
+				info->tx_stopped = 1;
 			}
-		} else {
-			info->tx_stopped = 1;
 		}
+
 	}
 
 	/* Clear status condition... */
-	write_zsreg(info->zs_channel, 0, RES_EXT_INT);
-	info->read_reg_zero = status;
+	write_zsreg(info->zs_channel, R0, RES_EXT_INT);
+	info->read_reg_zero = stat;
 }
 
 /*
@@ -459,7 +575,7 @@
 		shift = 0;	/* Channel B */
 
 	for (;;) {
-		zs_intreg = read_zsreg(info->zs_chan_a, 3) >> shift; 
+		zs_intreg = read_zsreg(info->zs_chan_a, R3) >> shift; 
 		if ((zs_intreg & CHAN_IRQMASK) == 0)
 			break;
 
@@ -473,8 +589,31 @@
 			status_handle(info);
 		}
 	}
+	
+	/* Why do we need this ? */
+	write_zsreg(info->zs_channel, 0, RES_H_IUS);
 }
 
+#ifdef ZS_DEBUG_REGS
+void zs_dump (void) {
+	int i, j;
+	for (i = 0; i < zs_channels_found; i++) {
+		struct dec_zschannel *ch = &zs_channels[i]; 
+		if ((long)ch->control == UNI_IO_BASE+UNI_SCC1A_CTRL) {
+			for (j = 0; j < 15; j++) {
+				printk("W%d = 0x%x\t", 
+				       j, (int)ch->curregs[j]);
+			}
+			for (j = 0; j < 15; j++) {
+				printk("R%d = 0x%x\t", 
+				       j, (int)read_zsreg(ch,j));
+			}
+			printk("\n\n");
+		}
+	}
+}
+#endif
+
 /*
  * -------------------------------------------------------------------
  * Here ends the serial interrupt routines.
@@ -559,7 +698,7 @@
 	}
 }
 
-static int startup(struct dec_serial * info)
+int zs_startup(struct dec_serial * info)
 {
 	unsigned long flags;
 
@@ -575,7 +714,7 @@
 	save_flags(flags); cli();
 
 #ifdef SERIAL_DEBUG_OPEN
-	printk("starting up ttyS%d (irq %d)...", info->line, info->irq);
+	printk("starting up ttyS%02d (irq %d)...", info->line, info->irq);
 #endif
 
 	/*
@@ -593,7 +732,7 @@
 	/*
 	 * Turn on RTS and DTR.
 	 */
-	zs_rtsdtr(info, 1);
+	zs_rtsdtr(info, RTS | DTR, 1);
 
 	/*
 	 * Finally, enable sequencing and interrupts
@@ -664,8 +803,7 @@
 	info->zs_channel->curregs[5] &= ~TxENAB;
 	write_zsreg(info->zs_channel, 5, info->zs_channel->curregs[5]);
 	if (!info->tty || C_HUPCL(info->tty)) {
-		info->zs_chan_a->curregs[5] &= ~(DTR | RTS);
-		write_zsreg(info->zs_chan_a, 5, info->zs_chan_a->curregs[5]);
+		zs_rtsdtr(info, RTS | DTR, 0);
 	}
 
 	if (info->tty)
@@ -681,29 +819,45 @@
  */
 static void change_speed(struct dec_serial *info)
 {
-	unsigned short port;
 	unsigned cflag;
 	int	i;
-	int	brg;
+	int	brg, bits;
 	unsigned long flags;
 
-	if (!info->tty || !info->tty->termios)
-		return;
-	cflag = info->tty->termios->c_cflag;
-	if (!(port = info->port))
-		return;
+	if (!info->hook) {
+		if (!info->tty || !info->tty->termios)
+			return;
+		cflag = info->tty->termios->c_cflag;
+		if (!info->port)
+			return;
+	} else {
+		cflag = info->hook->cflags;
+	}
+
 	i = cflag & CBAUD;
+	if (i & CBAUDEX) {
+		i &= ~CBAUDEX;
+		if (i < 1 || i > 2) {
+			if (!info->hook)
+				info->tty->termios->c_cflag &= ~CBAUDEX;
+			else
+				info->hook->cflags &= ~CBAUDEX;
+		} else
+			i += 15;
+	}
 
 	save_flags(flags); cli();
 	info->zs_baud = baud_table[i];
 	info->clk_divisor = 16;
-
-	switch (info->zs_baud) {
-	default:
+	if (info->zs_baud) {
 		info->zs_channel->curregs[4] = X16CLK;
-		brg = BPS_TO_BRG(info->zs_baud, ZS_CLOCK/info->clk_divisor);
+		brg = BPS_TO_BRG(info->zs_baud, zs_parms->clock/info->clk_divisor);
 		info->zs_channel->curregs[12] = (brg & 255);
 		info->zs_channel->curregs[13] = ((brg >> 8) & 255);
+		zs_rtsdtr(info, DTR, 1); 
+	} else {
+		zs_rtsdtr(info, RTS | DTR, 0);
+		return;
 	}
 
 	/* byte size and parity */
@@ -711,24 +865,31 @@
 	info->zs_channel->curregs[5] &= ~TxNBITS_MASK;
 	switch (cflag & CSIZE) {
 	case CS5:
+		bits = 7;
 		info->zs_channel->curregs[3] |= Rx5;
 		info->zs_channel->curregs[5] |= Tx5;
 		break;
 	case CS6:
+		bits = 8;
 		info->zs_channel->curregs[3] |= Rx6;
 		info->zs_channel->curregs[5] |= Tx6;
 		break;
 	case CS7:
+		bits = 9;
 		info->zs_channel->curregs[3] |= Rx7;
 		info->zs_channel->curregs[5] |= Tx7;
 		break;
 	case CS8:
 	default: /* defaults to 8 bits */
+		bits = 10;
 		info->zs_channel->curregs[3] |= Rx8;
 		info->zs_channel->curregs[5] |= Tx8;
 		break;
 	}
 
+	info->timeout = ((info->xmit_fifo_size*HZ*bits) / info->zs_baud);
+        info->timeout += HZ/50;         /* Add .02 seconds of slop */
+
 	info->zs_channel->curregs[4] &= ~(SB_MASK | PAR_ENA | PAR_EVEN);
 	if (cflag & CSTOPB) {
 		info->zs_channel->curregs[4] |= SB2;
@@ -750,7 +911,7 @@
 		info->zs_channel->curregs[15] &= ~DCDIE;
 	if (cflag & CRTSCTS) {
 		info->zs_channel->curregs[15] |= CTSIE;
-		if ((read_zsreg(info->zs_channel, 0) & CTS) != 0)
+		if ((read_zsreg(info->zs_channel, 0) & CTS) == 0)
 			info->tx_stopped = 1;
 	} else {
 		info->zs_channel->curregs[15] &= ~CTSIE;
@@ -895,17 +1056,7 @@
 	}
 
 	if (C_CRTSCTS(tty)) {
-		/*
-		 * Here we want to turn off the RTS line.  On Macintoshes,
-		 * we only get the DTR line, which goes to both DTR and
-		 * RTS on the modem.  RTS doesn't go out to the serial
-		 * port socket.  So you should make sure your modem is
-		 * set to ignore DTR if you're using CRTSCTS.
-		 */
-		save_flags(flags); cli();
-		info->zs_chan_a->curregs[5] &= ~(DTR | RTS);
-		write_zsreg(info->zs_chan_a, 5, info->zs_chan_a->curregs[5]);
-		restore_flags(flags);
+		zs_rtsdtr(info, RTS, 0);
 	}
 }
 
@@ -937,11 +1088,7 @@
 	}
 
 	if (C_CRTSCTS(tty)) {
-		/* Assert RTS and DTR lines */
-		save_flags(flags); cli();
-		info->zs_chan_a->curregs[5] |= DTR | RTS;
-		write_zsreg(info->zs_chan_a, 5, info->zs_chan_a->curregs[5]);
-		restore_flags(flags);
+		zs_rtsdtr(info, RTS, 1);
 	}
 }
 
@@ -983,7 +1130,7 @@
 	copy_from_user(&new_serial,new_info,sizeof(new_serial));
 	old_info = *info;
 
-	if (!suser()) {
+	if (!capable(CAP_SYS_ADMIN)) {
 		if ((new_serial.baud_base != info->baud_base) ||
 		    (new_serial.type != info->type) ||
 		    (new_serial.close_delay != info->close_delay) ||
@@ -1012,7 +1159,7 @@
 	info->closing_wait = new_serial.closing_wait;
 
 check_and_exit:
-	retval = startup(info);
+	retval = zs_startup(info);
 	return retval;
 }
 
@@ -1039,18 +1186,25 @@
 
 static int get_modem_info(struct dec_serial *info, unsigned int *value)
 {
-	unsigned char control, status;
+	unsigned char control, status_a, status_b;
 	unsigned int result;
 
-	cli();
-	control = info->zs_chan_a->curregs[5];
-	status = read_zsreg(info->zs_channel, 0);
-	sti();
-	result =  ((control & RTS) ? TIOCM_RTS: 0)
-		| ((control & DTR) ? TIOCM_DTR: 0)
-		| ((status  & DCD) ? TIOCM_CAR: 0)
-		| ((status  & CTS) ? 0: TIOCM_CTS);
-	put_user(result,value);
+	if (info->zs_channel == info->zs_chan_a)
+		result = 0;
+	else {
+		cli();
+		control = info->zs_chan_a->curregs[5];
+		status_a = read_zsreg(info->zs_chan_a, 0);
+		status_b = read_zsreg(info->zs_channel, 0);
+		sti();
+		result =  ((control  & RTS) ? TIOCM_RTS: 0)
+			| ((control  & DTR) ? TIOCM_DTR: 0)
+			| ((status_b & DCD) ? TIOCM_CAR: 0)
+			| ((status_a & DCD) ? TIOCM_RNG: 0)
+			| ((status_a & SYNC_HUNT) ? TIOCM_DSR: 0)
+			| ((status_b & CTS) ? TIOCM_CTS: 0);
+	}
+	put_user(result, value);
 	return 0;
 }
 
@@ -1063,6 +1217,10 @@
 	error = verify_area(VERIFY_READ, value, sizeof(int));
 	if (error)
 		return error;
+
+	if (info->zs_channel == info->zs_chan_a)
+		return 0;
+
 	get_user(arg, value);
 	bits = (arg & TIOCM_RTS? RTS: 0) + (arg & TIOCM_DTR? DTR: 0);
 	cli();
@@ -1074,7 +1232,8 @@
 		info->zs_chan_a->curregs[5] &= ~bits;
 		break;
 	case TIOCMSET:
-		info->zs_chan_a->curregs[5] = (info->zs_chan_a->curregs[5] & ~(DTR | RTS)) | bits;
+		info->zs_chan_a->curregs[5] = 
+			(info->zs_chan_a->curregs[5] & ~(DTR | RTS)) | bits;
 		break;
 	default:
 		sti();
@@ -1113,10 +1272,9 @@
 	int error;
 	struct dec_serial * info = (struct dec_serial *)tty->driver_data;
 
-#ifdef CONFIG_KGDB
-	if (info->kgdb_channel)
+	if (info->hook)
 		return -ENODEV;
-#endif
+
 	if (serial_paranoia_check(info, tty->device, "rs_ioctl"))
 		return -ENODEV;
 
@@ -1210,7 +1368,7 @@
 	}
 	
 #ifdef SERIAL_DEBUG_OPEN
-	printk("rs_close ttys%d, count = %d\n", info->line, info->count);
+	printk("rs_close ttyS%02d, count = %d\n", info->line, info->count);
 #endif
 	if ((tty->count == 1) && (info->count != 1)) {
 		/*
@@ -1225,7 +1383,7 @@
 		info->count = 1;
 	}
 	if (--info->count < 0) {
-		printk("rs_close: bad serial port count for ttys%d: %d\n",
+		printk("rs_close: bad serial port count for ttyS%02d: %d\n",
 		       info->line, info->count);
 		info->count = 0;
 	}
@@ -1415,7 +1573,7 @@
 	retval = 0;
 	add_wait_queue(&info->open_wait, &wait);
 #ifdef SERIAL_DEBUG_OPEN
-	printk("block_til_ready before block: ttys%d, count = %d\n",
+	printk("block_til_ready before block: ttyS%02d, count = %d\n",
 	       info->line, info->count);
 #endif
 	cli();
@@ -1427,7 +1585,7 @@
 		cli();
 		if (!(info->flags & ZILOG_CALLOUT_ACTIVE) &&
 		    (tty->termios->c_cflag & CBAUD))
-			zs_rtsdtr(info, 1);
+			zs_rtsdtr(info, RTS | DTR, 1);
 		sti();
 		set_current_state(TASK_INTERRUPTIBLE);
 		if (tty_hung_up_p(filp) ||
@@ -1451,7 +1609,7 @@
 			break;
 		}
 #ifdef SERIAL_DEBUG_OPEN
-		printk("block_til_ready blocking: ttys%d, count = %d\n",
+		printk("block_til_ready blocking: ttyS%02d, count = %d\n",
 		       info->line, info->count);
 #endif
 		schedule();
@@ -1462,7 +1620,7 @@
 		info->count++;
 	info->blocked_open--;
 #ifdef SERIAL_DEBUG_OPEN
-	printk("block_til_ready after blocking: ttys%d, count = %d\n",
+	printk("block_til_ready after blocking: ttyS%02d, count = %d\n",
 	       info->line, info->count);
 #endif
 	if (retval)
@@ -1487,10 +1645,9 @@
 		return -ENODEV;
 	info = zs_soft + line;
 
-#ifdef CONFIG_KGDB
-	if (info->kgdb_channel)
+	if (info->hook)
 		return -ENODEV;
-#endif
+
 	if (serial_paranoia_check(info, tty->device, "rs_open"))
 		return -ENODEV;
 #ifdef SERIAL_DEBUG_OPEN
@@ -1520,7 +1677,7 @@
 	/*
 	 * Start up serial port
 	 */
-	retval = startup(info);
+	retval = zs_startup(info);
 	if (retval)
 		return retval;
 
@@ -1552,7 +1709,7 @@
 	info->pgrp = current->pgrp;
 
 #ifdef SERIAL_DEBUG_OPEN
-	printk("rs_open ttys%d successful...", info->line);
+	printk("rs_open ttyS%02d successful...", info->line);
 #endif
 /* tty->low_latency = 1; */
 	return 0;
@@ -1562,7 +1719,7 @@
 
 static void __init show_serial_version(void)
 {
-	printk("DECstation Z8530 serial driver version 0.03\n");
+	printk("DECstation Z8530 serial driver version 0.05\n");
 }
 
 /*  Initialize Z8530s zs_channels
@@ -1576,7 +1733,7 @@
 	/*
 	 * did we get here by accident?
 	 */
-	if(!IOASIC) {
+	if(!BUS_PRESENT) {
 		printk("Not on JUNKIO machine, skipping probe_sccs\n");
 		return;
 	}
@@ -1587,19 +1744,36 @@
 	 * system_base for this case :-(. HK
 	 */
 	switch(mips_machtype) {
+#ifdef CONFIG_DECSTATION
 	case MACH_DS5000_2X0:
 		system_base = 0xbf800000;
 		n_chips = 2;
+		zs_parms = &ds_parms;
 		break;
 	case MACH_DS5000_1XX:
 		system_base = 0xbc000000;
 		n_chips = 2;
+		zs_parms = &ds_parms;
 		break;
 	case MACH_DS5000_XX:
 		system_base = 0xbc000000;
 		n_chips = 1;
+		zs_parms = &ds_parms;
+		break;
+#endif
+#ifdef CONFIG_BAGET_MIPS
+	case MACH_BAGET202:
+		system_base = UNI_IO_BASE;
+		n_chips = 2;
+		zs_parms = &baget_parms;
+		zs_init_regs[2] = 0x8;
 		break;
+#endif
+	default:
+		panic("zs: unsupported bus");
 	}
+	if (!zs_parms)
+		panic("zs: uninitialized parms");
 
 	pp = &zs_chain;
 
@@ -1610,16 +1784,44 @@
 			/*
 			 * The sccs reside on the high byte of the 16 bit IOBUS
 			 */
-			zs_channels[n_channels].control = (volatile unsigned char *)
-				system_base + (0 == chip ? SCC0 : SCC1) + (0 == channel ? 1 : 9);
-			zs_channels[n_channels].data = zs_channels[n_channels].control + 4;
+			zs_channels[n_channels].control = 
+				(volatile unsigned char *)system_base + 
+			  (0 == chip ? zs_parms->scc0 : zs_parms->scc1) + 
+			  (0 == channel ? zs_parms->channel_a_offset : 
+			                  zs_parms->channel_b_offset);
+			zs_channels[n_channels].data = 
+				zs_channels[n_channels].control + 4;
+
+#ifndef CONFIG_SERIAL_CONSOLE
+			/*
+			 * We're called early and memory managment isn't up, yet.
+			 * Thus check_region would fail.
+			 */
+			if (check_region((unsigned long)
+					 zs_channels[n_channels].control,
+					 ZS_CHAN_IO_SIZE) < 0) {
+				panic("SCC I/O region is not free");
+			}
+			request_region((unsigned long)
+				       zs_channels[n_channels].control,
+				       ZS_CHAN_IO_SIZE, "SCC");
+#endif
 			zs_soft[n_channels].zs_channel = &zs_channels[n_channels];
-			zs_soft[n_channels].irq = SERIAL;
+			zs_soft[n_channels].irq = zs_parms->irq;
 
-			if (0 == channel)
-				zs_soft[n_channels].zs_chan_a = &zs_channels[n_channels+1];
+			/* 
+			 *  Identification of channel A. Location of channel A
+                         *  inside chip depends on mapping of internal address
+			 *  the chip decodes channels by.
+			 *  CHANNEL_A_NR returns either 0 (in case of 
+			 *  DECstations) or 1 (in case of Baget).
+			 */
+			if (CHANNEL_A_NR == channel)
+				zs_soft[n_channels].zs_chan_a = 
+				    &zs_channels[n_channels+1-2*CHANNEL_A_NR];
 			else
-				zs_soft[n_channels].zs_chan_a = &zs_channels[n_channels];
+				zs_soft[n_channels].zs_chan_a = 
+				    &zs_channels[n_channels];
 
 			*pp = &zs_soft[n_channels];
 			pp = &zs_soft[n_channels].zs_next;
@@ -1639,9 +1841,9 @@
 /*	save_and_cli(flags);
 	for (n = 0; n < zs_channels_found; n++) {
 		if (((int)zs_channels[n].control & 0xf) == 1) {
-			write_zsreg(zs_soft[channel].zs_chan_a, R9, FHWRES);
-			udelay(10000);
-			write_zsreg(zs_soft[channel].zs_chan_a, R9, 0);
+			write_zsreg(zs_soft[n].zs_chan_a, R9, FHWRES);
+			mdelay(10);
+			write_zsreg(zs_soft[n].zs_chan_a, R9, 0);
 		}
 		load_zsregs(zs_soft[n].zs_channel, zs_soft[n].zs_channel->curregs);
 	} 
@@ -1655,7 +1857,7 @@
 	unsigned long flags;
 	struct dec_serial *info;
 
-	if(!IOASIC)
+	if(!BUS_PRESENT)
 		return -ENODEV;
 
 	/* Setup base handler, and timer table. */
@@ -1672,7 +1874,11 @@
 
 	memset(&serial_driver, 0, sizeof(struct tty_driver));
 	serial_driver.magic = TTY_DRIVER_MAGIC;
+#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))
+	serial_driver.name = "tts/%d";
+#else
 	serial_driver.name = "ttyS";
+#endif
 	serial_driver.major = TTY_MAJOR;
 	serial_driver.minor_start = 64;
 	serial_driver.num = zs_channels_found;
@@ -1682,7 +1888,7 @@
 
 	serial_driver.init_termios.c_cflag =
 		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-	serial_driver.flags = TTY_DRIVER_REAL_RAW;
+	serial_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
 	serial_driver.refcount = &serial_refcount;
 	serial_driver.table = serial_table;
 	serial_driver.termios = serial_termios;
@@ -1710,7 +1916,11 @@
 	 * major number and the subtype code.
 	 */
 	callout_driver = serial_driver;
+#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))
+	callout_driver.name = "cua/%d";
+#else
 	callout_driver.name = "cua";
+#endif
 	callout_driver.major = TTYAUX_MAJOR;
 	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
 
@@ -1722,36 +1932,26 @@
 	save_flags(flags); cli();
 
 	for (channel = 0; channel < zs_channels_found; ++channel) {
-#ifdef CONFIG_KGDB
-		if (zs_soft[channel].kgdb_channel) {
-			continue;
-		}
-#endif
+		if (zs_soft[channel].hook &&
+		    zs_soft[channel].hook->init_channel)
+			(*zs_soft[channel].hook->init_channel)
+				(&zs_soft[channel]);
+
 		zs_soft[channel].clk_divisor = 16;
 		zs_soft[channel].zs_baud = get_zsbaud(&zs_soft[channel]);
 
-		if (request_irq(SERIAL, rs_interrupt, SA_SHIRQ,
+		if (request_irq(zs_parms->irq, rs_interrupt, SA_SHIRQ,
 				"SCC", &zs_soft[channel]))
 			printk(KERN_ERR "decserial: can't get irq %d\n",
-			       SERIAL);
-
-		/* If console serial line, then enable interrupts. */
-/*		if (zs_soft[channel].is_cons) {
-			write_zsreg(zs_soft[channel].zs_channel, R1,
-				    (EXT_INT_ENAB | INT_ALL_Rx | TxINT_ENAB));
-			write_zsreg(zs_soft[channel].zs_channel, R9,
-				    (VIS | MIE));
-		}
-*/
+			       zs_parms->irq);
 	}
 
 	for (info = zs_chain, i = 0; info; info = info->zs_next, i++)
 	{
-#ifdef CONFIG_KGDB
-		if (info->kgdb_channel) {
+		if (info->hook && info->hook->init_info) {
+			(*info->hook->init_info)(info);
 			continue;
 		}
-#endif
 		info->magic = SERIAL_MAGIC;
 		info->port = (int) info->zs_channel->control;
 		info->line = i;
@@ -1765,13 +1965,18 @@
 		info->blocked_open = 0;
 		info->tqueue.routine = do_softint;
 		info->tqueue.data = info;
-		info->callout_termios =callout_driver.init_termios;
+		info->callout_termios = callout_driver.init_termios;
 		info->normal_termios = serial_driver.init_termios;
 		init_waitqueue_head(&info->open_wait);
 		init_waitqueue_head(&info->close_wait);
-		printk("tty%02d at 0x%08x (irq = %d)", info->line, 
+		printk("ttyS%02d at 0x%08x (irq = %d)", info->line, 
 		       info->port, info->irq);
 		printk(" is a Z85C30 SCC\n");
+		tty_register_devfs(&serial_driver, 0,
+				   serial_driver.minor_start + info->line);
+		tty_register_devfs(&callout_driver, 0,
+				   callout_driver.minor_start + info->line);
+
 	}
 
 	restore_flags(flags);
@@ -1795,38 +2000,116 @@
 }
 
 /*
- * ------------------------------------------------------------
- * Serial console driver
- * ------------------------------------------------------------
+ * polling I/O routines
  */
-#ifdef CONFIG_SERIAL_CONSOLE
+static int
+zs_poll_tx_char(struct dec_serial *info, unsigned char ch)
+{
+	struct dec_zschannel *chan = info->zs_channel;
+	int    ret;
 
+	if(chan) {
+		int loops = 10000;
+//		int nine = read_zsreg(chan, R9);
 
-/*
- *	Print a string to the serial port trying not to disturb
- *	any possible real use of the port...
- */
+		RECOVERY_DELAY;
+//        	write_zsreg(chan, R9, nine & ~MIE);
+               	wbflush();
+		RECOVERY_DELAY;
+
+        	while (!(*(chan->control) & Tx_BUF_EMP) && --loops)
+	        	RECOVERY_DELAY;
+
+                if (loops) {
+                        ret = 0;
+        	        *(chan->data) = ch;
+                	wbflush();
+			RECOVERY_DELAY;
+                } else
+                        ret = -EAGAIN;
+
+//        	write_zsreg(chan, R9, nine);
+               	wbflush();
+		RECOVERY_DELAY;
+
+                return ret;
+        }
 
-/* This is for console output */
-static void
-zs_console_putchar(struct dec_serial *info, char ch)
+	return -ENODEV;
+}
+
+static int
+zs_poll_rx_char(struct dec_serial *info)
 {
-	int loops = 10000;
-	unsigned long flags;
+        struct dec_zschannel *chan = info->zs_channel;
+        int    ret;
 
-	if(!info->zs_channel)
-		return;
+	if(chan) {
+                int loops = 10000;
 
-	save_flags(flags); cli();
+                while((read_zsreg(chan, 0) & Rx_CH_AV) == 0)
+		        loops--;
 
-	while (!(*(info->zs_channel->control) & Tx_BUF_EMP) && --loops)
-		RECOVERY_DELAY;
-	*(info->zs_channel->data) = ch;
-	wbflush(); RECOVERY_DELAY;
+                if (loops)
+                        ret = read_zsdata(chan);
+                else
+                        ret = -EAGAIN;
 
-	restore_flags(flags);
+                return ret;
+        } else
+                return -ENODEV;
+}
+
+unsigned int register_zs_hook(unsigned int channel, struct zs_hook *hook)
+{
+	struct dec_serial *info = &zs_soft[channel];
+
+	if (info->hook) {
+		printk(__FUNCTION__": line %d has already a hook registered\n", channel);
+
+		return 0;
+	} else {
+		info->hook = hook;
+
+		if (zs_chain == 0)
+			probe_sccs();
+
+		if (!(info->flags & ZILOG_INITIALIZED))
+			zs_startup(info);
+
+		hook->poll_rx_char = zs_poll_rx_char;
+		hook->poll_tx_char = zs_poll_tx_char;
+
+		return 1;
+	}
+}
+
+unsigned int unregister_zs_hook(unsigned int channel)
+{
+	struct dec_serial *info = &zs_soft[channel];
+
+        if (info->hook) {
+                info->hook = NULL;
+                return 1;
+        } else {
+                printk(__FUNCTION__": trying to unregister hook on line %d,"
+                       " but none is registered\n", channel);
+                return 0;
+        }
 }
 
+/*
+ * ------------------------------------------------------------
+ * Serial console driver
+ * ------------------------------------------------------------
+ */
+#ifdef CONFIG_SERIAL_CONSOLE
+
+
+/*
+ *	Print a string to the serial port trying not to disturb
+ *	any possible real use of the port...
+ */
 static void serial_console_write(struct console *co, const char *s,
 				 unsigned count)
 {
@@ -1835,28 +2118,11 @@
 
 	info = zs_soft + co->index;
 
-#if 0
-	/*
-	 * disable master interrupt if necessary
-	 */
-	nine = info->zs_channel->curregs[9];
-	if(nine & MIE)
-		write_zsreg(info->zs_channel, R9, nine & ~MIE);
-#endif
-	/*
-	 * do it
-	 */
 	for (i = 0; i < count; i++, s++) {
 		if(*s == '\n')
-			zs_console_putchar(info, '\r');
-		zs_console_putchar(info, *s);
+			zs_poll_tx_char(info, '\r');
+		zs_poll_tx_char(info, *s);
 	}
-	/*
-	 * restore master interrupt enable
-	 */
-#if 0
-	write_zsreg(info->zs_channel, R9, nine);
-#endif
 }
 
 /*
@@ -1864,7 +2130,11 @@
  */
 static int serial_console_wait_key(struct console *co)
 {
-	return 0;
+	struct dec_serial *info;
+
+        info = zs_soft + co->index;
+
+        return zs_poll_rx_char(info);
 }
 
 static kdev_t serial_console_device(struct console *c)
@@ -1888,7 +2158,7 @@
 	char	*s;
 	unsigned long flags;
 
-	if(!IOASIC)
+	if(!BUS_PRESENT)
 		return -ENODEV;
 
 	info = zs_soft + co->index;
@@ -1963,7 +2233,7 @@
 	/*
 	 * Turn on RTS and DTR.
 	 */
-	zs_rtsdtr(info, 1);
+	zs_rtsdtr(info, RTS | DTR, 1);
 
 	/*
 	 * Finally, enable sequencing
@@ -2017,6 +2287,18 @@
 #endif /* ifdef CONFIG_SERIAL_CONSOLE */
 
 #ifdef CONFIG_KGDB
+struct dec_zschannel *zs_kgdbchan;
+static unsigned char scc_inittab[] = {
+	9,  0x80,	/* reset A side (CHRA) */
+	13, 0,		/* set baud rate divisor */
+	12, 1,
+	14, 1,		/* baud rate gen enable, src=rtxc (BRENABL) */
+	11, 0x50,	/* clocks = br gen (RCBR | TCBR) */
+	5,  0x6a,	/* tx 8 bits, assert RTS (Tx8 | TxENAB | RTS) */
+	4,  0x44,	/* x16 clock, 1 stop (SB1 | X16CLK)*/
+	3,  0xc1,	/* rx enable, 8 bits (RxENABLE | Rx8)*/
+};
+
 /* These are for receiving and sending characters under the kgdb
  * source level kernel debugger.
  */
@@ -2051,6 +2333,25 @@
 	write_zsreg(chan, 1, one);
 	write_zsreg(chan, 9, nine);
 }
+
+static int kgdbhook_init_channel(struct dec_serial* info) 
+{
+	return 0;
+}
+
+static void kgdbhook_init_info(struct dec_serial* info)
+{
+}
+
+static void kgdbhook_rx_char(struct dec_serial* info, 
+			     unsigned char ch, unsigned char stat)
+{
+	if (ch == 0x03 || ch == '$')
+		breakpoint();
+	if (stat & (Rx_OVR|FRM_ERR|PAR_ERR))
+		write_zsreg(info->zs_channel, 0, ERR_RES);
+}
+
 /* This sets up the serial port we're using, and turns on
  * interrupts for that channel, so kgdb is usable once we're done.
  */
@@ -2059,7 +2360,7 @@
 	int brg;
 	int i, x;
 	volatile char *sccc = ms->control;
-	brg = BPS_TO_BRG(bps, ZS_CLOCK/16);
+	brg = BPS_TO_BRG(bps, zs_parms->clock/16);
 	printk("setting bps on kgdb line to %d [brg=%x]\n", bps, brg);
 	for (i = 20000; i != 0; --i) {
 		x = *sccc; eieio();
@@ -2074,6 +2375,13 @@
  * for /dev/ttyb which is determined in setup_arch() from the
  * boot command line flags.
  */
+struct zs_hook zs_kgdbhook = {
+	init_channel : kgdbhook_init_channel,
+	init_info    : kgdbhook_init_info,
+	cflags       : B38400|CS8|CLOCAL,
+	rx_char      : kgdbhook_rx_char,
+}
+
 void __init zs_kgdb_hook(int tty_num)
 {
 	/* Find out how many Z8530 SCCs we have */
@@ -2084,11 +2392,12 @@
 	zs_soft[tty_num].change_needed = 0;
 	zs_soft[tty_num].clk_divisor = 16;
 	zs_soft[tty_num].zs_baud = 38400;
-	zs_soft[tty_num].kgdb_channel = 1;     /* This runs kgdb */
-	zs_soft[tty_num ^ 1].kgdb_channel = 0; /* This does not */
+ 	zs_soft[tty_num].hook = &zs_kgdbhook; /* This runs kgdb */
 	/* Turn on transmitter/receiver at 8-bits/char */
         kgdb_chaninit(zs_soft[tty_num].zs_channel, 1, 38400);
 	printk("KGDB: on channel %d initialized\n", tty_num);
 	set_debug_traps(); /* init stub */
 }
 #endif /* ifdef CONFIG_KGDB */
+
+
diff -u --recursive --new-file v2.4.9/linux/drivers/tc/zs.h linux/drivers/tc/zs.h
--- v2.4.9/linux/drivers/tc/zs.h	Sat May 13 08:31:25 2000
+++ linux/drivers/tc/zs.h	Mon Aug 27 08:56:31 2001
@@ -89,6 +89,18 @@
 	unsigned char curregs[NUM_ZSREGS];
 };
 
+struct dec_serial;
+
+struct zs_hook {
+	int (*init_channel)(struct dec_serial* info);
+	void (*init_info)(struct dec_serial* info);
+	void (*rx_char)(unsigned char ch, unsigned char stat);
+	int  (*poll_rx_char)(struct dec_serial* info);
+	int  (*poll_tx_char)(struct dec_serial* info,
+			     unsigned char ch);
+	unsigned cflags;
+};
+
 struct dec_serial {
 	struct dec_serial *zs_next;	/* For IRQ servicing chain */
 	struct dec_zschannel *zs_channel; /* Channel registers */
@@ -97,7 +109,7 @@
 
 	char soft_carrier;  /* Use soft carrier on this channel */
 	char break_abort;   /* Is serial console in, so process brk/abrt */
-	char kgdb_channel;  /* Kgdb is running on this channel */
+	struct zs_hook *hook;  /* Hook on this channel */
 	char is_cons;       /* Is this our console. */
 	unsigned char tx_active; /* character is being xmitted */
 	unsigned char tx_stopped; /* output is suspended */
diff -u --recursive --new-file v2.4.9/linux/drivers/telephony/Config.in linux/drivers/telephony/Config.in
--- v2.4.9/linux/drivers/telephony/Config.in	Wed Dec 29 17:13:59 1999
+++ linux/drivers/telephony/Config.in	Fri Sep  7 09:28:37 2001
@@ -6,4 +6,5 @@
 
 tristate 'Linux telephony support' CONFIG_PHONE
 dep_tristate 'QuickNet Internet LineJack/PhoneJack support' CONFIG_PHONE_IXJ $CONFIG_PHONE
+dep_tristate 'QuickNet Internet LineJack/PhoneJack PCMCIA support' CONFIG_PHONE_IXJ_PCMCIA $CONFIG_PHONE_IXJ
 endmenu
diff -u --recursive --new-file v2.4.9/linux/drivers/telephony/Makefile linux/drivers/telephony/Makefile
--- v2.4.9/linux/drivers/telephony/Makefile	Fri Dec 29 14:07:23 2000
+++ linux/drivers/telephony/Makefile	Fri Sep  7 09:28:37 2001
@@ -10,10 +10,11 @@
 obj-n   :=
 obj-m   :=
 obj-    :=
-export-objs := phonedev.o
+export-objs := phonedev.o ixj.o
 
 obj-$(CONFIG_PHONE) += phonedev.o
 obj-$(CONFIG_PHONE_IXJ) += ixj.o
+obj-$(CONFIG_PHONE_IXJ_PCMCIA) += ixj_pcmcia.o
 
 O_TARGET := telephony.o
 
diff -u --recursive --new-file v2.4.9/linux/drivers/telephony/ixj-ver.h linux/drivers/telephony/ixj-ver.h
--- v2.4.9/linux/drivers/telephony/ixj-ver.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/telephony/ixj-ver.h	Fri Sep  7 09:28:37 2001
@@ -0,0 +1,4 @@
+/* configuration management identifiers */
+#define IXJ_VER_MAJOR 1
+#define IXJ_VER_MINOR 0
+#define IXJ_BLD_VER   1
diff -u --recursive --new-file v2.4.9/linux/drivers/telephony/ixj.c linux/drivers/telephony/ixj.c
--- v2.4.9/linux/drivers/telephony/ixj.c	Mon Aug 27 12:41:45 2001
+++ linux/drivers/telephony/ixj.c	Sun Sep  9 10:52:35 2001
@@ -1,10 +1,12 @@
 /****************************************************************************
  *    ixj.c
  *
- *    Device Driver for the Internet PhoneJACK and
- *    Internet LineJACK Telephony Cards.
+ * Device Driver for Quicknet Technologies, Inc.'s Telephony cards
+ * including the Internet PhoneJACK, Internet PhoneJACK Lite,
+ * Internet PhoneJACK PCI, Internet LineJACK, Internet PhoneCARD and
+ * SmartCABLE
  *
- *    (c) Copyright 1999-2000  Quicknet Technologies, Inc.
+ *    (c) Copyright 1999-2001  Quicknet Technologies, Inc.
  *
  *    This program is free software; you can redistribute it and/or
  *    modify it under the terms of the GNU General Public License
@@ -18,17 +20,17 @@
  *                  John Sellers, <jsellers@quicknet.net>
  *                  Mike Preston, <mpreston@quicknet.net>
  *    
- * Fixes:
- *                  Marc Boucher, <marc@mbsi.ca>
- *		    David Huggins-Daines <dhd@cepstral.com>
- * 
+ * Fixes:           David Huggins-Daines, <dhd@cepstral.com>
+ *                  Fabio Ferrari, <fabio.ferrari@digitro.com.br>
+ *                  Artis Kugevics, <artis@mt.lv>
+ *
  * More information about the hardware related to this driver can be found  
  * at our website:    http://www.quicknet.net
  *
  * IN NO EVENT SHALL QUICKNET TECHNOLOGIES, INC. BE LIABLE TO ANY PARTY FOR
  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF QUICKNET
- * TECHNOLOGIES, INC.HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * TECHNOLOGIES, INC. HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *    
  * QUICKNET TECHNOLOGIES, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
@@ -38,14 +40,215 @@
  *
  ***************************************************************************/
 
-static char ixj_c_rcsid[] = "$Id: ixj.c,v 3.31 2000/04/14 19:24:47 jaugenst Exp $";
-static char ixj_c_revision[] = "$Revision: 3.31 $";
+static char ixj_c_rcsid[] = "$Id: ixj.c,v 4.7 2001/08/13 06:19:33 craigs Exp $";
+static char ixj_c_revision[] = "$Revision: 4.7 $";
 
-//#define PERFMON_STATS
+/*
+ * $Log: ixj.c,v $
+ * Revision 4.7  2001/08/13 06:19:33  craigs
+ * Added additional changes from Alan Cox and John Anderson for
+ * 2.2 to 2.4 cleanup and bounds checking
+ *
+ * Revision 4.6  2001/08/13 01:05:05  craigs
+ * Really fixed PHONE_QUERY_CODEC problem this time
+ *
+ * Revision 4.5  2001/08/13 00:11:03  craigs
+ * Fixed problem in handling of PHONE_QUERY_CODEC, thanks to Shane Anderson
+ *
+ * Revision 4.4  2001/08/07 07:58:12  craigs
+ * Changed back to three digit version numbers
+ * Added tagbuild target to allow automatic and easy tagging of versions
+ *
+ * Revision 4.3  2001/08/07 07:24:47  craigs
+ * Added ixj-ver.h to allow easy configuration management of driver
+ * Added display of version number in /prox/ixj
+ *
+ * Revision 4.2  2001/08/06 07:07:19  craigs
+ * Reverted IXJCTL_DSP_TYPE and IXJCTL_DSP_VERSION files to original
+ * behaviour of returning int rather than short *
+ *
+ * Revision 4.1  2001/08/05 00:17:37  craigs
+ * More changes for correct PCMCIA installation
+ * Start of changes for backward Linux compatibility
+ *
+ * Revision 4.0  2001/08/04 12:33:12  craigs
+ * New version using GNU autoconf
+ *
+ * Revision 3.105  2001/07/20 23:14:32  eokerson
+ * More work on CallerID generation when using ring cadences.
+ *
+ * Revision 3.104  2001/07/06 01:33:55  eokerson
+ * Some bugfixes from Robert Vojta <vojta@ipex.cz> and a few mods to the Makefile.
+ *
+ * Revision 3.103  2001/07/05 19:20:16  eokerson
+ * Updated HOWTO
+ * Changed mic gain to 30dB on Internet LineJACK mic/speaker port.
+ *
+ * Revision 3.102  2001/07/03 23:51:21  eokerson
+ * Un-mute mic on Internet LineJACK when in speakerphone mode.
+ *
+ * Revision 3.101  2001/07/02 19:26:56  eokerson
+ * Removed initialiazation of ixjdebug and ixj_convert_loaded so they will go in the .bss instead of the .data
+ *
+ * Revision 3.100  2001/07/02 19:18:27  eokerson
+ * Changed driver to make dynamic allocation possible.  We now pass IXJ * between functions instead of array indexes.
+ * Fixed the way the POTS and PSTN ports interact during a PSTN call to allow local answering.
+ * Fixed speaker mode on Internet LineJACK.
+ *
+ * Revision 3.99  2001/05/09 14:11:16  eokerson
+ * Fixed kmalloc error in ixj_build_filter_cadence.  Thanks David Chan <cat@waulogy.stanford.edu>.
+ *
+ * Revision 3.98  2001/05/08 19:55:33  eokerson
+ * Fixed POTS hookstate detection while it is connected to PSTN port.
+ *
+ * Revision 3.97  2001/05/08 00:01:04  eokerson
+ * Fixed kernel oops when sending caller ID data.
+ *
+ * Revision 3.96  2001/05/04 23:09:30  eokerson
+ * Now uses one kernel timer for each card, instead of one for the entire driver.
+ *
+ * Revision 3.95  2001/04/25 22:06:47  eokerson
+ * Fixed squawking at beginning of some G.723.1 calls.
+ *
+ * Revision 3.94  2001/04/03 23:42:00  eokerson
+ * Added linear volume ioctls
+ * Added raw filter load ioctl
+ *
+ * Revision 3.93  2001/02/27 01:00:06  eokerson
+ * Fixed blocking in CallerID.
+ * Reduced size of ixj structure for smaller driver footprint.
+ *
+ * Revision 3.92  2001/02/20 22:02:59  eokerson
+ * Fixed isapnp and pcmcia module compatibility for 2.4.x kernels.
+ * Improved PSTN ring detection.
+ * Fixed wink generation on POTS ports.
+ *
+ * Revision 3.91  2001/02/13 00:55:44  eokerson
+ * Turn AEC back on after changing frame sizes.
+ *
+ * Revision 3.90  2001/02/12 16:42:00  eokerson
+ * Added ALAW codec, thanks to Fabio Ferrari for the table based converters to make ALAW from ULAW.
+ *
+ * Revision 3.89  2001/02/12 15:41:16  eokerson
+ * Fix from Artis Kugevics - Tone gains were not being set correctly.
+ *
+ * Revision 3.88  2001/02/05 23:25:42  eokerson
+ * Fixed lockup bugs with deregister.
+ *
+ * Revision 3.87  2001/01/29 21:00:39  eokerson
+ * Fix from Fabio Ferrari <fabio.ferrari@digitro.com.br> to properly handle EAGAIN and EINTR during non-blocking write.
+ * Updated copyright date.
+ *
+ * Revision 3.86  2001/01/23 23:53:46  eokerson
+ * Fixes to G.729 compatibility.
+ *
+ * Revision 3.85  2001/01/23 21:30:36  eokerson
+ * Added verbage about cards supported.
+ * Removed commands that put the card in low power mode at some times that it should not be in low power mode.
+ *
+ * Revision 3.84  2001/01/22 23:32:10  eokerson
+ * Some bugfixes from David Huggins-Daines, <dhd@cepstral.com> and other cleanups.
+ *
+ * Revision 3.83  2001/01/19 14:51:41  eokerson
+ * Fixed ixj_WriteDSPCommand to decrement usage counter when command fails.
+ *
+ * Revision 3.82  2001/01/19 00:34:49  eokerson
+ * Added verbosity to write overlap errors.
+ *
+ * Revision 3.81  2001/01/18 23:56:54  eokerson
+ * Fixed PSTN line test functions.
+ *
+ * Revision 3.80  2001/01/18 22:29:27  eokerson
+ * Updated AEC/AGC values for different cards.
+ *
+ * Revision 3.79  2001/01/17 02:58:54  eokerson
+ * Fixed AEC reset after Caller ID.
+ * Fixed Codec lockup after Caller ID on Call Waiting when not using 30ms frames.
+ *
+ * Revision 3.78  2001/01/16 19:43:09  eokerson
+ * Added support for Linux 2.4.x kernels.
+ *
+ * Revision 3.77  2001/01/09 04:00:52  eokerson
+ * Linetest will now test the line, even if it has previously succeded.
+ *
+ * Revision 3.76  2001/01/08 19:27:00  eokerson
+ * Fixed problem with standard cable on Internet PhoneCARD.
+ *
+ * Revision 3.75  2000/12/22 16:52:14  eokerson
+ * Modified to allow hookstate detection on the POTS port when the PSTN port is selected.
+ *
+ * Revision 3.74  2000/12/08 22:41:50  eokerson
+ * Added capability for G729B.
+ *
+ * Revision 3.73  2000/12/07 23:35:16  eokerson
+ * Added capability to have different ring pattern before CallerID data.
+ * Added hookstate checks in CallerID routines to stop FSK.
+ *
+ * Revision 3.72  2000/12/06 19:31:31  eokerson
+ * Modified signal behavior to only send one signal per event.
+ *
+ * Revision 3.71  2000/12/06 03:23:08  eokerson
+ * Fixed CallerID on Call Waiting.
+ *
+ * Revision 3.70  2000/12/04 21:29:37  eokerson
+ * Added checking to Smart Cable gain functions.
+ *
+ * Revision 3.69  2000/12/04 21:05:20  eokerson
+ * Changed ixjdebug levels.
+ * Added ioctls to change gains in Internet Phone CARD Smart Cable.
+ *
+ * Revision 3.68  2000/12/04 00:17:21  craigs
+ * Changed mixer voice gain to +6dB rather than 0dB
+ *
+ * Revision 3.67  2000/11/30 21:25:51  eokerson
+ * Fixed write signal errors.
+ *
+ * Revision 3.66  2000/11/29 22:42:44  eokerson
+ * Fixed PSTN ring detect problems.
+ *
+ * Revision 3.65  2000/11/29 07:31:55  craigs
+ * Added new 425Hz filter co-efficients
+ * Added card-specific DTMF prescaler initialisation
+ *
+ * Revision 3.64  2000/11/28 14:03:32  craigs
+ * Changed certain mixer initialisations to be 0dB rather than 12dB
+ * Added additional information to /proc/ixj
+ *
+ * Revision 3.63  2000/11/28 11:38:41  craigs
+ * Added display of AEC modes in AUTO and AGC mode
+ *
+ * Revision 3.62  2000/11/28 04:05:44  eokerson
+ * Improved PSTN ring detection routine.
+ *
+ * Revision 3.61  2000/11/27 21:53:12  eokerson
+ * Fixed flash detection.
+ *
+ * Revision 3.60  2000/11/27 15:57:29  eokerson
+ * More work on G.729 load routines.
+ *
+ * Revision 3.59  2000/11/25 21:55:12  eokerson
+ * Fixed errors in G.729 load routine.
+ *
+ * Revision 3.58  2000/11/25 04:08:29  eokerson
+ * Added board locks around G.729 and TS85 load routines.
+ *
+ * Revision 3.57  2000/11/24 05:35:17  craigs
+ * Added ability to retrieve mixer values on LineJACK
+ * Added complete initialisation of all mixer values at startup
+ * Fixed spelling mistake
+ *
+ * Revision 3.56  2000/11/23 02:52:11  robertj
+ * Added cvs change log keyword.
+ * Fixed bug in capabilities list when using G.729 module.
+ *
+ */
+
+#include "ixj-ver.h"
+
+#define PERFMON_STATS
 #define IXJDEBUG 0
 #define MAXRINGS 5
 
-#include <linux/config.h>
 #include <linux/module.h>
 
 #include <linux/init.h>
@@ -68,34 +271,128 @@
 #include <asm/segment.h>
 #include <asm/uaccess.h>
 
-#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE)
-#include <pcmcia/version.h>
-#include <pcmcia/cs_types.h>
-#include <pcmcia/cs.h>
-#include <pcmcia/cistpl.h>
-#include <pcmcia/ds.h>
-#endif
-
-#ifdef CONFIG_ISAPNP
 #include <linux/isapnp.h>
-#endif
 
 #include "ixj.h"
 
 #define TYPE(dev) (MINOR(dev) >> 4)
 #define NUM(dev) (MINOR(dev) & 0xf)
 
-static int ixjdebug = 0;
+static int ixjdebug;
 static int hertz = HZ;
 static int samplerate = 100;
 
 MODULE_PARM(ixjdebug, "i");
 
-static IXJ* ixj[IXJMAX];
+/************************************************************************
+*
+* ixjdebug meanings are now bit mapped instead of level based
+* Values can be or'ed together to turn on multiple messages
+*
+* bit  0 (0x0001) = any failure
+* bit  1 (0x0002) = general messages
+* bit  2 (0x0004) = POTS ringing related
+* bit  3 (0x0008) = PSTN events
+* bit  4 (0x0010) = PSTN Cadence state details
+* bit  5 (0x0020) = Tone detection triggers
+* bit  6 (0x0040) = Tone detection cadence details
+* bit  7 (0x0080) = ioctl tracking
+* bit  8 (0x0100) = signal tracking
+* bit  9 (0x0200) = CallerID generation details
+*
+************************************************************************/
+
+#ifdef IXJ_DYN_ALLOC
 
-static struct timer_list ixj_timer;
+static IXJ *ixj[IXJMAX];
+#define	get_ixj(b)	ixj[(b)]
 
-int ixj_convert_loaded = 0;
+/*
+ *	Allocate a free IXJ device
+ */
+ 
+static IXJ *ixj_alloc()
+{
+	for(cnt=0; cnt<IXJMAX; cnt++)
+	{
+		if(ixj[cnt] == NULL || !ixj[cnt]->DSPbase)
+		{
+			j = kmalloc(sizeof(IXJ), GFP_KERNEL);
+			if (j == NULL)
+				return NULL;
+			ixj[cnt] = j;
+			return j;
+		}
+	}
+	return NULL;
+}
+
+static void ixj_fsk_free(IXJ *j)
+{
+	if(j->fskdata != NULL) {
+		kfree(j->fskdata);
+		j->fskdata = NULL;
+	}
+}
+
+static void ixj_fsk_alloc(IXJ *j)
+{
+	if(!j->fskdata) {
+		j->fskdata = kmalloc(8000, GFP_KERNEL);
+		if (!j->fskdata) {
+			if(ixjdebug & 0x0200) {
+				printk("IXJ phone%d - allocate failed\n", j->board);
+			}
+			return;
+		} else {
+			j->fsksize = 8000;
+			if(ixjdebug & 0x0200) {
+				printk("IXJ phone%d - allocate succeded\n", j->board);
+			}
+		}
+	}
+}
+
+#else
+
+static IXJ ixj[IXJMAX];
+#define	get_ixj(b)	(&ixj[(b)])
+
+/*
+ *	Allocate a free IXJ device
+ */
+ 
+static IXJ *ixj_alloc(void)
+{
+	int cnt;
+	for(cnt=0; cnt<IXJMAX; cnt++)
+	{
+		if(!ixj[cnt].DSPbase)
+		{
+			return &ixj[cnt];
+		}
+	}
+	return NULL;
+}
+
+static inline void ixj_fsk_free(IXJ *j) {;}
+
+static inline void ixj_fsk_alloc(IXJ *j)
+{
+	j->fsksize = 8000;
+}
+
+#endif
+
+#ifdef PERFMON_STATS
+#define ixj_perfmon(x)	((x)++)
+#else
+#deifne ixj_perfmon(x)	do {} while(0);
+#endif
+
+static int ixj_convert_loaded;
+
+static int ixj_WriteDSPCommand(unsigned short, IXJ *j);
 
 /************************************************************************
 *
@@ -104,7 +401,7 @@
 *
 ************************************************************************/
 
-static int Stub(IXJ * j, unsigned long arg)
+static int Stub(IXJ * J, unsigned long arg)
 {
 	return 0;
 }
@@ -120,8 +417,8 @@
 
 static void ixj_read_frame(IXJ *j);
 static void ixj_write_frame(IXJ *j);
-static void ixj_init_timer(void);
-static void ixj_add_timer(void);
+static void ixj_init_timer(IXJ *j);
+static void ixj_add_timer(IXJ *	j);
 static void ixj_timeout(unsigned long ptr);
 static int read_filters(IXJ *j);
 static int LineMonitor(IXJ *j);
@@ -132,12 +429,15 @@
 static int ixj_record_start(IXJ *j);
 static void ixj_record_stop(IXJ *j);
 static void set_rec_volume(IXJ *j, int volume);
+static int get_rec_volume(IXJ *j);
+static int set_rec_codec(IXJ *j, int rate);
 static void ixj_vad(IXJ *j, int arg);
 static int ixj_play_start(IXJ *j);
 static void ixj_play_stop(IXJ *j);
 static int ixj_set_tone_on(unsigned short arg, IXJ *j);
 static int ixj_set_tone_off(unsigned short, IXJ *j);
 static int ixj_play_tone(IXJ *j, char tone);
+static void ixj_aec_start(IXJ *j, int level);
 static int idle(IXJ *j);
 static void ixj_ring_on(IXJ *j);
 static void ixj_ring_off(IXJ *j);
@@ -147,6 +447,7 @@
 static void ixj_dialtone(IXJ *j);
 static void ixj_cpt_stop(IXJ *j);
 static char daa_int_read(IXJ *j);
+static char daa_CR_read(IXJ *j, int cr);
 static int daa_set_mode(IXJ *j, int mode);
 static int ixj_linetest(IXJ *j);
 static int ixj_daa_write(IXJ *j);
@@ -158,22 +459,24 @@
 static void DAA_Coeff_Australia(IXJ *j);
 static void DAA_Coeff_Japan(IXJ *j);
 static int ixj_init_filter(IXJ *j, IXJ_FILTER * jf);
+static int ixj_init_filter_raw(IXJ *j, IXJ_FILTER_RAW * jfr);
 static int ixj_init_tone(IXJ *j, IXJ_TONE * ti);
 static int ixj_build_cadence(IXJ *j, IXJ_CADENCE * cp);
 static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE * cp);
-// Serial Control Interface funtions
+/* Serial Control Interface funtions */
 static int SCI_Control(IXJ *j, int control);
 static int SCI_Prepare(IXJ *j);
 static int SCI_WaitHighSCI(IXJ *j);
 static int SCI_WaitLowSCI(IXJ *j);
 static DWORD PCIEE_GetSerialNumber(WORD wAddress);
 static int ixj_PCcontrol_wait(IXJ *j);
+static void ixj_pre_cid(IXJ *j);
 static void ixj_write_cid(IXJ *j);
 static void ixj_write_cid_bit(IXJ *j, int bit);
 static int set_base_frame(IXJ *j, int size);
 static int set_play_codec(IXJ *j, int rate);
 static void set_rec_depth(IXJ *j, int depth);
-static void set_play_depth(IXJ *j, int depth);
+static int ixj_mixer(long val, IXJ *j);
 
 /************************************************************************
 CT8020/CT8021 Host Programmers Model
@@ -186,58 +489,95 @@
 8-9		Hardware Status Register			Read Only
 A-B		Hardware Control Register			Read Write
 C-D Host Transmit (Write) Data Buffer Access Port (buffer input)Write Only
-E-F Host Receive (Read) Data Buffer Access Port (buffer input)	Read Only
+E-F Host Recieve (Read) Data Buffer Access Port (buffer input)	Read Only
 ************************************************************************/
 
-extern __inline__ void ixj_read_HSR(IXJ *j)
+static inline void ixj_read_HSR(IXJ *j)
 {
 	j->hsr.bytes.low = inb_p(j->DSPbase + 8);
 	j->hsr.bytes.high = inb_p(j->DSPbase + 9);
 }
 
-extern __inline__ int IsControlReady(IXJ *j)
+static inline int IsControlReady(IXJ *j)
 {
 	ixj_read_HSR(j);
 	return j->hsr.bits.controlrdy ? 1 : 0;
 }
 
-extern __inline__ int IsPCControlReady(IXJ *j)
+static inline int IsPCControlReady(IXJ *j)
 {
 	j->pccr1.byte = inb_p(j->XILINXbase + 3);
 	return j->pccr1.bits.crr ? 1 : 0;
 }
 
-extern __inline__ int IsStatusReady(IXJ *j)
+static inline int IsStatusReady(IXJ *j)
 {
 	ixj_read_HSR(j);
 	return j->hsr.bits.statusrdy ? 1 : 0;
 }
 
-extern __inline__ int IsRxReady(IXJ *j)
+static inline int IsRxReady(IXJ *j)
 {
 	ixj_read_HSR(j);
-#ifdef PERFMON_STATS
-	++j->rxreadycheck;
-#endif
+	ixj_perfmon(j->rxreadycheck);
 	return j->hsr.bits.rxrdy ? 1 : 0;
 }
 
-extern __inline__ int IsTxReady(IXJ *j)
+static inline int IsTxReady(IXJ *j)
 {
 	ixj_read_HSR(j);
-#ifdef PERFMON_STATS
-	++j->txreadycheck;
-#endif
+	ixj_perfmon(j->txreadycheck);
 	return j->hsr.bits.txrdy ? 1 : 0;
 }
 
-extern __inline__ void set_play_volume(IXJ *j, int volume)
+static inline void set_play_volume(IXJ *j, int volume)
 {
+	if (ixjdebug & 0x0002)
+		printk(KERN_INFO "IXJ: /dev/phone%d Setting Play Volume to 0x%4.4x\n", j->board, volume);
 	ixj_WriteDSPCommand(0xCF02, j);
 	ixj_WriteDSPCommand(volume, j);
 }
 
-extern __inline__ void set_play_depth(IXJ *j, int depth)
+static int set_play_volume_linear(IXJ *j, int volume)
+{
+	int newvolume, dspplaymax;
+
+	if (ixjdebug & 0x0002)
+		printk(KERN_INFO "IXJ: /dev/phone %d Setting Linear Play Volume to 0x%4.4x\n", j->board, volume);
+	if(volume > 100 || volume < 0) {
+		return -1;
+	}
+
+	/* This should normalize the perceived volumes between the different cards caused by differences in the hardware */
+	switch (j->cardtype) {
+	case QTI_PHONEJACK:
+		dspplaymax = 0x380;
+		break;
+	case QTI_LINEJACK:
+		if(j->port == PORT_PSTN) {
+			dspplaymax = 0x48;
+		} else {
+			dspplaymax = 0x100;
+		}
+		break;
+	case QTI_PHONEJACK_LITE:
+		dspplaymax = 0x380;
+		break;
+	case QTI_PHONEJACK_PCI:
+		dspplaymax = 0x6C;
+		break;
+	case QTI_PHONECARD:
+		dspplaymax = 0x50;
+		break;
+	default:
+		return -1;
+	}
+	newvolume = (dspplaymax * volume) / 100;
+	set_play_volume(j, newvolume);
+	return 0;
+}
+
+static inline void set_play_depth(IXJ *j, int depth)
 {
 	if (depth > 60)
 		depth = 60;
@@ -246,13 +586,48 @@
 	ixj_WriteDSPCommand(0x5280 + depth, j);
 }
 
-extern __inline__ int get_play_volume(IXJ *j)
+static inline int get_play_volume(IXJ *j)
 {
 	ixj_WriteDSPCommand(0xCF00, j);
 	return j->ssr.high << 8 | j->ssr.low;
 }
 
-extern __inline__ BYTE SLIC_GetState(IXJ *j)
+static int get_play_volume_linear(IXJ *j)
+{
+	int volume, newvolume, dspplaymax;
+
+	/* This should normalize the perceived volumes between the different cards caused by differences in the hardware */
+	switch (j->cardtype) {
+	case QTI_PHONEJACK:
+		dspplaymax = 0x380;
+		break;
+	case QTI_LINEJACK:
+		if(j->port == PORT_PSTN) {
+			dspplaymax = 0x48;
+		} else {
+			dspplaymax = 0x100;
+		}
+		break;
+	case QTI_PHONEJACK_LITE:
+		dspplaymax = 0x380;
+		break;
+	case QTI_PHONEJACK_PCI:
+		dspplaymax = 0x6C;
+		break;
+	case QTI_PHONECARD:
+		dspplaymax = 100;
+		break;
+	default:
+		return -1;
+	}
+	volume = get_play_volume(j);
+	newvolume = (volume * 100) / dspplaymax;
+	if(newvolume > 100)
+		newvolume = 100;
+	return newvolume;
+}
+
+static inline BYTE SLIC_GetState(IXJ *j)
 {
 	if (j->cardtype == QTI_PHONECARD) {
 		j->pccr1.byte = 0;
@@ -295,7 +670,7 @@
 					fRetVal = TRUE;
 				}
 				break;
-			case PLD_SLIC_STATE_OHT:	// On-hook transmit
+			case PLD_SLIC_STATE_OHT:	/* On-hook transmit */
 
 			case PLD_SLIC_STATE_STANDBY:
 			case PLD_SLIC_STATE_ACTIVE:
@@ -307,9 +682,9 @@
 				j->pslic.bits.ring0 = j->pslic.bits.ring1 = 0;
 				fRetVal = TRUE;
 				break;
-			case PLD_SLIC_STATE_APR:	// Active polarity reversal
+			case PLD_SLIC_STATE_APR:	/* Active polarity reversal */
 
-			case PLD_SLIC_STATE_OHTPR:	// OHT polarity reversal
+			case PLD_SLIC_STATE_OHTPR:	/* OHT polarity reversal */
 
 			default:
 				fRetVal = FALSE;
@@ -321,7 +696,7 @@
 			ixj_PCcontrol_wait(j);
 		}
 	} else {
-		// Set the C1, C2, C3 & B2EN signals.
+		/* Set the C1, C2, C3 & B2EN signals. */
 		switch (byState) {
 		case PLD_SLIC_STATE_OC:
 			j->pld_slicw.bits.c1 = 0;
@@ -347,7 +722,7 @@
 			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
 			fRetVal = TRUE;
 			break;
-		case PLD_SLIC_STATE_OHT:	// On-hook transmit
+		case PLD_SLIC_STATE_OHT:	/* On-hook transmit */
 
 			j->pld_slicw.bits.c1 = 1;
 			j->pld_slicw.bits.c2 = 1;
@@ -372,7 +747,7 @@
 			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
 			fRetVal = TRUE;
 			break;
-		case PLD_SLIC_STATE_APR:	// Active polarity reversal
+		case PLD_SLIC_STATE_APR:	/* Active polarity reversal */
 
 			j->pld_slicw.bits.c1 = 0;
 			j->pld_slicw.bits.c2 = 1;
@@ -381,7 +756,7 @@
 			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
 			fRetVal = TRUE;
 			break;
-		case PLD_SLIC_STATE_OHTPR:	// OHT polarity reversal
+		case PLD_SLIC_STATE_OHTPR:	/* OHT polarity reversal */
 
 			j->pld_slicw.bits.c1 = 1;
 			j->pld_slicw.bits.c2 = 1;
@@ -399,22 +774,52 @@
 	return fRetVal;
 }
 
-int ixj_register(int index, IXJ_REGFUNC regfunc)
+static int ixj_wink(IXJ *j)
+{
+	BYTE slicnow;
+
+	slicnow = SLIC_GetState(j);
+
+	j->pots_winkstart = jiffies;
+	SLIC_SetState(PLD_SLIC_STATE_OC, j);
+
+	while (time_before(jiffies, j->pots_winkstart + j->winktime)) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(1);
+	}
+
+	SLIC_SetState(slicnow, j);
+	return 0;
+}
+
+static int ixj_register(int index, IXJ_REGFUNC regfunc)
 {
 	int cnt;
 	int retval = 0;
 	switch (index) {
 	case G729LOADER:
 		ixj_DownloadG729 = regfunc;
-		for (cnt = 0; cnt < IXJMAX; cnt++)
-			if (ixj[cnt] != NULL)
-				ixj_DownloadG729(ixj[cnt], 0L);
+		for (cnt = 0; cnt < IXJMAX; cnt++) {
+			IXJ *j = get_ixj(cnt);
+			while(test_and_set_bit(cnt, (void *)&j->busyflags) != 0) {
+				set_current_state(TASK_INTERRUPTIBLE);
+				schedule_timeout(1);
+			}
+			ixj_DownloadG729(j, 0L);
+			clear_bit(cnt, &j->busyflags);
+		}
 		break;
 	case TS85LOADER:
 		ixj_DownloadTS85 = regfunc;
-		for (cnt = 0; cnt < IXJMAX; cnt++)
-			if (ixj[cnt] != NULL)
-				ixj_DownloadTS85(ixj[cnt], 0L);
+		for (cnt = 0; cnt < IXJMAX; cnt++) {
+			IXJ *j = get_ixj(cnt);
+			while(test_and_set_bit(cnt, (void *)&j->busyflags) != 0) {
+				set_current_state(TASK_INTERRUPTIBLE);
+				schedule_timeout(1);
+			}
+			ixj_DownloadTS85(j, 0L);
+			clear_bit(cnt, &j->busyflags);
+		}
 		break;
 	case PRE_READ:
 		ixj_PreRead = regfunc;
@@ -440,7 +845,9 @@
 	return retval;
 }
 
-int ixj_unregister(int index)
+EXPORT_SYMBOL(ixj_register);
+
+static int ixj_unregister(int index)
 {
 	int retval = 0;
 	switch (index) {
@@ -474,17 +881,19 @@
 	return retval;
 }
 
-static void ixj_init_timer(void)
+EXPORT_SYMBOL(ixj_unregister);
+
+static void ixj_init_timer(IXJ *j)
 {
-	init_timer(&ixj_timer);
-	ixj_timer.function = ixj_timeout;
-	ixj_timer.data = (int) NULL;
+	init_timer(&j->timer);
+	j->timer.function = ixj_timeout;
+	j->timer.data = (unsigned long)j;
 }
 
-static void ixj_add_timer(void)
+static void ixj_add_timer(IXJ *j)
 {
-	ixj_timer.expires = jiffies + (hertz / samplerate);
-	add_timer(&ixj_timer);
+	j->timer.expires = jiffies + (hertz / samplerate);
+	add_timer(&j->timer);
 }
 
 static void ixj_tone_timeout(IXJ *j)
@@ -537,268 +946,573 @@
 	}
 }
 
-extern __inline__ void ixj_kill_fasync(IXJ *j, int band)
+static inline void ixj_kill_fasync(IXJ *j, IXJ_SIGEVENT event, int dir)
 {
-	kill_fasync(&j->async_queue, SIGIO, band);
+	if(j->ixj_signals[event]) {
+		if(ixjdebug & 0x0100)
+			printk("Sending signal for event %d\n", event);
+			/* Send apps notice of change */
+		/* see config.h for macro definition */
+		kill_fasync(&(j->async_queue), j->ixj_signals[event], dir);
+	}
 }
 
-static void ixj_timeout(unsigned long ptr)
+static void ixj_pstn_state(IXJ *j)
 {
-	int board;
-	unsigned long jifon;
+	int var;
+	union XOPXR0 XR0, daaint;
 
-	for (board = 0; board < IXJMAX; board++) {
-		IXJ *j = ixj[board];
+	var = 10;
 
-		if (j == NULL)
-			continue;
+	XR0.reg = j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.reg;
+	daaint.reg = 0;
+	XR0.bitreg.RMR = j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.bitreg.RMR;
 
-		if (j->DSPbase) {
-#ifdef PERFMON_STATS
-			j->timerchecks++;
-#endif
-			if (j->tone_state) {
-				if (!ixj_hookstate(j)) {
-					ixj_cpt_stop(j);
-					if (j->m_hook) {
-						j->m_hook = 0;
-						j->ex.bits.hookstate = 1;
-						ixj_kill_fasync(j, POLL_PRI);
+	j->pld_scrr.byte = inb_p(j->XILINXbase);
+	if (j->pld_scrr.bits.daaflag) {
+		daa_int_read(j);
+		if(j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.RING) {
+			if(time_after(jiffies, j->pstn_sleeptil) && !(j->flags.pots_pstn && j->hookstate)) {
+				daaint.bitreg.RING = 1;
+				if(ixjdebug & 0x0008) {
+					printk(KERN_INFO "IXJ DAA Ring Interrupt /dev/phone%d at %ld\n", j->board, jiffies);
+				}
+			} else {
+				daa_set_mode(j, SOP_PU_RESET);
+			}
+		}
+		if(j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.Caller_ID) {
+			daaint.bitreg.Caller_ID = 1;
+			j->pstn_cid_intr = 1;
+			j->pstn_cid_received = jiffies;
+			if(ixjdebug & 0x0008) {
+				printk(KERN_INFO "IXJ DAA Caller_ID Interrupt /dev/phone%d at %ld\n", j->board, jiffies);
+			}
+		}
+		if(j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.Cadence) {
+			daaint.bitreg.Cadence = 1;
+			if(ixjdebug & 0x0008) {
+				printk(KERN_INFO "IXJ DAA Cadence Interrupt /dev/phone%d at %ld\n", j->board, jiffies);
+			}
+		}
+		if(j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK != XR0.bitreg.VDD_OK) {
+			daaint.bitreg.VDD_OK = 1;
+			daaint.bitreg.SI_0 = j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK;
+		}
+	}
+	daa_CR_read(j, 1);
+	if(j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.bitreg.RMR != XR0.bitreg.RMR && time_after(jiffies, j->pstn_sleeptil) && !(j->flags.pots_pstn && j->hookstate)) {
+		daaint.bitreg.RMR = 1;
+		daaint.bitreg.SI_1 = j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.bitreg.RMR;
+		if(ixjdebug & 0x0008) {
+                        printk(KERN_INFO "IXJ DAA RMR /dev/phone%d was %s for %ld\n", j->board, XR0.bitreg.RMR?"on":"off", jiffies - j->pstn_last_rmr);
+		}
+		j->pstn_prev_rmr = j->pstn_last_rmr;
+		j->pstn_last_rmr = jiffies;
+	}
+	switch(j->daa_mode) {
+		case SOP_PU_SLEEP:
+			if (daaint.bitreg.RING) {
+				if (!j->flags.pstn_ringing) {
+					if (j->daa_mode != SOP_PU_RINGING) {
+						j->pstn_ring_int = jiffies;
+						daa_set_mode(j, SOP_PU_RINGING);
 					}
-					continue;
 				}
-				if (j->tone_state == 1)
-					jifon = (hertz * j->tone_on_time * 25 / 100000);
-				else
-					jifon = (hertz * j->tone_on_time * 25 / 100000) +
-					    (hertz * j->tone_off_time * 25 / 100000);
-				if (time_before(jiffies, j->tone_start_jif + jifon)) {
-					if (j->tone_state == 1) {
-						ixj_play_tone(j, j->tone_index);
-						if (j->dsp.low == 0x20) {
-							continue;
+			}
+			break;
+		case SOP_PU_RINGING:
+			if (daaint.bitreg.RMR) {
+				if (ixjdebug & 0x0008) {
+					printk(KERN_INFO "IXJ Ring Cadence a state = %d /dev/phone%d at %ld\n", j->cadence_f[4].state, j->board, jiffies);
+				}
+				if (daaint.bitreg.SI_1) {                /* Rising edge of RMR */
+					j->flags.pstn_rmr = 1;
+					j->pstn_ring_start = jiffies;
+					j->pstn_ring_stop = 0;
+					j->ex.bits.pstn_ring = 0;
+					if (j->cadence_f[4].state == 0) {
+						j->cadence_f[4].state = 1;
+						j->cadence_f[4].on1min = jiffies + (long)((j->cadence_f[4].on1 * hertz * (100 - var)) / 10000);
+						j->cadence_f[4].on1dot = jiffies + (long)((j->cadence_f[4].on1 * hertz * (100)) / 10000);
+						j->cadence_f[4].on1max = jiffies + (long)((j->cadence_f[4].on1 * hertz * (100 + var)) / 10000);
+					} else if (j->cadence_f[4].state == 2) {
+						if((time_after(jiffies, j->cadence_f[4].off1min) &&
+						    time_before(jiffies, j->cadence_f[4].off1max))) {
+							if (j->cadence_f[4].on2) {
+								j->cadence_f[4].state = 3;
+								j->cadence_f[4].on2min = jiffies + (long)((j->cadence_f[4].on2 * (hertz * (100 - var)) / 10000));
+								j->cadence_f[4].on2dot = jiffies + (long)((j->cadence_f[4].on2 * (hertz * (100)) / 10000));
+								j->cadence_f[4].on2max = jiffies + (long)((j->cadence_f[4].on2 * (hertz * (100 + var)) / 10000));
+							} else {
+								j->cadence_f[4].state = 7;
+							}
+						} else {
+							if (ixjdebug & 0x0008) {
+								printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n",
+										j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr,
+										j->cadence_f[4].off1);
+							}
+							j->cadence_f[4].state = 0;
 						}
-					} else {
-						ixj_play_tone(j, 0);
-						if (j->dsp.low == 0x20) {
-							continue;
+					} else if (j->cadence_f[4].state == 4) {
+						if((time_after(jiffies, j->cadence_f[4].off2min) &&
+						    time_before(jiffies, j->cadence_f[4].off2max))) {
+							if (j->cadence_f[4].on3) {
+								j->cadence_f[4].state = 5;
+								j->cadence_f[4].on3min = jiffies + (long)((j->cadence_f[4].on3 * (hertz * (100 - var)) / 10000));
+								j->cadence_f[4].on3dot = jiffies + (long)((j->cadence_f[4].on3 * (hertz * (100)) / 10000));
+								j->cadence_f[4].on3max = jiffies + (long)((j->cadence_f[4].on3 * (hertz * (100 + var)) / 10000));
+							} else {
+								j->cadence_f[4].state = 7;
+							}
+						} else {
+							if (ixjdebug & 0x0008) {
+								printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n",
+										j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr,
+										j->cadence_f[4].off2);
+							}
+							j->cadence_f[4].state = 0;
 						}
-					}
-				} else {
-					ixj_tone_timeout(j);
-					if (j->flags.dialtone) {
-						ixj_dialtone(j);
-					}
-					if (j->flags.busytone) {
-						ixj_busytone(j);
-						if (j->dsp.low == 0x20) {
-							continue;
+					} else if (j->cadence_f[4].state == 6) {
+						if((time_after(jiffies, j->cadence_f[4].off3min) &&
+						    time_before(jiffies, j->cadence_f[4].off3max))) {
+							j->cadence_f[4].state = 7;
+						} else {
+							if (ixjdebug & 0x0008) {
+								printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n",
+										j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr,
+										j->cadence_f[4].off3);
+							}
+							j->cadence_f[4].state = 0;
 						}
+					} else {
+						j->cadence_f[4].state = 0;
 					}
-					if (j->flags.ringback) {
-						ixj_ringback(j);
-						if (j->dsp.low == 0x20) {
-							continue;
+				} else {                                /* Falling edge of RMR */
+					j->pstn_ring_start = 0;
+					j->pstn_ring_stop = jiffies;
+					if (j->cadence_f[4].state == 1) {
+						if(!j->cadence_f[4].on1) {
+							j->cadence_f[4].state = 7;
+						} else if((time_after(jiffies, j->cadence_f[4].on1min) &&
+					          time_before(jiffies, j->cadence_f[4].on1max))) {
+							if (j->cadence_f[4].off1) {
+								j->cadence_f[4].state = 2;
+								j->cadence_f[4].off1min = jiffies + (long)((j->cadence_f[4].off1 * (hertz * (100 - var)) / 10000));
+								j->cadence_f[4].off1dot = jiffies + (long)((j->cadence_f[4].off1 * (hertz * (100)) / 10000));
+								j->cadence_f[4].off1max = jiffies + (long)((j->cadence_f[4].off1 * (hertz * (100 + var)) / 10000));
+							} else {
+								j->cadence_f[4].state = 7;
+							}
+						} else {
+							if (ixjdebug & 0x0008) {
+								printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n",
+										j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr,
+										j->cadence_f[4].on1);
+							}
+							j->cadence_f[4].state = 0;
+						}
+					} else if (j->cadence_f[4].state == 3) {
+						if((time_after(jiffies, j->cadence_f[4].on2min) &&
+						    time_before(jiffies, j->cadence_f[4].on2max))) {
+							if (j->cadence_f[4].off2) {
+								j->cadence_f[4].state = 4;
+								j->cadence_f[4].off2min = jiffies + (long)((j->cadence_f[4].off2 * (hertz * (100 - var)) / 10000));
+								j->cadence_f[4].off2dot = jiffies + (long)((j->cadence_f[4].off2 * (hertz * (100)) / 10000));
+								j->cadence_f[4].off2max = jiffies + (long)((j->cadence_f[4].off2 * (hertz * (100 + var)) / 10000));
+							} else {
+								j->cadence_f[4].state = 7;
+							}
+						} else {
+							if (ixjdebug & 0x0008) {
+								printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n",
+										j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr,
+										j->cadence_f[4].on2);
+							}
+							j->cadence_f[4].state = 0;
 						}
+					} else if (j->cadence_f[4].state == 5) {
+						if((time_after(jiffies, j->cadence_f[4].on3min) &&
+						    time_before(jiffies, j->cadence_f[4].on3max))) {
+							if (j->cadence_f[4].off3) {
+								j->cadence_f[4].state = 6;
+								j->cadence_f[4].off3min = jiffies + (long)((j->cadence_f[4].off3 * (hertz * (100 - var)) / 10000));
+								j->cadence_f[4].off3dot = jiffies + (long)((j->cadence_f[4].off3 * (hertz * (100)) / 10000));
+								j->cadence_f[4].off3max = jiffies + (long)((j->cadence_f[4].off3 * (hertz * (100 + var)) / 10000));
+							} else {
+								j->cadence_f[4].state = 7;
+							}
+						} else {
+							j->cadence_f[4].state = 0;
+						}
+					} else {
+						if (ixjdebug & 0x0008) {
+							printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n",
+									j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr,
+									j->cadence_f[4].on3);
+						}
+						j->cadence_f[4].state = 0;
 					}
-					if (!j->tone_state) {
-						if (j->dsp.low == 0x20 || (j->play_mode == -1 && j->rec_mode == -1))
-							idle(j);
-						if (j->dsp.low == 0x20 && j->play_mode != -1)
-							ixj_play_start(j);
-						if (j->dsp.low == 0x20 && j->rec_mode != -1)
-							ixj_record_start(j);
+				}
+				if (ixjdebug & 0x0010) {
+					printk(KERN_INFO "IXJ Ring Cadence b state = %d /dev/phone%d at %ld\n", j->cadence_f[4].state, j->board, jiffies);
+				}
+				if (ixjdebug & 0x0010) {
+					switch(j->cadence_f[4].state) {
+						case 1:
+							printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board,
+						j->cadence_f[4].on1, j->cadence_f[4].on1min, j->cadence_f[4].on1dot, j->cadence_f[4].on1max);
+							break;
+						case 2:
+							printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board,
+						j->cadence_f[4].off1, j->cadence_f[4].off1min, j->cadence_f[4].off1dot, j->cadence_f[4].off1max);
+							break;
+						case 3:
+							printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board,
+						j->cadence_f[4].on2, j->cadence_f[4].on2min, j->cadence_f[4].on2dot, j->cadence_f[4].on2max);
+							break;
+						case 4:
+							printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board,
+						j->cadence_f[4].off2, j->cadence_f[4].off2min, j->cadence_f[4].off2dot, j->cadence_f[4].off2max);
+							break;
+						case 5:
+							printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board,
+						j->cadence_f[4].on3, j->cadence_f[4].on3min, j->cadence_f[4].on3dot, j->cadence_f[4].on3max);
+							break;
+						case 6:	
+							printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board,
+						j->cadence_f[4].off3, j->cadence_f[4].off3min, j->cadence_f[4].off3dot, j->cadence_f[4].off3max);
+							break;
 					}
 				}
 			}
-			if (!(j->tone_state && j->dsp.low == 0x20)) {
-				if (IsRxReady(j)) {
-					ixj_read_frame(j);
+			if (j->cadence_f[4].state == 7) {
+				j->cadence_f[4].state = 0;
+				j->pstn_ring_stop = jiffies;
+				j->ex.bits.pstn_ring = 1;
+				ixj_kill_fasync(j, SIG_PSTN_RING, POLL_IN);
+				if(ixjdebug & 0x0008) {
+					printk(KERN_INFO "IXJ Ring int set /dev/phone%d at %ld\n", j->board, jiffies);
+				}
+			}
+			if((j->pstn_ring_int != 0 && time_after(jiffies, j->pstn_ring_int + (hertz * 5)) && !j->flags.pstn_rmr) ||
+			   (j->pstn_ring_stop != 0 && time_after(jiffies, j->pstn_ring_stop + (hertz * 5)))) {
+				if(ixjdebug & 0x0008) {
+					printk("IXJ DAA no ring in 5 seconds /dev/phone%d at %ld\n", j->board, jiffies);
+					printk("IXJ DAA pstn ring int /dev/phone%d at %ld\n", j->board, j->pstn_ring_int);
+					printk("IXJ DAA pstn ring stop /dev/phone%d at %ld\n", j->board, j->pstn_ring_stop);
 				}
-				if (IsTxReady(j) && !j->flags.cidplay) {
-					ixj_write_frame(j);
+				j->pstn_ring_stop = j->pstn_ring_int = 0;
+				daa_set_mode(j, SOP_PU_SLEEP);
+			} 
+			outb_p(j->pld_scrw.byte, j->XILINXbase);
+			if (j->pstn_cid_intr && time_after(jiffies, j->pstn_cid_received + hertz)) {
+				ixj_daa_cid_read(j);
+				j->ex.bits.caller_id = 1;
+				ixj_kill_fasync(j, SIG_CALLER_ID, POLL_IN);
+				j->pstn_cid_intr = 0;
+			}
+			if (daaint.bitreg.Cadence) {
+				if(ixjdebug & 0x0008) {
+					printk("IXJ DAA Cadence interrupt going to sleep /dev/phone%d\n", j->board);
 				}
+				daa_set_mode(j, SOP_PU_SLEEP);
+				j->ex.bits.pstn_ring = 0;
 			}
-			if (j->flags.cringing) {
-				if (ixj_hookstate(j) & 1) {
-					j->flags.cringing = 0;
-					ixj_ring_off(j);
+			break;
+		case SOP_PU_CONVERSATION:
+			if (daaint.bitreg.VDD_OK) {
+				if(!daaint.bitreg.SI_0) {
+					if (!j->pstn_winkstart) {
+						if(ixjdebug & 0x0008) {
+							printk("IXJ DAA possible wink /dev/phone%d %ld\n", j->board, jiffies);
+						}
+						j->pstn_winkstart = jiffies;
+					} 
 				} else {
-					if (jiffies - j->ring_cadence_jif >= (hertz/2)) {
-						if (j->flags.cidring && !j->flags.cidsent) {
-							j->flags.cidsent = 1;
-							ixj_write_cid(j);
-							j->flags.cidring = 0;
+					if (j->pstn_winkstart) {
+						if(ixjdebug & 0x0008) {
+							printk("IXJ DAA possible wink end /dev/phone%d %ld\n", j->board, jiffies);
 						}
-						j->ring_cadence_t--;
-						if (j->ring_cadence_t == -1)
-							j->ring_cadence_t = 15;
-						j->ring_cadence_jif = jiffies;
-					}
-					if (j->ring_cadence & 1 << j->ring_cadence_t) {
-						ixj_ring_on(j);
-					} else {
-						ixj_ring_off(j);
-						j->flags.cidring = 1;
+						j->pstn_winkstart = 0;
 					}
-					continue;
 				}
 			}
-			if (!j->flags.ringing) {
-				if (ixj_hookstate(j)) {
-					if (j->dsp.low != 0x20 &&
-					    SLIC_GetState(j) != PLD_SLIC_STATE_ACTIVE) {
-						SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j);
-					}
-					LineMonitor(j);
-					read_filters(j);
-					ixj_WriteDSPCommand(0x511B, j);
-					j->proc_load = j->ssr.high << 8 | j->ssr.low;
-					if (!j->m_hook) {
-						j->m_hook = j->ex.bits.hookstate = 1;
-						ixj_kill_fasync(j, POLL_PRI);
+			if (j->pstn_winkstart && time_after(jiffies, j->pstn_winkstart + ((hertz * j->winktime) / 1000))) {
+				if(ixjdebug & 0x0008) {
+					printk("IXJ DAA wink detected going to sleep /dev/phone%d %ld\n", j->board, jiffies);
+				}
+				daa_set_mode(j, SOP_PU_SLEEP);
+				j->pstn_winkstart = 0;
+				j->ex.bits.pstn_wink = 1;
+				ixj_kill_fasync(j, SIG_PSTN_WINK, POLL_IN);
+			}
+			break;
+	}
+}
+
+static void ixj_timeout(unsigned long ptr)
+{
+	int board;
+	unsigned long jifon;
+	IXJ *j = (IXJ *)ptr;
+	board = j->board;
+
+	if (j->DSPbase && atomic_read(&j->DSPWrite) == 0 && test_and_set_bit(board, (void *)&j->busyflags) == 0) {
+		ixj_perfmon(j->timerchecks);
+		j->hookstate = ixj_hookstate(j);
+		if (j->tone_state) {
+			if (!(j->hookstate)) {
+				ixj_cpt_stop(j);
+				if (j->m_hook) {
+					j->m_hook = 0;
+					j->ex.bits.hookstate = 1;
+					ixj_kill_fasync(j, SIG_HOOKSTATE, POLL_IN);
+				}
+				clear_bit(board, &j->busyflags);
+				ixj_add_timer(j);
+				return;
+			}
+			if (j->tone_state == 1)
+				jifon = ((hertz * j->tone_on_time) * 25 / 100000);
+			else
+				jifon = ((hertz * j->tone_on_time) * 25 / 100000) + ((hertz * j->tone_off_time) * 25 / 100000);
+			if (time_before(jiffies, j->tone_start_jif + jifon)) {
+				if (j->tone_state == 1) {
+					ixj_play_tone(j, j->tone_index);
+					if (j->dsp.low == 0x20) {
+						clear_bit(board, &j->busyflags);
+						ixj_add_timer(j);
+						return;
 					}
 				} else {
-					if (j->dsp.low != 0x20 &&
-					    SLIC_GetState(j) == PLD_SLIC_STATE_ACTIVE)
-						// Internet LineJACK
-					{
-						SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
+					ixj_play_tone(j, 0);
+					if (j->dsp.low == 0x20) {
+						clear_bit(board, &j->busyflags);
+						ixj_add_timer(j);
+						return;
 					}
-					if (j->ex.bits.dtmf_ready) {
-						j->dtmf_wp = j->dtmf_rp = j->ex.bits.dtmf_ready = 0;
+				}
+			} else {
+				ixj_tone_timeout(j);
+				if (j->flags.dialtone) {
+					ixj_dialtone(j);
+				}
+				if (j->flags.busytone) {
+					ixj_busytone(j);
+					if (j->dsp.low == 0x20) {
+						clear_bit(board, &j->busyflags);
+						ixj_add_timer(j);
+						return;
 					}
-					if (j->m_hook) {
-						j->m_hook = 0;
-						j->ex.bits.hookstate = 1;
-						ixj_kill_fasync(j, POLL_PRI);
+				}
+				if (j->flags.ringback) {
+					ixj_ringback(j);
+					if (j->dsp.low == 0x20) {
+						clear_bit(board, &j->busyflags);
+						ixj_add_timer(j);
+						return;
 					}
 				}
+				if (!j->tone_state) {
+					ixj_cpt_stop(j);
+				}
 			}
-			if (j->cardtype == 300 && !j->flags.incheck) {
-				if (j->flags.pstn_present) {
-					j->pld_scrr.byte = inb_p(j->XILINXbase);
-					if (j->pld_scrr.bits.daaflag) {
-						daa_int_read(j);
-						if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.RING) {
-							if (!j->flags.pstn_ringing) {
-								j->flags.pstn_ringing = 1;
-								if (j->daa_mode != SOP_PU_RINGING)
-									daa_set_mode(j, SOP_PU_RINGING);
+		}
+		if (!(j->tone_state && j->dsp.low == 0x20)) {
+			if (IsRxReady(j)) {
+				ixj_read_frame(j);
+			}
+			if (IsTxReady(j)) {
+				ixj_write_frame(j);
+			}
+		}
+		if (j->flags.cringing) {
+			if (j->hookstate & 1) {
+				j->flags.cringing = 0;
+				ixj_ring_off(j);
+			} else if(j->cadence_f[5].enable && ((!j->cadence_f[5].en_filter) || (j->cadence_f[5].en_filter && j->flags.firstring))) {
+				switch(j->cadence_f[5].state) {
+					case 0:
+						j->cadence_f[5].on1dot = jiffies + (long)((j->cadence_f[5].on1 * (hertz * 100) / 10000));
+						if (time_before(jiffies, j->cadence_f[5].on1dot)) {
+							if(ixjdebug & 0x0004) {
+								printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
 							}
+							ixj_ring_on(j);
 						}
-						if (time_after(jiffies, j->pstn_sleeptil) && j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) {
-							j->pstn_winkstart = 0;
-							j->pstn_ring_stop = 0;
-							j->pld_scrw.bits.led1 = 1;
-							if (j->flags.pstn_ringing && !j->pstn_envelope) {
-								if (j->daa_mode != SOP_PU_RINGING) {
-									j->flags.pstn_ringing = 0;
-								} else {
-									j->pld_scrw.bits.led2 = 0;
-									j->pstn_envelope = 1;
-									j->pstn_ring_start = jiffies;
-									j->pstn_ring_stop = 0;
-								}
-								j->ex.bits.pstn_ring = 0;
+						j->cadence_f[5].state = 1;
+						break;
+					case 1:
+						if (time_after(jiffies, j->cadence_f[5].on1dot)) {
+							j->cadence_f[5].off1dot = jiffies + (long)((j->cadence_f[5].off1 * (hertz * 100) / 10000));
+							if(ixjdebug & 0x0004) {
+								printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
 							}
-							outb_p(j->pld_scrw.byte, j->XILINXbase);
-						} else {
-							j->pld_scrw.bits.led1 = 0;
-							j->pld_scrw.bits.led2 = 1;
-							outb_p(j->pld_scrw.byte, j->XILINXbase);
-							if (j->flags.pstn_ringing && j->pstn_envelope) {
-								if(!j->pstn_ring_stop) {
-									j->pstn_ring_stop = jiffies;
-								} else if (time_after(jiffies, j->pstn_ring_stop + ((hertz * 5) / 100))){
-									j->pstn_ring_stop = 0;
-									j->ex.bits.pstn_ring = 1;
-									j->pstn_envelope = 0;
-								}
-							} else if (j->daa_mode == SOP_PU_CONVERSATION) {
-								if (!j->pstn_winkstart) {
-									j->pstn_winkstart = jiffies;
-								} else if (time_after(jiffies, j->pstn_winkstart + (hertz * j->winktime / 1000))) {
-									daa_set_mode(j, SOP_PU_SLEEP);
-									j->pstn_winkstart = 0;
-									j->ex.bits.pstn_wink = 1;
-								}
+							ixj_ring_off(j);
+							j->cadence_f[5].state = 2;
+						}
+						break;
+					case 2:
+						if (time_after(jiffies, j->cadence_f[5].off1dot)) {
+							if(ixjdebug & 0x0004) {
+								printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
+							}
+							ixj_ring_on(j);
+							if (j->cadence_f[5].on2) {
+								j->cadence_f[5].on2dot = jiffies + (long)((j->cadence_f[5].on2 * (hertz * 100) / 10000));
+								j->cadence_f[5].state = 3;
 							} else {
-								j->ex.bits.pstn_ring = 0;
+								j->cadence_f[5].state = 7;
 							}
 						}
-						if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.Cadence) {
-							if (j->daa_mode == SOP_PU_RINGING) {
-								daa_set_mode(j, SOP_PU_SLEEP);
-								j->flags.pstn_ringing = 0;
-								j->ex.bits.pstn_ring = 0;
+						break;
+					case 3:
+						if (time_after(jiffies, j->cadence_f[5].on2dot)) {
+							if(ixjdebug & 0x0004) {
+								printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
 							}
-						}
-						if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.Caller_ID) {
-							if (j->daa_mode == SOP_PU_RINGING && j->flags.pstn_ringing) {
-								j->pstn_cid_intr = 1;
-								j->pstn_cid_received = jiffies;
+							ixj_ring_off(j);
+							if (j->cadence_f[5].off2) {
+								j->cadence_f[5].off2dot = jiffies + (long)((j->cadence_f[5].off2 * (hertz * 100) / 10000));
+								j->cadence_f[5].state = 4;
+							} else {
+								j->cadence_f[5].state = 7;
 							}
 						}
-					} else {
-						if (j->pld_scrr.bits.daaflag) {
-							daa_int_read(j);
+						break;
+					case 4:
+						if (time_after(jiffies, j->cadence_f[5].off2dot)) {
+							if(ixjdebug & 0x0004) {
+								printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
+							}
+							ixj_ring_on(j);
+							if (j->cadence_f[5].on3) {
+								j->cadence_f[5].on3dot = jiffies + (long)((j->cadence_f[5].on3 * (hertz * 100) / 10000));
+								j->cadence_f[5].state = 5;
+							} else {
+								j->cadence_f[5].state = 7;
+							}
 						}
-						j->ex.bits.pstn_ring = 0;
-						if (j->pstn_cid_intr && jiffies > j->pstn_cid_received + (hertz * 3)) {
-							if (j->daa_mode == SOP_PU_RINGING) {
-								ixj_daa_cid_read(j);
-								j->ex.bits.caller_id = 1;
+						break;
+					case 5:
+						if (time_after(jiffies, j->cadence_f[5].on3dot)) {
+							if(ixjdebug & 0x0004) {
+								printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
+							}
+							ixj_ring_off(j);
+							if (j->cadence_f[5].off3) {
+								j->cadence_f[5].off3dot = jiffies + (long)((j->cadence_f[5].off3 * (hertz * 100) / 10000));
+								j->cadence_f[5].state = 6;
+							} else {
+								j->cadence_f[5].state = 7;
 							}
-							j->pstn_cid_intr = 0;
-						} else {
-							j->ex.bits.caller_id = 0;
 						}
-						if (!j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) {
-							j->pld_scrw.bits.led1 = 0;
-							j->pld_scrw.bits.led2 = 1;
-							outb_p(j->pld_scrw.byte, j->XILINXbase);
-							if (j->flags.pstn_ringing && j->pstn_envelope) {
-								if(!j->pstn_ring_stop) {
-									j->pstn_ring_stop = jiffies;
-								} else if (time_after(jiffies, j->pstn_ring_stop + ((hertz * 5) / 100))){
-									j->pstn_ring_stop = 0;
-									j->ex.bits.pstn_ring = 1;
-									j->pstn_envelope = 0;
-								}
-								j->pld_scrw.bits.led1 = 0;
-								outb_p(j->pld_scrw.byte, j->XILINXbase);
-							} else if (j->daa_mode == SOP_PU_CONVERSATION) {
-								if (!j->pstn_winkstart) {
-									j->pstn_winkstart = jiffies;
-								} else if (time_after(jiffies, j->pstn_winkstart + (hertz * j->winktime / 1000))) {
-									daa_set_mode(j, SOP_PU_SLEEP);
-									j->pstn_winkstart = 0;
-									j->ex.bits.pstn_wink = 1;
-								}
+						break;
+					case 6:
+						if (time_after(jiffies, j->cadence_f[5].off3dot)) {
+							if(ixjdebug & 0x0004) {
+								printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
 							}
+							j->cadence_f[5].state = 7;
+						}
+						break;
+					case 7:
+						if(ixjdebug & 0x0004) {
+							printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
 						}
+						j->flags.cidring = 1;
+						j->cadence_f[5].state = 0;
+						break;
+				}
+				if (j->flags.cidring && !j->flags.cidsent) {
+					j->flags.cidsent = 1;
+					if(j->fskdcnt) {
+						SLIC_SetState(PLD_SLIC_STATE_OHT, j);
+						ixj_pre_cid(j);
+					}
+					j->flags.cidring = 0;
+				}
+				clear_bit(board, &j->busyflags);
+				ixj_add_timer(j);
+				return;
+			} else {
+				if (time_after(jiffies, j->ring_cadence_jif + (hertz / 2))) {
+					if (j->flags.cidring && !j->flags.cidsent) {
+						j->flags.cidsent = 1;
+						if(j->fskdcnt) {
+							SLIC_SetState(PLD_SLIC_STATE_OHT, j);
+							ixj_pre_cid(j);
+						}
+						j->flags.cidring = 0;
+					}
+					j->ring_cadence_t--;
+					if (j->ring_cadence_t == -1)
+						j->ring_cadence_t = 15;
+					j->ring_cadence_jif = jiffies;
+
+					if (j->ring_cadence & 1 << j->ring_cadence_t) {
+						if(j->flags.cidsent && j->cadence_f[5].en_filter)
+							j->flags.firstring = 1;
+						else
+							ixj_ring_on(j);
+					} else {
+						ixj_ring_off(j);
+						if(!j->flags.cidsent)
+							j->flags.cidring = 1;
 					}
 				}
+				clear_bit(board, &j->busyflags);
+				ixj_add_timer(j);
+				return;
 			}
-			if (j->ex.bytes) {
-				wake_up_interruptible(&j->poll_q);	// Wake any blocked selects
-				ixj_kill_fasync(j, POLL_PRI);
+		}
+		if (!j->flags.ringing) {
+			if (j->hookstate) { /* & 1) { */
+				if (j->dsp.low != 0x20 &&
+				    SLIC_GetState(j) != PLD_SLIC_STATE_ACTIVE) {
+					SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j);
+				}
+				LineMonitor(j);
+				read_filters(j);
+				ixj_WriteDSPCommand(0x511B, j);
+				j->proc_load = j->ssr.high << 8 | j->ssr.low;
+				if (!j->m_hook && (j->hookstate & 1)) {
+					j->m_hook = j->ex.bits.hookstate = 1;
+					ixj_kill_fasync(j, SIG_HOOKSTATE, POLL_IN);
+				}
+			} else {
+				if (j->ex.bits.dtmf_ready) {
+					j->dtmf_wp = j->dtmf_rp = j->ex.bits.dtmf_ready = 0;
+				}
+				if (j->m_hook) {
+					j->m_hook = 0;
+					j->ex.bits.hookstate = 1;
+					ixj_kill_fasync(j, SIG_HOOKSTATE, POLL_IN);
+				}
 			}
-		} else {
-			break;
 		}
+		if (j->cardtype == QTI_LINEJACK && !j->flags.pstncheck && j->flags.pstn_present) {
+			ixj_pstn_state(j);
+		}
+		if (j->ex.bytes) {
+			wake_up_interruptible(&j->poll_q);	/* Wake any blocked selects */
+		}
+		clear_bit(board, &j->busyflags);
 	}
-	ixj_add_timer();
+	ixj_add_timer(j);
 }
 
 static int ixj_status_wait(IXJ *j)
 {
 	unsigned long jif;
 
-	jif = jiffies;
+	jif = jiffies + ((60 * hertz) / 100);
 	while (!IsStatusReady(j)) {
-		if (jiffies - jif > (60 * (hertz / 100))) {
+		ixj_perfmon(j->statuswait);
+		if (time_after(jiffies, jif)) {
+			ixj_perfmon(j->statuswaitfail);
 			return -1;
 		}
 	}
@@ -809,39 +1523,69 @@
 {
 	unsigned long jif;
 
-	jif = jiffies;
+	jif = jiffies + ((60 * hertz) / 100);
 	while (!IsPCControlReady(j)) {
-		if (jiffies - jif > (60 * (hertz / 100))) {
+		ixj_perfmon(j->pcontrolwait);
+		if (time_after(jiffies, jif)) {
+			ixj_perfmon(j->pcontrolwaitfail);
 			return -1;
 		}
 	}
 	return 0;
 }
 
-int ixj_WriteDSPCommand(unsigned short cmd, IXJ *j)
+static int ixj_WriteDSPCommand(unsigned short cmd, IXJ *j)
 {
 	BYTES bytes;
 	unsigned long jif;
 
+	atomic_inc(&j->DSPWrite);
+	if(atomic_read(&j->DSPWrite) > 1) {
+		printk("IXJ %d DSP write overlap attempting command 0x%4.4x\n", j->board, cmd);
+		return -1;
+	}
 	bytes.high = (cmd & 0xFF00) >> 8;
 	bytes.low = cmd & 0x00FF;
-	jif = jiffies;
+	jif = jiffies + ((60 * hertz) / 100);
 	while (!IsControlReady(j)) {
-		if (jiffies - jif > (60 * (hertz / 100))) {
+		ixj_perfmon(j->iscontrolready);
+		if (time_after(jiffies, jif)) {
+			ixj_perfmon(j->iscontrolreadyfail);
+			atomic_dec(&j->DSPWrite);
+			if(atomic_read(&j->DSPWrite) > 0) {
+				printk("IXJ %d DSP overlaped command 0x%4.4x during control ready failure.\n", j->board, cmd);
+				while(atomic_read(&j->DSPWrite) > 0) {
+					atomic_dec(&j->DSPWrite);
+				}
+			}
 			return -1;
 		}
 	}
-	outb_p(bytes.low, j->DSPbase + 6);
-	outb_p(bytes.high, j->DSPbase + 7);
+	outb(bytes.low, j->DSPbase + 6);
+	outb(bytes.high, j->DSPbase + 7);
 
 	if (ixj_status_wait(j)) {
 		j->ssr.low = 0xFF;
 		j->ssr.high = 0xFF;
+		atomic_dec(&j->DSPWrite);
+		if(atomic_read(&j->DSPWrite) > 0) {
+			printk("IXJ %d DSP overlaped command 0x%4.4x during status wait failure.\n", j->board, cmd);
+			while(atomic_read(&j->DSPWrite) > 0) {
+				atomic_dec(&j->DSPWrite);
+			}
+		}
 		return -1;
 	}
 /* Read Software Status Register */
 	j->ssr.low = inb_p(j->DSPbase + 2);
 	j->ssr.high = inb_p(j->DSPbase + 3);
+	atomic_dec(&j->DSPWrite);
+	if(atomic_read(&j->DSPWrite) > 0) {
+		printk("IXJ %d DSP overlaped command 0x%4.4x\n", j->board, cmd);
+		while(atomic_read(&j->DSPWrite) > 0) {
+			atomic_dec(&j->DSPWrite);
+		}
+	}
 	return 0;
 }
 
@@ -850,7 +1594,7 @@
 *  General Purpose IO Register read routine
 *
 ***************************************************************************/
-extern __inline__ int ixj_gpio_read(IXJ *j)
+static inline int ixj_gpio_read(IXJ *j)
 {
 	if (ixj_WriteDSPCommand(0x5143, j))
 		return -1;
@@ -861,7 +1605,7 @@
 	return 0;
 }
 
-extern __inline__ void LED_SetState(int state, IXJ *j)
+static inline void LED_SetState(int state, IXJ *j)
 {
 	if (j->cardtype == QTI_LINEJACK) {
 		j->pld_scrw.bits.led1 = state & 0x1 ? 1 : 0;
@@ -869,7 +1613,7 @@
 		j->pld_scrw.bits.led3 = state & 0x4 ? 1 : 0;
 		j->pld_scrw.bits.led4 = state & 0x8 ? 1 : 0;
 
-		outb_p(j->pld_scrw.byte, j->XILINXbase);
+		outb(j->pld_scrw.byte, j->XILINXbase);
 	}
 }
 
@@ -908,22 +1652,31 @@
 		case QTI_PHONEJACK_PCI:
 			j->pld_slicw.pcib.mic = 0;
 			j->pld_slicw.pcib.spk = 0;
-			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+			outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
 			break;
 		case QTI_LINEJACK:
-			ixj_set_pots(j, 0);
+			ixj_set_pots(j, 0);			/* Disconnect POTS/PSTN relay */
 			if (ixj_WriteDSPCommand(0xC528, j))		/* Write CODEC config to
 									   Software Control Register */
 				return 2;
-			j->pld_scrw.bits.daafsyncen = 0;	// Turn off DAA Frame Sync
+			j->pld_scrw.bits.daafsyncen = 0;	/* Turn off DAA Frame Sync */
 
-			outb_p(j->pld_scrw.byte, j->XILINXbase);
+			outb(j->pld_scrw.byte, j->XILINXbase);
 			j->pld_clock.byte = 0;
-			outb_p(j->pld_clock.byte, j->XILINXbase + 0x04);
+			outb(j->pld_clock.byte, j->XILINXbase + 0x04);
 			j->pld_slicw.bits.rly1 = 1;
 			j->pld_slicw.bits.spken = 0;
-			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+			outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
+			ixj_mixer(0x1200, j);	/* Turn Off MIC switch on mixer left */
+			ixj_mixer(0x1401, j);	/* Turn On Mono1 switch on mixer left */
+			ixj_mixer(0x1300, j);       /* Turn Off MIC switch on mixer right */
+			ixj_mixer(0x1501, j);       /* Turn On Mono1 switch on mixer right */
+			ixj_mixer(0x0E80, j);	/*Mic mute */
+			ixj_mixer(0x0F00, j);	/* Set mono out (SLIC) to 0dB */
+			ixj_mixer(0x0080, j);	/* Mute Master Left volume */
+			ixj_mixer(0x0180, j);	/* Mute Master Right volume */
 			SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
+/*			SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j); */
 			break;
 		case QTI_PHONEJACK:
 			j->gpio.bytes.high = 0x0B;
@@ -940,7 +1693,7 @@
 			j->pld_slicw.bits.rly3 = 0;
 			j->pld_slicw.bits.rly1 = 1;
 			j->pld_slicw.bits.spken = 0;
-			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+			outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
 			j->port = PORT_PSTN;
 		} else {
 			return 4;
@@ -957,10 +1710,29 @@
 		case QTI_PHONEJACK_PCI:
 			j->pld_slicw.pcib.mic = 1;
 			j->pld_slicw.pcib.spk = 1;
-			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+			outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
 			break;
 		case QTI_LINEJACK:
-			ixj_set_pots(j, 0);
+			ixj_set_pots(j, 0);			/* Disconnect POTS/PSTN relay */
+			if (ixj_WriteDSPCommand(0xC528, j))		/* Write CODEC config to
+									   Software Control Register */
+				return 2;
+			j->pld_scrw.bits.daafsyncen = 0;	/* Turn off DAA Frame Sync */
+
+			outb(j->pld_scrw.byte, j->XILINXbase);
+			j->pld_clock.byte = 0;
+			outb(j->pld_clock.byte, j->XILINXbase + 0x04);
+			j->pld_slicw.bits.rly1 = 1;
+			j->pld_slicw.bits.spken = 1;
+			outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
+			ixj_mixer(0x1201, j);	/* Turn On MIC switch on mixer left */
+			ixj_mixer(0x1400, j);	/* Turn Off Mono1 switch on mixer left */
+			ixj_mixer(0x1301, j);       /* Turn On MIC switch on mixer right */
+			ixj_mixer(0x1500, j);       /* Turn Off Mono1 switch on mixer right */
+			ixj_mixer(0x0E06, j);	/*Mic un-mute 0dB */
+			ixj_mixer(0x0F80, j);	/* Mute mono out (SLIC) */
+			ixj_mixer(0x0000, j);	/* Set Master Left volume to 0dB */
+			ixj_mixer(0x0100, j);	/* Set Master Right volume to 0dB */
 			break;
 		case QTI_PHONEJACK:
 			j->gpio.bytes.high = 0x0B;
@@ -971,7 +1743,7 @@
 		}
 		break;
 	case PORT_HANDSET:
-		if (j->cardtype == QTI_LINEJACK || j->cardtype == QTI_PHONEJACK_PCI) {
+		if (j->cardtype != QTI_PHONEJACK) {
 			return 5;
 		} else {
 			j->gpio.bytes.high = 0x0B;
@@ -994,14 +1766,17 @@
 		if (arg) {
 			if (j->port == PORT_PSTN) {
 				j->pld_slicw.bits.rly1 = 0;
-				outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+				outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
+				j->flags.pots_pstn = 1;
 				return 1;
 			} else {
+				j->flags.pots_pstn = 0;
 				return 0;
 			}
 		} else {
 			j->pld_slicw.bits.rly1 = 1;
-			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+			outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
+			j->flags.pots_pstn = 0;
 			return 1;
 		}
 	} else {
@@ -1011,18 +1786,76 @@
 
 static void ixj_ring_on(IXJ *j)
 {
-	if (j->dsp.low == 0x20) { // Internet PhoneJACK
+	if (j->dsp.low == 0x20)	/* Internet PhoneJACK */
+	 {
+		if (ixjdebug & 0x0004)
+			printk(KERN_INFO "IXJ Ring On /dev/phone%d\n", 	j->board);
+
 		j->gpio.bytes.high = 0x0B;
 		j->gpio.bytes.low = 0x00;
 		j->gpio.bits.gpio1 = 1;
 		j->gpio.bits.gpio2 = 1;
 		j->gpio.bits.gpio5 = 0;
 		ixj_WriteDSPCommand(j->gpio.word, j);	/* send the ring signal */
-	} else {			// Internet LineJACK, Internet PhoneJACK Lite or Internet PhoneJACK PCI
+	} else			/* Internet LineJACK, Internet PhoneJACK Lite or Internet PhoneJACK PCI */
+	{
+		if (ixjdebug & 0x0004)
+			printk(KERN_INFO "IXJ Ring On /dev/phone%d\n", j->board);
+
 		SLIC_SetState(PLD_SLIC_STATE_RINGING, j);
 	}
 }
 
+static int ixj_siadc(IXJ *j, int val)
+{
+	if(j->cardtype == QTI_PHONECARD){
+		if(j->flags.pcmciascp){
+			if(val == -1)
+				return j->siadc.bits.rxg;
+
+			if(val < 0 || val > 0x1F)
+				return -1;
+
+			j->siadc.bits.hom = 0;				/* Handset Out Mute */
+			j->siadc.bits.lom = 0;				/* Line Out Mute */
+			j->siadc.bits.rxg = val;			/*(0xC000 - 0x41C8) / 0x4EF;    RX PGA Gain */
+			j->psccr.bits.addr = 6;				/* R/W Smart Cable Register Address */
+			j->psccr.bits.rw = 0;				/* Read / Write flag */
+			j->psccr.bits.dev = 0;
+			outb(j->siadc.byte, j->XILINXbase + 0x00);
+			outb(j->psccr.byte, j->XILINXbase + 0x01);
+			ixj_PCcontrol_wait(j);
+			return j->siadc.bits.rxg;
+		}
+	}
+	return -1;
+}
+
+static int ixj_sidac(IXJ *j, int val)
+{
+	if(j->cardtype == QTI_PHONECARD){
+		if(j->flags.pcmciascp){
+			if(val == -1)
+				return j->sidac.bits.txg;
+
+			if(val < 0 || val > 0x1F)
+				return -1;
+
+			j->sidac.bits.srm = 1;				/* Speaker Right Mute */
+			j->sidac.bits.slm = 1;				/* Speaker Left Mute */
+			j->sidac.bits.txg = val;			/* (0xC000 - 0x45E4) / 0x5D3;	 TX PGA Gain */
+			j->psccr.bits.addr = 7;				/* R/W Smart Cable Register Address */
+			j->psccr.bits.rw = 0;				/* Read / Write flag */
+			j->psccr.bits.dev = 0;
+			outb(j->sidac.byte, j->XILINXbase + 0x00);
+			outb(j->psccr.byte, j->XILINXbase + 0x01);
+			ixj_PCcontrol_wait(j);
+			return j->sidac.bits.txg;
+		}
+	}
+	return -1;
+}
+
 static int ixj_pcmcia_cable_check(IXJ *j)
 {
 	j->pccr1.byte = inb_p(j->XILINXbase + 0x03);
@@ -1058,8 +1891,8 @@
 	} else if (j->flags.pcmciastate == 3) {
 		j->pccr2.bits.pwr = 0;
 		j->pccr2.bits.rstc = 1;
-		outb_p(j->pccr2.byte, j->XILINXbase + 0x02);
-		j->checkwait = jiffies + hertz * 2;
+		outb(j->pccr2.byte, j->XILINXbase + 0x02);
+		j->checkwait = jiffies + (hertz * 2);
 		j->flags.incheck = 1;
 		j->flags.pcmciastate = 2;
 		return 0;
@@ -1083,9 +1916,9 @@
 			j->psccr.bits.rw = 1;
 			outb_p(j->psccr.byte, j->XILINXbase + 0x01);
 			ixj_PCcontrol_wait(j);
-			j->flags.pcmciascp = 1;		// Set Cable Present Flag
+			j->flags.pcmciascp = 1;		/* Set Cable Present Flag */
 
-			j->flags.pcmciasct = (inw_p(j->XILINXbase + 0x00) >> 8) & 0x03;		// Get Cable Type
+			j->flags.pcmciasct = (inw_p(j->XILINXbase + 0x00) >> 8) & 0x03;		/* Get Cable Type */
 
 			if (j->flags.pcmciasct == 3) {
 				j->flags.pcmciastate = 4;
@@ -1098,113 +1931,63 @@
 			} else {
 				j->port = PORT_POTS;
 			}
-			j->sic1.bits.cpd = 0;	// Chip Power Down
-
-			j->sic1.bits.mpd = 0;	// MIC Bias Power Down
-
-			j->sic1.bits.hpd = 0;	// Handset Bias Power Down
-
-			j->sic1.bits.lpd = 0;	// Line Bias Power Down
-
-			j->sic1.bits.spd = 1;	// Speaker Drive Power Down
-
-			j->psccr.bits.addr = 1;		// R/W Smart Cable Register Address
-
-			j->psccr.bits.rw = 0;	// Read / Write flag
-
+			j->sic1.bits.cpd = 0;				/* Chip Power Down */
+			j->sic1.bits.mpd = 0;				/* MIC Bias Power Down */
+			j->sic1.bits.hpd = 0;				/* Handset Bias Power Down */
+			j->sic1.bits.lpd = 0;				/* Line Bias Power Down */
+			j->sic1.bits.spd = 1;				/* Speaker Drive Power Down */
+			j->psccr.bits.addr = 1;				/* R/W Smart Cable Register Address */
+			j->psccr.bits.rw = 0;				/* Read / Write flag */
 			j->psccr.bits.dev = 0;
-			outb(j->sic1.byte, j->XILINXbase + 0x00);
-			outb(j->psccr.byte, j->XILINXbase + 0x01);
-			ixj_PCcontrol_wait(j);
-			j->sic2.bits.al = 0;	// Analog Loopback DAC analog -> ADC analog
-
-			j->sic2.bits.dl2 = 0;	// Digital Loopback DAC -> ADC one bit
-
-			j->sic2.bits.dl1 = 0;	// Digital Loopback ADC -> DAC one bit
-
-			j->sic2.bits.pll = 0;	// 1 = div 10, 0 = div 5
-
-			j->sic2.bits.hpd = 0;	// HPF disable
-
-			j->psccr.bits.addr = 2;		// R/W Smart Cable Register Address
-
-			j->psccr.bits.rw = 0;	// Read / Write flag
-
-			j->psccr.bits.dev = 0;
-			outb(j->sic2.byte, j->XILINXbase + 0x00);
-			outb(j->psccr.byte, j->XILINXbase + 0x01);
-			ixj_PCcontrol_wait(j);
-			j->psccr.bits.addr = 3;		// R/W Smart Cable Register Address
-
-			j->psccr.bits.rw = 0;	// Read / Write flag
-
-			j->psccr.bits.dev = 0;
-			outb(0x00, j->XILINXbase + 0x00);	// PLL Divide N1
-
+			outb(j->sic1.byte, j->XILINXbase + 0x00);
 			outb(j->psccr.byte, j->XILINXbase + 0x01);
 			ixj_PCcontrol_wait(j);
-			j->psccr.bits.addr = 4;		// R/W Smart Cable Register Address
-
-			j->psccr.bits.rw = 0;	// Read / Write flag
 
+			j->sic2.bits.al = 0;				/* Analog Loopback DAC analog -> ADC analog */
+			j->sic2.bits.dl2 = 0;				/* Digital Loopback DAC -> ADC one bit */
+			j->sic2.bits.dl1 = 0;				/* Digital Loopback ADC -> DAC one bit */
+			j->sic2.bits.pll = 0;				/* 1 = div 10, 0 = div 5 */
+			j->sic2.bits.hpd = 0;				/* HPF disable */
+			j->psccr.bits.addr = 2;				/* R/W Smart Cable Register Address */
+			j->psccr.bits.rw = 0;				/* Read / Write flag */
 			j->psccr.bits.dev = 0;
-			outb(0x09, j->XILINXbase + 0x00);	// PLL Multiply M1
-
+			outb(j->sic2.byte, j->XILINXbase + 0x00);
 			outb(j->psccr.byte, j->XILINXbase + 0x01);
 			ixj_PCcontrol_wait(j);
-			j->sirxg.bits.lig = 1;	// Line In Gain
-
-			j->sirxg.bits.lim = 1;	// Line In Mute
-
-			j->sirxg.bits.mcg = 0;	// MIC In Gain // was 3
-
-			j->sirxg.bits.mcm = 0;	// MIC In Mute
-
-			j->sirxg.bits.him = 0;	// Handset In Mute
-
-			j->sirxg.bits.iir = 1;	// IIR
-
-			j->psccr.bits.addr = 5;		// R/W Smart Cable Register Address
-
-			j->psccr.bits.rw = 0;	// Read / Write flag
 
+			j->psccr.bits.addr = 3;				/* R/W Smart Cable Register Address */
+			j->psccr.bits.rw = 0;				/* Read / Write flag */
 			j->psccr.bits.dev = 0;
-			outb(j->sirxg.byte, j->XILINXbase + 0x00);
+			outb(0x00, j->XILINXbase + 0x00);		/* PLL Divide N1 */
 			outb(j->psccr.byte, j->XILINXbase + 0x01);
 			ixj_PCcontrol_wait(j);
-			j->siadc.bits.hom = 0;	// Handset Out Mute
-
-			j->siadc.bits.lom = 0;	// Line Out Mute
-
-			j->siadc.bits.rxg = 23;		//(0xC000 - 0x41C8) / 0x4EF;    // RX PGA Gain
-
-			j->psccr.bits.addr = 6;		// R/W Smart Cable Register Address
-
-			j->psccr.bits.rw = 0;	// Read / Write flag
 
+			j->psccr.bits.addr = 4;				/* R/W Smart Cable Register Address */
+			j->psccr.bits.rw = 0;				/* Read / Write flag */
 			j->psccr.bits.dev = 0;
-			outb(j->siadc.byte, j->XILINXbase + 0x00);
+			outb(0x09, j->XILINXbase + 0x00);		/* PLL Multiply M1 */
 			outb(j->psccr.byte, j->XILINXbase + 0x01);
 			ixj_PCcontrol_wait(j);
-			j->sidac.bits.srm = 1;	// Speaker Right Mute
-
-			j->sidac.bits.slm = 1;	// Speaker Left Mute
-
-			j->sidac.bits.txg = (0xC000 - 0x45E4) / 0x5D3;	// TX PGA Gain
-
-			j->psccr.bits.addr = 7;		// R/W Smart Cable Register Address
-
-			j->psccr.bits.rw = 0;	// Read / Write flag
 
+			j->sirxg.bits.lig = 1;				/* Line In Gain */
+			j->sirxg.bits.lim = 1;				/* Line In Mute */
+			j->sirxg.bits.mcg = 0;				/* MIC In Gain was 3 */
+			j->sirxg.bits.mcm = 0;				/* MIC In Mute */
+			j->sirxg.bits.him = 0;				/* Handset In Mute */
+			j->sirxg.bits.iir = 1;				/* IIR */
+			j->psccr.bits.addr = 5;				/* R/W Smart Cable Register Address */
+			j->psccr.bits.rw = 0;				/* Read / Write flag */
 			j->psccr.bits.dev = 0;
-			outb(j->sidac.byte, j->XILINXbase + 0x00);
+			outb(j->sirxg.byte, j->XILINXbase + 0x00);
 			outb(j->psccr.byte, j->XILINXbase + 0x01);
 			ixj_PCcontrol_wait(j);
-			j->siaatt.bits.sot = 0;
-			j->psccr.bits.addr = 9;		// R/W Smart Cable Register Address
 
-			j->psccr.bits.rw = 0;	// Read / Write flag
+			ixj_siadc(j, 0x17);
+			ixj_sidac(j, 0x1D);
 
+			j->siaatt.bits.sot = 0;
+			j->psccr.bits.addr = 9;				/* R/W Smart Cable Register Address */
+			j->psccr.bits.rw = 0;				/* Read / Write flag */
 			j->psccr.bits.dev = 0;
 			outb(j->siaatt.byte, j->XILINXbase + 0x00);
 			outb(j->psccr.byte, j->XILINXbase + 0x01);
@@ -1241,26 +2024,42 @@
 	case QTI_PHONEJACK_LITE:
 	case QTI_PHONEJACK_PCI:
 		SLIC_GetState(j);
-		if (j->pld_slicr.bits.state == PLD_SLIC_STATE_ACTIVE ||
-		    j->pld_slicr.bits.state == PLD_SLIC_STATE_STANDBY) {
-			if (j->flags.ringing) {
-				if (!in_interrupt()) {
-					det = jiffies + (hertz / 50);
-					while (time_before(jiffies, det)) {
-						set_current_state(TASK_INTERRUPTIBLE);
-						schedule_timeout(1);
-					}
+		if(j->cardtype == QTI_LINEJACK && j->flags.pots_pstn == 1 && (j->readers || j->writers)) {
+			fOffHook = j->pld_slicr.bits.potspstn ? 1 : 0;
+			if(fOffHook != j->p_hook) {
+				if(!j->checkwait) {
+					j->checkwait = jiffies;
+				} 
+				if(time_before(jiffies, j->checkwait + 2)) {
+					fOffHook ^= 1;
+				} else {
+					j->checkwait = 0;
 				}
-				SLIC_GetState(j);
-				if (j->pld_slicr.bits.state == PLD_SLIC_STATE_RINGING) {
-					ixj_ring_on(j);
+				j->p_hook = fOffHook;
+	 			printk("IXJ : /dev/phone%d pots-pstn hookstate check %d at %ld\n", j->board, fOffHook, jiffies);
+			}
+		} else {
+			if (j->pld_slicr.bits.state == PLD_SLIC_STATE_ACTIVE ||
+			    j->pld_slicr.bits.state == PLD_SLIC_STATE_STANDBY) {
+				if (j->flags.ringing || j->flags.cringing) {
+					if (!in_interrupt()) {
+						det = jiffies + (hertz / 50);
+						while (time_before(jiffies, det)) {
+							set_current_state(TASK_INTERRUPTIBLE);
+							schedule_timeout(1);
+						}
+					}
+					SLIC_GetState(j);
+					if (j->pld_slicr.bits.state == PLD_SLIC_STATE_RINGING) {
+						ixj_ring_on(j);
+					}
 				}
+				if (j->cardtype == QTI_PHONEJACK_PCI) {
+					j->pld_scrr.byte = inb_p(j->XILINXbase);
+					fOffHook = j->pld_scrr.pcib.det ? 1 : 0;
+				} else
+					fOffHook = j->pld_slicr.bits.det ? 1 : 0;
 			}
-			if (j->cardtype == QTI_PHONEJACK_PCI) {
-				j->pld_scrr.byte = inb_p(j->XILINXbase);
-				fOffHook = j->pld_scrr.pcib.det ? 1 : 0;
-			} else
-				fOffHook = j->pld_slicr.bits.det ? 1 : 0;
 		}
 		break;
 	case QTI_PHONECARD:
@@ -1269,34 +2068,49 @@
 	}
 	if (j->r_hook != fOffHook) {
 		j->r_hook = fOffHook;
-		if (j->port != PORT_POTS) {
+		if (j->port == PORT_SPEAKER || j->port == PORT_HANDSET) { // || (j->port == PORT_PSTN && j->flags.pots_pstn == 0)) {
 			j->ex.bits.hookstate = 1;
-			ixj_kill_fasync(j, POLL_PRI);
+			ixj_kill_fasync(j, SIG_HOOKSTATE, POLL_IN);
 		} else if (!fOffHook) {
-			j->flash_end = jiffies + (hertz / 10 * 6);
+			j->flash_end = jiffies + ((60 * hertz) / 100);
+		}
+	}
+	if (fOffHook) {
+		if(time_before(jiffies, j->flash_end)) {
+			j->ex.bits.flash = 1;
+			j->flash_end = 0;
+			ixj_kill_fasync(j, SIG_FLASH, POLL_IN);
+		}
+	} else {
+		if(time_before(jiffies, j->flash_end)) {
+			fOffHook = 1;
 		}
 	}
+
 	if (j->port == PORT_PSTN && j->daa_mode == SOP_PU_CONVERSATION)
 		fOffHook |= 2;
 
-	if (j->port == PORT_SPEAKER)
-		fOffHook |= 2;
+	if (j->port == PORT_SPEAKER) {
+		if(j->cardtype == QTI_PHONECARD) {
+			if(j->flags.pcmciascp && j->flags.pcmciasct) {
+				fOffHook |= 2;
+			}
+		} else {
+			fOffHook |= 2;
+		}
+	}
 
 	if (j->port == PORT_HANDSET)
 		fOffHook |= 2;
 
-	if (fOffHook && time_before(jiffies, j->flash_end))
-		return 0;
-	else
-		return fOffHook;
+	return fOffHook;
 }
 
 static void ixj_ring_off(IXJ *j)
 {
-
-	if (j->dsp.low == 0x20)	// Internet PhoneJACK
+	if (j->dsp.low == 0x20)	/* Internet PhoneJACK */
 	 {
-		if (ixjdebug > 0)
+		if (ixjdebug & 0x0004)
 			printk(KERN_INFO "IXJ Ring Off\n");
 		j->gpio.bytes.high = 0x0B;
 		j->gpio.bytes.low = 0x00;
@@ -1304,12 +2118,13 @@
 		j->gpio.bits.gpio2 = 1;
 		j->gpio.bits.gpio5 = 0;
 		ixj_WriteDSPCommand(j->gpio.word, j);
-	} else			// Internet LineJACK
-	 {
-		if (ixjdebug > 0)
+	} else			/* Internet LineJACK */
+	{
+		if (ixjdebug & 0x0004)
 			printk(KERN_INFO "IXJ Ring Off\n");
 
-		SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
+		if(!j->flags.cidplay)
+			SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
 
 		SLIC_GetState(j);
 	}
@@ -1318,10 +2133,20 @@
 static void ixj_ring_start(IXJ *j)
 {
 	j->flags.cringing = 1;
+	if (ixjdebug & 0x0004)
+		printk(KERN_INFO "IXJ Cadence Ringing Start /dev/phone%d\n", j->board);
 	if (ixj_hookstate(j) & 1) {
 		if (j->port == PORT_POTS)
 			ixj_ring_off(j);
 		j->flags.cringing = 0;
+		if (ixjdebug & 0x0004)
+			printk(KERN_INFO "IXJ Cadence Ringing Stopped /dev/phone%d off hook\n", j->board);
+	} else if(j->cadence_f[5].enable && (!j->cadence_f[5].en_filter)) {
+		j->ring_cadence_jif = jiffies;
+		j->flags.cidsent = j->flags.cidring = 0;
+		j->cadence_f[5].state = 0;
+		if(j->cadence_f[5].on1)
+			ixj_ring_on(j);
 	} else {
 		j->ring_cadence_jif = jiffies;
 		j->ring_cadence_t = 15;
@@ -1330,6 +2155,7 @@
 		} else {
 			ixj_ring_off(j);
 		}
+		j->flags.cidsent = j->flags.cidring = j->flags.firstring = 0;
 	}
 }
 
@@ -1386,12 +2212,10 @@
 	return 0;
 }
 
-int ixj_open(struct phone_device *p, struct file *file_p)
+static int ixj_open(struct phone_device *p, struct file *file_p)
 {
-	IXJ *j = file_p->private_data = ixj[p->board];
-
-	if (j == NULL)
-		return -ENODEV;
+	IXJ *j = get_ixj(p->board);
+	file_p->private_data = j;
 
 	if (!j->DSPbase)
 		return -ENODEV;
@@ -1423,7 +2247,12 @@
 		ixj_PCcontrol_wait(j);
 	}
 
-	if (ixjdebug > 0)
+	j->flags.cidplay = 0;
+	j->flags.cidcw_ack = 0;
+
+	MOD_INC_USE_COUNT;
+
+	if (ixjdebug & 0x0002)
 		printk(KERN_INFO "Opening board %d\n", p->board);
 
 	j->framesread = j->frameswritten = 0;
@@ -1435,14 +2264,24 @@
 	IXJ_TONE ti;
 	int cnt;
 	IXJ *j = file_p->private_data;
+	int board = j->p.board;
 
-	if (ixjdebug > 0)
+	/*
+	 *    Set up locks to ensure that only one process is talking to the DSP at a time.
+	 *    This is necessary to keep the DSP from locking up.
+	 */
+	while(test_and_set_bit(board, (void *)&j->busyflags) != 0) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(1);
+	}
+	if (ixjdebug & 0x0002)
 		printk(KERN_INFO "Closing board %d\n", NUM(inode->i_rdev));
 
 	if (j->cardtype == QTI_PHONECARD)
 		ixj_set_port(j, PORT_SPEAKER);
 	else
 		ixj_set_port(j, PORT_POTS);
+
 	aec_stop(j);
 	ixj_play_stop(j);
 	ixj_record_stop(j);
@@ -1450,22 +2289,25 @@
 	set_rec_volume(j, 0x100);
 	ixj_ring_off(j);
 
-	// Restore the tone table to default settings.
+	/* Restore the tone table to default settings. */
 	ti.tone_index = 10;
 	ti.gain0 = 1;
 	ti.freq0 = hz941;
 	ti.gain1 = 0;
 	ti.freq1 = hz1209;
+	ixj_init_tone(j, &ti);
 	ti.tone_index = 11;
 	ti.gain0 = 1;
 	ti.freq0 = hz941;
 	ti.gain1 = 0;
 	ti.freq1 = hz1336;
+	ixj_init_tone(j, &ti);
 	ti.tone_index = 12;
 	ti.gain0 = 1;
 	ti.freq0 = hz941;
 	ti.gain1 = 0;
 	ti.freq1 = hz1477;
+	ixj_init_tone(j, &ti);
 	ti.tone_index = 13;
 	ti.gain0 = 1;
 	ti.freq0 = hz800;
@@ -1557,9 +2399,9 @@
 	ti.freq1 = hz620;
 	ixj_init_tone(j, &ti);
 
-	set_rec_depth(j, 2);	// Set Record Channel Limit to 2 frames
+	set_rec_depth(j, 2);	/* Set Record Channel Limit to 2 frames */
 
-	set_play_depth(j, 2);	// Set Playback Channel Limit to 2 frames
+	set_play_depth(j, 2);	/* Set Playback Channel Limit to 2 frames */
 
 	j->ex.bits.dtmf_ready = 0;
 	j->dtmf_state = 0;
@@ -1568,6 +2410,9 @@
 	j->flags.ringing = 0;
 	j->maxrings = MAXRINGS;
 	j->ring_cadence = USA_RING_CADENCE;
+	if(j->cadence_f[5].enable) {
+		j->cadence_f[5].enable = j->cadence_f[5].en_filter = j->cadence_f[5].state = 0;
+	}
 	j->drybuffer = 0;
 	j->winktime = 320;
 	j->flags.dtmf_oob = 0;
@@ -1598,27 +2443,42 @@
 	j->rec_codec = j->play_codec = 0;
 	j->rec_frame_size = j->play_frame_size = 0;
 	j->flags.cidsent = j->flags.cidring = 0;
-	ixj_fasync(-1, file_p, 0);	// remove from list of async notification
+	ixj_fasync(-1, file_p, 0);	/* remove from list of async notification */
 
 	if(j->cardtype == QTI_LINEJACK && !j->readers && !j->writers) {
 		ixj_set_port(j, PORT_PSTN);
 		daa_set_mode(j, SOP_PU_SLEEP);
 		ixj_set_pots(j, 1);
 	}
-	ixj_WriteDSPCommand(0x0FE3, j);	// Put the DSP in 1/5 power mode.
+	ixj_WriteDSPCommand(0x0FE3, j);	/* Put the DSP in 1/5 power mode. */
+
+	/* Set up the default signals for events */
+	for (cnt = 0; cnt < 35; cnt++)
+		j->ixj_signals[cnt] = SIGIO;
+
+	/* Set the excetion signal enable flags */
+	j->ex_sig.bits.dtmf_ready = j->ex_sig.bits.hookstate = j->ex_sig.bits.flash = j->ex_sig.bits.pstn_ring = 
+	j->ex_sig.bits.caller_id = j->ex_sig.bits.pstn_wink = j->ex_sig.bits.f0 = j->ex_sig.bits.f1 = j->ex_sig.bits.f2 = 
+	j->ex_sig.bits.f3 = j->ex_sig.bits.fc0 = j->ex_sig.bits.fc1 = j->ex_sig.bits.fc2 = j->ex_sig.bits.fc3 = 1;
 
 	file_p->private_data = NULL;
+	clear_bit(board, &j->busyflags);
+	MOD_DEC_USE_COUNT;
 	return 0;
 }
 
 static int read_filters(IXJ *j)
 {
-	unsigned short fc, cnt;
+	unsigned short fc, cnt, trg;
 	int var;
 
-	if (ixj_WriteDSPCommand(0x5144, j))
+	trg = 0;
+	if (ixj_WriteDSPCommand(0x5144, j)) {
+		if(ixjdebug & 0x0001) {
+			printk(KERN_INFO "Read Frame Counter failed!\n");
+		}
 		return -1;
-
+	}
 	fc = j->ssr.high << 8 | j->ssr.low;
 	if (fc == j->frame_count)
 		return 1;
@@ -1631,65 +2491,97 @@
 	var = 10;
 
 	for (cnt = 0; cnt < 4; cnt++) {
-		if (ixj_WriteDSPCommand(0x5154 + cnt, j))
+		if (ixj_WriteDSPCommand(0x5154 + cnt, j)) {
+			if(ixjdebug & 0x0001) {
+				printk(KERN_INFO "Select Filter %d failed!\n", cnt);
+			}
 			return -1;
-
-		if (ixj_WriteDSPCommand(0x515C, j))
+		}
+		if (ixj_WriteDSPCommand(0x515C, j)) {
+			if(ixjdebug & 0x0001) {
+				printk(KERN_INFO "Read Filter History %d failed!\n", cnt);
+			}
 			return -1;
-
+		}
 		j->filter_hist[cnt] = j->ssr.high << 8 | j->ssr.low;
 
 		if (j->cadence_f[cnt].enable) {
 			if (j->filter_hist[cnt] & 3 && !(j->filter_hist[cnt] & 12)) {
 				if (j->cadence_f[cnt].state == 0) {
 					j->cadence_f[cnt].state = 1;
-					j->cadence_f[cnt].on1min = jiffies + (j->cadence_f[cnt].on1 * hertz * (100 - var) / 10000);
-					j->cadence_f[cnt].on1dot = jiffies + (j->cadence_f[cnt].on1 * hertz * (100) / 10000);
-					j->cadence_f[cnt].on1max = jiffies + (j->cadence_f[cnt].on1 * hertz * (100 + var) / 10000);
+					j->cadence_f[cnt].on1min = jiffies + (long)((j->cadence_f[cnt].on1 * (hertz * (100 - var)) / 10000));
+					j->cadence_f[cnt].on1dot = jiffies + (long)((j->cadence_f[cnt].on1 * (hertz * (100)) / 10000));
+					j->cadence_f[cnt].on1max = jiffies + (long)((j->cadence_f[cnt].on1 * (hertz * (100 + var)) / 10000));
 				} else if (j->cadence_f[cnt].state == 2 &&
 					   (time_after(jiffies, j->cadence_f[cnt].off1min) &&
 					    time_before(jiffies, j->cadence_f[cnt].off1max))) {
 					if (j->cadence_f[cnt].on2) {
 						j->cadence_f[cnt].state = 3;
-						j->cadence_f[cnt].on2min = jiffies + (j->cadence_f[cnt].on2 * hertz * (100 - var) / 10000);
-						j->cadence_f[cnt].on2dot = jiffies + (j->cadence_f[cnt].on2 * hertz * (100) / 10000);
-						j->cadence_f[cnt].on2max = jiffies + (j->cadence_f[cnt].on2 * hertz * (100 + var) / 10000);
+						j->cadence_f[cnt].on2min = jiffies + (long)((j->cadence_f[cnt].on2 * (hertz * (100 - var)) / 10000));
+						j->cadence_f[cnt].on2dot = jiffies + (long)((j->cadence_f[cnt].on2 * (hertz * (100)) / 10000));
+						j->cadence_f[cnt].on2max = jiffies + (long)((j->cadence_f[cnt].on2 * (hertz * (100 + var)) / 10000));
 					} else {
-						j->cadence_f[cnt].state = 6;
+						j->cadence_f[cnt].state = 7;
 					}
 				} else if (j->cadence_f[cnt].state == 4 &&
 					   (time_after(jiffies, j->cadence_f[cnt].off2min) &&
 					    time_before(jiffies, j->cadence_f[cnt].off2max))) {
-					if (j->cadence_f[cnt].on2) {
+					if (j->cadence_f[cnt].on3) {
 						j->cadence_f[cnt].state = 5;
-						j->cadence_f[cnt].on3min = jiffies + (j->cadence_f[cnt].on3 * hertz * (100 - var) / 10000);
-						j->cadence_f[cnt].on3dot = jiffies + (j->cadence_f[cnt].on3 * hertz * (100) / 10000);
-						j->cadence_f[cnt].on3max = jiffies + (j->cadence_f[cnt].on3 * hertz * (100 + var) / 10000);
+						j->cadence_f[cnt].on3min = jiffies + (long)((j->cadence_f[cnt].on3 * (hertz * (100 - var)) / 10000));
+						j->cadence_f[cnt].on3dot = jiffies + (long)((j->cadence_f[cnt].on3 * (hertz * (100)) / 10000));
+						j->cadence_f[cnt].on3max = jiffies + (long)((j->cadence_f[cnt].on3 * (hertz * (100 + var)) / 10000));
 					} else {
-						j->cadence_f[cnt].state = 6;
+						j->cadence_f[cnt].state = 7;
 					}
 				} else {
 					j->cadence_f[cnt].state = 0;
 				}
 			} else if (j->filter_hist[cnt] & 12 && !(j->filter_hist[cnt] & 3)) {
-				if (j->cadence_f[cnt].state == 1 &&
-				    (time_after(jiffies, j->cadence_f[cnt].on1min) &&
-				     time_before(jiffies, j->cadence_f[cnt].on1max))) {
-					j->cadence_f[cnt].state = 2;
-					j->cadence_f[cnt].off1min = jiffies + (j->cadence_f[cnt].off1 * hertz * (100 - var) / 10000);
-					j->cadence_f[cnt].off1max = jiffies + (j->cadence_f[cnt].off1 * hertz * (100 + var) / 10000);
-				} else if (j->cadence_f[cnt].state == 3 &&
-					   (time_after(jiffies, j->cadence_f[cnt].on2min) &&
+				if (j->cadence_f[cnt].state == 1) {
+					if(!j->cadence_f[cnt].on1) {
+						j->cadence_f[cnt].state = 7;
+					} else if((time_after(jiffies, j->cadence_f[cnt].on1min) &&
+					  time_before(jiffies, j->cadence_f[cnt].on1max))) {
+						if(j->cadence_f[cnt].off1) {
+							j->cadence_f[cnt].state = 2;
+							j->cadence_f[cnt].off1min = jiffies + (long)((j->cadence_f[cnt].off1 * (hertz * (100 - var)) / 10000));
+							j->cadence_f[cnt].off1dot = jiffies + (long)((j->cadence_f[cnt].off1 * (hertz * (100)) / 10000));
+							j->cadence_f[cnt].off1max = jiffies + (long)((j->cadence_f[cnt].off1 * (hertz * (100 + var)) / 10000));
+						} else {
+							j->cadence_f[cnt].state = 7;
+						}
+					} else {
+						j->cadence_f[cnt].state = 0;
+					}
+				} else if (j->cadence_f[cnt].state == 3) {
+					if((time_after(jiffies, j->cadence_f[cnt].on2min) &&
 					    time_before(jiffies, j->cadence_f[cnt].on2max))) {
-					j->cadence_f[cnt].state = 4;
-					j->cadence_f[cnt].off2min = jiffies + (j->cadence_f[cnt].off2 * hertz * (100 - var) / 10000);
-					j->cadence_f[cnt].off2max = jiffies + (j->cadence_f[cnt].off2 * hertz * (100 + var) / 10000);
-				} else if (j->cadence_f[cnt].state == 5 &&
-					   (time_after(jiffies, j->cadence_f[cnt].on3min) &&
+						if(j->cadence_f[cnt].off2) {
+							j->cadence_f[cnt].state = 4;
+							j->cadence_f[cnt].off2min = jiffies + (long)((j->cadence_f[cnt].off2 * (hertz * (100 - var)) / 10000));
+							j->cadence_f[cnt].off2dot = jiffies + (long)((j->cadence_f[cnt].off2 * (hertz * (100)) / 10000));
+							j->cadence_f[cnt].off2max = jiffies + (long)((j->cadence_f[cnt].off2 * (hertz * (100 + var)) / 10000));
+						} else {
+							j->cadence_f[cnt].state = 7;
+						}
+					} else {
+						j->cadence_f[cnt].state = 0;
+					}
+				} else if (j->cadence_f[cnt].state == 5) {
+					if ((time_after(jiffies, j->cadence_f[cnt].on3min) &&
 					    time_before(jiffies, j->cadence_f[cnt].on3max))) {
-					j->cadence_f[cnt].state = 6;
-					j->cadence_f[cnt].off3min = jiffies + (j->cadence_f[cnt].off3 * hertz * (100 - var) / 10000);
-					j->cadence_f[cnt].off3max = jiffies + (j->cadence_f[cnt].off3 * hertz * (100 + var) / 10000);
+						if(j->cadence_f[cnt].off3) {
+							j->cadence_f[cnt].state = 6;
+							j->cadence_f[cnt].off3min = jiffies + (long)((j->cadence_f[cnt].off3 * (hertz * (100 - var)) / 10000));
+							j->cadence_f[cnt].off3dot = jiffies + (long)((j->cadence_f[cnt].off3 * (hertz * (100)) / 10000));
+							j->cadence_f[cnt].off3max = jiffies + (long)((j->cadence_f[cnt].off3 * (hertz * (100 + var)) / 10000));
+						} else {
+							j->cadence_f[cnt].state = 7;
+						}
+					} else {
+						j->cadence_f[cnt].state = 0;
+					}
 				} else {
 					j->cadence_f[cnt].state = 0;
 				}
@@ -1700,58 +2592,128 @@
 						   !j->cadence_f[cnt].off1 &&
 						   !j->cadence_f[cnt].on2 && !j->cadence_f[cnt].off2 &&
 						   !j->cadence_f[cnt].on3 && !j->cadence_f[cnt].off3) {
-							j->cadence_f[cnt].state = 6;
+							j->cadence_f[cnt].state = 7;
 						}
 						break;
 					case 3:
 						if(time_after(jiffies, j->cadence_f[cnt].on2dot) &&
 						   !j->cadence_f[cnt].off2 &&
 						   !j->cadence_f[cnt].on3 && !j->cadence_f[cnt].off3) {
-							j->cadence_f[cnt].state = 6;
+							j->cadence_f[cnt].state = 7;
 						}
 						break;
 					case 5:
 						if(time_after(jiffies, j->cadence_f[cnt].on3dot) &&
 						   !j->cadence_f[cnt].off3) {
-							j->cadence_f[cnt].state = 6;
+							j->cadence_f[cnt].state = 7;
 						}
 						break;
 				}
 			}
+
+			if (ixjdebug & 0x0040) {
+				printk(KERN_INFO "IXJ Tone Cadence state = %d /dev/phone%d at %ld\n", j->cadence_f[cnt].state, j->board, jiffies);
+				switch(j->cadence_f[cnt].state) {
+					case 0:
+						printk(KERN_INFO "IXJ /dev/phone%d No Tone detected\n", j->board);
+						break;
+					case 1:
+						printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %u %ld - %ld - %ld\n", j->board,
+					j->cadence_f[cnt].on1, j->cadence_f[cnt].on1min, j->cadence_f[cnt].on1dot, j->cadence_f[cnt].on1max);
+						break;
+					case 2:
+						printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].off1min, 
+															j->cadence_f[cnt].off1max);
+						break;
+					case 3:
+						printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].on2min,
+															j->cadence_f[cnt].on2max);
+						break;
+					case 4:
+						printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].off2min,
+															j->cadence_f[cnt].off2max);
+						break;
+					case 5:
+						printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].on3min,
+															j->cadence_f[cnt].on3max);
+						break;
+					case 6:	
+						printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].off3min,
+															j->cadence_f[cnt].off3max);
+						break;
+				}
+			} 
 		}
-		if (j->cadence_f[cnt].state == 6) {
+		if (j->cadence_f[cnt].state == 7) {
 			j->cadence_f[cnt].state = 0;
 			if (j->cadence_f[cnt].enable == 1)
 				j->cadence_f[cnt].enable = 0;
 			switch (cnt) {
 			case 0:
+				if(ixjdebug & 0x0020) {
+					printk(KERN_INFO "Filter Cadence 0 triggered %ld\n", jiffies);
+				}
 				j->ex.bits.fc0 = 1;
+				ixj_kill_fasync(j, SIG_FC0, POLL_IN);
 				break;
 			case 1:
+				if(ixjdebug & 0x0020) {
+					printk(KERN_INFO "Filter Cadence 1 triggered %ld\n", jiffies);
+				}
 				j->ex.bits.fc1 = 1;
+				ixj_kill_fasync(j, SIG_FC1, POLL_IN);
 				break;
 			case 2:
+				if(ixjdebug & 0x0020) {
+					printk(KERN_INFO "Filter Cadence 2 triggered %ld\n", jiffies);
+				}
 				j->ex.bits.fc2 = 1;
+				ixj_kill_fasync(j, SIG_FC2, POLL_IN);
 				break;
 			case 3:
+				if(ixjdebug & 0x0020) {
+					printk(KERN_INFO "Filter Cadence 3 triggered %ld\n", jiffies);
+				}
 				j->ex.bits.fc3 = 1;
+				ixj_kill_fasync(j, SIG_FC3, POLL_IN);
 				break;
 			}
 		}
 		if (j->filter_en[cnt] && ((j->filter_hist[cnt] & 3 && !(j->filter_hist[cnt] & 12)) ||
 					  (j->filter_hist[cnt] & 12 && !(j->filter_hist[cnt] & 3)))) {
+			if((j->filter_hist[cnt] & 3 && !(j->filter_hist[cnt] & 12))) {
+				trg = 1;
+			} else if((j->filter_hist[cnt] & 12 && !(j->filter_hist[cnt] & 3))) {
+				trg = 0;
+			}
 			switch (cnt) {
 			case 0:
+				if(ixjdebug & 0x0020) {
+					printk(KERN_INFO "Filter 0 triggered %d at %ld\n", trg, jiffies);
+				}
 				j->ex.bits.f0 = 1;
+				ixj_kill_fasync(j, SIG_F0, POLL_IN);
 				break;
 			case 1:
+				if(ixjdebug & 0x0020) {
+					printk(KERN_INFO "Filter 1 triggered %d at %ld\n", trg, jiffies);
+				}
 				j->ex.bits.f1 = 1;
+				ixj_kill_fasync(j, SIG_F1, POLL_IN);
 				break;
 			case 2:
+				if(ixjdebug & 0x0020) {
+					printk(KERN_INFO "Filter 2 triggered %d at %ld\n", trg, jiffies);
+				}
 				j->ex.bits.f2 = 1;
+				ixj_kill_fasync(j, SIG_F2, POLL_IN);
 				break;
 			case 3:
+				if(ixjdebug & 0x0020) {
+					printk(KERN_INFO "Filter 3 triggered %d at %ld\n", trg, jiffies);
+				}
 				j->ex.bits.f3 = 1;
+				ixj_kill_fasync(j, SIG_F3, POLL_IN);
 				break;
 			}
 		}
@@ -1766,7 +2728,7 @@
 	}
 	j->dtmf_proc = 1;
 
-	if (ixj_WriteDSPCommand(0x7000, j))		// Line Monitor
+	if (ixj_WriteDSPCommand(0x7000, j))		/* Line Monitor */
 		return -1;
 
 	j->dtmf.bytes.high = j->ssr.high;
@@ -1775,16 +2737,22 @@
 		j->dtmf_state = 1;
 		j->dtmf_current = j->dtmf.bits.digit;
 	}
-	if (j->dtmf_state && !j->dtmf.bits.dtmf_valid)	// && j->dtmf_wp != j->dtmf_rp)
+	if (j->dtmf_state && !j->dtmf.bits.dtmf_valid)	/* && j->dtmf_wp != j->dtmf_rp) */
 	 {
-		if(!j->flags.cidplay) {
+		if(!j->cidcw_wait) {
 			j->dtmfbuffer[j->dtmf_wp] = j->dtmf_current;
 			j->dtmf_wp++;
 			if (j->dtmf_wp == 79)
 				j->dtmf_wp = 0;
 			j->ex.bits.dtmf_ready = 1;
+			if(j->ex_sig.bits.dtmf_ready) {
+				ixj_kill_fasync(j, SIG_DTMF_READY, POLL_IN);
+			}
 		}
-		else if(j->dtmf_current == 25 || j->dtmf_current == 31) {
+		else if(j->dtmf_current == 0x00 || j->dtmf_current == 0x0D) {
+			if(ixjdebug & 0x0020) {
+				printk("IXJ phone%d saw CIDCW Ack DTMF %d from display at %ld\n", j->board, j->dtmf_current, jiffies);
+			}
 			j->flags.cidcw_ack = 1;
 		}
 		j->dtmf_state = 0;
@@ -1794,14 +2762,102 @@
 	return 0;
 }
 
-ssize_t ixj_read(struct file * file_p, char *buf, size_t length, loff_t * ppos)
+/************************************************************************
+*
+* Functions to allow alaw <-> ulaw conversions.
+*
+************************************************************************/
+
+static void ulaw2alaw(unsigned char *buff, unsigned long len)
+{
+	static unsigned char table_ulaw2alaw[] =
+	{
+		0x2A, 0x2B, 0x28, 0x29, 0x2E, 0x2F, 0x2C, 0x2D, 
+		0x22, 0x23, 0x20, 0x21, 0x26, 0x27, 0x24, 0x25, 
+		0x3A, 0x3B, 0x38, 0x39, 0x3E, 0x3F, 0x3C, 0x3D, 
+		0x32, 0x33, 0x30, 0x31, 0x36, 0x37, 0x34, 0x35, 
+		0x0B, 0x08, 0x09, 0x0E, 0x0F, 0x0C, 0x0D, 0x02, 
+		0x03, 0x00, 0x01, 0x06, 0x07, 0x04, 0x05, 0x1A, 
+		0x1B, 0x18, 0x19, 0x1E, 0x1F, 0x1C, 0x1D, 0x12, 
+		0x13, 0x10, 0x11, 0x16, 0x17, 0x14, 0x15, 0x6B, 
+		0x68, 0x69, 0x6E, 0x6F, 0x6C, 0x6D, 0x62, 0x63, 
+		0x60, 0x61, 0x66, 0x67, 0x64, 0x65, 0x7B, 0x79, 
+		0x7E, 0x7F, 0x7C, 0x7D, 0x72, 0x73, 0x70, 0x71, 
+		0x76, 0x77, 0x74, 0x75, 0x4B, 0x49, 0x4F, 0x4D, 
+		0x42, 0x43, 0x40, 0x41, 0x46, 0x47, 0x44, 0x45, 
+		0x5A, 0x5B, 0x58, 0x59, 0x5E, 0x5F, 0x5C, 0x5D, 
+		0x52, 0x52, 0x53, 0x53, 0x50, 0x50, 0x51, 0x51, 
+		0x56, 0x56, 0x57, 0x57, 0x54, 0x54, 0x55, 0xD5, 
+		0xAA, 0xAB, 0xA8, 0xA9, 0xAE, 0xAF, 0xAC, 0xAD, 
+		0xA2, 0xA3, 0xA0, 0xA1, 0xA6, 0xA7, 0xA4, 0xA5, 
+		0xBA, 0xBB, 0xB8, 0xB9, 0xBE, 0xBF, 0xBC, 0xBD, 
+		0xB2, 0xB3, 0xB0, 0xB1, 0xB6, 0xB7, 0xB4, 0xB5, 
+		0x8B, 0x88, 0x89, 0x8E, 0x8F, 0x8C, 0x8D, 0x82, 
+		0x83, 0x80, 0x81, 0x86, 0x87, 0x84, 0x85, 0x9A, 
+		0x9B, 0x98, 0x99, 0x9E, 0x9F, 0x9C, 0x9D, 0x92, 
+		0x93, 0x90, 0x91, 0x96, 0x97, 0x94, 0x95, 0xEB, 
+		0xE8, 0xE9, 0xEE, 0xEF, 0xEC, 0xED, 0xE2, 0xE3, 
+		0xE0, 0xE1, 0xE6, 0xE7, 0xE4, 0xE5, 0xFB, 0xF9, 
+		0xFE, 0xFF, 0xFC, 0xFD, 0xF2, 0xF3, 0xF0, 0xF1, 
+		0xF6, 0xF7, 0xF4, 0xF5, 0xCB, 0xC9, 0xCF, 0xCD, 
+		0xC2, 0xC3, 0xC0, 0xC1, 0xC6, 0xC7, 0xC4, 0xC5, 
+		0xDA, 0xDB, 0xD8, 0xD9, 0xDE, 0xDF, 0xDC, 0xDD, 
+		0xD2, 0xD2, 0xD3, 0xD3, 0xD0, 0xD0, 0xD1, 0xD1, 
+		0xD6, 0xD6, 0xD7, 0xD7, 0xD4, 0xD4, 0xD5, 0xD5
+	};
+
+	while (len--)
+		*buff++ = table_ulaw2alaw[*(unsigned char *)buff];
+}
+
+static void alaw2ulaw(unsigned char *buff, unsigned long len)
+{
+	static unsigned char table_alaw2ulaw[] =
+	{
+		0x29, 0x2A, 0x27, 0x28, 0x2D, 0x2E, 0x2B, 0x2C, 
+		0x21, 0x22, 0x1F, 0x20, 0x25, 0x26, 0x23, 0x24, 
+		0x39, 0x3A, 0x37, 0x38, 0x3D, 0x3E, 0x3B, 0x3C, 
+		0x31, 0x32, 0x2F, 0x30, 0x35, 0x36, 0x33, 0x34, 
+		0x0A, 0x0B, 0x08, 0x09, 0x0E, 0x0F, 0x0C, 0x0D, 
+		0x02, 0x03, 0x00, 0x01, 0x06, 0x07, 0x04, 0x05, 
+		0x1A, 0x1B, 0x18, 0x19, 0x1E, 0x1F, 0x1C, 0x1D, 
+		0x12, 0x13, 0x10, 0x11, 0x16, 0x17, 0x14, 0x15, 
+		0x62, 0x63, 0x60, 0x61, 0x66, 0x67, 0x64, 0x65, 
+		0x5D, 0x5D, 0x5C, 0x5C, 0x5F, 0x5F, 0x5E, 0x5E, 
+		0x74, 0x76, 0x70, 0x72, 0x7C, 0x7E, 0x78, 0x7A, 
+		0x6A, 0x6B, 0x68, 0x69, 0x6E, 0x6F, 0x6C, 0x6D, 
+		0x48, 0x49, 0x46, 0x47, 0x4C, 0x4D, 0x4A, 0x4B, 
+		0x40, 0x41, 0x3F, 0x3F, 0x44, 0x45, 0x42, 0x43, 
+		0x56, 0x57, 0x54, 0x55, 0x5A, 0x5B, 0x58, 0x59, 
+		0x4F, 0x4F, 0x4E, 0x4E, 0x52, 0x53, 0x50, 0x51, 
+		0xA9, 0xAA, 0xA7, 0xA8, 0xAD, 0xAE, 0xAB, 0xAC, 
+		0xA1, 0xA2, 0x9F, 0xA0, 0xA5, 0xA6, 0xA3, 0xA4, 
+		0xB9, 0xBA, 0xB7, 0xB8, 0xBD, 0xBE, 0xBB, 0xBC, 
+		0xB1, 0xB2, 0xAF, 0xB0, 0xB5, 0xB6, 0xB3, 0xB4, 
+		0x8A, 0x8B, 0x88, 0x89, 0x8E, 0x8F, 0x8C, 0x8D, 
+		0x82, 0x83, 0x80, 0x81, 0x86, 0x87, 0x84, 0x85, 
+		0x9A, 0x9B, 0x98, 0x99, 0x9E, 0x9F, 0x9C, 0x9D, 
+		0x92, 0x93, 0x90, 0x91, 0x96, 0x97, 0x94, 0x95, 
+		0xE2, 0xE3, 0xE0, 0xE1, 0xE6, 0xE7, 0xE4, 0xE5, 
+		0xDD, 0xDD, 0xDC, 0xDC, 0xDF, 0xDF, 0xDE, 0xDE, 
+		0xF4, 0xF6, 0xF0, 0xF2, 0xFC, 0xFE, 0xF8, 0xFA, 
+		0xEA, 0xEB, 0xE8, 0xE9, 0xEE, 0xEF, 0xEC, 0xED, 
+		0xC8, 0xC9, 0xC6, 0xC7, 0xCC, 0xCD, 0xCA, 0xCB, 
+		0xC0, 0xC1, 0xBF, 0xBF, 0xC4, 0xC5, 0xC2, 0xC3, 
+		0xD6, 0xD7, 0xD4, 0xD5, 0xDA, 0xDB, 0xD8, 0xD9, 
+		0xCF, 0xCF, 0xCE, 0xCE, 0xD2, 0xD3, 0xD0, 0xD1
+	};
+
+        while (len--)
+                *buff++ = table_alaw2ulaw[*(unsigned char *)buff];
+}
+
+static ssize_t ixj_read(struct file * file_p, char *buf, size_t length, loff_t * ppos)
 {
 	unsigned long i = *ppos;
-	IXJ *j = ixj[NUM(file_p->f_dentry->d_inode->i_rdev)];
-	DECLARE_WAITQUEUE(wait, current);
+	IXJ * j = get_ixj(NUM(file_p->f_dentry->d_inode->i_rdev));
 
-	if (j == NULL) /* shouldn't happen! */
-		return -ENODEV;
+	DECLARE_WAITQUEUE(wait, current);
 
 	if (j->flags.inread)
 		return -EALREADY;
@@ -1814,12 +2870,6 @@
 
 	while (!j->read_buffer_ready || (j->dtmf_state && j->flags.dtmf_oob)) {
 		++j->read_wait;
-		if(j->tone_state) {
-			set_current_state(TASK_RUNNING);
-			remove_wait_queue(&j->read_q, &wait);
-			j->flags.inread = 0;
-			return -EAGAIN;
-		}
 		if (file_p->f_flags & O_NONBLOCK) {
 			set_current_state(TASK_RUNNING);
 			remove_wait_queue(&j->read_q, &wait);
@@ -1844,27 +2894,25 @@
 	remove_wait_queue(&j->read_q, &wait);
 	set_current_state(TASK_RUNNING);
 	/* Don't ever copy more than the user asks */
-	i = copy_to_user(buf, j->read_buffer,
-			 min(unsigned int, length, j->read_buffer_size));
+	if(j->rec_codec == ALAW)
+		ulaw2alaw(j->read_buffer, min(length, j->read_buffer_size));
+	i = copy_to_user(buf, j->read_buffer, min(length, j->read_buffer_size));
 	j->read_buffer_ready = 0;
 	if (i) {
 		j->flags.inread = 0;
 		return -EFAULT;
 	} else {
 		j->flags.inread = 0;
-		return min(unsigned int, length, j->read_buffer_size);
+		return min(length, j->read_buffer_size);
 	}
 }
 
-ssize_t ixj_enhanced_read(struct file * file_p, char *buf, size_t length,
+static ssize_t ixj_enhanced_read(struct file * file_p, char *buf, size_t length,
 			  loff_t * ppos)
 {
 	int pre_retval;
 	ssize_t read_retval = 0;
-	IXJ *j = ixj[NUM(file_p->f_dentry->d_inode->i_rdev)];
-
-	if (j == NULL) /* shouldn't happen! */
-		return -ENODEV;
+	IXJ *j = get_ixj(NUM(file_p->f_dentry->d_inode->i_rdev));
 
 	pre_retval = ixj_PreRead(j, 0L);
 	switch (pre_retval) {
@@ -1884,14 +2932,12 @@
 	return read_retval;
 }
 
-ssize_t ixj_write(struct file *file_p, const char *buf, size_t count, loff_t * ppos)
+static ssize_t ixj_write(struct file *file_p, const char *buf, size_t count, loff_t * ppos)
 {
 	unsigned long i = *ppos;
 	IXJ *j = file_p->private_data;
-	DECLARE_WAITQUEUE(wait, current);
 
-	if (j == NULL) /* shouldn't happen! */
-		return -ENODEV;
+	DECLARE_WAITQUEUE(wait, current);
 
 	if (j->flags.inwrite)
 		return -EALREADY;
@@ -1905,12 +2951,6 @@
 
 	while (!j->write_buffers_empty) {
 		++j->write_wait;
-		if(j->tone_state) {
-			set_current_state(TASK_RUNNING);
-			remove_wait_queue(&j->write_q, &wait);
-			j->flags.inwrite = 0;
-			return -EAGAIN;
-		}
 		if (file_p->f_flags & O_NONBLOCK) {
 			set_current_state(TASK_RUNNING);
 			remove_wait_queue(&j->write_q, &wait);
@@ -1935,30 +2975,29 @@
 	remove_wait_queue(&j->write_q, &wait);
 	if (j->write_buffer_wp + count >= j->write_buffer_end)
 		j->write_buffer_wp = j->write_buffer;
-	i = copy_from_user(j->write_buffer_wp, buf,
-			   min(unsigned int, count, j->write_buffer_size));
+	i = copy_from_user(j->write_buffer_wp, buf, min(count, j->write_buffer_size));
 	if (i) {
 		j->flags.inwrite = 0;
 		return -EFAULT;
 	}
+       if(j->play_codec == ALAW)
+               alaw2ulaw(j->write_buffer_wp, min(count, j->write_buffer_size));
 	j->flags.inwrite = 0;
-	return min(unsigned int, count, j->write_buffer_size);
+	return min(count, j->write_buffer_size);
 }
 
-ssize_t ixj_enhanced_write(struct file * file_p, const char *buf, size_t count, loff_t * ppos)
+static ssize_t ixj_enhanced_write(struct file * file_p, const char *buf, size_t count, loff_t * ppos)
 {
 	int pre_retval;
 	ssize_t write_retval = 0;
-	IXJ *j = ixj[NUM(file_p->f_dentry->d_inode->i_rdev)];
 
-	if (j == NULL) /* shouldn't happen! */
-		return -ENODEV;
+	IXJ *j = get_ixj(NUM(file_p->f_dentry->d_inode->i_rdev));
 
 	pre_retval = ixj_PreWrite(j, 0L);
 	switch (pre_retval) {
 	case NORMAL:
 		write_retval = ixj_write(file_p, buf, count, ppos);
-		if (write_retval != -EFAULT) {
+		if (write_retval > 0) {
 			ixj_PostWrite(j, 0L);
 			j->write_buffer_wp += write_retval;
 			j->write_buffers_empty--;
@@ -1966,7 +3005,7 @@
 		break;
 	case NOPOST:
 		write_retval = ixj_write(file_p, buf, count, ppos);
-		if (write_retval != -EFAULT) {
+		if (write_retval > 0) {
 			j->write_buffer_wp += write_retval;
 			j->write_buffers_empty--;
 		}
@@ -1996,8 +3035,8 @@
 					udelay(10);
 				}
 			}
-			// Throw away word 0 of the 8021 compressed format to get standard G.729.
-			if (j->rec_codec == G729 && (cnt == 0 || cnt == 5 || cnt == 10)) {
+			/* Throw away word 0 of the 8021 compressed format to get standard G.729. */
+			if (j->rec_codec == G729 && (cnt == 0 || cnt == 10 || cnt == 20)) {
 				inb_p(j->DSPbase + 0x0E);
 				inb_p(j->DSPbase + 0x0F);
 			}
@@ -2006,15 +3045,7 @@
 		}
 		++j->framesread;
 		if (j->intercom != -1) {
-			IXJ *icom = ixj[j->intercom];
-
-			if (icom == NULL) { /* shouldn't happen! */
-				printk(KERN_ERR "ixj_read_frame(): j->intercom = %d = NULL!",
-				       j->intercom);
-				return;
-			}
-
-			if (IsTxReady(icom)) {
+			if (IsTxReady(get_ixj(j->intercom))) {
 				for (cnt = 0; cnt < j->rec_frame_size * 2; cnt += 2) {
 					if (!(cnt % 16) && !IsTxReady(j)) {
 						dly = 0;
@@ -2026,18 +3057,19 @@
 							udelay(10);
 						}
 					}
-					outb_p(*(j->read_buffer + cnt), icom->DSPbase + 0x0C);
-					outb_p(*(j->read_buffer + cnt + 1), icom->DSPbase + 0x0D);
+					outb_p(*(j->read_buffer + cnt), get_ixj(j->intercom)->DSPbase + 0x0C);
+					outb_p(*(j->read_buffer + cnt + 1), get_ixj(j->intercom)->DSPbase + 0x0D);
 				}
-				++icom->frameswritten;
+				get_ixj(j->intercom)->frameswritten++;
 			}
 		} else {
 			j->read_buffer_ready = 1;
-			wake_up_interruptible(&j->read_q);	// Wake any blocked readers
+			wake_up_interruptible(&j->read_q);	/* Wake any blocked readers */
 
-			wake_up_interruptible(&j->poll_q);	// Wake any blocked selects
+			wake_up_interruptible(&j->poll_q);	/* Wake any blocked selects */
 
-			ixj_kill_fasync(j, POLL_IN);
+			if(j->ixj_signals[SIG_READ_READY])
+				ixj_kill_fasync(j, SIG_READ_READY, POLL_OUT);
 		}
 	}
 }
@@ -2101,25 +3133,10 @@
 
 static void ixj_write_cid_bit(IXJ *j, int bit)
 {
-	int dly;
-	IXJ_WORD dat;
-
 	while (j->fskcnt < 20) {
-		if (!IsTxReady(j)) {
-			dly = 0;
-			while (!IsTxReady(j)) {
-				if (dly++ > 5) {
-					dly = 0;
-					//      break;
-					//      printk("CID delay\n");
-				}
-				udelay(10);
-			}
-		}
-		dat.word = j->fskdata[j->fskdcnt++] =
-		    fsk[bit][j->fskz][j->fskcnt];
-		outb_p(dat.bytes.low, j->DSPbase + 0x0C);
-		outb_p(dat.bytes.high, j->DSPbase + 0x0D);
+		if(j->fskdcnt < (j->fsksize - 1))
+			j->fskdata[j->fskdcnt++] = fsk[bit][j->fskz][j->fskcnt];
+
 		j->fskcnt += 3;
 	}
 	j->fskcnt %= 20;
@@ -2131,52 +3148,51 @@
 
 }
 
-static void ixj_write_cid_byte(IXJ *board, char byte)
+static void ixj_write_cid_byte(IXJ *j, char byte)
 {
 	IXJ_CBYTE cb;
 
-//  printk("Writing CID data %x - %c\n", byte, byte);
-	cb.cbyte = byte;
-	ixj_write_cid_bit(board, 0);
-	ixj_write_cid_bit(board, cb.cbits.b0 ? 1 : 0);
-	ixj_write_cid_bit(board, cb.cbits.b1 ? 1 : 0);
-	ixj_write_cid_bit(board, cb.cbits.b2 ? 1 : 0);
-	ixj_write_cid_bit(board, cb.cbits.b3 ? 1 : 0);
-	ixj_write_cid_bit(board, cb.cbits.b4 ? 1 : 0);
-	ixj_write_cid_bit(board, cb.cbits.b5 ? 1 : 0);
-	ixj_write_cid_bit(board, cb.cbits.b6 ? 1 : 0);
-	ixj_write_cid_bit(board, cb.cbits.b7 ? 1 : 0);
-	ixj_write_cid_bit(board, 1);
+		cb.cbyte = byte;
+		ixj_write_cid_bit(j, 0);
+		ixj_write_cid_bit(j, cb.cbits.b0 ? 1 : 0);
+		ixj_write_cid_bit(j, cb.cbits.b1 ? 1 : 0);
+		ixj_write_cid_bit(j, cb.cbits.b2 ? 1 : 0);
+		ixj_write_cid_bit(j, cb.cbits.b3 ? 1 : 0);
+		ixj_write_cid_bit(j, cb.cbits.b4 ? 1 : 0);
+		ixj_write_cid_bit(j, cb.cbits.b5 ? 1 : 0);
+		ixj_write_cid_bit(j, cb.cbits.b6 ? 1 : 0);
+		ixj_write_cid_bit(j, cb.cbits.b7 ? 1 : 0);
+		ixj_write_cid_bit(j, 1);
 }
 
-static void ixj_write_cid_seize(IXJ *board)
+static void ixj_write_cid_seize(IXJ *j)
 {
 	int cnt;
 
 	for (cnt = 0; cnt < 150; cnt++) {
-		ixj_write_cid_bit(board, 0);
-		ixj_write_cid_bit(board, 1);
+		ixj_write_cid_bit(j, 0);
+		ixj_write_cid_bit(j, 1);
 	}
 	for (cnt = 0; cnt < 180; cnt++) {
-		ixj_write_cid_bit(board, 1);
+		ixj_write_cid_bit(j, 1);
 	}
 }
 
-static void ixj_write_cidcw_seize(IXJ *board)
+static void ixj_write_cidcw_seize(IXJ *j)
 {
 	int cnt;
 
 	for (cnt = 0; cnt < 80; cnt++) {
-		ixj_write_cid_bit(board, 1);
+		ixj_write_cid_bit(j, 1);
 	}
 }
 
-static int ixj_write_cid_string(IXJ *board, char *s, int checksum)
+static int ixj_write_cid_string(IXJ *j, char *s, int checksum)
 {
 	int cnt;
 
 	for (cnt = 0; cnt < strlen(s); cnt++) {
-		ixj_write_cid_byte(board, s[cnt]);
+		ixj_write_cid_byte(j, s[cnt]);
 		checksum = (checksum + s[cnt]);
 	}
 	return checksum;
@@ -2184,33 +3200,85 @@
 
 static void ixj_pad_fsk(IXJ *j, int pad)
 {
-	int cnt, dly;
+	int cnt; 
 
 	for (cnt = 0; cnt < pad; cnt++) {
-		if (!IsTxReady(j)) {
-			dly = 0;
-			while (!IsTxReady(j)) {
-				if (dly++ > 5) {
-					dly = 0;
-				}
-				udelay(10);
-			}
-		}
-		outb_p(0x00, j->DSPbase + 0x0C);
-		outb_p(0x00, j->DSPbase + 0x0D);
+		if(j->fskdcnt < (j->fsksize - 1))
+			j->fskdata[j->fskdcnt++] = 0x0000;
 	}
 	for (cnt = 0; cnt < 720; cnt++) {
-		if (!IsTxReady(j)) {
-			dly = 0;
-			while (!IsTxReady(j)) {
-				if (dly++ > 5) {
-					dly = 0;
-				}
-				udelay(10);
-			}
-		}
-		outb_p(0x00, j->DSPbase + 0x0C);
-		outb_p(0x00, j->DSPbase + 0x0D);
+		if(j->fskdcnt < (j->fsksize - 1))
+			j->fskdata[j->fskdcnt++] = 0x0000;
+	}
+}
+
+static void ixj_pre_cid(IXJ *j)
+{
+	j->cid_play_codec = j->play_codec;
+	j->cid_play_frame_size = j->play_frame_size;
+	j->cid_play_volume = get_play_volume(j);
+	j->cid_play_flag = j->flags.playing;
+
+	j->cid_rec_codec = j->rec_codec;
+	j->cid_rec_volume = get_rec_volume(j);
+	j->cid_rec_flag = j->flags.recording;
+
+	j->cid_play_aec_level = j->aec_level;
+
+	switch(j->baseframe.low) {
+		case 0xA0:
+			j->cid_base_frame_size = 20;
+			break;
+		case 0x50:
+			j->cid_base_frame_size = 10;
+			break;
+		case 0xF0:
+			j->cid_base_frame_size = 30;
+			break;
+	}
+
+	ixj_play_stop(j);
+	ixj_cpt_stop(j);
+
+	j->flags.cidplay = 1;
+
+	set_base_frame(j, 30);
+	set_play_codec(j, LINEAR16);
+	set_play_volume(j, 0x1B);
+	ixj_play_start(j);
+}
+
+static void ixj_post_cid(IXJ *j)
+{
+	ixj_play_stop(j);
+
+	if(j->cidsize > 5000) {
+		SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
+	}
+	j->flags.cidplay = 0;
+	if(ixjdebug & 0x0200) {
+		printk("IXJ phone%d Finished Playing CallerID data %ld\n", j->board, jiffies);
+	}
+
+	ixj_fsk_free(j);
+
+	j->fskdcnt = 0;
+	set_base_frame(j, j->cid_base_frame_size);
+	set_play_codec(j, j->cid_play_codec);
+	ixj_aec_start(j, j->cid_play_aec_level);
+	set_play_volume(j, j->cid_play_volume);
+
+	set_rec_codec(j, j->cid_rec_codec);
+	set_rec_volume(j, j->cid_rec_volume);
+
+	if(j->cid_rec_flag)
+		ixj_record_start(j);
+
+	if(j->cid_play_flag)
+		ixj_play_start(j);
+
+	if(j->cid_play_flag) {
+		wake_up_interruptible(&j->write_q);	/* Wake any blocked writers */
 	}
 }
 
@@ -2224,13 +3292,13 @@
 
 	int checksum = 0;
 
-	if (j->dsp.low == 0x20)
+	if (j->dsp.low == 0x20 || j->flags.cidplay)
 		return;
 
-	j->fskz = j->fskphase = j->fskcnt =
-	    j->fskdcnt = 0;
+	j->fskz = j->fskphase = j->fskcnt = j->fskdcnt = 0;
+	j->cidsize = j->cidcnt = 0;
 
-	j->flags.cidplay = 1;
+	ixj_fsk_alloc(j);
 
 	strcpy(sdmf1, j->cid_send.month);
 	strcat(sdmf1, j->cid_send.day);
@@ -2244,54 +3312,53 @@
 	len3 = strlen(sdmf3);
 	mdmflen = len1 + len2 + len3 + 6;
 
-	set_base_frame(j, 30);
-	set_play_codec(j, LINEAR16);
-
-	if (j->port == PORT_POTS)
-		if(!j->r_hook)
-			SLIC_SetState(PLD_SLIC_STATE_OHT, j);
-
-	set_play_volume(j, 0x1B);
-	ixj_play_start(j);
-	ixj_write_cid_seize(j);
-
-	ixj_write_cid_byte(j, 0x80);
-	checksum = 0x80;
-	ixj_write_cid_byte(j, mdmflen);
-	checksum = checksum + mdmflen;
+	while(1){
+		ixj_write_cid_seize(j);
 
-	ixj_write_cid_byte(j, 0x01);
-	checksum = checksum + 0x01;
-	ixj_write_cid_byte(j, len1);
-	checksum = checksum + len1;
-	checksum = ixj_write_cid_string(j, sdmf1, checksum);
+		ixj_write_cid_byte(j, 0x80);
+		checksum = 0x80;
+		ixj_write_cid_byte(j, mdmflen);
+		checksum = checksum + mdmflen;
 
-	ixj_write_cid_byte(j, 0x02);
-	checksum = checksum + 0x02;
-	ixj_write_cid_byte(j, len2);
-	checksum = checksum + len2;
-	checksum = ixj_write_cid_string(j, sdmf2, checksum);
+		ixj_write_cid_byte(j, 0x01);
+		checksum = checksum + 0x01;
+		ixj_write_cid_byte(j, len1);
+		checksum = checksum + len1;
+		checksum = ixj_write_cid_string(j, sdmf1, checksum);
+		if(ixj_hookstate(j) & 1)
+			break;
 
-	ixj_write_cid_byte(j, 0x07);
-	checksum = checksum + 0x07;
-	ixj_write_cid_byte(j, len3);
-	checksum = checksum + len3;
-	checksum = ixj_write_cid_string(j, sdmf3, checksum);
+		ixj_write_cid_byte(j, 0x02);
+		checksum = checksum + 0x02;
+		ixj_write_cid_byte(j, len2);
+		checksum = checksum + len2;
+		checksum = ixj_write_cid_string(j, sdmf2, checksum);
+		if(ixj_hookstate(j) & 1)
+			break;
 
-	checksum %= 256;
-	checksum ^= 0xFF;
-	checksum += 1;
+		ixj_write_cid_byte(j, 0x07);
+		checksum = checksum + 0x07;
+		ixj_write_cid_byte(j, len3);
+		checksum = checksum + len3;
+		checksum = ixj_write_cid_string(j, sdmf3, checksum);
+		if(ixj_hookstate(j) & 1)
+			break;
 
-	ixj_write_cid_byte(j, (char) checksum);
+		checksum %= 256;
+		checksum ^= 0xFF;
+		checksum += 1;
 
-	pad = j->fskdcnt % 240;
-	if (pad) {
-		pad = 240 - pad;
+		ixj_write_cid_byte(j, (char) checksum);
+
+		pad = j->fskdcnt % 240;
+		if (pad) {
+			pad = 240 - pad;
+		}
+		ixj_pad_fsk(j, pad);
+		break;
 	}
-	ixj_pad_fsk(j, pad);
-	SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
-	j->flags.cidplay = 0;
-	ixj_play_stop(j);
+
+	ixj_write_frame(j);
 }
 
 static void ixj_write_cidcw(IXJ *j)
@@ -2306,12 +3373,15 @@
 
 	int checksum = 0;
 
-	if (j->dsp.low == 0x20)
+	if (j->dsp.low == 0x20 || j->flags.cidplay)
 		return;
 
 	j->fskz = j->fskphase = j->fskcnt = j->fskdcnt = 0;
+	j->cidsize = j->cidcnt = 0;
 
-	j->flags.cidplay = 1;
+	ixj_fsk_alloc(j);
+
+	j->flags.cidcw_ack = 0;
 
 	ti.tone_index = 23;
 	ti.gain0 = 1;
@@ -2320,6 +3390,26 @@
 	ti.freq1 = 0;
 	ixj_init_tone(j, &ti);
 
+	ixj_set_tone_on(1500, j);
+	ixj_set_tone_off(32, j);
+	if(ixjdebug & 0x0200) {
+		printk("IXJ cidcw phone%d first tone start at %ld\n", j->board, jiffies);
+	}
+	ixj_play_tone(j, 23);
+
+	clear_bit(j->board, &j->busyflags);
+	while(j->tone_state) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(1);
+	}
+	while(test_and_set_bit(j->board, (void *)&j->busyflags) != 0) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(1);
+	}
+	if(ixjdebug & 0x0200) {
+		printk("IXJ cidcw phone%d first tone end at %ld\n", j->board, jiffies);
+	}
+
 	ti.tone_index = 24;
 	ti.gain0 = 1;
 	ti.freq0 = hz2130;
@@ -2327,33 +3417,51 @@
 	ti.freq1 = hz2750;
 	ixj_init_tone(j, &ti);
 
-	ixj_set_tone_on(1200, j);
-	ixj_play_tone(j, 23);
+	ixj_set_tone_off(10, j);
+	ixj_set_tone_on(600, j);
+	if(ixjdebug & 0x0200) {
+		printk("IXJ cidcw phone%d second tone start at %ld\n", j->board, jiffies);
+	}
+	ixj_play_tone(j, 24);
 
+	clear_bit(j->board, &j->busyflags);
 	while(j->tone_state) {
 		set_current_state(TASK_INTERRUPTIBLE);
 		schedule_timeout(1);
 	}
-
-	ixj_set_tone_on(320, j);
-	ixj_play_tone(j, 24);
-
-	while(j->tone_state) {
+	while(test_and_set_bit(j->board, (void *)&j->busyflags) != 0) {
 		set_current_state(TASK_INTERRUPTIBLE);
 		schedule_timeout(1);
 	}
+	if(ixjdebug & 0x0200) {
+		printk("IXJ cidcw phone%d sent second tone at %ld\n", j->board, jiffies);
+	}
 
-	j->cidcw_wait = jiffies + (200 * hertz / 100000);
+	j->cidcw_wait = jiffies + ((50 * hertz) / 100);
 
+	clear_bit(j->board, &j->busyflags);
 	while(!j->flags.cidcw_ack && time_before(jiffies, j->cidcw_wait)) {
 		set_current_state(TASK_INTERRUPTIBLE);
 		schedule_timeout(1);
 	}
-
+	while(test_and_set_bit(j->board, (void *)&j->busyflags) != 0) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(1);
+	}
+	j->cidcw_wait = 0;
 	if(!j->flags.cidcw_ack) {
+		if(ixjdebug & 0x0200) {
+			printk("IXJ cidcw phone%d did not recieve ACK from display %ld\n", j->board, jiffies);
+		}
+		ixj_post_cid(j);
+		if(j->cid_play_flag) {
+			wake_up_interruptible(&j->write_q);	/* Wake any blocked readers */
+		}
 		return;
+	} else {
+		ixj_pre_cid(j);
 	}
-
+	j->flags.cidcw_ack = 0;
 	strcpy(sdmf1, j->cid_send.month);
 	strcat(sdmf1, j->cid_send.day);
 	strcat(sdmf1, j->cid_send.hour);
@@ -2366,25 +3474,6 @@
 	len3 = strlen(sdmf3);
 	mdmflen = len1 + len2 + len3 + 6;
 
-	j->cid_play_codec = j->play_codec;
-	ixj_play_stop(j);
-
-	switch(j->baseframe.low) {
-		case 0xA0:
-			j->cid_base_frame_size = 20;
-			break;
-		case 0x50:
-			j->cid_base_frame_size = 10;
-			break;
-		default:
-			j->cid_base_frame_size = 30;
-			break;
-	}
-	set_base_frame(j, 30);
-	set_play_codec(j, LINEAR16);
-
-	set_play_volume(j, 0x1B);
-	ixj_play_start(j);
 	ixj_write_cidcw_seize(j);
 
 	ixj_write_cid_byte(j, 0x80);
@@ -2421,11 +3510,9 @@
 		pad = 240 - pad;
 	}
 	ixj_pad_fsk(j, pad);
-	j->flags.cidplay = 0;
-	ixj_play_stop(j);
-
-	set_base_frame(j, j->cid_base_frame_size);
-	set_play_codec(j, j->cid_play_codec);
+	if(ixjdebug & 0x0200) {
+		printk("IXJ cidcw phone%d sent FSK data at %ld\n", j->board, jiffies);
+	}
 }
 
 static void ixj_write_vmwi(IXJ *j, int msg)
@@ -2435,23 +3522,19 @@
 
 	int checksum = 0;
 
-	if (j->dsp.low == 0x20)
+	if (j->dsp.low == 0x20 || j->flags.cidplay)
 		return;
 
 	j->fskz = j->fskphase = j->fskcnt = j->fskdcnt = 0;
+	j->cidsize = j->cidcnt = 0;
 
-	j->flags.cidplay = 1;
+	ixj_fsk_alloc(j);
 
 	mdmflen = 3;
 
-	set_base_frame(j, 30);
-	set_play_codec(j, LINEAR16);
-
 	if (j->port == PORT_POTS)
 		SLIC_SetState(PLD_SLIC_STATE_OHT, j);
 
-	set_play_volume(j, 0x1B);
-	ixj_play_start(j);
 	ixj_write_cid_seize(j);
 
 	ixj_write_cid_byte(j, 0x82);
@@ -2484,18 +3567,49 @@
 		pad = 240 - pad;
 	}
 	ixj_pad_fsk(j, pad);
-	SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
-	j->flags.cidplay = 0;
-	ixj_play_stop(j);
 }
 
 static void ixj_write_frame(IXJ *j)
 {
 	int cnt, frame_count, dly;
+	IXJ_WORD dat;
 	BYTES blankword;
 
 	frame_count = 0;
-	if (j->write_buffer && j->write_buffers_empty < 2) {
+	if(j->flags.cidplay) {
+		for(cnt = 0; cnt < 480; cnt++) {
+			if (!(cnt % 16) && !IsTxReady(j)) {
+				dly = 0;
+				while (!IsTxReady(j)) {
+					if (dly++ > 5) {
+						dly = 0;
+						break;
+					}
+					udelay(10);
+				}
+			}
+			dat.word = j->fskdata[j->cidcnt++];
+			outb_p(dat.bytes.low, j->DSPbase + 0x0C);
+			outb_p(dat.bytes.high, j->DSPbase + 0x0D);
+			cnt++;
+		}
+		if(j->cidcnt >= j->fskdcnt) {
+			ixj_post_cid(j);
+		}
+		/* This may seem rude, but if we just played one frame of FSK data for CallerID
+		   and there is real audio data in the buffer, we need to throw it away because 
+		   we just used it's time slot */
+		if (j->write_buffer_rp > j->write_buffer_wp) {
+			j->write_buffer_rp += j->cid_play_frame_size * 2;
+			if (j->write_buffer_rp >= j->write_buffer_end) {
+				j->write_buffer_rp = j->write_buffer;
+			}
+			j->write_buffers_empty++;
+			wake_up_interruptible(&j->write_q);	/* Wake any blocked writers */
+
+			wake_up_interruptible(&j->poll_q);	/* Wake any blocked selects */
+		}
+	} else if (j->write_buffer && j->write_buffers_empty < 1) { 
 		if (j->write_buffer_wp > j->write_buffer_rp) {
 			frame_count =
 			    (j->write_buffer_wp - j->write_buffer_rp) / (j->play_frame_size * 2);
@@ -2535,6 +3649,29 @@
 					outb_p((blankword.high), j->DSPbase + 0x0D);
 				}
 				j->flags.play_first_frame = 0;
+			} else	if (j->play_codec == G723_63 && j->flags.play_first_frame) {
+				for (cnt = 0; cnt < 24; cnt++) {
+					if(cnt == 12) {
+						blankword.low = 0x02;
+						blankword.high = 0x00;
+					}
+					else {
+						blankword.low = blankword.high = 0x00;
+					}
+					if (!(cnt % 16) && !IsTxReady(j)) {
+						dly = 0;
+						while (!IsTxReady(j)) {
+							if (dly++ > 5) {
+								dly = 0;
+								break;
+							}
+							udelay(10);
+						}
+					}
+					outb_p((blankword.low), j->DSPbase + 0x0C);
+					outb_p((blankword.high), j->DSPbase + 0x0D);
+				}
+				j->flags.play_first_frame = 0;
 			}
 			for (cnt = 0; cnt < j->play_frame_size * 2; cnt += 2) {
 				if (!(cnt % 16) && !IsTxReady(j)) {
@@ -2547,11 +3684,20 @@
 						udelay(10);
 					}
 				}
-// Add word 0 to G.729 frames for the 8021.  Right now we don't do VAD/CNG 
-				// so all frames are type 1.
-				if (j->play_codec == G729 && (cnt == 0 || cnt == 5 || cnt == 10)) {
-					outb_p(0x01, j->DSPbase + 0x0C);
-					outb_p(0x00, j->DSPbase + 0x0D);
+			/* Add word 0 to G.729 frames for the 8021.  Right now we don't do VAD/CNG  */
+				if (j->play_codec == G729 && (cnt == 0 || cnt == 10 || cnt == 20)) {
+					if(j->write_buffer_rp + cnt == 0 && j->write_buffer_rp + cnt + 1 == 0 && j->write_buffer_rp + cnt + 2 == 0 &&
+					   j->write_buffer_rp + cnt + 3 == 0 && j->write_buffer_rp + cnt + 4 == 0 && j->write_buffer_rp + cnt + 5 == 0 &&
+					   j->write_buffer_rp + cnt + 6 == 0 && j->write_buffer_rp + cnt + 7 == 0 && j->write_buffer_rp + cnt + 8 == 0 &&
+					   j->write_buffer_rp + cnt + 9 == 0) {
+					/* someone is trying to write silence lets make this a type 0 frame. */
+						outb_p(0x00, j->DSPbase + 0x0C);
+						outb_p(0x00, j->DSPbase + 0x0D);
+					} else {
+					/* so all other frames are type 1. */
+						outb_p(0x01, j->DSPbase + 0x0C);
+						outb_p(0x00, j->DSPbase + 0x0D);
+					}
 				}
 				outb_p(*(j->write_buffer_rp + cnt), j->DSPbase + 0x0C);
 				outb_p(*(j->write_buffer_rp + cnt + 1), j->DSPbase + 0x0D);
@@ -2563,27 +3709,35 @@
 				j->write_buffer_rp = j->write_buffer;
 			}
 			j->write_buffers_empty++;
-			wake_up_interruptible(&j->write_q);	// Wake any blocked writers
+			wake_up_interruptible(&j->write_q);	/* Wake any blocked writers */
 
-			wake_up_interruptible(&j->poll_q);	// Wake any blocked selects
+			wake_up_interruptible(&j->poll_q);	/* Wake any blocked selects */
 
-			ixj_kill_fasync(j, POLL_OUT);
 			++j->frameswritten;
 		}
 	} else {
 		j->drybuffer++;
 	}
+	if(j->ixj_signals[SIG_WRITE_READY]) {
+		ixj_kill_fasync(j, SIG_WRITE_READY, POLL_OUT);
+	}
 }
 
 static int idle(IXJ *j)
 {
-	if (ixj_WriteDSPCommand(0x0000, j))		// DSP Idle
+	if (ixj_WriteDSPCommand(0x0000, j))		/* DSP Idle */
 
 		return 0;
-	if (j->ssr.high || j->ssr.low)
+
+	if (j->ssr.high || j->ssr.low) {
 		return 0;
-	else
+	} else {
+		j->play_mode = -1;
+		j->flags.playing = 0;
+		j->rec_mode = -1;
+		j->flags.recording = 0;
 		return 1;
+        }
 }
 
 static int set_base_frame(IXJ *j, int size)
@@ -2591,6 +3745,8 @@
 	unsigned short cmd;
 	int cnt;
 
+	idle(j);
+	j->cid_play_aec_level = j->aec_level;
 	aec_stop(j);
 	for (cnt = 0; cnt < 10; cnt++) {
 		if (idle(j))
@@ -2627,7 +3783,12 @@
 	} else {
 		j->baseframe.high = j->ssr.high;
 		j->baseframe.low = j->ssr.low;
+		/* If the status returned is 0x0000 (pg9-9 8021) the call failed */
+		if(j->baseframe.high == 0x00 && j->baseframe.low == 0x00) {
+			return -1;
+		}
 	}
+	ixj_aec_start(j, j->cid_play_aec_level);
 	return size;
 }
 
@@ -2708,6 +3869,28 @@
 			retval = 1;
 		}
 		break;
+	case G729B:
+		if (j->dsp.low != 0x20) {
+			if (!j->flags.g729_loaded) {
+				retval = 1;
+				break;
+			}
+			switch (j->baseframe.low) {
+			case 0xA0:
+				j->rec_frame_size = 12;
+				break;
+			case 0x50:
+				j->rec_frame_size = 6;
+				break;
+			default:
+				j->rec_frame_size = 18;
+				break;
+			}
+			j->rec_mode = 0;
+		} else {
+			retval = 1;
+		}
+		break;
 	case ULAW:
 		switch (j->baseframe.low) {
 		case 0xA0:
@@ -2800,7 +3983,10 @@
 		ixj_record_stop(j);
 	}
 	j->flags.recording = 1;
-	ixj_WriteDSPCommand(0x0FE0, j);	// Put the DSP in full power mode.
+	ixj_WriteDSPCommand(0x0FE0, j);	/* Put the DSP in full power mode. */
+
+	if(ixjdebug & 0x0002)
+		printk("IXJ %d Starting Record Codec %d at %ld\n", j->board, j->rec_codec, jiffies);
 
 	if (!j->rec_mode) {
 		switch (j->rec_codec) {
@@ -2811,21 +3997,22 @@
 			cmd = 0x5132;
 			break;
 		case TS85:
-			cmd = 0x5130;	// TrueSpeech 8.5
+			cmd = 0x5130;	/* TrueSpeech 8.5 */
 
 			break;
 		case TS48:
-			cmd = 0x5133;	// TrueSpeech 4.8
+			cmd = 0x5133;	/* TrueSpeech 4.8 */
 
 			break;
 		case TS41:
-			cmd = 0x5134;	// TrueSpeech 4.1
+			cmd = 0x5134;	/* TrueSpeech 4.1 */
 
 			break;
 		case G728:
 			cmd = 0x5135;
 			break;
 		case G729:
+		case G729B:
 			cmd = 0x5136;
 			break;
 		default:
@@ -2838,67 +4025,70 @@
 		if (!j->read_buffer)
 			j->read_buffer = kmalloc(j->rec_frame_size * 2, GFP_ATOMIC);
 		if (!j->read_buffer) {
-			printk("Read buffer allocation for ixj board %d failed!\n",
-			       j->p.board);
+			printk("Read buffer allocation for ixj board %d failed!\n", j->board);
 			return -ENOMEM;
 		}
 	}
 	j->read_buffer_size = j->rec_frame_size * 2;
 
-	if (ixj_WriteDSPCommand(0x5102, j))		// Set Poll sync mode
+	if (ixj_WriteDSPCommand(0x5102, j))		/* Set Poll sync mode */
 
 		return -1;
 
 	switch (j->rec_mode) {
 	case 0:
-		cmd = 0x1C03;	// Record C1
+		cmd = 0x1C03;	/* Record C1 */
 
 		break;
 	case 4:
 		if (j->ver.low == 0x12) {
-			cmd = 0x1E03;	// Record C1
+			cmd = 0x1E03;	/* Record C1 */
 
 		} else {
-			cmd = 0x1E01;	// Record C1
+			cmd = 0x1E01;	/* Record C1 */
 
 		}
 		break;
 	case 5:
 		if (j->ver.low == 0x12) {
-			cmd = 0x1E83;	// Record C1
+			cmd = 0x1E83;	/* Record C1 */
 
 		} else {
-			cmd = 0x1E81;	// Record C1
+			cmd = 0x1E81;	/* Record C1 */
 
 		}
 		break;
 	case 6:
 		if (j->ver.low == 0x12) {
-			cmd = 0x1F03;	// Record C1
+			cmd = 0x1F03;	/* Record C1 */
 
 		} else {
-			cmd = 0x1F01;	// Record C1
+			cmd = 0x1F01;	/* Record C1 */
 
 		}
 		break;
 	case 7:
 		if (j->ver.low == 0x12) {
-			cmd = 0x1F83;	// Record C1
-
+			cmd = 0x1F83;	/* Record C1 */
 		} else {
-			cmd = 0x1F81;	// Record C1
-
+			cmd = 0x1F81;	/* Record C1 */
 		}
 		break;
 	}
 	if (ixj_WriteDSPCommand(cmd, j))
 		return -1;
 
+	if (j->flags.playing) {
+		ixj_aec_start(j, j->aec_level);
+	}
 	return 0;
 }
 
 static void ixj_record_stop(IXJ *j)
 {
+	if(ixjdebug & 0x0002)
+		printk("IXJ %d Stopping Record Codec %d at %ld\n", j->board, j->rec_codec, jiffies);
+
 	if (j->read_buffer) {
 		kfree(j->read_buffer);
 		j->read_buffer = NULL;
@@ -2909,9 +4099,6 @@
 		j->rec_mode = -1;
 	}
 	j->flags.recording = 0;
-	if (!j->flags.playing)
-		ixj_WriteDSPCommand(0x0FE3, j);	// Put the DSP in 1/5 power mode.
-
 }
 static void ixj_vad(IXJ *j, int arg)
 {
@@ -2930,18 +4117,118 @@
 	ixj_WriteDSPCommand(0x5180 + depth, j);
 }
 
-static void set_rec_volume(IXJ *j, int volume)
+static void set_dtmf_prescale(IXJ *j, int volume)
 {
-	ixj_WriteDSPCommand(0xCF03, j);
+	ixj_WriteDSPCommand(0xCF07, j);
 	ixj_WriteDSPCommand(volume, j);
 }
 
-static int get_rec_volume(IXJ *j)
+static int get_dtmf_prescale(IXJ *j)
 {
-	ixj_WriteDSPCommand(0xCF01, j);
+	ixj_WriteDSPCommand(0xCF05, j);
 	return j->ssr.high << 8 | j->ssr.low;
 }
 
+static void set_rec_volume(IXJ *j, int volume)
+{
+	if(j->aec_level == AEC_AGC) {
+		if (ixjdebug & 0x0002)
+			printk(KERN_INFO "IXJ: /dev/phone%d Setting AGC Threshold to 0x%4.4x\n", j->board, volume);
+		ixj_WriteDSPCommand(0xCF96, j);
+		ixj_WriteDSPCommand(volume, j);
+	} else {
+		if (ixjdebug & 0x0002)
+			printk(KERN_INFO "IXJ: /dev/phone %d Setting Record Volume to 0x%4.4x\n", j->board, volume);
+		ixj_WriteDSPCommand(0xCF03, j);
+		ixj_WriteDSPCommand(volume, j);
+	}
+}
+
+static int set_rec_volume_linear(IXJ *j, int volume)
+{
+	int newvolume, dsprecmax;
+
+	if (ixjdebug & 0x0002)
+		printk(KERN_INFO "IXJ: /dev/phone %d Setting Linear Record Volume to 0x%4.4x\n", j->board, volume);
+	if(volume > 100 || volume < 0) {
+	  return -1;
+	}
+
+	/* This should normalize the perceived volumes between the different cards caused by differences in the hardware */
+	switch (j->cardtype) {
+	case QTI_PHONEJACK:
+		dsprecmax = 0x440;
+		break;
+	case QTI_LINEJACK:
+		dsprecmax = 0x180;
+		ixj_mixer(0x0203, j);	/*Voice Left Volume unmute 6db */
+		ixj_mixer(0x0303, j);	/*Voice Right Volume unmute 6db */
+		ixj_mixer(0x0C00, j);	/*Mono1 unmute 12db */
+		break;
+	case QTI_PHONEJACK_LITE:
+		dsprecmax = 0x4C0;
+		break;
+	case QTI_PHONEJACK_PCI:
+		dsprecmax = 0x100;
+		break;
+	case QTI_PHONECARD:
+		dsprecmax = 0x400;
+		break;
+	default:
+		return -1;
+	}
+	newvolume = (dsprecmax * volume) / 100;
+	set_rec_volume(j, newvolume);
+	return 0;
+}
+
+static int get_rec_volume(IXJ *j)
+{
+	if(j->aec_level == AEC_AGC) {
+		if (ixjdebug & 0x0002)
+			printk(KERN_INFO "Getting AGC Threshold\n");
+		ixj_WriteDSPCommand(0xCF86, j);
+		if (ixjdebug & 0x0002)
+			printk(KERN_INFO "AGC Threshold is 0x%2.2x%2.2x\n", j->ssr.high, j->ssr.low);
+		return j->ssr.high << 8 | j->ssr.low;
+	} else {
+		if (ixjdebug & 0x0002)
+			printk(KERN_INFO "Getting Record Volume\n");
+		ixj_WriteDSPCommand(0xCF01, j);
+		return j->ssr.high << 8 | j->ssr.low;
+	}
+}
+
+static int get_rec_volume_linear(IXJ *j)
+{
+	int volume, newvolume, dsprecmax;
+
+	switch (j->cardtype) {
+	case QTI_PHONEJACK:
+		dsprecmax = 0x440;
+		break;
+	case QTI_LINEJACK:
+		dsprecmax = 0x180;
+		break;
+	case QTI_PHONEJACK_LITE:
+		dsprecmax = 0x4C0;
+		break;
+	case QTI_PHONEJACK_PCI:
+		dsprecmax = 0x100;
+		break;
+	case QTI_PHONECARD:
+		dsprecmax = 0x400;
+		break;
+	default:
+		return -1;
+	}
+	volume = get_rec_volume(j);
+	newvolume = (volume * 100) / dsprecmax;
+	if(newvolume > 100)
+		newvolume = 100;
+	return newvolume;
+}
+
 static int get_rec_level(IXJ *j)
 {
 	int retval;
@@ -2956,52 +4243,117 @@
 static void ixj_aec_start(IXJ *j, int level)
 {
 	j->aec_level = level;
+	if (ixjdebug & 0x0002)
+		printk(KERN_INFO "AGC set = 0x%2.2x\n", j->aec_level);
 	if (!level) {
 		aec_stop(j);
 	} else {
-		if (j->rec_codec == G729 || j->play_codec == G729) {
-			ixj_WriteDSPCommand(0xE022, j);	// Move AEC filter buffer
+		if (j->rec_codec == G729 || j->play_codec == G729 || j->rec_codec == G729B || j->play_codec == G729B) {
+			ixj_WriteDSPCommand(0xE022, j);	/* Move AEC filter buffer */
 
 			ixj_WriteDSPCommand(0x0300, j);
 		}
-		ixj_WriteDSPCommand(0xB001, j);	// AEC On
+		ixj_WriteDSPCommand(0xB001, j);	/* AEC On */
 
-		ixj_WriteDSPCommand(0xE013, j);	// Advanced AEC C1
+		ixj_WriteDSPCommand(0xE013, j);	/* Advanced AEC C1 */
 
 		switch (level) {
 		case AEC_LOW:
-			ixj_WriteDSPCommand(0x0000, j);	// Advanced AEC C2 = off
+			ixj_WriteDSPCommand(0x0000, j);	/* Advanced AEC C2 = off */
 
 			ixj_WriteDSPCommand(0xE011, j);
 			ixj_WriteDSPCommand(0xFFFF, j);
+
+			ixj_WriteDSPCommand(0xCF97, j);	/* Set AGC Enable */
+			ixj_WriteDSPCommand(0x0000, j);	/* to off */
+			
 			break;
 
 		case AEC_MED:
-			ixj_WriteDSPCommand(0x0600, j);	// Advanced AEC C2 = on medium
+			ixj_WriteDSPCommand(0x0600, j);	/* Advanced AEC C2 = on medium */
 
 			ixj_WriteDSPCommand(0xE011, j);
 			ixj_WriteDSPCommand(0x0080, j);
+
+			ixj_WriteDSPCommand(0xCF97, j);	/* Set AGC Enable */
+			ixj_WriteDSPCommand(0x0000, j);	/* to off */
+			
 			break;
 
 		case AEC_HIGH:
-			ixj_WriteDSPCommand(0x0C00, j);	// Advanced AEC C2 = on high
+			ixj_WriteDSPCommand(0x0C00, j);	/* Advanced AEC C2 = on high */
 
 			ixj_WriteDSPCommand(0xE011, j);
 			ixj_WriteDSPCommand(0x0080, j);
+
+			ixj_WriteDSPCommand(0xCF97, j);	/* Set AGC Enable */
+			ixj_WriteDSPCommand(0x0000, j);	/* to off */
+			
+			break;
+
+		case AEC_AGC:
+                        /* First we have to put the AEC into advance auto mode so that AGC will not conflict with it */
+			ixj_WriteDSPCommand(0x0002, j);	/* Attenuation scaling factor of 2 */
+
+			ixj_WriteDSPCommand(0xE011, j);
+			ixj_WriteDSPCommand(0x0100, j);	/* Higher Threshold Floor */
+
+			ixj_WriteDSPCommand(0xE012, j);	/* Set Train and Lock */
+
+			if(j->cardtype == QTI_LINEJACK || j->cardtype == QTI_PHONECARD)
+				ixj_WriteDSPCommand(0x0224, j);
+			else
+				ixj_WriteDSPCommand(0x1224, j);
+
+			ixj_WriteDSPCommand(0xE014, j);
+			ixj_WriteDSPCommand(0x0003, j);	/* Lock threashold at 3dB */
+
+			ixj_WriteDSPCommand(0xE338, j);	/* Set Echo Suppresser Attenuation to 0dB */
+
+			/* Now we can set the AGC initial parameters and turn it on */
+			ixj_WriteDSPCommand(0xCF90, j);	/* Set AGC Minumum gain */
+			ixj_WriteDSPCommand(0x0020, j);	/* to 0.125 (-18dB) */
+	
+			ixj_WriteDSPCommand(0xCF91, j);	/* Set AGC Maximum gain */
+			ixj_WriteDSPCommand(0x1000, j);	/* to 16 (24dB) */
+			
+			ixj_WriteDSPCommand(0xCF92, j);	/* Set AGC start gain */
+			ixj_WriteDSPCommand(0x0800, j);	/* to 8 (+18dB) */
+		
+			ixj_WriteDSPCommand(0xCF93, j);	/* Set AGC hold time */
+			ixj_WriteDSPCommand(0x1F40, j);	/* to 2 seconds (units are 250us) */
+			
+			ixj_WriteDSPCommand(0xCF94, j);	/* Set AGC Attack Time Constant */
+			ixj_WriteDSPCommand(0x0005, j);	/* to 8ms */
+			
+			ixj_WriteDSPCommand(0xCF95, j);	/* Set AGC Decay Time Constant */
+			ixj_WriteDSPCommand(0x000D, j);	/* to 4096ms */
+			
+			ixj_WriteDSPCommand(0xCF96, j);	/* Set AGC Attack Threshold */
+			ixj_WriteDSPCommand(0x1200, j);	/* to 25% */
+			
+			ixj_WriteDSPCommand(0xCF97, j);	/* Set AGC Enable */
+			ixj_WriteDSPCommand(0x0001, j);	/* to on */
+			
 			break;
 
 		case AEC_AUTO:
-			ixj_WriteDSPCommand(0x0002, j);	// Attenuation scaling factor of 2
+			ixj_WriteDSPCommand(0x0002, j);	/* Attenuation scaling factor of 2 */
 
 			ixj_WriteDSPCommand(0xE011, j);
-			ixj_WriteDSPCommand(0x0100, j);	// Higher Threshold Floor
+			ixj_WriteDSPCommand(0x0100, j);	/* Higher Threshold Floor */
 
-			ixj_WriteDSPCommand(0xE012, j);	// Set Train and Lock
+			ixj_WriteDSPCommand(0xE012, j);	/* Set Train and Lock */
 
-			ixj_WriteDSPCommand(0x0023, j);
+			if(j->cardtype == QTI_LINEJACK || j->cardtype == QTI_PHONECARD)
+				ixj_WriteDSPCommand(0x0224, j);
+			else
+				ixj_WriteDSPCommand(0x1224, j);
 
 			ixj_WriteDSPCommand(0xE014, j);
-			ixj_WriteDSPCommand(0x0003, j);	// Lock threashold at 3dB
+			ixj_WriteDSPCommand(0x0003, j);	/* Lock threashold at 3dB */
+
+			ixj_WriteDSPCommand(0xE338, j);	/* Set Echo Suppresser Attenuation to 0dB */
 
 			break;
 		}
@@ -3010,15 +4362,15 @@
 
 static void aec_stop(IXJ *j)
 {
-	if (j->rec_codec == G729 || j->play_codec == G729) {
-		ixj_WriteDSPCommand(0xE022, j);	// Move AEC filter buffer back
+	j->aec_level = AEC_OFF;
+	if (j->rec_codec == G729 || j->play_codec == G729 || j->rec_codec == G729B || j->play_codec == G729B) {
+		ixj_WriteDSPCommand(0xE022, j);	/* Move AEC filter buffer back */
 
 		ixj_WriteDSPCommand(0x0700, j);
 	}
 	if (j->play_mode != -1 && j->rec_mode != -1)
 	{
-		ixj_WriteDSPCommand(0xB002, j);	// AEC Stop
-
+		ixj_WriteDSPCommand(0xB002, j);	/* AEC Stop */
 	}
 }
 
@@ -3099,6 +4451,28 @@
 			retval = 1;
 		}
 		break;
+	case G729B:
+		if (j->dsp.low != 0x20) {
+			if (!j->flags.g729_loaded) {
+				retval = 1;
+				break;
+			}
+			switch (j->baseframe.low) {
+			case 0xA0:
+				j->play_frame_size = 12;
+				break;
+			case 0x50:
+				j->play_frame_size = 6;
+				break;
+			default:
+				j->play_frame_size = 18;
+				break;
+			}
+			j->play_mode = 0;
+		} else {
+			retval = 1;
+		}
+		break;
 	case ULAW:
 		switch (j->baseframe.low) {
 		case 0xA0:
@@ -3190,8 +4564,12 @@
 	if (j->write_buffer) {
 		ixj_play_stop(j);
 	}
+
+	if(ixjdebug & 0x0002)
+		printk("IXJ %d Starting Play Codec %d at %ld\n", j->board, j->play_codec, jiffies);
+
 	j->flags.playing = 1;
-	ixj_WriteDSPCommand(0x0FE0, j);	// Put the DSP in full power mode.
+	ixj_WriteDSPCommand(0x0FE0, j);	/* Put the DSP in full power mode. */
 
 	j->flags.play_first_frame = 1;
 	j->drybuffer = 0;
@@ -3205,21 +4583,22 @@
 			cmd = 0x5232;
 			break;
 		case TS85:
-			cmd = 0x5230;	// TrueSpeech 8.5
+			cmd = 0x5230;	/* TrueSpeech 8.5 */
 
 			break;
 		case TS48:
-			cmd = 0x5233;	// TrueSpeech 4.8
+			cmd = 0x5233;	/* TrueSpeech 4.8 */
 
 			break;
 		case TS41:
-			cmd = 0x5234;	// TrueSpeech 4.1
+			cmd = 0x5234;	/* TrueSpeech 4.1 */
 
 			break;
 		case G728:
 			cmd = 0x5235;
 			break;
 		case G729:
+		case G729B:
 			cmd = 0x5236;
 			break;
 		default:
@@ -3230,16 +4609,16 @@
 	}
 	j->write_buffer = kmalloc(j->play_frame_size * 2, GFP_ATOMIC);
 	if (!j->write_buffer) {
-		printk("Write buffer allocation for ixj board %d failed!\n",
-		       j->p.board);
+		printk("Write buffer allocation for ixj board %d failed!\n", j->board);
 		return -ENOMEM;
 	}
-	j->write_buffers_empty = 2;
+/*	j->write_buffers_empty = 2; */
+	j->write_buffers_empty = 1; 
 	j->write_buffer_size = j->play_frame_size * 2;
 	j->write_buffer_end = j->write_buffer + j->play_frame_size * 2;
 	j->write_buffer_rp = j->write_buffer_wp = j->write_buffer;
 
-	if (ixj_WriteDSPCommand(0x5202, j))		// Set Poll sync mode
+	if (ixj_WriteDSPCommand(0x5202, j))		/* Set Poll sync mode */
 
 		return -1;
 
@@ -3279,42 +4658,42 @@
 	if (ixj_WriteDSPCommand(cmd, j))
 		return -1;
 
-	if (ixj_WriteDSPCommand(0x2000, j))		// Playback C2
-
+	if (ixj_WriteDSPCommand(0x2000, j))		/* Playback C2 */
 		return -1;
 
-	if (ixj_WriteDSPCommand(0x2000 + j->play_frame_size, j))	// Playback C3
-
+	if (ixj_WriteDSPCommand(0x2000 + j->play_frame_size, j))	/* Playback C3 */
 		return -1;
 
+	if (j->flags.recording) {
+		ixj_aec_start(j, j->aec_level);
+	}
 
-	ixj_kill_fasync(j, POLL_OUT);
 	return 0;
 }
 
 static void ixj_play_stop(IXJ *j)
 {
+	if(ixjdebug & 0x0002)
+		printk("IXJ %d Stopping Play Codec %d at %ld\n", j->board, j->play_codec, jiffies);
+
 	if (j->write_buffer) {
 		kfree(j->write_buffer);
 		j->write_buffer = NULL;
 		j->write_buffer_size = 0;
 	}
 	if (j->play_mode > -1) {
-		ixj_WriteDSPCommand(0x5221, j);	// Stop playback and flush buffers.  8022 reference page 9-40
+		ixj_WriteDSPCommand(0x5221, j);	/* Stop playback and flush buffers.  8022 reference page 9-40 */
 
 		j->play_mode = -1;
 	}
 	j->flags.playing = 0;
-	if (!j->flags.recording)
-		ixj_WriteDSPCommand(0x0FE3, j);	// Put the DSP in 1/5 power mode.
-
 }
 
-extern __inline__ int get_play_level(IXJ *j)
+static inline int get_play_level(IXJ *j)
 {
 	int retval;
 
-	ixj_WriteDSPCommand(0xCF8F, j); // 8022 Reference page 9-38
+	ixj_WriteDSPCommand(0xCF8F, j); /* 8022 Reference page 9-38 */
 	return j->ssr.high << 8 | j->ssr.low;
 	retval = j->ssr.high << 8 | j->ssr.low;
 	retval = (retval * 256) / 240;
@@ -3324,10 +4703,8 @@
 static unsigned int ixj_poll(struct file *file_p, poll_table * wait)
 {
 	unsigned int mask = 0;
-	IXJ *j = ixj[NUM(file_p->f_dentry->d_inode->i_rdev)];
 
-	if (j == NULL) /* shouldn't happen! */
-		return -ENODEV;
+	IXJ *j = get_ixj(NUM(file_p->f_dentry->d_inode->i_rdev));
 
 	poll_wait(file_p, &(j->poll_q), wait);
 	if (j->read_buffer_ready > 0)
@@ -3341,18 +4718,22 @@
 
 static int ixj_play_tone(IXJ *j, char tone)
 {
-	if (!j->tone_state && j->dsp.low == 0x20)
-		idle(j);
-
-	j->tone_index = tone;
-	if (ixj_WriteDSPCommand(0x6000 + j->tone_index, j))
-		return -1;
-
 	if (!j->tone_state) {
+		if(ixjdebug & 0x0002) {
+			printk("IXJ %d starting tone %d at %ld\n", j->board, tone, jiffies);
+		}
+		if (j->dsp.low == 0x20) {
+			idle(j);
+		}
 		j->tone_start_jif = jiffies;
 
 		j->tone_state = 1;
 	}
+
+	j->tone_index = tone;
+	if (ixj_WriteDSPCommand(0x6000 + j->tone_index, j))
+		return -1;
+
 	return 0;
 }
 
@@ -3360,7 +4741,7 @@
 {
 	j->tone_on_time = arg;
 
-	if (ixj_WriteDSPCommand(0x6E04, j))		// Set Tone On Period
+	if (ixj_WriteDSPCommand(0x6E04, j))		/* Set Tone On Period */
 
 		return -1;
 
@@ -3383,7 +4764,7 @@
 			if ((j->pld_scrr.bits.sci))
 				return 1;
 		}
-		if (ixjdebug > 1)
+		if (ixjdebug & 0x0001)
 			printk(KERN_INFO "SCI Wait High failed %x\n", j->pld_scrr.byte);
 		return 0;
 	} else
@@ -3403,7 +4784,7 @@
 			if (!(j->pld_scrr.bits.sci))
 				return 1;
 		}
-		if (ixjdebug > 1)
+		if (ixjdebug & 0x0001)
 			printk(KERN_INFO "SCI Wait Low failed %x\n", j->pld_scrr.byte);
 		return 0;
 	} else
@@ -3414,27 +4795,27 @@
 {
 	switch (control) {
 	case SCI_End:
-		j->pld_scrw.bits.c0 = 0;	// Set PLD Serial control interface
+		j->pld_scrw.bits.c0 = 0;	/* Set PLD Serial control interface */
 
-		j->pld_scrw.bits.c1 = 0;	// to no selection 
+		j->pld_scrw.bits.c1 = 0;	/* to no selection */
 
 		break;
 	case SCI_Enable_DAA:
-		j->pld_scrw.bits.c0 = 1;	// Set PLD Serial control interface
+		j->pld_scrw.bits.c0 = 1;	/* Set PLD Serial control interface */
 
-		j->pld_scrw.bits.c1 = 0;	// to write to DAA
+		j->pld_scrw.bits.c1 = 0;	/* to write to DAA */
 
 		break;
 	case SCI_Enable_Mixer:
-		j->pld_scrw.bits.c0 = 0;	// Set PLD Serial control interface
+		j->pld_scrw.bits.c0 = 0;	/* Set PLD Serial control interface */
 
-		j->pld_scrw.bits.c1 = 1;	// to write to mixer 
+		j->pld_scrw.bits.c1 = 1;	/* to write to mixer */
 
 		break;
 	case SCI_Enable_EEPROM:
-		j->pld_scrw.bits.c0 = 1;	// Set PLD Serial control interface
+		j->pld_scrw.bits.c0 = 1;	/* Set PLD Serial control interface */
 
-		j->pld_scrw.bits.c1 = 1;	// to write to EEPROM 
+		j->pld_scrw.bits.c1 = 1;	/* to write to EEPROM */
 
 		break;
 	default:
@@ -3471,16 +4852,25 @@
 	return 1;
 }
 
+static int ixj_get_mixer(long val, IXJ *j)
+{
+	int reg = (val & 0x1F00) >> 8;
+        return j->mix.vol[reg];
+}
+
 static int ixj_mixer(long val, IXJ *j)
 {
 	BYTES bytes;
 
-	bytes.high = (val & 0xFF00) >> 8;
+	bytes.high = (val & 0x1F00) >> 8;
 	bytes.low = val & 0x00FF;
 
-	outb_p(bytes.high & 0x1F, j->XILINXbase + 0x03);	// Load Mixer Address
+        /* save mixer value so we can get back later on */
+        j->mix.vol[bytes.high] = bytes.low;
 
-	outb_p(bytes.low, j->XILINXbase + 0x02);	// Load Mixer Data
+	outb_p(bytes.high & 0x1F, j->XILINXbase + 0x03);	/* Load Mixer Address */
+
+	outb_p(bytes.low, j->XILINXbase + 0x02);	/* Load Mixer Data */
 
 	SCI_Control(j, SCI_Enable_Mixer);
 
@@ -3564,7 +4954,7 @@
 	bytes.high = inb_p(j->XILINXbase + 0x03);
 	bytes.low = inb_p(j->XILINXbase + 0x02);
 	if (bytes.low != ALISDAA_ID_BYTE) {
-		if (ixjdebug > 0)
+		if (ixjdebug & 0x0001)
 			printk("Cannot read DAA ID Byte high = %d low = %d\n", bytes.high, bytes.low);
 		return 0;
 	}
@@ -3577,6 +4967,77 @@
 	bytes.low = inb_p(j->XILINXbase + 0x02);
 
 	j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.reg = bytes.high;
+
+	return 1;
+}
+
+static char daa_CR_read(IXJ *j, int cr)
+{
+	IXJ_WORD wdata;
+	BYTES bytes;
+
+	if (!SCI_Prepare(j))
+		return 0;
+
+	switch (j->daa_mode) {
+	case SOP_PU_SLEEP:
+		bytes.high = 0x30 + cr;
+		break;
+	case SOP_PU_RINGING:
+		bytes.high = 0x70 + cr;
+		break;
+	case SOP_PU_CONVERSATION:
+		bytes.high = 0xB0 + cr;
+		break;
+	case SOP_PU_PULSEDIALING:
+		bytes.high = 0xF0 + cr;
+		break;
+	}
+
+	bytes.low = 0x00;
+
+	outb_p(bytes.high, j->XILINXbase + 0x03);
+	outb_p(bytes.low, j->XILINXbase + 0x02);
+
+	if (!SCI_Control(j, SCI_Enable_DAA))
+		return 0;
+
+	bytes.high = inb_p(j->XILINXbase + 0x03);
+	bytes.low = inb_p(j->XILINXbase + 0x02);
+	if (bytes.low != ALISDAA_ID_BYTE) {
+		if (ixjdebug & 0x0001)
+			printk("Cannot read DAA ID Byte high = %d low = %d\n", bytes.high, bytes.low);
+		return 0;
+	}
+	if (!SCI_Control(j, SCI_Enable_DAA))
+		return 0;
+	if (!SCI_Control(j, SCI_End))
+		return 0;
+
+	wdata.word = inw_p(j->XILINXbase + 0x02);
+
+	switch(cr){
+		case 5:
+			j->m_DAAShadowRegs.SOP_REGS.SOP.cr5.reg = wdata.bytes.high;
+			break;
+		case 4:
+			j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = wdata.bytes.high;
+			break;
+		case 3:
+			j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = wdata.bytes.high;
+			break;
+		case 2:
+			j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = wdata.bytes.high;
+			break;
+		case 1:
+			j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = wdata.bytes.high;
+			break;
+		case 0:
+			j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = wdata.bytes.high;
+			break;
+		default:
+			return 0;
+	}
 	return 1;
 }
 
@@ -3585,6 +5046,9 @@
 	int i;
 	BYTES bytes;
 
+	if (ixjdebug & 0x0002)
+		printk("DAA Clearing CID ram\n");
+
 	if (!SCI_Prepare(j))
 		return 0;
 
@@ -3617,6 +5081,9 @@
 	if (!SCI_Control(j, SCI_End))
 		return 0;
 
+	if (ixjdebug & 0x0002)
+		printk("DAA CID ram cleared\n");
+
 	return 1;
 }
 
@@ -3644,7 +5111,7 @@
 	bytes.high = inb_p(j->XILINXbase + 0x03);
 	bytes.low = inb_p(j->XILINXbase + 0x02);
 	if (bytes.low != ALISDAA_ID_BYTE) {
-		if (ixjdebug > 0)
+		if (ixjdebug & 0x0001)
 			printk("DAA Get Version Cannot read DAA ID Byte high = %d low = %d\n", bytes.high, bytes.low);
 		return 0;
 	}
@@ -3727,7 +5194,7 @@
 	bytes.high = inb_p(j->XILINXbase + 0x03);
 	bytes.low = inb_p(j->XILINXbase + 0x02);
 	if (bytes.low != ALISDAA_ID_BYTE) {
-		if (ixjdebug > 0)
+		if (ixjdebug & 0x0001)
 			printk("DAA Get Version Cannot read DAA ID Byte high = %d low = %d\n", bytes.high, bytes.low);
 		return 0;
 	}
@@ -3739,7 +5206,7 @@
 
 	bytes.high = inb_p(j->XILINXbase + 0x03);
 	bytes.low = inb_p(j->XILINXbase + 0x02);
-	if (ixjdebug > 0)
+	if (ixjdebug & 0x0002)
 		printk("DAA CR5 Byte high = 0x%x low = 0x%x\n", bytes.high, bytes.low);
 	j->m_DAAShadowRegs.SOP_REGS.SOP.cr5.reg = bytes.high;
 	return bytes.high;
@@ -3747,30 +5214,52 @@
 
 static int daa_set_mode(IXJ *j, int mode)
 {
-	// NOTE:
-	//      The DAA *MUST* be in the conversation mode if the
-	//      PSTN line is to be seized (PSTN line off-hook).
-	//      Taking the PSTN line off-hook while the DAA is in
-	//      a mode other than conversation mode will cause a
-	//      hardware failure of the ALIS-A part.
-
-	// NOTE:
-	//      The DAA can only go to SLEEP, RINGING or PULSEDIALING modes
-	//      if the PSTN line is on-hook.  Failure to have the PSTN line
-	//      in the on-hook state WILL CAUSE A HARDWARE FAILURE OF THE
-	//      ALIS-A part.
-	//
+	/* NOTE:
+	      The DAA *MUST* be in the conversation mode if the
+	      PSTN line is to be seized (PSTN line off-hook).
+	      Taking the PSTN line off-hook while the DAA is in
+	      a mode other than conversation mode will cause a
+	      hardware failure of the ALIS-A part.
+
+	   NOTE:
+	      The DAA can only go to SLEEP, RINGING or PULSEDIALING modes
+	      if the PSTN line is on-hook.  Failure to have the PSTN line
+	      in the on-hook state WILL CAUSE A HARDWARE FAILURE OF THE
+	      ALIS-A part.
+	*/
 
 	BYTES bytes;
 
+	j->flags.pstn_rmr = 0;
+
 	if (!SCI_Prepare(j))
 		return 0;
 
 	switch (mode) {
+	case SOP_PU_RESET:
+		j->pld_scrw.bits.daafsyncen = 0;	/* Turn off DAA Frame Sync */
+
+		outb_p(j->pld_scrw.byte, j->XILINXbase);
+		j->pld_slicw.bits.rly2 = 0;
+		outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+		bytes.high = 0x10;
+		bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
+		daa_load(&bytes, j);
+		if (!SCI_Prepare(j))
+			return 0;
+
+		j->daa_mode = SOP_PU_SLEEP;
+		break;
 	case SOP_PU_SLEEP:
-		if(j->daa_mode == SOP_PU_CONVERSATION)
+		if(j->daa_mode == SOP_PU_SLEEP)
 		{
-			j->pld_scrw.bits.daafsyncen = 0;	// Turn off DAA Frame Sync
+			break;
+		}
+		if (ixjdebug & 0x0008)
+			printk(KERN_INFO "phone DAA: SOP_PU_SLEEP at %ld\n", jiffies);
+/*		if(j->daa_mode == SOP_PU_CONVERSATION) */
+		{
+			j->pld_scrw.bits.daafsyncen = 0;	/* Turn off DAA Frame Sync */
 
 			outb_p(j->pld_scrw.byte, j->XILINXbase);
 			j->pld_slicw.bits.rly2 = 0;
@@ -3781,7 +5270,7 @@
 			if (!SCI_Prepare(j))
 				return 0;
 		}
-		j->pld_scrw.bits.daafsyncen = 0;	// Turn off DAA Frame Sync
+		j->pld_scrw.bits.daafsyncen = 0;	/* Turn off DAA Frame Sync */
 
 		outb_p(j->pld_scrw.byte, j->XILINXbase);
 		j->pld_slicw.bits.rly2 = 0;
@@ -3795,13 +5284,15 @@
 		j->daa_mode = SOP_PU_SLEEP;
 		j->flags.pstn_ringing = 0;
 		j->ex.bits.pstn_ring = 0;
-		j->pstn_sleeptil = jiffies + (hertz / 2);
-		wake_up_interruptible(&j->read_q);      // Wake any blocked readers
-		wake_up_interruptible(&j->write_q);     // Wake any blocked writers
-		wake_up_interruptible(&j->poll_q);      // Wake any blocked selects
+		j->pstn_sleeptil = jiffies + (hertz / 4);
+		wake_up_interruptible(&j->read_q);      /* Wake any blocked readers */
+		wake_up_interruptible(&j->write_q);     /* Wake any blocked writers */
+		wake_up_interruptible(&j->poll_q);      /* Wake any blocked selects */
  		break;
 	case SOP_PU_RINGING:
-		j->pld_scrw.bits.daafsyncen = 0;	// Turn off DAA Frame Sync
+		if (ixjdebug & 0x0008)
+			printk(KERN_INFO "phone DAA: SOP_PU_RINGING at %ld\n", jiffies);
+		j->pld_scrw.bits.daafsyncen = 0;	/* Turn off DAA Frame Sync */
 
 		outb_p(j->pld_scrw.byte, j->XILINXbase);
 		j->pld_slicw.bits.rly2 = 0;
@@ -3814,6 +5305,8 @@
 		j->daa_mode = SOP_PU_RINGING;
 		break;
 	case SOP_PU_CONVERSATION:
+		if (ixjdebug & 0x0008)
+			printk(KERN_INFO "phone DAA: SOP_PU_CONVERSATION at %ld\n", jiffies);
 		bytes.high = 0x90;
 		bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
 		daa_load(&bytes, j);
@@ -3821,17 +5314,19 @@
 			return 0;
 		j->pld_slicw.bits.rly2 = 1;
 		outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-		j->pld_scrw.bits.led1 = 0;
-		j->pld_scrw.bits.led2 = 1;
-		j->pld_scrw.bits.daafsyncen = 1;	// Turn on DAA Frame Sync
+		j->pld_scrw.bits.daafsyncen = 1;	/* Turn on DAA Frame Sync */
 
 		outb_p(j->pld_scrw.byte, j->XILINXbase);
 		j->daa_mode = SOP_PU_CONVERSATION;
 		j->flags.pstn_ringing = 0;
 		j->ex.bits.pstn_ring = 0;
+		j->pstn_sleeptil = jiffies;
+		j->pstn_ring_start = j->pstn_ring_stop = j->pstn_ring_int = 0;
 		break;
 	case SOP_PU_PULSEDIALING:
-		j->pld_scrw.bits.daafsyncen = 0;	// Turn off DAA Frame Sync
+		if (ixjdebug & 0x0008)
+			printk(KERN_INFO "phone DAA: SOP_PU_PULSEDIALING at %ld\n", jiffies);
+		j->pld_scrw.bits.daafsyncen = 0;	/* Turn off DAA Frame Sync */
 
 		outb_p(j->pld_scrw.byte, j->XILINXbase);
 		j->pld_slicw.bits.rly2 = 0;
@@ -3853,9 +5348,15 @@
 {
 	BYTES bytes;
 
+	j->flags.pstncheck = 1;
+
+	daa_set_mode(j, SOP_PU_SLEEP);
+
 	if (!SCI_Prepare(j))
 		return 0;
 
+	outb_p(j->pld_scrw.byte, j->XILINXbase);
+
 	bytes.high = 0x14;
 	bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg;
 	if (!daa_load(&bytes, j))
@@ -4332,13 +5833,19 @@
 	if (!SCI_Control(j, SCI_End))
 		return 0;
 
+	outb_p(j->pld_scrw.byte, j->XILINXbase);
+
+	if (ixjdebug & 0x0002)
+		printk("DAA Coefficients Loaded\n");
+
+	j->flags.pstncheck = 0;
 	return 1;
 }
 
 int ixj_set_tone_off(unsigned short arg, IXJ *j)
 {
 	j->tone_off_time = arg;
-	if (ixj_WriteDSPCommand(0x6E05, j))		// Set Tone Off Period
+	if (ixj_WriteDSPCommand(0x6E05, j))		/* Set Tone Off Period */
 
 		return -1;
 	if (ixj_WriteDSPCommand(arg, j))
@@ -4348,7 +5855,7 @@
 
 static int ixj_get_tone_on(IXJ *j)
 {
-	if (ixj_WriteDSPCommand(0x6E06, j))		// Get Tone On Period
+	if (ixj_WriteDSPCommand(0x6E06, j))		/* Get Tone On Period */
 
 		return -1;
 	return 0;
@@ -4356,7 +5863,8 @@
 
 static int ixj_get_tone_off(IXJ *j)
 {
-	if (ixj_WriteDSPCommand(0x6E07, j))		// Get Tone Off Period
+	if (ixj_WriteDSPCommand(0x6E07, j))		/* Get Tone Off Period */
+
 		return -1;
 	return 0;
 }
@@ -4387,7 +5895,7 @@
 
 static void ixj_cpt_stop(IXJ *j)
 {
-	if(j->tone_state)
+	if(j->tone_state || j->tone_cadence_state)
 	{
 		j->flags.dialtone = 0;
 		j->flags.busytone = 0;
@@ -4395,7 +5903,7 @@
 		ixj_set_tone_on(0x0001, j);
 		ixj_set_tone_off(0x0000, j);
 		ixj_play_tone(j, 0);
-		j->tone_state = 0;
+		j->tone_state = j->tone_cadence_state = 0;
 		if (j->cadence_t) {
 			if (j->cadence_t->ce) {
 				kfree(j->cadence_t->ce);
@@ -4436,12 +5944,11 @@
 	lcp = kmalloc(sizeof(IXJ_CADENCE), GFP_KERNEL);
 	if (lcp == NULL)
 		return -ENOMEM;
-	if (copy_from_user(lcp, (char *) cp, sizeof(IXJ_CADENCE)) ||
-	    (unsigned)lcp->elements_used >= ~0U/sizeof(IXJ_CADENCE) )
-	{
-		kfree(lcp);
-		return -EFAULT;
-	}
+	if (copy_from_user(lcp, (char *) cp, sizeof(IXJ_CADENCE)) || (unsigned)lcp->elements_used >= ~0U/sizeof(IXJ_CADENCE) )
+        {
+                kfree(lcp);
+                return -EFAULT;
+        }
 	lcep = kmalloc(sizeof(IXJ_CADENCE_ELEMENT) * lcp->elements_used, GFP_KERNEL);
 	if (lcep == NULL) {
 		kfree(lcp);
@@ -4477,18 +5984,23 @@
 static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE * cp)
 {
 	IXJ_FILTER_CADENCE *lcp;
-
 	lcp = kmalloc(sizeof(IXJ_FILTER_CADENCE), GFP_KERNEL);
-	if (lcp == NULL)
+	if (lcp == NULL) {
+		if(ixjdebug & 0x0001) {
+			printk(KERN_INFO "Could not allocate memory for cadence\n");
+		}
 		return -ENOMEM;
-	if (copy_from_user(lcp, (char *) cp, sizeof(IXJ_FILTER_CADENCE)))
-	{
-		kfree(lcp);
+        }
+	if (copy_from_user(lcp, (char *) cp, sizeof(IXJ_FILTER_CADENCE))) {
+		if(ixjdebug & 0x0001) {
+			printk(KERN_INFO "Could not copy cadence to kernel\n");
+		}
 		return -EFAULT;
 	}
-	if (lcp->filter >= 4)
-	{
-		kfree(lcp);
+	if (lcp->filter > 5) {
+		if(ixjdebug & 0x0001) {
+			printk(KERN_INFO "Cadence out of range\n");
+		}
 		return -1;
 	}
 	j->cadence_f[lcp->filter].state = 0;
@@ -4513,6 +6025,9 @@
 	j->cadence_f[lcp->filter].off3min = 0;
 	j->cadence_f[lcp->filter].off3max = 0;
 	kfree(lcp);
+	if(ixjdebug & 0x0002) {
+		printk(KERN_INFO "Cadence %d loaded\n", lcp->filter);
+	}
 	return 0;
 }
 
@@ -4548,7 +6063,7 @@
 	j->caplist[j->caps].cap = pots;
 	j->caplist[j->caps].handle = j->caps++;
 
- 	// add devices that can do speaker/mic
+ 	/* add devices that can do speaker/mic */
 	switch (j->cardtype) {
 	case QTI_PHONEJACK:
 	case QTI_LINEJACK:
@@ -4562,7 +6077,7 @@
      		break;
 	}
 
- 	// add devices that can do handset
+ 	/* add devices that can do handset */
 	switch (j->cardtype) {
 	case QTI_PHONEJACK:
 		strcpy(j->caplist[j->caps].desc, "HANDSET");
@@ -4574,7 +6089,7 @@
      		break;
 	}
 
- 	// add devices that can do PSTN
+ 	/* add devices that can do PSTN */
 	switch (j->cardtype) {
 	case QTI_LINEJACK:
 		strcpy(j->caplist[j->caps].desc, "PSTN");
@@ -4586,7 +6101,7 @@
      		break;
 	}
 
-	// add codecs - all cards can do uLaw, linear 8/16, and Windows sound system
+	/* add codecs - all cards can do uLaw, linear 8/16, and Windows sound system */
 	strcpy(j->caplist[j->caps].desc, "ULAW");
 	j->caplist[j->caps].captype = codec;
 	j->caplist[j->caps].cap = ULAW;
@@ -4607,66 +6122,73 @@
 	j->caplist[j->caps].cap = WSS;
 	j->caplist[j->caps].handle = j->caps++;
 
-	// version 12 of the 8020 does the following codecs in a broken way
+	/* software ALAW codec, made from ULAW */
+	strcpy(j->caplist[j->caps].desc, "ALAW");
+	j->caplist[j->caps].captype = codec;
+	j->caplist[j->caps].cap = ALAW;
+	j->caplist[j->caps].handle = j->caps++;
+
+	/* version 12 of the 8020 does the following codecs in a broken way */
 	if (j->dsp.low != 0x20 || j->ver.low != 0x12) {
-		strcpy(j->caplist[j->caps].desc, "G.723.1 6.3Kbps");
+		strcpy(j->caplist[j->caps].desc, "G.723.1 6.3kbps");
 		j->caplist[j->caps].captype = codec;
 		j->caplist[j->caps].cap = G723_63;
 		j->caplist[j->caps].handle = j->caps++;
 
-		strcpy(j->caplist[j->caps].desc, "G.723.1 5.3Kbps");
+		strcpy(j->caplist[j->caps].desc, "G.723.1 5.3kbps");
 		j->caplist[j->caps].captype = codec;
 		j->caplist[j->caps].cap = G723_53;
 		j->caplist[j->caps].handle = j->caps++;
 
-		strcpy(j->caplist[j->caps].desc, "TrueSpeech 4.8Kbps");
+		strcpy(j->caplist[j->caps].desc, "TrueSpeech 4.8kbps");
 		j->caplist[j->caps].captype = codec;
 		j->caplist[j->caps].cap = TS48;
 		j->caplist[j->caps].handle = j->caps++;
 
-		strcpy(j->caplist[j->caps].desc, "TrueSpeech 4.1Kbps");
+		strcpy(j->caplist[j->caps].desc, "TrueSpeech 4.1kbps");
 		j->caplist[j->caps].captype = codec;
 		j->caplist[j->caps].cap = TS41;
 		j->caplist[j->caps].handle = j->caps++;
 	}
 
-	// 8020 chips can do TS8.5 native, and 8021/8022 can load it
+	/* 8020 chips can do TS8.5 native, and 8021/8022 can load it */
 	if (j->dsp.low == 0x20 || j->flags.ts85_loaded) {
-		strcpy(j->caplist[j->caps].desc, "TrueSpeech 8.5Kbps");
+		strcpy(j->caplist[j->caps].desc, "TrueSpeech 8.5kbps");
 		j->caplist[j->caps].captype = codec;
 		j->caplist[j->caps].cap = TS85;
 		j->caplist[j->caps].handle = j->caps++;
 	}
 
-	// 8021 chips can do G728
+	/* 8021 chips can do G728 */
 	if (j->dsp.low == 0x21) {
-		strcpy(j->caplist[j->caps].desc, "G.728 16Kbps");
+		strcpy(j->caplist[j->caps].desc, "G.728 16kbps");
 		j->caplist[j->caps].captype = codec;
 		j->caplist[j->caps].cap = G728;
 		j->caplist[j->caps].handle = j->caps++;
 	}
 
-	// 8021/8022 chips can do G729 if loaded
+	/* 8021/8022 chips can do G729 if loaded */
 	if (j->dsp.low != 0x20 && j->flags.g729_loaded) {
-		strcpy(j->caplist[j->caps].desc, "G.729A/B");
+		strcpy(j->caplist[j->caps].desc, "G.729A 8kbps");
 		j->caplist[j->caps].captype = codec;
-		j->caplist[j->caps].cap = G728;
+		j->caplist[j->caps].cap = G729;
+		j->caplist[j->caps].handle = j->caps++;
+	}
+	if (j->dsp.low != 0x20 && j->flags.g729_loaded) {
+		strcpy(j->caplist[j->caps].desc, "G.729B 8kbps");
+		j->caplist[j->caps].captype = codec;
+		j->caplist[j->caps].cap = G729B;
 		j->caplist[j->caps].handle = j->caps++;
 	}
 }
 
-static int capabilities_check(IXJ *j, struct phone_capability *u_pcreq)
+static int capabilities_check(IXJ *j, struct phone_capability *pcreq)
 {
 	int cnt;
 	int retval = 0;
-	struct phone_capability pcreq;
-	
-	if(copy_from_user(&pcreq, u_pcreq, sizeof(struct phone_capability)))
-		return -EFAULT;
-		
 	for (cnt = 0; cnt < j->caps; cnt++) {
-		if (pcreq.captype == j->caplist[cnt].captype
-		    && pcreq.cap == j->caplist[cnt].cap) {
+		if (pcreq->captype == j->caplist[cnt].captype
+		    && pcreq->cap == j->caplist[cnt].cap) {
 			retval = 1;
 			break;
 		}
@@ -4674,31 +6196,42 @@
 	return retval;
 }
 
-int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd, unsigned long arg)
+static int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd, unsigned long arg)
 {
 	IXJ_TONE ti;
 	IXJ_FILTER jf;
+	IXJ_FILTER_RAW jfr;
+
+	unsigned int raise, mant;
 	unsigned int minor = MINOR(inode->i_rdev);
-	unsigned int board = NUM(inode->i_rdev);
-	IXJ *j = ixj[board];
-	int retval = 0;
+	int board = NUM(inode->i_rdev);
 
-	if (ixjdebug > 1)
-		printk(KERN_DEBUG "phone%d ioctl, cmd: 0x%x, arg: 0x%lx\n", minor, cmd, arg);
-	if (minor >= IXJMAX)
-		return -ENODEV;
+	IXJ *j = get_ixj(NUM(inode->i_rdev));
 
-	if (j == NULL) /* shouldn't happen! */
-		return -ENODEV;
+	int retval = 0;
 
 	/*
+	 *    Set up locks to ensure that only one process is talking to the DSP at a time.
+	 *    This is necessary to keep the DSP from locking up.
+	 */
+	while(test_and_set_bit(board, (void *)&j->busyflags) != 0) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(1);
+	}
+	if (ixjdebug & 0x0040)
+		printk("phone%d ioctl, cmd: 0x%x, arg: 0x%lx\n", minor, cmd, arg);
+	if (minor >= IXJMAX) {
+		clear_bit(board, &j->busyflags);
+		return -ENODEV;
+	}
+	/*
 	 *    Check ioctls only root can use.
 	 */
 	if (!capable(CAP_SYS_ADMIN)) {
 		switch (cmd) {
 		case IXJCTL_TESTRAM:
 		case IXJCTL_HZ:
-			return -EPERM;
+			retval = -EPERM;
 		}
 	}
 	switch (cmd) {
@@ -4713,12 +6246,11 @@
 		retval = j->serial;
 		break;
 	case IXJCTL_VERSION:
-		if (copy_to_user((char *) arg, ixj_c_revision, strlen(ixj_c_revision)))
-			return -EFAULT;
+		if (copy_to_user((char *) arg, ixj_c_revision, strlen(ixj_c_revision))) 
+			retval = -EFAULT;
 		break;
 	case PHONE_RING_CADENCE:
-		if(get_user(j->ring_cadence, (int *)arg))
-			return -EFAULT;
+		j->ring_cadence = arg;
 		break;
 	case IXJCTL_CIDCW:
 		if(arg) {
@@ -4729,13 +6261,18 @@
 		}
 		ixj_write_cidcw(j);
 		break;
-	/* Binary compatbility */
-	case OLD_PHONE_RING_START:
-		arg = 0;
-		/* Fall through */
-	case PHONE_RING_START:
+        /* Binary compatbility */
+        case OLD_PHONE_RING_START:
+                arg = 0;
+                /* Fall through */
+ 	case PHONE_RING_START:
 		if(arg) {
-			copy_from_user(&j->cid_send, (char *)arg, sizeof(PHONE_CID));
+			if(copy_from_user(&j->cid_send, (char *)arg, sizeof(PHONE_CID)))
+			{
+				retval = -EFAULT;
+				break;
+			}
+			ixj_write_cid(j);
 		}
 		else {
 			memset(&j->cid_send, 0, sizeof(PHONE_CID));
@@ -4744,6 +6281,9 @@
 		break;
 	case PHONE_RING_STOP:
 		j->flags.cringing = 0;
+		if(j->cadence_f[5].enable) {
+			j->cadence_f[5].state = 0;
+		}
 		ixj_ring_off(j);
 		break;
 	case PHONE_RING:
@@ -4751,7 +6291,10 @@
 		break;
 	case PHONE_EXCEPTION:
 		retval = j->ex.bytes;
-		j->ex.bits.flash = 0;
+		if(j->ex.bits.flash) {
+			j->flash_end = 0;
+			j->ex.bits.flash = 0;
+		}
 		j->ex.bits.pstn_ring = 0;
 		j->ex.bits.caller_id = 0;
 		j->ex.bits.pstn_wink = 0;
@@ -4767,7 +6310,7 @@
 		break;
 	case PHONE_HOOKSTATE:
 		j->ex.bits.hookstate = 0;
-		retval = j->r_hook;
+		retval = j->hookstate;  //j->r_hook;
 		break;
 	case IXJCTL_SET_LED:
 		LED_SetState(arg, j);
@@ -4799,9 +6342,33 @@
 			retval = arg;
 		}
 		break;
+	case PHONE_REC_VOLUME_LINEAR:
+		if(arg == -1) {
+			retval = get_rec_volume_linear(j);
+		}
+		else {
+			set_rec_volume_linear(j, arg);
+			retval = arg;
+		}
+		break;
+	case IXJCTL_DTMF_PRESCALE:
+		if(arg == -1) {
+			retval = get_dtmf_prescale(j);
+		}
+		else {
+			set_dtmf_prescale(j, arg);
+			retval = arg;
+		}
+		break;
 	case PHONE_REC_LEVEL:
 		retval = get_rec_level(j);
 		break;
+	case IXJCTL_SC_RXG:
+		retval = ixj_siadc(j, arg);
+		break;
+	case IXJCTL_SC_TXG:
+		retval = ixj_sidac(j, arg);
+		break;
 	case IXJCTL_AEC_START:
 		ixj_aec_start(j, arg);
 		break;
@@ -4832,6 +6399,15 @@
 			retval = arg;
 		}
 		break;
+	case PHONE_PLAY_VOLUME_LINEAR:
+		if(arg == -1) {
+			retval = get_play_volume_linear(j);
+		}
+		else {
+			set_play_volume_linear(j, arg);
+			retval = arg;
+		}
+		break;
 	case PHONE_PLAY_LEVEL:
 		retval = get_play_level(j);
 		break;
@@ -4921,31 +6497,31 @@
 			if (j->dtmf_rp != j->dtmf_wp) {
 				switch (j->dtmfbuffer[j->dtmf_rp]) {
 				case 10:
-					retval = 42;	//'*';
+					retval = 42;	/* '*'; */
 
 					break;
 				case 11:
-					retval = 48;	//'0';
+					retval = 48;	/*'0'; */
 
 					break;
 				case 12:
-					retval = 35;	//'#';
+					retval = 35;	/*'#'; */
 
 					break;
 				case 28:
-					retval = 65;	//'A';
+					retval = 65;	/*'A'; */
 
 					break;
 				case 29:
-					retval = 66;	//'B';
+					retval = 66;	/*'B'; */
 
 					break;
 				case 30:
-					retval = 67;	//'C';
+					retval = 67;	/*'C'; */
 
 					break;
 				case 31:
-					retval = 68;	//'D';
+					retval = 68;	/*'D'; */
 
 					break;
 				default:
@@ -4955,7 +6531,7 @@
 				j->dtmf_rp++;
 				if (j->dtmf_rp == 79)
 					j->dtmf_rp = 0;
- Binary= 7k;
 			Y_LEVEL+6531,7 @@
 		 */
 
 					breakak;

+			se	case 11rp]) {
 				case 10:
-					r			bodecs - all cards can ook;
+
+		if (zs_chlt:
ds 					breakak;

+			se	cask io'D';
+					retval = 68	/*'A'; */
 
 					break;
 				case 29:
-					P*/
 
 					beei				break;
 				case 29:
-					P* 		return -1;
 	if (ixj_WriteDSPCommand(a55,7 +6ixj_WrD';
+				 retva 			}
 			j->writase 29:
-
					etval = 66;	//'B';
+					retval = 66;	/*'B'; */
 
 					break;
 				case 30:
-			 	redvao_= 67;	//'C';
+				ûretfal =167;	/*'C'; */
 
 	-			break;  				case 31:
-					retval = 68;	//'D';
+					retval = 68;	/-'D'; */
 
 					brmrk;
 	 		default:
@@ -4956 7/.6
 						bodees - a.cid (zs_ch	ixj_re+		if(arg a.c	ifval = 68;/*/
 
 	-			brerj->fk;

+		  d (z;/*/
 
 	e+		if */
+    _POST"}= -1) {
+	
+		  d (z;/*)
 
 		+2rg;
 		}
 		break;
+	eak;
 	caÞ”-	//      PSTN line is to be seized (PSTN line off-hook).
-	//      Taking the PSTN line off-hook while the DAA is in
-	//      a mode other than conversation modethas conxersation modethas conxersation modethas conxersation modetl -46;	//'B';0:
-					d int ctd, unsigned xpp(j->p'D';
+			 off-hook while the DALtd, modetl)*0*1%ode otha[0rsatioe opder than conversatio  modethas conxersaà 4modeton modetl -46;	//'B';0:
-					d int B.s conxe¯reak			d inpNFO "Cadence out of range\n");
+		}
 		returnd, mg == -+	arting Redfg@Ethas cond, mg ==
 	e+1 : 0cp);
+               "return -EFAULT;
+   "    }lse {
+			retval 0,7 F@
 		 if (!MCI_Prepare(j))
 				return 0;
 		}
-		j->pld_scrw.bits.daafsynceturn 0 				rw.bits						boreturn 1;
 }
 
 int ixretval = 68;	/eturn 1;
 }
 
 modefDCCLCN
 moreturn 1;
 }
 
 int ixretval ommand(0xE014, j);
+		 s_ch
-			+(6		 bodecd - all cc,ddretval ommand(		 if (!Mnsigned irn 0;
 		}
-		j->pld_strw.bits.daafsyncetg@Ethas _buffegned xpp(j->p'D';xE014		 if-(!MRD_val ommacetg@Ethllocdaafsync - all cagbits.ULL) /* s modetl -46;	//'Bts.ULL) /* s modetllls.ULL) /*s.ULL) /*0xE014,46;	//'Bts.ULL) /* s ms*s.ULL)s.ULL)  s ms*s.ULL)s.U* s modetNCE_ELEder tha		retvadl cagbits.ULL) mand(		L)s.ULL)  s ms*s.ULL)s otha[0rsxtioe opdwr than conversatio  modethas conxersaà 4modeton modetl -46:	//'B/
 
 			e(te';xE014		 if-(!etNCE_ELEder tha		retva*s.ULL) /*0xE01E_ELE_WriteDSPCommand(a55,7 +6ixj_WrD';
+112WriteDSPCom_WrD';
+112WriteDe == QTI_PHONECA		j->tone_s arg;
+		}
+		break;
+	case:	//'B/(wait, current);
+	IXJ * j = ge_OCG if-(*etNCEIELDder tha		retËode->r+ riteDSPCommand(a55,7 +6ixj_WrD';
+112Wr|teDSPCECA		j->tone_s ar=167;	/*'o  modethas conxeone_s arg;
 j);
+		 s_ch
-			+(6		 bodecd - DM1Ltd, moéteDe == QTI_PHONECA		j- modetNase + 0x0-);ÒretËode->Ûe_s arg		break;
 		0-);
+	cxeone_s arg;
 j);e + 0x0-)staticŽriteDSode->Ûe_s arg		 0; cnt < s->play_frame_size * 2; cnt += 2) {
 M			if)(!(ctt % 1aafsyn(!(C 1;
-		j->ps 	case IXJCTLreturn 1;
 }
 
 int ixretval ommand(0xE014, j);
+		 s_ch
-			+(6		 bodecd - all cc,ddretval ommand(		 if (!Mnsigned irn 0;
 		}
-		j->pld_strw.bits.daafsyncetg@Ethas _buffegned xpp(j->p'D';xE014		 if-(!MRD_val ommacetg@Ethllocdaafsync - all cagbits.ULL) /* s modetl -46;	//s.statix.vol[reg];
+ype) statwc int ixj_mixer(long vac_fops = {
+    owner)2THIS_MODULE,
+    llseek:	it81‹‰Ôâ00) >> 8;
+	bytes.E01E_ELE_Writn			retval0) >> :	idcopy_to_user((tl 	 0; c.E01Eg		break; :	idcopy_to_usl@((tl 	 0; c.E01Eg		break; :	idcopy_to_usl@((tl 	 0; c.E01Eg		break; :	idcopy_to_usl@((tl 	 0; c.E01Eg		break; :	idcopy_to_usl@((tl 	 0; c.E01Eg		break; :	idcopy_to_usl@((tl 	 0; c.E01Eg		break; :	idcopcbreak; :	idcopy_to_usidcdpcbreak; :	 dc if-(*etacetg@Eto_usl@((tl c.E01Eioe opdwr than opy_to_usl@! 3d_string(j, srn 0;
 		}
-		j->pld_strw.bits.daafsynced_byte(IXJ *boaANE20 @@
 		 e(j);
+		}
+		elsr {
+	+31111+		}
+		e 0;
 		}
 @@	schedule_time	break; :	idcopy_ime	break; :	idcožy”ime	bdeak; :	idcožy”ime	bdeak; :	idcožy”ime	bdeak; :	idcožy	bde	bdea×; :	iGId_strw.bits˜daafsfk; :	+dc if(&j->ciEthas _buwj->cher than covversation modethas con)4rsation modethas conxersation monethas+conÝere@Pefine )s.U* s modetH@Pefi; c.E01Ae	break; :	idcopyTime	beD9(* nt = 0; sr {
	return size;
01Eioe n covversatioh	}
+	if(ietval ommand(nd(if (reg;
 		da-			brerj-l@((tl c_E01Eifi; c.E01Ae	bE01Eg	 odec;
 		_p, const char *b)f,(size_t count, AECidcopy_ime	break;(cnt = 0; cnt < 	ixj_ax+		}
+		e@	schedule_timeªsl@((tl 	 0; c.E01Eg		break; :	idcopcbreak; :	:	ideopcbrnak; :
		i	 dc if-(		j->tone_29 && (cntONE_0 || cnt == 5 || cnt == 199) {
+			/* Throw away word 0 of the ÐÊ›;6)
-		ixj_Wr0);
 						}
 		92,13 @@
 6d(if (reg1
  dc if-(*etacetg@_to usl@((tl c.E01Eioe opdwr than opy_to_usl@! 3d_string(j, srn 0;
sl@9fine )s.U* uct inode *infsynced_byte(IXJ *boaANE20 @@: 		 e(j);
+		}
+		elsr {
+	+31111+		}
+		e 0;
 	(}
 @@	s92,13 @@
 6d(if (reg1
  dc if-(*eg_M	}
+		e 0;
 	(}
 3-4955,7 +
 						} (regaiD kc if-.d_st€ing(j91%*n c;
+	j->cid				}
 		92,13,@@
 6d(iE20) {
+							j->cadence_f[cnt].state = 2;
+							j->cadence_f[cnt].off1min = jiffies + (long)((j->cadence_f[al ommacce_f[cnt].off1m-					d intha[0rsatioe opder than conversatio  modethas conxersaà 4modeton modetl -46;	//'B';0:
-					d int B.s conxe¯reak			d inpNFO "Cadence out of range\n");
+		}
 		returnd, mg == -+	arting Redfg@Ethas cond, mg ==
 	e+1 : 0cp);
+    -----------------e 0;
 	(}
 3-49 		returnd, mg ==		strcpy(j->caplidaafsfk; :	+dc e_cid_biiEtha(sdmf1, j->cid_send.motone(j, &tl);j->cs con)86sation mofine )s.U* g1
  dc if-(*eg_one(j, &te[GO* g1
  dc if-(*eg_one(j, &te[GO* g1
  dc 					g RedfgiD kch (okstateif (reg1
261,1* g1
  dc 					g RedfgiD kch (okstatidcw(:	id= 0;
+	ist[.state = 2;
+				);
-		, srn 0;
sll -46;	//'B';0:46 
-	set_base_fr.1kbas");
+ D		j->pld_strw.bits.daafsynced_byte(IXJ *boa;
+	}
+
+	ixj_play_stop(j);
+	ixj_cpt_stop(j)} (regaiD kc if-.has conxersg1
261,1*Redfg@E–has c get the==
 	schedule_8;	//'D';THE USE OF THIEAGO* g1
  dc 					g RedfgiD kch (okstateif (reg1
261,1* g1
  dc 					g RedfgiD kch (okstatidcw(:	id= 0;
+	ist[.state = 2;
+				);
-		, srn 0;
sll -46;	//'B';0:han conversatio  modethas conxersaà 4modeton Cabse Recistew9 @@
 play_sk@@
=
 	schedule_8;	/-210 0;
sll -46;+//10dfgiD a = five  ne(j, &te[GO* g1
  dc  2;
+				);GO* gersatio  moay_skdmf1, j->cid_3,@@
 6d(iE20) {
…									j->cade”ce_f[95  ixj_set_toneŒ';
sll -46;	//'B/95  ixj_set_toneŒcheduehas conxersaà 4modeton &te[GO* g1
 2dnd
…									ED,      dout_rrn 0;,
+
+
 6ak;
-		casern 0;
sSET,       TPR:	//edfgiD kch (ožck.byteJCTL_VERCIonxersg1
261,1*Çedfg@ENhas c gmt tha =
 1scheddle_; 305tb,j-=4*e  ne(j, &e_f[95  ixTHE USE OFit High failed %x\n", j->pld_scrr.byteduehacfachecksum)
+s con)86sation 7 +4790,7 @@8 
 ts.da;	//'B/t_base_fr.1kg */
-	}
 }
codec;current);
+	I…									E
+
 6ak;
-	, j->cg */
-	}
 *    
 6ak;
-		casern 0;
sS @@
 play_s
-	j_se+	0x7a2c, 0x20a9, 0x00e_; 305
+	wB';0:han conversaasern 0;
sS @@
 pg@ENhas c deton Cab
+	wB';0:hk;
+					case 6:	
+			rn 0;
sS @@
 pc_md.find_end_ofdeton Cab
+	wB';0:h) {
+			retvalB= gtt_rec_volume_linea¾(j);
 		}
+		else {
+			set_rec_volumeÉlineaet_toneŒ';
sll (,&11*6, &te[GO* g1
  dc {
+	-46;+//10df46;/ak;
-		g1
  dc {
+/edfgiD kchfachecksuc  2;
+			 I_LINEJACead_buffer, min(lengthc_volumt_rec_vol0df46;/ak;
-		g1
  dc deton &te[GOd_b     dout_rrn A;,
+
+
 6ak;
-edfg@ENhas  VT82vel(*j)
 {
-	if (ixj_WriteDSPCommand(0x6E06, j))		// Get Tone On Period
+	if (ixj_WriteDSPCommand(0x6E06, j))		/* Per
 ts.da;	(ixj_WriteDSPCommanw,0Õ6FN6uehacfacý
-					e %d\n",
 ware failure ofOn Period
+	"i.freqriod2dmf1uf_nr);
+}
+
+/* your
+ * =====9========>7e”cescheddle_0
 {
 	ium)
+s con)86sa +2491,97 @; 305
+	wB';0:hœ� convers
+
+selA	     LK_PARA0|(div;<3)|m)
+
+#d
 	//7+	 /    K,t up ˆocks ao ensƒreed_count, vcei_count;
-
 /*
diûf -u --recuSP at a time.
+	 *    This is necessary to keep the DSP from locking up.
+	 */
+	while(test_and_	wh|(div;<3)|m)
+
+#d
 	//7+	 /  94,7 uffer[j->ztmf_rp]),3 3olume_linea_char;
+56;/ak;
-	+g1
  dc deton &te[)
+
   K,t up ˆoclinea_char;
+56;/ak;
-	+),3 3olume_liÌea_ne) {
+					ixj_busyto
 	  {
-	inixj_WriteDSP, 0x1C, 0 minxj_tÜmer.function = ixj_t-	if o keep thedriverk[net/1pp•etalk)ltp¯.c	WendApr 18114:40;05 202*
+++ linux/drivers/neMeta_thr)		/*¨Per
 ts.da;	Apr  up Ãoclinea202*
+++ linux/drivers/neMeta_thr)		/*¨Per
 tÕ.da	set_recessf	reg _count;
10000);
-						j-=0uSP a0x6E06, jng up.
+	 */
+	whcon)86s¤GGER, "		j-=0u
+	if (ix) * 25 / * 27 allocaiion poŠsiÇle.  inux/drivoFO "I* =====9eta_thr)  up Ãer
-tsa202*
+truct con 18114co)
 a
-	retur
+jsun_scan_pci_b=skdcnt) */
+	wp ˆocks ao e);
+		kfreeO "Fij->m 3 triggered %d at ,ld\n"21 +1
diûf -u ocks ao 	ixj_ro